/* lkrloc.c */
/*
* Copyright (C) 1989-2009 Alan R. Baldwin
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*
*
* Alan R. Baldwin
* 721 Berkeley St.
* Kent, Ohio 44240
*
* With enhancements from:
*
* John L. Hartman (JLH)
* jhartman@compuserve.com
*
* Bill McKinnon (BM)
* w_mckinnon@conknet.com
*/
#include
#include "aslink.h"
/*)Module lkrloc.c
*
* The module lkrloc.c contains the functions which
* perform the relocation calculations.
*
* lkrloc.c contains the following functions:
* a_uint adb_1b()
* a_uint adb_2b()
* a_uint adb_3b()
* a_uint adb_4b()
* a_uint adb_xb()
* a_uint evword()
* VOID prntval()
* VOID reloc()
*
*
*/
/*)Function VOID reloc(c)
*
* int c process code
*
* The function reloc() calls the proper version
* of the linker code.
*
* local variable:
* none
*
* global variables:
* ASxxxx_VERSION ASxxxx REL file version
*
* called functions:
* VOID reloc3() lkrloc3.c
* VOID reloc4() lkrloc4.c
*
* side effects:
* Refer to the called relocation functions.
*
*/
VOID
reloc(int c)
{
switch(ASxxxx_VERSION) {
case 3:
reloc3(c);
break;
// case 4:
// reloc4(c);
// break;
default:
fprintf(stderr, "Internal Version Error");
lkexit(ER_FATAL);
break;
}
}
/*)Function a_uint evword()
*
* The function evword() combines two byte values
* into a single word value.
*
* local variable:
* a_uint v temporary evaluation variable
*
* global variables:
* hilo byte ordering parameter
*
* called functions:
* int eval() lkeval.c
*
* side effects:
* Relocation text line is scanned to combine
* two byte values into a single word value.
*
*/
a_uint
evword(void)
{
a_uint v;
if (hilo) {
v = (eval() << 8);
v += eval();
} else {
v = eval();
v += (eval() << 8);
}
return(v);
}
/*)Function a_uint adb_1b(v, i)
*
* a_uint v value to add to byte
* int i rtval[] index
*
* The function adb_1b() adds the value of v to
* the single byte value contained in rtval[i].
* The new value of rtval[i] is returned.
*
* local variable:
* a_uint j temporary evaluation variable
*
* global variables:
* none
*
* called functions:
* none
*
* side effects:
* The byte value of rtval[] is changed.
*
*/
a_uint
adb_1b(a_uint v, int i)
{
a_uint j;
j = v + rtval[i];
rtval[i] = j & ((a_uint) 0x000000FF);
return(j);
}
/*)Function a_uint adb_2b(v, i)
*
* a_uint v value to add to word
* int i rtval[] index
*
* The function adb_2b() adds the value of v to the
* 2 byte value contained in rtval[i] and rtval[i+1].
* The new value of rtval[i] / rtval[i+1] is returned.
*
* local variable:
* a_uint j temporary evaluation variable
*
* global variables:
* hilo byte ordering parameter
*
* called functions:
* none
*
* side effects:
* The 2 byte value of rtval[] is changed.
*
*/
a_uint
adb_2b(a_uint v, int i)
{
a_uint j;
if (hilo) {
j = v + (rtval[i+0] << 8) +
(rtval[i+1] << 0);
rtval[i+0] = (j >> 8) & ((a_uint) 0x000000FF);
rtval[i+1] = (j >> 0) & ((a_uint) 0x000000FF);
} else {
j = v + (rtval[i+0] << 0) +
(rtval[i+1] << 8);
rtval[i+0] = (j >> 0) & ((a_uint) 0x000000FF);
rtval[i+1] = (j >> 8) & ((a_uint) 0x000000FF);
}
return(j);
}
/*)Function a_uint adb_3b(v, i)
*
* a_uint v value to add to word
* int i rtval[] index
*
* The function adb_3b() adds the value of v to the
* three byte value contained in rtval[i], rtval[i+1], and rtval[i+2].
* The new value of rtval[i] / rtval[i+1] / rtval[i+2] is returned.
*
* local variable:
* a_uint j temporary evaluation variable
*
* global variables:
* hilo byte ordering parameter
*
* called functions:
* none
*
* side effects:
* The 3 byte value of rtval[] is changed.
*
*/
a_uint
adb_3b(a_uint v, int i)
{
a_uint j;
if (hilo) {
j = v + (rtval[i+0] << 16) +
(rtval[i+1] << 8) +
(rtval[i+2] << 0);
rtval[i+0] = (j >> 16) & ((a_uint) 0x000000FF);
rtval[i+1] = (j >> 8) & ((a_uint) 0x000000FF);
rtval[i+2] = (j >> 0) & ((a_uint) 0x000000FF);
} else {
j = v + (rtval[i+0] << 0) +
(rtval[i+1] << 8) +
(rtval[i+2] << 16);
rtval[i+0] = (j >> 0) & ((a_uint) 0x000000FF);
rtval[i+1] = (j >> 8) & ((a_uint) 0x000000FF);
rtval[i+2] = (j >> 16) & ((a_uint) 0x000000FF);
}
return(j);
}
/*)Function a_uint adb_4b(v, i)
*
* a_uint v value to add to word
* int i rtval[] index
*
* The function adb_4b() adds the value of v to the
* four byte value contained in rtval[i], ..., rtval[i+3].
* The new value of rtval[i], ..., rtval[i+3] is returned.
*
* local variable:
* a_uint j temporary evaluation variable
*
* global variables:
* hilo byte ordering parameter
*
* called functions:
* none
*
* side effects:
* The 4 byte value of rtval[] is changed.
*
*/
a_uint
adb_4b(a_uint v, int i)
{
a_uint j;
if (hilo) {
j = v + (rtval[i+0] << 24) +
(rtval[i+1] << 16) +
(rtval[i+2] << 8) +
(rtval[i+3] << 0);
rtval[i+0] = (j >> 24) & ((a_uint) 0x000000FF);
rtval[i+1] = (j >> 16) & ((a_uint) 0x000000FF);
rtval[i+2] = (j >> 8) & ((a_uint) 0x000000FF);
rtval[i+3] = (j >> 0) & ((a_uint) 0x000000FF);
} else {
j = v + (rtval[i+0] << 0) +
(rtval[i+1] << 8) +
(rtval[i+2] << 16) +
(rtval[i+3] << 24);
rtval[i+0] = (j >> 0) & ((a_uint) 0x000000FF);
rtval[i+1] = (j >> 8) & ((a_uint) 0x000000FF);
rtval[i+2] = (j >> 16) & ((a_uint) 0x000000FF);
rtval[i+3] = (j >> 24) & ((a_uint) 0x000000FF);
}
return(j);
}
/*)Function a_uint adb_xb(v, i)
*
* a_uint v value to add to x-bytes
* int i rtval[] index
*
* The function adb_xb() adds the value of v to
* the value contained in rtval[i] for x-bytes.
* The new value of rtval[i] for x-bytes is returned.
*
* local variable:
* none
*
* global variables:
* int a_bytes T Line Address Bytes
*
* called functions:
* a_uint adb_1b() lkrloc.c
* a_uint adb_2b() lkrloc.c
* a_uint adb_3b() lkrloc.c
* a_uint adb_4b() lkrloc.c
*
* side effects:
* The x-byte value of rtval[] is changed.
*
*/
a_uint
adb_xb(a_uint v, int i)
{
a_uint j;
switch(a_bytes){
case 1:
j = adb_1b(v, i);
j = (j & ((a_uint) 0x00000080) ? j | ~((a_uint) 0x0000007F) : j & ((a_uint) 0x0000007F));
break;
case 2:
j = adb_2b(v, i);
j = (j & ((a_uint) 0x00008000) ? j | ~((a_uint) 0x00007FFF) : j & ((a_uint) 0x00007FFF));
break;
case 3:
j = adb_3b(v, i);
j = (j & ((a_uint) 0x00800000) ? j | ~((a_uint) 0x007FFFFF) : j & ((a_uint) 0x007FFFFF));
break;
case 4:
j = adb_4b(v, i);
j = (j & ((a_uint) 0x80000000) ? j | ~((a_uint) 0x7FFFFFFF) : j & ((a_uint) 0x7FFFFFFF));
break;
default:
j = 0;
break;
}
return(j);
}
/*)Function VOID prntval(fptr, v)
*
* FILE *fptr output file handle
* a_uint v value to output
*
* The function prntval() outputs the value v, in the
* currently selected radix, to the device specified
* by fptr.
*
* local variable:
* none
*
* global variables:
* int xflag current radix
*
* called functions:
* int fprintf() c_library
*
* side effects:
* none
*
*/
VOID
prntval(FILE *fptr, a_uint v)
{
char *frmt;
switch(xflag) {
default:
case 0:
switch(a_bytes) {
default:
case 2: frmt = " %04X\n"; break;
case 3: frmt = " %06X\n"; break;
case 4: frmt = " %08X\n"; break;
}
break;
case 1:
switch(a_bytes) {
default:
case 2: frmt = " %06o\n"; break;
case 3: frmt = " %08o\n"; break;
case 4: frmt = "%011o\n"; break;
}
break;
case 2:
switch(a_bytes) {
default:
case 2: frmt = " %05u\n"; break;
case 3: frmt = " %08u\n"; break;
case 4: frmt = " %010u\n"; break;
}
break;
}
fprintf(fptr, frmt, v & a_mask);
}