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
23 * The module lkrloc.c contains the functions which
24 * perform the relocation calculations.
26 * lkrloc.c contains the following functions:
45 * lkrloc.c the local variable errmsg[].
49 /* Global which holds the upper 16 bits of the last 32 bit area adress
50 * output. Useful only for iHex mode.
52 int lastExtendedAddress=-1;
54 /*)Function VOID reloc(c)
58 * The function reloc() calls a particular relocation
59 * function determined by the process code.
65 * int lkerr error flag
68 * int fprintf() c_library
69 * VOID rele() lkrloc.c
70 * VOID relp() lkrloc.c
71 * VOID relr() lkrloc.c
72 * VOId relt() lkrloc.c
75 * Refer to the called relocation functions.
102 fprintf(stderr, "Undefined Relocation Operation\n");
110 /*)Function VOID relt()
112 * The function relt() evaluates a T line read by
113 * the linker. Each byte value read is saved in the
114 * rtval[] array, rtflg[] is set, and the number of
115 * evaluations is maintained in rtcnt.
119 * T xx xx nn nn nn nn nn ...
122 * In: "T n0 n1 n2 n3 ... nn"
124 * Out: 0 1 2 .. rtcnt
125 * +----+----+----+----+----+
126 * rtval | n0 | n1 | n2 | .. | nn |
127 * +----+----+----+----+----+
128 * rtflag| 1 | 1 | 1 | 1 | 1 |
129 * +----+----+----+----+----+
131 * The T line contains the assembled code output by the assem-
132 * bler with xx xx being the offset address from the current area
133 * base address and nn being the assembled instructions and data in
140 * int rtcnt number of values evaluated
141 * int rtflg[] array of evaluation flags
142 * int rtval[] array of evaluation values
145 * int eval() lkeval.c
149 * Linker input T line evaluated.
159 rtval[rtcnt] = eval();
166 /*)Function VOID relr()
168 * The function relr() evaluates a R line read by
169 * the linker. The R line data is combined with the
170 * previous T line data to perform the relocation of
171 * code and data bytes. The S19 / IHX output and
172 * translation of the LST files to RST files may be
177 * R 0 0 nn nn n1 n2 xx xx ...
179 * The R line provides the relocation information to the linker.
180 * The nn nn value is the current area index, i.e. which area the
181 * current values were assembled. Relocation information is en-
182 * coded in groups of 4 bytes:
184 * 1. n1 is the relocation mode and object format
185 * 1. bit 0 word(0x00)/byte(0x01)
186 * 2. bit 1 relocatable area(0x00)/symbol(0x02)
187 * 3. bit 2 normal(0x00)/PC relative(0x04) relocation
188 * 4. bit 3 1-byte(0x00)/2-byte(0x08) object format for
190 * 5. bit 4 signed(0x00)/unsigned(0x10) byte data
191 * 6. bit 5 normal(0x00)/page '0'(0x20) reference
192 * 7. bit 6 normal(0x00)/page 'nnn'(0x40) reference
194 * 2. n2 is a byte index into the corresponding (i.e. pre-
195 * ceeding) T line data (i.e. a pointer to the data to be
196 * updated by the relocation). The T line data may be
197 * 1-byte or 2-byte byte data format or 2-byte word
200 * 3. xx xx is the area/symbol index for the area/symbol be-
201 * ing referenced. the corresponding area/symbol is found
202 * in the header area/symbol lists.
204 * The groups of 4 bytes are repeated for each item requiring relo-
205 * cation in the preceeding T line.
208 * areax **a pointer to array of area pointers
209 * int aindex area index
210 * char *errmsg[] array of pointers to error strings
211 * int error error code
212 * int lkerr error flag
213 * int mode relocation mode
214 * adrr_t paga paging base area address
215 * Addr_T pags paging symbol address
216 * Addr_T pc relocated base address
217 * Addr_T r PCR relocation value
218 * Addr_T reli relocation initial value
219 * Addr_T relv relocation final value
220 * int rindex symbol / area index
221 * Addr_T rtbase base code address
222 * Addr_T rtofst rtval[] index offset
223 * int rtp index into T data
224 * sym **s pointer to array of symbol pointers
227 * head *hp pointer to the head structure
228 * rerr rerr linker error structure
229 * FILE *stderr standard error device
232 * Addr_T adb_b() lkrloc.c
233 * Addr_T adb_lo() lkrloc.c
234 * Addr_T adb_hi() lkrloc.c
235 * Addr_T adw_w() lkrloc.c
236 * Addr_T evword() lkrloc.c
237 * int eval() lkeval.c
238 * int fprintf() c_library
240 * int lkulist lklist.c
242 * VOID relerr() lkrloc.c
244 * int symval() lksym.c
247 * The R and T lines are combined to produce
248 * relocated code and data. Output S19 / IHX
249 * and relocated listing files may be produced.
257 register Addr_T reli, relv;
258 int aindex, rindex, rtp, error;
259 Addr_T r, rtbase, rtofst, paga, pags, pc;
264 * Get area and symbol lists
272 if (eval() != (R_WORD | R_AREA) || eval()) {
273 fprintf(stderr, "R input error\n");
281 if (aindex >= hp->h_narea) {
282 fprintf(stderr, "R area error\n");
290 rtbase = adw_w(0, 0);
296 pc = adw_w(a[aindex]->a_addr, 0);
299 printf("area %d base address: 0x%x size: 0x%x rtbase: 0x%x\n", aindex,
300 a[aindex]->a_addr, a[aindex]->a_size, rtbase);
303 * Do remaining relocations
309 if ((mode & R_ESCAPE_MASK) == R_ESCAPE_MASK)
311 mode = ((mode & ~R_ESCAPE_MASK) << 8) | eval();
312 /* printf("unescaping rmode\n"); */
319 * R_SYM or R_AREA references
322 if (rindex >= hp->h_nglob) {
323 fprintf(stderr, "R symbol error\n");
327 reli = symval(s[rindex]);
329 if (rindex >= hp->h_narea) {
330 fprintf(stderr, "R area error\n");
334 reli = a[rindex]->a_addr;
342 reli -= (pc + (rtp-rtofst) + 1);
344 reli -= (pc + (rtp-rtofst) + 2);
349 * R_PAG0 or R_PAG addressing
351 if (mode & (R_PAG0 | R_PAG)) {
352 paga = sdp.s_area->a_addr;
358 * R_BYTE or R_WORD operation
363 /* This is a three byte address, of which
364 * we will select one byte.
368 /* printf("24 bit address selecting hi byte.\n"); */
369 relv = adb_24_hi(reli, rtp);
371 else if (mode & R_MSB)
373 /* Note that in 24 bit mode, R_MSB
374 * is really the middle byte, not
375 * the most significant byte.
377 * This is ugly and I can only apologize
380 /* printf("24 bit address selecting middle byte.\n"); */
381 relv = adb_24_mid(reli, rtp);
385 /* printf("24 bit address selecting lo byte.\n"); */
386 relv = adb_24_lo(reli, rtp);
389 else if (mode & R_BYT2) {
390 /* This is a two byte address, of
391 * which we will select one byte.
394 relv = adb_hi(reli, rtp);
396 relv = adb_lo(reli, rtp);
399 relv = adb_b(reli, rtp);
401 } else if (IS_R_J11(mode)) {
402 /* JLH: 11 bit jump destination for 8051. Forms
403 / two byte instruction with op-code bits
405 / rtp points at 3 byte locus: first two
406 / will get the instructiion. third one
410 /* Calculate absolute destination
411 / relv must be on same 2K page as pc
413 relv = adw_w(reli, rtp);
415 if ((relv & ~0x7ff) != ((pc + rtp - rtofst) & ~0x7ff)) {
419 /* Merge MSB (byte 0) with op-code, ignoring
420 / top 5 bits of address. Then hide the op-code
422 rtval[rtp] = ((rtval[rtp] & 0x07)<<5) | rtval[rtp+2];
426 else if (IS_R_J19(mode)) {
427 /* 19 bit jump destination for DS80C390. Forms
428 / three byte instruction with op-code bits
430 / rtp points at 4 byte locus: first three
431 / will get the instructiion. fourth one
435 /* Calculate absolute destination
436 / relv must be on same 512K page as pc
438 relv = adw_24(reli, rtp);
440 if ((relv & ~0x7ffff) != ((pc + rtp - rtofst) & ~0x7ffff)) {
444 /* Merge MSB (byte 0) with op-code, ignoring
445 / top 5 bits of address. Then hide the op-code
447 rtval[rtp] = ((rtval[rtp] & 0x07)<<5) | rtval[rtp+3];
451 else if (IS_C24(mode))
454 relv = adw_24(reli, rtp);
458 /* 16 bit address. */
459 relv = adw_w(reli, rtp);
463 * R_BYTE with R_BYT2 offset adjust
472 * Unsigned Byte Checking
474 if (mode & R_USGN && mode & R_BYTE && relv & ~0xFF)
478 * PCR Relocation Error Checking
480 if (mode & R_PCR && mode & R_BYTE) {
482 if (r != (Addr_T) ~0x7F && r != 0)
487 * Page Relocation Error Checking
489 /* if (mode & R_PAG0 && (relv & ~0xFF || paga || pags))
491 if (mode & R_PAG && (relv & ~0xFF))
498 rerr.aindex = aindex;
500 rerr.rtbase = rtbase + rtp - rtofst - 1;
501 rerr.rindex = rindex;
502 rerr.rval = relv - reli;
503 relerr(errmsg[error-1]);
510 /* JLH: output only if data (beyond two byte address) */
511 if ((oflag == 1) && (rtcnt > 2)) {
512 int extendedAddress = (a[aindex]->a_addr >> 16) & 0xffff;
514 /* Boy, is this a hack: for ABS sections, the
515 * base address is stored as zero, and the T records
516 * indicate the offset from zero.
518 * Since T records can only indicate a 16 bit offset, this
519 * obviously creates a problem for ABS segments located
520 * above 64K (this is only meaningful in flat24 mode).
522 * However, the size of an ABS area is stored as
523 * base address + section size (I suspect this is a bug,
524 * but it's a handy one right now). So the upper 8 bits of
525 * the 24 bit address are stored in the size record.
528 * This is another reason why we can't have areas greater
529 * than 64K yet, even in flat24 mode.
531 extendedAddress += ((a[aindex]->a_size) >> 16 & 0xffff);
533 if (extendedAddress != lastExtendedAddress)
537 if (lastExtendedAddress!=-1) {
538 printf("output extended linear address record 0x%x 0x%x\n",
539 extendedAddress, lastExtendedAddress);
545 ihxEntendedLinearAddress(extendedAddress);
547 else if (extendedAddress)
549 /* Not allowed to generate extended address records,
550 * but one is called for here...
553 "warning: extended linear address encountered; "
554 "you probably want the -r flag.\n");
556 lastExtendedAddress = extendedAddress;
560 if ((oflag == 2) && (rtcnt > 2)) {
566 "Unsigned Byte error",
567 "Byte PCR relocation error",
568 "Page0 relocation error",
569 "Page Mode relocation error"
573 /*)Function VOID relp()
575 * The function relp() evaluates a P line read by
576 * the linker. The P line data is combined with the
577 * previous T line data to set the base page address
578 * and test the paging boundary and length.
582 * P 0 0 nn nn n1 n2 xx xx
584 * The P line provides the paging information to the linker as
585 * specified by a .setdp directive. The format of the relocation
586 * information is identical to that of the R line. The correspond-
587 * ing T line has the following information:
588 * T xx xx aa aa bb bb
590 * Where aa aa is the area reference number which specifies the
591 * selected page area and bb bb is the base address of the page.
592 * bb bb will require relocation processing if the 'n1 n2 xx xx' is
593 * specified in the P line. The linker will verify that the base
594 * address is on a 256 byte boundary and that the page length of an
595 * area defined with the PAG type is not larger than 256 bytes.
598 * areax **a pointer to array of area pointers
599 * int aindex area index
600 * int mode relocation mode
601 * Addr_T relv relocation value
602 * int rindex symbol / area index
603 * int rtp index into T data
604 * sym **s pointer to array of symbol pointers
607 * head *hp pointer to the head structure
608 * int lkerr error flag
609 * sdp sdp base page structure
610 * FILE *stderr standard error device
613 * Addr_T adw_w() lkrloc.c
614 * Addr_T evword() lkrloc.c
615 * int eval() lkeval.c
616 * int fprintf() c_library
618 * int symval() lksym.c
621 * The P and T lines are combined to set
622 * the base page address and report any
630 register int aindex, rindex;
637 * Get area and symbol lists
645 if (eval() != (R_WORD | R_AREA) || eval()) {
646 fprintf(stderr, "P input error\n");
654 if (aindex >= hp->h_narea) {
655 fprintf(stderr, "P area error\n");
661 * Do remaining relocations
669 * R_SYM or R_AREA references
672 if (rindex >= hp->h_nglob) {
673 fprintf(stderr, "P symbol error\n");
677 relv = symval(s[rindex]);
679 if (rindex >= hp->h_narea) {
680 fprintf(stderr, "P area error\n");
684 relv = a[rindex]->a_addr;
693 if (aindex >= hp->h_narea) {
694 fprintf(stderr, "P area error\n");
698 sdp.s_areax = a[aindex];
699 sdp.s_area = sdp.s_areax->a_bap;
700 sdp.s_addr = adw_w(0,4);
701 if (sdp.s_area->a_addr & 0xFF || sdp.s_addr & 0xFF)
702 relerp("Page Definition Boundary Error");
705 /*)Function VOID rele()
707 * The function rele() closes all open output files
708 * at the end of the linking process.
714 * int oflag output type flag
715 * int uflag relocation listing flag
719 * VOID lkulist() lklist.c
723 * All open output files are closed.
741 /*)Function Addr_T evword()
743 * The function evword() combines two byte values
744 * into a single word value.
747 * Addr_T v temporary evaluation variable
750 * hilo byte ordering parameter
753 * int eval() lkeval.c
756 * Relocation text line is scanned to combine
757 * two byte values into a single word value.
776 /*)Function Addr_T adb_b(v, i)
778 * int v value to add to byte
779 * int i rtval[] index
781 * The function adb_b() adds the value of v to
782 * the single byte value contained in rtval[i].
783 * The new value of rtval[i] is returned.
795 * The value of rtval[] is changed.
804 return(rtval[i] += v);
807 /*)Function Addr_T adb_lo(v, i)
809 * int v value to add to byte
810 * int i rtval[] index
812 * The function adb_lo() adds the value of v to the
813 * double byte value contained in rtval[i] and rtval[i+1].
814 * The new value of rtval[i] / rtval[i+1] is returned.
815 * The MSB rtflg[] is cleared.
818 * Addr_T j temporary evaluation variable
821 * hilo byte ordering parameter
827 * The value of rtval[] is changed.
828 * The rtflg[] value corresponding to the
829 * MSB of the word value is cleared to reflect
830 * the fact that the LSB is the selected byte.
853 /*)Function Addr_T adb_hi(v, i)
855 * int v value to add to byte
856 * int i rtval[] index
858 * The function adb_hi() adds the value of v to the
859 * double byte value contained in rtval[i] and rtval[i+1].
860 * The new value of rtval[i] / rtval[i+1] is returned.
861 * The LSB rtflg[] is cleared.
864 * Addr_T j temporary evaluation variable
867 * hilo byte ordering parameter
873 * The value of rtval[] is changed.
874 * The rtflg[] value corresponding to the
875 * LSB of the word value is cleared to reflect
876 * the fact that the MSB is the selected byte.
899 /*)Function Addr_T adb_24_hi(v, i)
901 * int v value to add to byte
902 * int i rtval[] index
904 * The function adb_24_hi() adds the value of v to the
905 * 24 bit value contained in rtval[i] - rtval[i+2].
906 * The new value of rtval[i] / rtval[i+1] is returned.
907 * The LSB & middle byte rtflg[] is cleared.
910 * Addr_T j temporary evaluation variable
913 * hilo byte ordering parameter
919 * The value of rtval[] is changed.
920 * The rtflg[] value corresponding to the
921 * LSB & middle byte of the word value is cleared to
922 * reflect the fact that the MSB is the selected byte.
927 adb_24_hi(Addr_T v, int i)
933 /* Remove the lower two bytes. */
947 /*)Function Addr_T adb_24_mid(v, i)
949 * int v value to add to byte
950 * int i rtval[] index
952 * The function adb_24_mid() adds the value of v to the
953 * 24 bit value contained in rtval[i] - rtval[i+2].
954 * The new value of rtval[i] / rtval[i+1] is returned.
955 * The LSB & MSB byte rtflg[] is cleared.
958 * Addr_T j temporary evaluation variable
961 * hilo byte ordering parameter
967 * The value of rtval[] is changed.
968 * The rtflg[] value corresponding to the
969 * LSB & MSB of the 24 bit value is cleared to reflect
970 * the fact that the middle byte is the selected byte.
975 adb_24_mid(Addr_T v, int i)
981 /* remove the MSB & LSB. */
988 /*)Function Addr_T adb_24_lo(v, i)
990 * int v value to add to byte
991 * int i rtval[] index
993 * The function adb_24_lo() adds the value of v to the
994 * 24 bit value contained in rtval[i] - rtval[i+2].
995 * The new value of rtval[i] / rtval[i+1] is returned.
996 * The MSB & middle byte rtflg[] is cleared.
999 * Addr_T j temporary evaluation variable
1002 * hilo byte ordering parameter
1008 * The value of rtval[] is changed.
1009 * The rtflg[] value corresponding to the
1010 * MSB & middle byte of the word value is cleared to
1011 * reflect the fact that the LSB is the selected byte.
1016 adb_24_lo(Addr_T v, int i)
1022 /* Remove the upper two bytes. */
1036 /*)Function Addr_T adw_w(v, i)
1038 * int v value to add to word
1039 * int i rtval[] index
1041 * The function adw_w() adds the value of v to the
1042 * word value contained in rtval[i] and rtval[i+1].
1043 * The new value of rtval[i] / rtval[i+1] is returned.
1046 * Addr_T j temporary evaluation variable
1049 * hilo byte ordering parameter
1055 * The word value of rtval[] is changed.
1067 j = v + (rtval[i] << 8) + (rtval[i+1] & 0xff);
1068 rtval[i] = (j >> 8) & 0xff;
1069 rtval[i+1] = j & 0xff;
1071 j = v + (rtval[i] & 0xff) + (rtval[i+1] << 8);
1072 rtval[i] = j & 0xff;
1073 rtval[i+1] = (j >> 8) & 0xff;
1078 /*)Function Addr_T adw_24(v, i)
1080 * int v value to add to word
1081 * int i rtval[] index
1083 * The function adw_w() adds the value of v to the
1084 * 24 bit value contained in rtval[i] - rtval[i+2].
1085 * The new value of rtval[i] - rtval[i+2] is returned.
1088 * Addr_T j temporary evaluation variable
1091 * hilo byte ordering parameter
1097 * The word value of rtval[] is changed.
1101 adw_24(Addr_T v, int i)
1106 j = v + ((rtval[i] & 0xff) << 16)
1107 + ((rtval[i+1] & 0xff) << 8)
1108 + (rtval[i+2] & 0xff);
1109 rtval[i] = (j >> 16) & 0xff;
1110 rtval[i+1] = (j >> 8) & 0xff;
1111 rtval[i+2] = j & 0xff;
1113 j = v + (rtval[i] & 0xff)
1114 + ((rtval[i+1] & 0xff) << 8)
1115 + ((rtval[i+2] & 0xff) << 16);
1116 rtval[i] = j & 0xff;
1117 rtval[i+1] = (j >> 8) & 0xff;
1118 rtval[i+2] = (j >> 16) & 0xff;
1123 /*)Function Addr_T adw_lo(v, i)
1125 * int v value to add to byte
1126 * int i rtval[] index
1128 * The function adw_lo() adds the value of v to the
1129 * double byte value contained in rtval[i] and rtval[i+1].
1130 * The new value of rtval[i] / rtval[i+1] is returned.
1131 * The MSB rtval[] is zeroed.
1134 * Addr_T j temporary evaluation variable
1137 * hilo byte ordering parameter
1143 * The value of rtval[] is changed.
1144 * The MSB of the word value is cleared to reflect
1145 * the fact that the LSB is the selected byte.
1168 /*)Function Addr_T adw_hi(v, i)
1170 * int v value to add to byte
1171 * int i rtval[] index
1173 * The function adw_hi() adds the value of v to the
1174 * double byte value contained in rtval[i] and rtval[i+1].
1175 * The new value of rtval[i] / rtval[i+1] is returned.
1176 * The MSB and LSB values are interchanged.
1177 * The MSB rtval[] is zeroed.
1180 * Addr_T j temporary evaluation variable
1183 * hilo byte ordering parameter
1189 * The value of rtval[] is changed.
1190 * The MSB and LSB values are interchanged and
1191 * then the MSB cleared.
1204 * LSB = MSB, Clear MSB
1207 rtval[i+1] = rtval[i];
1210 rtval[i] = rtval[i+1];
1216 /*)Function VOID relerr(str)
1218 * char *str error string
1220 * The function relerr() outputs the error string to
1221 * stderr and to the map file (if it is open).
1227 * FILE *mfp handle for the map file
1230 * VOID errdmp() lkrloc.c
1233 * Error message inserted into map file.
1241 errdmp(stderr, str);
1246 /*)Function VOID errdmp(fptr, str)
1248 * FILE *fptr output file handle
1249 * char *str error string
1251 * The function errdmp() outputs the error string str
1252 * to the device specified by fptr. Additional information
1253 * is output about the definition and referencing of
1254 * the symbol / area error.
1257 * int mode error mode
1258 * int aindex area index
1259 * int lkerr error flag
1260 * int rindex error index
1261 * sym **s pointer to array of symbol pointers
1262 * areax **a pointer to array of area pointers
1263 * areax *raxp error area extension pointer
1266 * sdp sdp base page structure
1269 * int fprintf() c_library
1270 * VOID prntval() lkrloc.c
1282 int mode, aindex, rindex;
1291 aindex = rerr.aindex;
1292 rindex = rerr.rindex;
1297 fprintf(fptr, "\n?ASlink-Warning-%s", str);
1301 * Print symbol if symbol based
1304 fprintf(fptr, " for symbol %s\n",
1305 &s[rindex]->s_id[0]);
1307 fprintf(fptr, "\n");
1314 " file module area offset\n");
1316 " Refby %-8.8s %-8.8s %-8.8s ",
1319 &a[aindex]->a_bap->a_id[0]);
1320 prntval(fptr, rerr.rtbase);
1326 raxp = s[rindex]->s_axp;
1331 " Defin %-8.8s %-8.8s %-8.8s ",
1332 raxp->a_bhp->h_lfile->f_idp,
1333 &raxp->a_bhp->m_id[0],
1334 &raxp->a_bap->a_id[0]);
1336 prntval(fptr, s[rindex]->s_addr);
1338 prntval(fptr, rerr.rval);
1342 /*)Function VOID prntval(fptr, v)
1344 * FILE *fptr output file handle
1345 * Addr_T v value to output
1347 * The function prntval() outputs the value v, in the
1348 * currently selected radix, to the device specified
1355 * int xflag current radix
1358 * int fprintf() c_library
1371 fprintf(fptr, "%04X\n", v);
1374 fprintf(fptr, "%06o\n", v);
1377 fprintf(fptr, "%05u\n", v);
1381 /*)Function VOID relerp(str)
1383 * char *str error string
1385 * The function relerp() outputs the paging error string to
1386 * stderr and to the map file (if it is open).
1392 * FILE *mfp handle for the map file
1395 * VOID erpdmp() lkrloc.c
1398 * Error message inserted into map file.
1406 erpdmp(stderr, str);
1411 /*)Function VOID erpdmp(fptr, str)
1413 * FILE *fptr output file handle
1414 * char *str error string
1416 * The function erpdmp() outputs the error string str
1417 * to the device specified by fptr.
1420 * head *thp pointer to head structure
1423 * int lkerr error flag
1424 * sdp sdp base page structure
1427 * int fprintf() c_library
1428 * VOID prntval() lkrloc.c
1440 register struct head *thp;
1442 thp = sdp.s_areax->a_bhp;
1447 fprintf(fptr, "\n?ASlink-Warning-%s\n", str);
1454 " file module pgarea pgoffset\n");
1456 " PgDef %-8.8s %-8.8s %-8.8s ",
1457 thp->h_lfile->f_idp,
1459 &sdp.s_area->a_id[0]);
1460 prntval(fptr, sdp.s_area->a_addr + sdp.s_addr);