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
24 * The module lkrloc.c contains the functions which
25 * perform the relocation calculations.
27 * lkrloc.c contains the following functions:
46 * lkrloc.c the local variable errmsg[].
50 /* Global which holds the upper 16 bits of the last 32 bit area adress
51 * output. Useful only for iHex mode.
53 int lastExtendedAddress;
55 /*)Function VOID reloc(c)
59 * The function reloc() calls a particular relocation
60 * function determined by the process code.
66 * int lkerr error flag
69 * int fprintf() c_library
70 * VOID rele() lkrloc.c
71 * VOID relp() lkrloc.c
72 * VOID relr() lkrloc.c
73 * VOId relt() lkrloc.c
76 * Refer to the called relocation functions.
103 fprintf(stderr, "Undefined Relocation Operation\n");
111 /*)Function VOID relt()
113 * The function relt() evaluates a T line read by
114 * the linker. Each byte value read is saved in the
115 * rtval[] array, rtflg[] is set, and the number of
116 * evaluations is maintained in rtcnt.
120 * T xx xx nn nn nn nn nn ...
123 * In: "T n0 n1 n2 n3 ... nn"
125 * Out: 0 1 2 .. rtcnt
126 * +----+----+----+----+----+
127 * rtval | n0 | n1 | n2 | .. | nn |
128 * +----+----+----+----+----+
129 * rtflag| 1 | 1 | 1 | 1 | 1 |
130 * +----+----+----+----+----+
132 * The T line contains the assembled code output by the assem-
133 * bler with xx xx being the offset address from the current area
134 * base address and nn being the assembled instructions and data in
141 * int rtcnt number of values evaluated
142 * int rtflg[] array of evaluation flags
143 * int rtval[] array of evaluation values
146 * int eval() lkeval.c
150 * Linker input T line evaluated.
160 rtval[rtcnt] = eval();
167 /*)Function VOID relr()
169 * The function relr() evaluates a R line read by
170 * the linker. The R line data is combined with the
171 * previous T line data to perform the relocation of
172 * code and data bytes. The S19 / IHX output and
173 * translation of the LST files to RST files may be
178 * R 0 0 nn nn n1 n2 xx xx ...
180 * The R line provides the relocation information to the linker.
181 * The nn nn value is the current area index, i.e. which area the
182 * current values were assembled. Relocation information is en-
183 * coded in groups of 4 bytes:
185 * 1. n1 is the relocation mode and object format
186 * 1. bit 0 word(0x00)/byte(0x01)
187 * 2. bit 1 relocatable area(0x00)/symbol(0x02)
188 * 3. bit 2 normal(0x00)/PC relative(0x04) relocation
189 * 4. bit 3 1-byte(0x00)/2-byte(0x08) object format for
191 * 5. bit 4 signed(0x00)/unsigned(0x10) byte data
192 * 6. bit 5 normal(0x00)/page '0'(0x20) reference
193 * 7. bit 6 normal(0x00)/page 'nnn'(0x40) reference
195 * 2. n2 is a byte index into the corresponding (i.e. pre-
196 * ceeding) T line data (i.e. a pointer to the data to be
197 * updated by the relocation). The T line data may be
198 * 1-byte or 2-byte byte data format or 2-byte word
201 * 3. xx xx is the area/symbol index for the area/symbol be-
202 * ing referenced. the corresponding area/symbol is found
203 * in the header area/symbol lists.
205 * The groups of 4 bytes are repeated for each item requiring relo-
206 * cation in the preceeding T line.
209 * areax **a pointer to array of area pointers
210 * int aindex area index
211 * char *errmsg[] array of pointers to error strings
212 * int error error code
213 * int lkerr error flag
214 * int mode relocation mode
215 * adrr_t paga paging base area address
216 * addr_t pags paging symbol address
217 * addr_t pc relocated base address
218 * addr_t r PCR relocation value
219 * addr_t reli relocation initial value
220 * addr_t relv relocation final value
221 * int rindex symbol / area index
222 * addr_t rtbase base code address
223 * addr_t rtofst rtval[] index offset
224 * int rtp index into T data
225 * sym **s pointer to array of symbol pointers
228 * head *hp pointer to the head structure
229 * rerr rerr linker error structure
230 * FILE *stderr standard error device
233 * addr_t adb_b() lkrloc.c
234 * addr_t adb_lo() lkrloc.c
235 * addr_t adb_hi() lkrloc.c
236 * addr_t adw_w() lkrloc.c
237 * addr_t evword() lkrloc.c
238 * int eval() lkeval.c
239 * int fprintf() c_library
241 * int lkulist lklist.c
243 * VOID relerr() lkrloc.c
245 * int symval() lksym.c
248 * The R and T lines are combined to produce
249 * relocated code and data. Output S19 / IHX
250 * and relocated listing files may be produced.
258 register addr_t reli, relv;
259 int aindex, rindex, rtp, error;
260 addr_t r, rtbase, rtofst, paga, pags, pc;
265 * Get area and symbol lists
273 if (eval() != (R_WORD | R_AREA) || eval()) {
274 fprintf(stderr, "R input error\n");
282 if (aindex >= hp->h_narea) {
283 fprintf(stderr, "R area error\n");
291 rtbase = adw_w(0, 0);
297 pc = adw_w(a[aindex]->a_addr, 0);
300 printf("area %d base address: 0x%x size: 0x%x rtbase: 0x%x\n", aindex,
301 a[aindex]->a_addr, a[aindex]->a_size, rtbase);
304 * Do remaining relocations
310 if ((mode & R_ESCAPE_MASK) == R_ESCAPE_MASK)
312 mode = ((mode & ~R_ESCAPE_MASK) << 8) | eval();
313 /* printf("unescaping rmode\n"); */
320 * R_SYM or R_AREA references
323 if (rindex >= hp->h_nglob) {
324 fprintf(stderr, "R symbol error\n");
328 reli = symval(s[rindex]);
330 if (rindex >= hp->h_narea) {
331 fprintf(stderr, "R area error\n");
335 reli = a[rindex]->a_addr;
343 reli -= (pc + (rtp-rtofst) + 1);
345 reli -= (pc + (rtp-rtofst) + 2);
350 * R_PAG0 or R_PAG addressing
352 if (mode & (R_PAG0 | R_PAG)) {
353 paga = sdp.s_area->a_addr;
359 * R_BYTE or R_WORD operation
364 /* This is a three byte address, of which
365 * we will select one byte.
369 /* printf("24 bit address selecting hi byte.\n"); */
370 relv = adb_24_hi(reli, rtp);
372 else if (mode & R_MSB)
374 /* Note that in 24 bit mode, R_MSB
375 * is really the middle byte, not
376 * the most significant byte.
378 * This is ugly and I can only apologize
381 /* printf("24 bit address selecting middle byte.\n"); */
382 relv = adb_24_mid(reli, rtp);
386 /* printf("24 bit address selecting lo byte.\n"); */
387 relv = adb_24_lo(reli, rtp);
390 else if (mode & R_BYT2) {
391 /* This is a two byte address, of
392 * which we will select one byte.
395 relv = adb_hi(reli, rtp);
397 relv = adb_lo(reli, rtp);
400 relv = adb_b(reli, rtp);
402 } else if (IS_R_J11(mode)) {
403 /* JLH: 11 bit jump destination for 8051. Forms
404 / two byte instruction with op-code bits
406 / rtp points at 3 byte locus: first two
407 / will get the instructiion. third one
411 /* Calculate absolute destination
412 / relv must be on same 2K page as pc
414 relv = adw_w(reli, rtp);
416 if ((relv & ~0x7ff) != ((pc + rtp - rtofst) & ~0x7ff)) {
420 /* Merge MSB (byte 0) with op-code, ignoring
421 / top 5 bits of address. Then hide the op-code
423 rtval[rtp] = ((rtval[rtp] & 0x07)<<5) | rtval[rtp+2];
427 else if (IS_R_J19(mode)) {
428 /* 19 bit jump destination for DS80C390. Forms
429 / three byte instruction with op-code bits
431 / rtp points at 4 byte locus: first three
432 / will get the instructiion. fourth one
436 /* Calculate absolute destination
437 / relv must be on same 512K page as pc
439 relv = adw_24(reli, rtp);
441 if ((relv & ~0x7ffff) != ((pc + rtp - rtofst) & ~0x7ffff)) {
445 /* Merge MSB (byte 0) with op-code, ignoring
446 / top 5 bits of address. Then hide the op-code
448 rtval[rtp] = ((rtval[rtp] & 0x07)<<5) | rtval[rtp+3];
452 else if (IS_C24(mode))
455 relv = adw_24(reli, rtp);
459 /* 16 bit address. */
460 relv = adw_w(reli, rtp);
464 * R_BYTE with R_BYT2 offset adjust
473 * Unsigned Byte Checking
475 if (mode & R_USGN && mode & R_BYTE && relv & ~0xFF)
479 * PCR Relocation Error Checking
481 if (mode & R_PCR && mode & R_BYTE) {
483 if (r != (addr_t) ~0x7F && r != 0)
488 * Page Relocation Error Checking
490 /* if (mode & R_PAG0 && (relv & ~0xFF || paga || pags))
492 if (mode & R_PAG && (relv & ~0xFF))
499 rerr.aindex = aindex;
501 rerr.rtbase = rtbase + rtp - rtofst - 1;
502 rerr.rindex = rindex;
503 rerr.rval = relv - reli;
504 relerr(errmsg[error-1]);
511 /* JLH: output only if data (beyond two byte address) */
512 if ((oflag == 1) && (rtcnt > 2)) {
513 int extendedAddress = (a[aindex]->a_addr >> 16) & 0xffff;
515 /* Boy, is this a hack: for ABS sections, the
516 * base address is stored as zero, and the T records
517 * indicate the offset from zero.
519 * Since T records can only indicate a 16 bit offset, this
520 * obviously creates a problem for ABS segments located
521 * above 64K (this is only meaningful in flat24 mode).
523 * However, the size of an ABS area is stored as
524 * base address + section size (I suspect this is a bug,
525 * but it's a handy one right now). So the upper 8 bits of
526 * the 24 bit address are stored in the size record.
529 * This is another reason why we can't have areas greater
530 * than 64K yet, even in flat24 mode.
532 extendedAddress += ((a[aindex]->a_size) >> 16 & 0xffff);
534 if (extendedAddress != lastExtendedAddress)
538 printf("output extended linear address record 0x%x\n",
544 ihxEntendedLinearAddress(extendedAddress);
546 else if (extendedAddress)
548 /* Not allowed to generate extended address records,
549 * but one is called for here...
552 "warning: extended linear address encountered; "
553 "you probably want the -r flag.\n");
555 lastExtendedAddress = extendedAddress;
559 if ((oflag == 2) && (rtcnt > 2)) {
565 "Unsigned Byte error",
566 "Byte PCR relocation error",
567 "Page0 relocation error",
568 "Page Mode relocation error"
572 /*)Function VOID relp()
574 * The function relp() evaluates a P line read by
575 * the linker. The P line data is combined with the
576 * previous T line data to set the base page address
577 * and test the paging boundary and length.
581 * P 0 0 nn nn n1 n2 xx xx
583 * The P line provides the paging information to the linker as
584 * specified by a .setdp directive. The format of the relocation
585 * information is identical to that of the R line. The correspond-
586 * ing T line has the following information:
587 * T xx xx aa aa bb bb
589 * Where aa aa is the area reference number which specifies the
590 * selected page area and bb bb is the base address of the page.
591 * bb bb will require relocation processing if the 'n1 n2 xx xx' is
592 * specified in the P line. The linker will verify that the base
593 * address is on a 256 byte boundary and that the page length of an
594 * area defined with the PAG type is not larger than 256 bytes.
597 * areax **a pointer to array of area pointers
598 * int aindex area index
599 * int mode relocation mode
600 * addr_t relv relocation value
601 * int rindex symbol / area index
602 * int rtp index into T data
603 * sym **s pointer to array of symbol pointers
606 * head *hp pointer to the head structure
607 * int lkerr error flag
608 * sdp sdp base page structure
609 * FILE *stderr standard error device
612 * addr_t adw_w() lkrloc.c
613 * addr_t evword() lkrloc.c
614 * int eval() lkeval.c
615 * int fprintf() c_library
617 * int symval() lksym.c
620 * The P and T lines are combined to set
621 * the base page address and report any
629 register int aindex, rindex;
636 * Get area and symbol lists
644 if (eval() != (R_WORD | R_AREA) || eval()) {
645 fprintf(stderr, "P input error\n");
653 if (aindex >= hp->h_narea) {
654 fprintf(stderr, "P area error\n");
660 * Do remaining relocations
668 * R_SYM or R_AREA references
671 if (rindex >= hp->h_nglob) {
672 fprintf(stderr, "P symbol error\n");
676 relv = symval(s[rindex]);
678 if (rindex >= hp->h_narea) {
679 fprintf(stderr, "P area error\n");
683 relv = a[rindex]->a_addr;
692 if (aindex >= hp->h_narea) {
693 fprintf(stderr, "P area error\n");
697 sdp.s_areax = a[aindex];
698 sdp.s_area = sdp.s_areax->a_bap;
699 sdp.s_addr = adw_w(0,4);
700 if (sdp.s_area->a_addr & 0xFF || sdp.s_addr & 0xFF)
701 relerp("Page Definition Boundary Error");
704 /*)Function VOID rele()
706 * The function rele() closes all open output files
707 * at the end of the linking process.
713 * int oflag output type flag
714 * int uflag relocation listing flag
718 * VOID lkulist() lklist.c
722 * All open output files are closed.
740 /*)Function addr_t evword()
742 * The function evword() combines two byte values
743 * into a single word value.
746 * addr_t v temporary evaluation variable
749 * hilo byte ordering parameter
752 * int eval() lkeval.c
755 * Relocation text line is scanned to combine
756 * two byte values into a single word value.
775 /*)Function addr_t adb_b(v, i)
777 * int v value to add to byte
778 * int i rtval[] index
780 * The function adb_b() adds the value of v to
781 * the single byte value contained in rtval[i].
782 * The new value of rtval[i] is returned.
794 * The value of rtval[] is changed.
803 return(rtval[i] += v);
806 /*)Function addr_t adb_lo(v, i)
808 * int v value to add to byte
809 * int i rtval[] index
811 * The function adb_lo() adds the value of v to the
812 * double byte value contained in rtval[i] and rtval[i+1].
813 * The new value of rtval[i] / rtval[i+1] is returned.
814 * The MSB rtflg[] is cleared.
817 * addr_t j temporary evaluation variable
820 * hilo byte ordering parameter
826 * The value of rtval[] is changed.
827 * The rtflg[] value corresponding to the
828 * MSB of the word value is cleared to reflect
829 * the fact that the LSB is the selected byte.
852 /*)Function addr_t adb_hi(v, i)
854 * int v value to add to byte
855 * int i rtval[] index
857 * The function adb_hi() adds the value of v to the
858 * double byte value contained in rtval[i] and rtval[i+1].
859 * The new value of rtval[i] / rtval[i+1] is returned.
860 * The LSB rtflg[] is cleared.
863 * addr_t j temporary evaluation variable
866 * hilo byte ordering parameter
872 * The value of rtval[] is changed.
873 * The rtflg[] value corresponding to the
874 * LSB of the word value is cleared to reflect
875 * the fact that the MSB is the selected byte.
898 /*)Function addr_t adb_24_hi(v, i)
900 * int v value to add to byte
901 * int i rtval[] index
903 * The function adb_24_hi() adds the value of v to the
904 * 24 bit value contained in rtval[i] - rtval[i+2].
905 * The new value of rtval[i] / rtval[i+1] is returned.
906 * The LSB & middle byte rtflg[] is cleared.
909 * addr_t j temporary evaluation variable
912 * hilo byte ordering parameter
918 * The value of rtval[] is changed.
919 * The rtflg[] value corresponding to the
920 * LSB & middle byte of the word value is cleared to
921 * reflect the fact that the MSB is the selected byte.
926 adb_24_hi(addr_t v, int i)
932 /* Remove the lower two bytes. */
946 /*)Function addr_t adb_24_mid(v, i)
948 * int v value to add to byte
949 * int i rtval[] index
951 * The function adb_24_mid() adds the value of v to the
952 * 24 bit value contained in rtval[i] - rtval[i+2].
953 * The new value of rtval[i] / rtval[i+1] is returned.
954 * The LSB & MSB byte rtflg[] is cleared.
957 * addr_t j temporary evaluation variable
960 * hilo byte ordering parameter
966 * The value of rtval[] is changed.
967 * The rtflg[] value corresponding to the
968 * LSB & MSB of the 24 bit value is cleared to reflect
969 * the fact that the middle byte is the selected byte.
974 adb_24_mid(addr_t v, int i)
980 /* remove the MSB & LSB. */
987 /*)Function addr_t adb_24_lo(v, i)
989 * int v value to add to byte
990 * int i rtval[] index
992 * The function adb_24_lo() adds the value of v to the
993 * 24 bit value contained in rtval[i] - rtval[i+2].
994 * The new value of rtval[i] / rtval[i+1] is returned.
995 * The MSB & middle byte rtflg[] is cleared.
998 * addr_t j temporary evaluation variable
1001 * hilo byte ordering parameter
1007 * The value of rtval[] is changed.
1008 * The rtflg[] value corresponding to the
1009 * MSB & middle byte of the word value is cleared to
1010 * reflect the fact that the LSB is the selected byte.
1015 adb_24_lo(addr_t v, int i)
1021 /* Remove the upper two bytes. */
1035 /*)Function addr_t adw_w(v, i)
1037 * int v value to add to word
1038 * int i rtval[] index
1040 * The function adw_w() adds the value of v to the
1041 * word value contained in rtval[i] and rtval[i+1].
1042 * The new value of rtval[i] / rtval[i+1] is returned.
1045 * addr_t j temporary evaluation variable
1048 * hilo byte ordering parameter
1054 * The word value of rtval[] is changed.
1066 j = v + (rtval[i] << 8) + (rtval[i+1] & 0xff);
1067 rtval[i] = (j >> 8) & 0xff;
1068 rtval[i+1] = j & 0xff;
1070 j = v + (rtval[i] & 0xff) + (rtval[i+1] << 8);
1071 rtval[i] = j & 0xff;
1072 rtval[i+1] = (j >> 8) & 0xff;
1077 /*)Function addr_t adw_24(v, i)
1079 * int v value to add to word
1080 * int i rtval[] index
1082 * The function adw_w() adds the value of v to the
1083 * 24 bit value contained in rtval[i] - rtval[i+2].
1084 * The new value of rtval[i] - rtval[i+2] is returned.
1087 * addr_t j temporary evaluation variable
1090 * hilo byte ordering parameter
1096 * The word value of rtval[] is changed.
1100 adw_24(addr_t v, int i)
1105 j = v + ((rtval[i] & 0xff) << 16)
1106 + ((rtval[i+1] & 0xff) << 8)
1107 + (rtval[i+2] & 0xff);
1108 rtval[i] = (j >> 16) & 0xff;
1109 rtval[i+1] = (j >> 8) & 0xff;
1110 rtval[i+2] = j & 0xff;
1112 j = v + (rtval[i] & 0xff)
1113 + ((rtval[i+1] & 0xff) << 8)
1114 + ((rtval[i+2] & 0xff) << 16);
1115 rtval[i] = j & 0xff;
1116 rtval[i+1] = (j >> 8) & 0xff;
1117 rtval[i+2] = (j >> 16) & 0xff;
1122 /*)Function addr_t adw_lo(v, i)
1124 * int v value to add to byte
1125 * int i rtval[] index
1127 * The function adw_lo() adds the value of v to the
1128 * double byte value contained in rtval[i] and rtval[i+1].
1129 * The new value of rtval[i] / rtval[i+1] is returned.
1130 * The MSB rtval[] is zeroed.
1133 * addr_t j temporary evaluation variable
1136 * hilo byte ordering parameter
1142 * The value of rtval[] is changed.
1143 * The MSB of the word value is cleared to reflect
1144 * the fact that the LSB is the selected byte.
1167 /*)Function addr_t adw_hi(v, i)
1169 * int v value to add to byte
1170 * int i rtval[] index
1172 * The function adw_hi() adds the value of v to the
1173 * double byte value contained in rtval[i] and rtval[i+1].
1174 * The new value of rtval[i] / rtval[i+1] is returned.
1175 * The MSB and LSB values are interchanged.
1176 * The MSB rtval[] is zeroed.
1179 * addr_t j temporary evaluation variable
1182 * hilo byte ordering parameter
1188 * The value of rtval[] is changed.
1189 * The MSB and LSB values are interchanged and
1190 * then the MSB cleared.
1203 * LSB = MSB, Clear MSB
1206 rtval[i+1] = rtval[i];
1209 rtval[i] = rtval[i+1];
1215 /*)Function VOID relerr(str)
1217 * char *str error string
1219 * The function relerr() outputs the error string to
1220 * stderr and to the map file (if it is open).
1226 * FILE *mfp handle for the map file
1229 * VOID errdmp() lkrloc.c
1232 * Error message inserted into map file.
1240 errdmp(stderr, str);
1245 /*)Function VOID errdmp(fptr, str)
1247 * FILE *fptr output file handle
1248 * char *str error string
1250 * The function errdmp() outputs the error string str
1251 * to the device specified by fptr. Additional information
1252 * is output about the definition and referencing of
1253 * the symbol / area error.
1256 * int mode error mode
1257 * int aindex area index
1258 * int lkerr error flag
1259 * int rindex error index
1260 * sym **s pointer to array of symbol pointers
1261 * areax **a pointer to array of area pointers
1262 * areax *raxp error area extension pointer
1265 * sdp sdp base page structure
1268 * int fprintf() c_library
1269 * VOID prntval() lkrloc.c
1281 int mode, aindex, rindex;
1290 aindex = rerr.aindex;
1291 rindex = rerr.rindex;
1296 fprintf(fptr, "\n?ASlink-Warning-%s", str);
1300 * Print symbol if symbol based
1303 fprintf(fptr, " for symbol %s\n",
1304 &s[rindex]->s_id[0]);
1306 fprintf(fptr, "\n");
1313 " file module area offset\n");
1315 " Refby %-8.8s %-8.8s %-8.8s ",
1318 &a[aindex]->a_bap->a_id[0]);
1319 prntval(fptr, rerr.rtbase);
1325 raxp = s[rindex]->s_axp;
1330 " Defin %-8.8s %-8.8s %-8.8s ",
1331 raxp->a_bhp->h_lfile->f_idp,
1332 &raxp->a_bhp->m_id[0],
1333 &raxp->a_bap->a_id[0]);
1335 prntval(fptr, s[rindex]->s_addr);
1337 prntval(fptr, rerr.rval);
1341 /*)Function VOID prntval(fptr, v)
1343 * FILE *fptr output file handle
1344 * addr_t v value to output
1346 * The function prntval() outputs the value v, in the
1347 * currently selected radix, to the device specified
1354 * int xflag current radix
1357 * int fprintf() c_library
1370 fprintf(fptr, "%04X\n", v);
1373 fprintf(fptr, "%06o\n", v);
1376 fprintf(fptr, "%05u\n", v);
1380 /*)Function VOID relerp(str)
1382 * char *str error string
1384 * The function relerp() outputs the paging error string to
1385 * stderr and to the map file (if it is open).
1391 * FILE *mfp handle for the map file
1394 * VOID erpdmp() lkrloc.c
1397 * Error message inserted into map file.
1405 erpdmp(stderr, str);
1410 /*)Function VOID erpdmp(fptr, str)
1412 * FILE *fptr output file handle
1413 * char *str error string
1415 * The function erpdmp() outputs the error string str
1416 * to the device specified by fptr.
1419 * head *thp pointer to head structure
1422 * int lkerr error flag
1423 * sdp sdp base page structure
1426 * int fprintf() c_library
1427 * VOID prntval() lkrloc.c
1439 register struct head *thp;
1441 thp = sdp.s_areax->a_bhp;
1446 fprintf(fptr, "\n?ASlink-Warning-%s\n", str);
1453 " file module pgarea pgoffset\n");
1455 " PgDef %-8.8s %-8.8s %-8.8s ",
1456 thp->h_lfile->f_idp,
1458 &sdp.s_area->a_id[0]);
1459 prntval(fptr, sdp.s_area->a_addr + sdp.s_addr);