4 * (C) Copyright 1989-1995
12 * - errdmp: show s_id as string rather than array [NCPS]
13 * - relr: add support for 11 bit 8051 addressing
14 * 02-Apr-98 JLH: don't output empty hex records
19 #if !defined(_MSC_VER)
26 * The module lkrloc.c contains the functions which
27 * perform the relocation calculations.
29 * lkrloc.c contains the following functions:
48 * lkrloc.c the local variable errmsg[].
52 /* Global which holds the upper 16 bits of the last 32 bit area adress
53 * output. Useful only for iHex mode.
55 int lastExtendedAddress;
57 /*)Function VOID reloc(c)
61 * The function reloc() calls a particular relocation
62 * function determined by the process code.
68 * int lkerr error flag
71 * int fprintf() c_library
72 * VOID rele() lkrloc.c
73 * VOID relp() lkrloc.c
74 * VOID relr() lkrloc.c
75 * VOId relt() lkrloc.c
78 * Refer to the called relocation functions.
105 fprintf(stderr, "Undefined Relocation Operation\n");
113 /*)Function VOID relt()
115 * The function relt() evaluates a T line read by
116 * the linker. Each byte value read is saved in the
117 * rtval[] array, rtflg[] is set, and the number of
118 * evaluations is maintained in rtcnt.
122 * T xx xx nn nn nn nn nn ...
125 * In: "T n0 n1 n2 n3 ... nn"
127 * Out: 0 1 2 .. rtcnt
128 * +----+----+----+----+----+
129 * rtval | n0 | n1 | n2 | .. | nn |
130 * +----+----+----+----+----+
131 * rtflag| 1 | 1 | 1 | 1 | 1 |
132 * +----+----+----+----+----+
134 * The T line contains the assembled code output by the assem-
135 * bler with xx xx being the offset address from the current area
136 * base address and nn being the assembled instructions and data in
143 * int rtcnt number of values evaluated
144 * int rtflg[] array of evaluation flags
145 * int rtval[] array of evaluation values
148 * int eval() lkeval.c
152 * Linker input T line evaluated.
162 rtval[rtcnt] = eval();
169 /*)Function VOID relr()
171 * The function relr() evaluates a R line read by
172 * the linker. The R line data is combined with the
173 * previous T line data to perform the relocation of
174 * code and data bytes. The S19 / IHX output and
175 * translation of the LST files to RST files may be
180 * R 0 0 nn nn n1 n2 xx xx ...
182 * The R line provides the relocation information to the linker.
183 * The nn nn value is the current area index, i.e. which area the
184 * current values were assembled. Relocation information is en-
185 * coded in groups of 4 bytes:
187 * 1. n1 is the relocation mode and object format
188 * 1. bit 0 word(0x00)/byte(0x01)
189 * 2. bit 1 relocatable area(0x00)/symbol(0x02)
190 * 3. bit 2 normal(0x00)/PC relative(0x04) relocation
191 * 4. bit 3 1-byte(0x00)/2-byte(0x08) object format for
193 * 5. bit 4 signed(0x00)/unsigned(0x10) byte data
194 * 6. bit 5 normal(0x00)/page '0'(0x20) reference
195 * 7. bit 6 normal(0x00)/page 'nnn'(0x40) reference
197 * 2. n2 is a byte index into the corresponding (i.e. pre-
198 * ceeding) T line data (i.e. a pointer to the data to be
199 * updated by the relocation). The T line data may be
200 * 1-byte or 2-byte byte data format or 2-byte word
203 * 3. xx xx is the area/symbol index for the area/symbol be-
204 * ing referenced. the corresponding area/symbol is found
205 * in the header area/symbol lists.
207 * The groups of 4 bytes are repeated for each item requiring relo-
208 * cation in the preceeding T line.
211 * areax **a pointer to array of area pointers
212 * int aindex area index
213 * char *errmsg[] array of pointers to error strings
214 * int error error code
215 * int lkerr error flag
216 * int mode relocation mode
217 * adrr_t paga paging base area address
218 * addr_t pags paging symbol address
219 * addr_t pc relocated base address
220 * addr_t r PCR relocation value
221 * addr_t reli relocation initial value
222 * addr_t relv relocation final value
223 * int rindex symbol / area index
224 * addr_t rtbase base code address
225 * addr_t rtofst rtval[] index offset
226 * int rtp index into T data
227 * sym **s pointer to array of symbol pointers
230 * head *hp pointer to the head structure
231 * rerr rerr linker error structure
232 * FILE *stderr standard error device
235 * addr_t adb_b() lkrloc.c
236 * addr_t adb_lo() lkrloc.c
237 * addr_t adb_hi() lkrloc.c
238 * addr_t adw_w() lkrloc.c
239 * addr_t evword() lkrloc.c
240 * int eval() lkeval.c
241 * int fprintf() c_library
243 * int lkulist lklist.c
245 * VOID relerr() lkrloc.c
247 * int symval() lksym.c
250 * The R and T lines are combined to produce
251 * relocated code and data. Output S19 / IHX
252 * and relocated listing files may be produced.
260 register addr_t reli, relv;
261 int aindex, rindex, rtp, error;
262 addr_t r, rtbase, rtofst, paga, pags, pc;
267 * Get area and symbol lists
275 if (eval() != (R_WORD | R_AREA) || eval()) {
276 fprintf(stderr, "R input error\n");
284 if (aindex >= hp->h_narea) {
285 fprintf(stderr, "R area error\n");
293 rtbase = adw_w(0, 0);
299 pc = adw_w(a[aindex]->a_addr, 0);
302 printf("area %d base address: 0x%x size: 0x%x rtbase: 0x%x\n", aindex,
303 a[aindex]->a_addr, a[aindex]->a_size, rtbase);
306 * Do remaining relocations
312 if ((mode & R_ESCAPE_MASK) == R_ESCAPE_MASK)
314 mode = ((mode & ~R_ESCAPE_MASK) << 8) | eval();
315 /* printf("unescaping rmode\n"); */
322 * R_SYM or R_AREA references
325 if (rindex >= hp->h_nglob) {
326 fprintf(stderr, "R symbol error\n");
330 reli = symval(s[rindex]);
332 if (rindex >= hp->h_narea) {
333 fprintf(stderr, "R area error\n");
337 reli = a[rindex]->a_addr;
345 reli -= (pc + (rtp-rtofst) + 1);
347 reli -= (pc + (rtp-rtofst) + 2);
352 * R_PAG0 or R_PAG addressing
354 if (mode & (R_PAG0 | R_PAG)) {
355 paga = sdp.s_area->a_addr;
361 * R_BYTE or R_WORD operation
366 /* This is a three byte address, of which
367 * we will select one byte.
371 /* printf("24 bit address selecting hi byte.\n"); */
372 relv = adb_24_hi(reli, rtp);
374 else if (mode & R_MSB)
376 /* Note that in 24 bit mode, R_MSB
377 * is really the middle byte, not
378 * the most significant byte.
380 * This is ugly and I can only apologize
383 /* printf("24 bit address selecting middle byte.\n"); */
384 relv = adb_24_mid(reli, rtp);
388 /* printf("24 bit address selecting lo byte.\n"); */
389 relv = adb_24_lo(reli, rtp);
392 else if (mode & R_BYT2) {
393 /* This is a two byte address, of
394 * which we will select one byte.
397 relv = adb_hi(reli, rtp);
399 relv = adb_lo(reli, rtp);
402 relv = adb_b(reli, rtp);
404 } else if (IS_R_J11(mode)) {
405 /* JLH: 11 bit jump destination for 8051. Forms
406 / two byte instruction with op-code bits
408 / rtp points at 3 byte locus: first two
409 / will get the instructiion. third one
413 /* Calculate absolute destination
414 / relv must be on same 2K page as pc
416 relv = adw_w(reli, rtp);
418 if ((relv & ~0x7ff) != ((pc + rtp - rtofst) & ~0x7ff)) {
422 /* Merge MSB (byte 0) with op-code, ignoring
423 / top 5 bits of address. Then hide the op-code
425 rtval[rtp] = ((rtval[rtp] & 0x07)<<5) | rtval[rtp+2];
429 else if (IS_R_J19(mode)) {
430 /* 19 bit jump destination for DS80C390. Forms
431 / three byte instruction with op-code bits
433 / rtp points at 4 byte locus: first three
434 / will get the instructiion. fourth one
438 /* Calculate absolute destination
439 / relv must be on same 512K page as pc
441 relv = adw_24(reli, rtp);
443 if ((relv & ~0x7ffff) != ((pc + rtp - rtofst) & ~0x7ffff)) {
447 /* Merge MSB (byte 0) with op-code, ignoring
448 / top 5 bits of address. Then hide the op-code
450 rtval[rtp] = ((rtval[rtp] & 0x07)<<5) | rtval[rtp+3];
454 else if (IS_C24(mode))
457 relv = adw_24(reli, rtp);
461 /* 16 bit address. */
462 relv = adw_w(reli, rtp);
466 * R_BYTE with R_BYT2 offset adjust
475 * Unsigned Byte Checking
477 if (mode & R_USGN && mode & R_BYTE && relv & ~0xFF)
481 * PCR Relocation Error Checking
483 if (mode & R_PCR && mode & R_BYTE) {
485 if (r != (addr_t) ~0x7F && r != 0)
490 * Page Relocation Error Checking
492 /* if (mode & R_PAG0 && (relv & ~0xFF || paga || pags))
494 if (mode & R_PAG && (relv & ~0xFF))
501 rerr.aindex = aindex;
503 rerr.rtbase = rtbase + rtp - rtofst - 1;
504 rerr.rindex = rindex;
505 rerr.rval = relv - reli;
506 relerr(errmsg[error-1]);
513 /* JLH: output only if data (beyond two byte address) */
514 if ((oflag == 1) && (rtcnt > 2)) {
515 int extendedAddress = (a[aindex]->a_addr >> 16) & 0xffff;
517 /* Boy, is this a hack: for ABS sections, the
518 * base address is stored as zero, and the T records
519 * indicate the offset from zero.
521 * Since T records can only indicate a 16 bit offset, this
522 * obviously creates a problem for ABS segments located
523 * above 64K (this is only meaningful in flat24 mode).
525 * However, the size of an ABS area is stored as
526 * base address + section size (I suspect this is a bug,
527 * but it's a handy one right now). So the upper 8 bits of
528 * the 24 bit address are stored in the size record.
531 * This is another reason why we can't have areas greater
532 * than 64K yet, even in flat24 mode.
534 extendedAddress += ((a[aindex]->a_size) >> 16 & 0xffff);
536 if (extendedAddress != lastExtendedAddress)
540 printf("output extended linear address record 0x%x\n",
546 ihxEntendedLinearAddress(extendedAddress);
548 else if (extendedAddress)
550 /* Not allowed to generate extended address records,
551 * but one is called for here...
554 "warning: extended linear address encountered; "
555 "you probably want the -r flag.\n");
557 lastExtendedAddress = extendedAddress;
561 if ((oflag == 2) && (rtcnt > 2)) {
567 "Unsigned Byte error",
568 "Byte PCR relocation error",
569 "Page0 relocation error",
570 "Page Mode relocation error"
574 /*)Function VOID relp()
576 * The function relp() evaluates a P line read by
577 * the linker. The P line data is combined with the
578 * previous T line data to set the base page address
579 * and test the paging boundary and length.
583 * P 0 0 nn nn n1 n2 xx xx
585 * The P line provides the paging information to the linker as
586 * specified by a .setdp directive. The format of the relocation
587 * information is identical to that of the R line. The correspond-
588 * ing T line has the following information:
589 * T xx xx aa aa bb bb
591 * Where aa aa is the area reference number which specifies the
592 * selected page area and bb bb is the base address of the page.
593 * bb bb will require relocation processing if the 'n1 n2 xx xx' is
594 * specified in the P line. The linker will verify that the base
595 * address is on a 256 byte boundary and that the page length of an
596 * area defined with the PAG type is not larger than 256 bytes.
599 * areax **a pointer to array of area pointers
600 * int aindex area index
601 * int mode relocation mode
602 * addr_t relv relocation value
603 * int rindex symbol / area index
604 * int rtp index into T data
605 * sym **s pointer to array of symbol pointers
608 * head *hp pointer to the head structure
609 * int lkerr error flag
610 * sdp sdp base page structure
611 * FILE *stderr standard error device
614 * addr_t adw_w() lkrloc.c
615 * addr_t evword() lkrloc.c
616 * int eval() lkeval.c
617 * int fprintf() c_library
619 * int symval() lksym.c
622 * The P and T lines are combined to set
623 * the base page address and report any
631 register int aindex, rindex;
638 * Get area and symbol lists
646 if (eval() != (R_WORD | R_AREA) || eval()) {
647 fprintf(stderr, "P input error\n");
655 if (aindex >= hp->h_narea) {
656 fprintf(stderr, "P area error\n");
662 * Do remaining relocations
670 * R_SYM or R_AREA references
673 if (rindex >= hp->h_nglob) {
674 fprintf(stderr, "P symbol error\n");
678 relv = symval(s[rindex]);
680 if (rindex >= hp->h_narea) {
681 fprintf(stderr, "P area error\n");
685 relv = a[rindex]->a_addr;
694 if (aindex >= hp->h_narea) {
695 fprintf(stderr, "P area error\n");
699 sdp.s_areax = a[aindex];
700 sdp.s_area = sdp.s_areax->a_bap;
701 sdp.s_addr = adw_w(0,4);
702 if (sdp.s_area->a_addr & 0xFF || sdp.s_addr & 0xFF)
703 relerp("Page Definition Boundary Error");
706 /*)Function VOID rele()
708 * The function rele() closes all open output files
709 * at the end of the linking process.
715 * int oflag output type flag
716 * int uflag relocation listing flag
720 * VOID lkulist() lklist.c
724 * All open output files are closed.
742 /*)Function addr_t evword()
744 * The function evword() combines two byte values
745 * into a single word value.
748 * addr_t v temporary evaluation variable
751 * hilo byte ordering parameter
754 * int eval() lkeval.c
757 * Relocation text line is scanned to combine
758 * two byte values into a single word value.
777 /*)Function addr_t adb_b(v, i)
779 * int v value to add to byte
780 * int i rtval[] index
782 * The function adb_b() adds the value of v to
783 * the single byte value contained in rtval[i].
784 * The new value of rtval[i] is returned.
796 * The value of rtval[] is changed.
805 return(rtval[i] += v);
808 /*)Function addr_t adb_lo(v, i)
810 * int v value to add to byte
811 * int i rtval[] index
813 * The function adb_lo() adds the value of v to the
814 * double byte value contained in rtval[i] and rtval[i+1].
815 * The new value of rtval[i] / rtval[i+1] is returned.
816 * The MSB rtflg[] is cleared.
819 * addr_t j temporary evaluation variable
822 * hilo byte ordering parameter
828 * The value of rtval[] is changed.
829 * The rtflg[] value corresponding to the
830 * MSB of the word value is cleared to reflect
831 * the fact that the LSB is the selected byte.
854 /*)Function addr_t adb_hi(v, i)
856 * int v value to add to byte
857 * int i rtval[] index
859 * The function adb_hi() adds the value of v to the
860 * double byte value contained in rtval[i] and rtval[i+1].
861 * The new value of rtval[i] / rtval[i+1] is returned.
862 * The LSB rtflg[] is cleared.
865 * addr_t j temporary evaluation variable
868 * hilo byte ordering parameter
874 * The value of rtval[] is changed.
875 * The rtflg[] value corresponding to the
876 * LSB of the word value is cleared to reflect
877 * the fact that the MSB is the selected byte.
900 /*)Function addr_t adb_24_hi(v, i)
902 * int v value to add to byte
903 * int i rtval[] index
905 * The function adb_24_hi() adds the value of v to the
906 * 24 bit value contained in rtval[i] - rtval[i+2].
907 * The new value of rtval[i] / rtval[i+1] is returned.
908 * The LSB & middle byte rtflg[] is cleared.
911 * addr_t j temporary evaluation variable
914 * hilo byte ordering parameter
920 * The value of rtval[] is changed.
921 * The rtflg[] value corresponding to the
922 * LSB & middle byte of the word value is cleared to
923 * reflect the fact that the MSB is the selected byte.
928 adb_24_hi(addr_t v, int i)
934 /* Remove the lower two bytes. */
948 /*)Function addr_t adb_24_mid(v, i)
950 * int v value to add to byte
951 * int i rtval[] index
953 * The function adb_24_mid() adds the value of v to the
954 * 24 bit value contained in rtval[i] - rtval[i+2].
955 * The new value of rtval[i] / rtval[i+1] is returned.
956 * The LSB & MSB byte rtflg[] is cleared.
959 * addr_t j temporary evaluation variable
962 * hilo byte ordering parameter
968 * The value of rtval[] is changed.
969 * The rtflg[] value corresponding to the
970 * LSB & MSB of the 24 bit value is cleared to reflect
971 * the fact that the middle byte is the selected byte.
976 adb_24_mid(addr_t v, int i)
982 /* remove the MSB & LSB. */
989 /*)Function addr_t adb_24_lo(v, i)
991 * int v value to add to byte
992 * int i rtval[] index
994 * The function adb_24_lo() adds the value of v to the
995 * 24 bit value contained in rtval[i] - rtval[i+2].
996 * The new value of rtval[i] / rtval[i+1] is returned.
997 * The MSB & middle byte rtflg[] is cleared.
1000 * addr_t j temporary evaluation variable
1003 * hilo byte ordering parameter
1009 * The value of rtval[] is changed.
1010 * The rtflg[] value corresponding to the
1011 * MSB & middle byte of the word value is cleared to
1012 * reflect the fact that the LSB is the selected byte.
1017 adb_24_lo(addr_t v, int i)
1023 /* Remove the upper two bytes. */
1037 /*)Function addr_t adw_w(v, i)
1039 * int v value to add to word
1040 * int i rtval[] index
1042 * The function adw_w() adds the value of v to the
1043 * word value contained in rtval[i] and rtval[i+1].
1044 * The new value of rtval[i] / rtval[i+1] is returned.
1047 * addr_t j temporary evaluation variable
1050 * hilo byte ordering parameter
1056 * The word value of rtval[] is changed.
1068 j = v + (rtval[i] << 8) + (rtval[i+1] & 0xff);
1069 rtval[i] = (j >> 8) & 0xff;
1070 rtval[i+1] = j & 0xff;
1072 j = v + (rtval[i] & 0xff) + (rtval[i+1] << 8);
1073 rtval[i] = j & 0xff;
1074 rtval[i+1] = (j >> 8) & 0xff;
1079 /*)Function addr_t adw_24(v, i)
1081 * int v value to add to word
1082 * int i rtval[] index
1084 * The function adw_w() adds the value of v to the
1085 * 24 bit value contained in rtval[i] - rtval[i+2].
1086 * The new value of rtval[i] - rtval[i+2] is returned.
1089 * addr_t j temporary evaluation variable
1092 * hilo byte ordering parameter
1098 * The word value of rtval[] is changed.
1102 adw_24(addr_t v, int i)
1107 j = v + ((rtval[i] & 0xff) << 16)
1108 + ((rtval[i+1] & 0xff) << 8)
1109 + (rtval[i+2] & 0xff);
1110 rtval[i] = (j >> 16) & 0xff;
1111 rtval[i+1] = (j >> 8) & 0xff;
1112 rtval[i+2] = j & 0xff;
1114 j = v + (rtval[i] & 0xff)
1115 + ((rtval[i+1] & 0xff) << 8)
1116 + ((rtval[i+2] & 0xff) << 16);
1117 rtval[i] = j & 0xff;
1118 rtval[i+1] = (j >> 8) & 0xff;
1119 rtval[i+2] = (j >> 16) & 0xff;
1124 /*)Function addr_t adw_lo(v, i)
1126 * int v value to add to byte
1127 * int i rtval[] index
1129 * The function adw_lo() adds the value of v to the
1130 * double byte value contained in rtval[i] and rtval[i+1].
1131 * The new value of rtval[i] / rtval[i+1] is returned.
1132 * The MSB rtval[] is zeroed.
1135 * addr_t j temporary evaluation variable
1138 * hilo byte ordering parameter
1144 * The value of rtval[] is changed.
1145 * The MSB of the word value is cleared to reflect
1146 * the fact that the LSB is the selected byte.
1169 /*)Function addr_t adw_hi(v, i)
1171 * int v value to add to byte
1172 * int i rtval[] index
1174 * The function adw_hi() adds the value of v to the
1175 * double byte value contained in rtval[i] and rtval[i+1].
1176 * The new value of rtval[i] / rtval[i+1] is returned.
1177 * The MSB and LSB values are interchanged.
1178 * The MSB rtval[] is zeroed.
1181 * addr_t j temporary evaluation variable
1184 * hilo byte ordering parameter
1190 * The value of rtval[] is changed.
1191 * The MSB and LSB values are interchanged and
1192 * then the MSB cleared.
1205 * LSB = MSB, Clear MSB
1208 rtval[i+1] = rtval[i];
1211 rtval[i] = rtval[i+1];
1217 /*)Function VOID relerr(str)
1219 * char *str error string
1221 * The function relerr() outputs the error string to
1222 * stderr and to the map file (if it is open).
1228 * FILE *mfp handle for the map file
1231 * VOID errdmp() lkrloc.c
1234 * Error message inserted into map file.
1242 errdmp(stderr, str);
1247 /*)Function VOID errdmp(fptr, str)
1249 * FILE *fptr output file handle
1250 * char *str error string
1252 * The function errdmp() outputs the error string str
1253 * to the device specified by fptr. Additional information
1254 * is output about the definition and referencing of
1255 * the symbol / area error.
1258 * int mode error mode
1259 * int aindex area index
1260 * int lkerr error flag
1261 * int rindex error index
1262 * sym **s pointer to array of symbol pointers
1263 * areax **a pointer to array of area pointers
1264 * areax *raxp error area extension pointer
1267 * sdp sdp base page structure
1270 * int fprintf() c_library
1271 * VOID prntval() lkrloc.c
1283 int mode, aindex, rindex;
1292 aindex = rerr.aindex;
1293 rindex = rerr.rindex;
1298 fprintf(fptr, "\n?ASlink-Warning-%s", str);
1302 * Print symbol if symbol based
1305 fprintf(fptr, " for symbol %s\n",
1306 &s[rindex]->s_id[0]);
1308 fprintf(fptr, "\n");
1315 " file module area offset\n");
1317 " Refby %-8.8s %-8.8s %-8.8s ",
1320 &a[aindex]->a_bap->a_id[0]);
1321 prntval(fptr, rerr.rtbase);
1327 raxp = s[rindex]->s_axp;
1332 " Defin %-8.8s %-8.8s %-8.8s ",
1333 raxp->a_bhp->h_lfile->f_idp,
1334 &raxp->a_bhp->m_id[0],
1335 &raxp->a_bap->a_id[0]);
1337 prntval(fptr, s[rindex]->s_addr);
1339 prntval(fptr, rerr.rval);
1343 /*)Function VOID prntval(fptr, v)
1345 * FILE *fptr output file handle
1346 * addr_t v value to output
1348 * The function prntval() outputs the value v, in the
1349 * currently selected radix, to the device specified
1356 * int xflag current radix
1359 * int fprintf() c_library
1372 fprintf(fptr, "%04X\n", v);
1375 fprintf(fptr, "%06o\n", v);
1378 fprintf(fptr, "%05u\n", v);
1382 /*)Function VOID relerp(str)
1384 * char *str error string
1386 * The function relerp() outputs the paging error string to
1387 * stderr and to the map file (if it is open).
1393 * FILE *mfp handle for the map file
1396 * VOID erpdmp() lkrloc.c
1399 * Error message inserted into map file.
1407 erpdmp(stderr, str);
1412 /*)Function VOID erpdmp(fptr, str)
1414 * FILE *fptr output file handle
1415 * char *str error string
1417 * The function erpdmp() outputs the error string str
1418 * to the device specified by fptr.
1421 * head *thp pointer to head structure
1424 * int lkerr error flag
1425 * sdp sdp base page structure
1428 * int fprintf() c_library
1429 * VOID prntval() lkrloc.c
1441 register struct head *thp;
1443 thp = sdp.s_areax->a_bhp;
1448 fprintf(fptr, "\n?ASlink-Warning-%s\n", str);
1455 " file module pgarea pgoffset\n");
1457 " PgDef %-8.8s %-8.8s %-8.8s ",
1458 thp->h_lfile->f_idp,
1460 &sdp.s_area->a_id[0]);
1461 prntval(fptr, sdp.s_area->a_addr + sdp.s_addr);