3 Copyright (C) 1989-1995 Alan R. Baldwin
4 721 Berkeley St., Kent, Ohio 44240
6 This program is free software; you can redistribute it and/or modify it
7 under the terms of the GNU General Public License as published by the
8 Free Software Foundation; either version 3, or (at your option) any
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program. If not, see <http://www.gnu.org/licenses/>. */
21 * - errdmp: show s_id as string rather than array [NCPS]
22 * - relr: add support for 11 bit 8051 addressing
23 * 02-Apr-98 JLH: don't output empty hex records
32 * The module lkrloc.c contains the functions which
33 * perform the relocation calculations.
35 * lkrloc.c contains the following functions:
54 * lkrloc.c the local variable errmsg[].
58 /* Global which holds the upper 16 bits of the last 32 bit area adress
59 * output. Useful only for iHex mode.
61 int lastExtendedAddress=-1;
63 /* Static variable which holds the index of last processed area.
64 * Useful only for iHex mode.
66 static int lastAreaIndex = -1;
68 /*)Function VOID reloc(c)
72 * The function reloc() calls a particular relocation
73 * function determined by the process code.
79 * int lkerr error flag
82 * int fprintf() c_library
83 * VOID rele() lkrloc.c
84 * VOID relp() lkrloc.c
85 * VOID relr() lkrloc.c
86 * VOId relt() lkrloc.c
89 * Refer to the called relocation functions.
114 fprintf(stderr, "Undefined Relocation Operation\n");
122 /*)Function VOID relt()
124 * The function relt() evaluates a T line read by
125 * the linker. Each byte value read is saved in the
126 * rtval[] array, rtflg[] is set, and the number of
127 * evaluations is maintained in rtcnt.
131 * T xx xx nn nn nn nn nn ...
134 * In: "T n0 n1 n2 n3 ... nn"
136 * Out: 0 1 2 .. rtcnt
137 * +----+----+----+----+----+
138 * rtval | n0 | n1 | n2 | .. | nn |
139 * +----+----+----+----+----+
140 * rtflag| 1 | 1 | 1 | 1 | 1 |
141 * +----+----+----+----+----+
143 * The T line contains the assembled code output by the assem-
144 * bler with xx xx being the offset address from the current area
145 * base address and nn being the assembled instructions and data in
152 * int rtcnt number of values evaluated
153 * int rtflg[] array of evaluation flags
154 * int rtval[] array of evaluation values
157 * int eval() lkeval.c
161 * Linker input T line evaluated.
170 rtval[rtcnt] = eval();
177 /*)Function VOID relr()
179 * The function relr() evaluates a R line read by
180 * the linker. The R line data is combined with the
181 * previous T line data to perform the relocation of
182 * code and data bytes. The S19 / IHX output and
183 * translation of the LST files to RST files may be
188 * R 0 0 nn nn n1 n2 xx xx ...
190 * The R line provides the relocation information to the linker.
191 * The nn nn value is the current area index, i.e. which area the
192 * current values were assembled. Relocation information is en-
193 * coded in groups of 4 bytes:
195 * 1. n1 is the relocation mode and object format
196 * 1. bit 0 word(0x00)/byte(0x01)
197 * 2. bit 1 relocatable area(0x00)/symbol(0x02)
198 * 3. bit 2 normal(0x00)/PC relative(0x04) relocation
199 * 4. bit 3 1-byte(0x00)/2-byte(0x08) object format for
201 * 5. bit 4 signed(0x00)/unsigned(0x10) byte data
202 * 6. bit 5 normal(0x00)/page '0'(0x20) reference
203 * 7. bit 6 normal(0x00)/page 'nnn'(0x40) reference
205 * 2. n2 is a byte index into the corresponding (i.e. pre-
206 * ceeding) T line data (i.e. a pointer to the data to be
207 * updated by the relocation). The T line data may be
208 * 1-byte or 2-byte byte data format or 2-byte word
211 * 3. xx xx is the area/symbol index for the area/symbol be-
212 * ing referenced. the corresponding area/symbol is found
213 * in the header area/symbol lists.
215 * The groups of 4 bytes are repeated for each item requiring relo-
216 * cation in the preceeding T line.
219 * areax **a pointer to array of area pointers
220 * int aindex area index
221 * char *errmsg[] array of pointers to error strings
222 * int error error code
223 * int lkerr error flag
224 * int mode relocation mode
225 * adrr_t paga paging base area address
226 * Addr_T pags paging symbol address
227 * Addr_T pc relocated base address
228 * Addr_T r PCR relocation value
229 * Addr_T reli relocation initial value
230 * Addr_T relv relocation final value
231 * int rindex symbol / area index
232 * Addr_T rtbase base code address
233 * Addr_T rtofst rtval[] index offset
234 * int rtp index into T data
235 * sym **s pointer to array of symbol pointers
238 * head *hp pointer to the head structure
239 * rerr rerr linker error structure
240 * FILE *stderr standard error device
243 * Addr_T adb_b() lkrloc.c
244 * Addr_T adb_lo() lkrloc.c
245 * Addr_T adb_hi() lkrloc.c
246 * Addr_T adw_w() lkrloc.c
247 * Addr_T evword() lkrloc.c
248 * int eval() lkeval.c
249 * int fprintf() c_library
251 * int lkulist lklist.c
253 * VOID relerr() lkrloc.c
255 * int symval() lksym.c
258 * The R and T lines are combined to produce
259 * relocated code and data. Output S19 / IHX
260 * and relocated listing files may be produced.
267 register Addr_T reli, relv;
268 int aindex, rindex, rtp, error;
269 Addr_T r, rtbase, rtofst, paga, pags, pc;
274 * Get area and symbol lists
282 if (eval() != (R_WORD | R_AREA) || eval()) {
283 fprintf(stderr, "R input error\n");
291 if (aindex >= hp->h_narea) {
292 fprintf(stderr, "R area error\n");
300 rtbase = adw_w(0, 0);
306 pc = adw_w(a[aindex]->a_addr, 0);
309 printf("area %d base address: 0x%x size: 0x%x rtbase: 0x%x\n", aindex,
310 a[aindex]->a_addr, a[aindex]->a_size, rtbase);
313 * Do remaining relocations
319 if ((mode & R_ESCAPE_MASK) == R_ESCAPE_MASK)
321 mode = ((mode & ~R_ESCAPE_MASK) << 8) | eval();
322 /* printf("unescaping rmode\n"); */
329 * R_SYM or R_AREA references
332 if (rindex >= hp->h_nglob) {
333 fprintf(stderr, "R symbol error\n");
337 reli = symval(s[rindex]);
338 } else if ((IS_R_J11(mode) || IS_R_J19(mode)) && (rindex == 0xFFFF)) {
339 /* absolute acall/ajmp address */
342 if (rindex >= hp->h_narea) {
343 fprintf(stderr, "R area error\n");
347 reli = a[rindex]->a_addr;
355 reli -= (pc + (rtp-rtofst) + 1);
357 reli -= (pc + (rtp-rtofst) + 2);
362 * R_PAG0 or R_PAG addressing
364 if (mode & (R_PAG0 | R_PAG)) {
365 paga = sdp.s_area->a_addr;
371 * R_BYTE or R_WORD operation
376 /* This is a three byte address, of which
377 * we will select one byte.
381 relv = adb_24_bit(reli, rtp);
383 else if (mode & R_HIB)
385 /* printf("24 bit address selecting hi byte.\n"); */
386 relv = adb_24_hi(reli, rtp);
388 else if (mode & R_MSB)
390 /* Note that in 24 bit mode, R_MSB
391 * is really the middle byte, not
392 * the most significant byte.
394 * This is ugly and I can only apologize
397 /* printf("24 bit address selecting middle byte.\n"); */
398 relv = adb_24_mid(reli, rtp);
402 /* printf("24 bit address selecting lo byte.\n"); */
403 relv = adb_24_lo(reli, rtp);
406 else if (mode & R_BYT2) {
407 /* This is a two byte address, of
408 * which we will select one byte.
411 relv = adb_bit(reli, rtp);
412 } else if (mode & R_MSB) {
413 relv = adb_hi(reli, rtp);
415 relv = adb_lo(reli, rtp);
418 relv = adb_b(reli, rtp);
420 } else if (IS_R_J11(mode)) {
421 /* JLH: 11 bit jump destination for 8051. Forms
422 / two byte instruction with op-code bits
424 / rtp points at 3 byte locus: first two
425 / will get the instructiion. third one
429 /* Calculate absolute destination
430 / relv must be on same 2K page as pc
432 relv = adw_w(reli, rtp);
434 if ((relv & ~0x7ff) != ((pc + rtp - rtofst) & ~0x7ff)) {
438 /* Merge MSB (byte 0) with op-code, ignoring
439 / top 5 bits of address. Then hide the op-code
441 rtval[rtp] = ((rtval[rtp] & 0x07)<<5) | rtval[rtp+2];
445 else if (IS_R_J19(mode)) {
446 /* 19 bit jump destination for DS80C390. Forms
447 / three byte instruction with op-code bits
449 / rtp points at 4 byte locus: first three
450 / will get the instructiion. fourth one
454 /* Calculate absolute destination
455 / relv must be on same 512K page as pc
457 relv = adw_24(reli, rtp);
459 if ((relv & ~0x7ffff) != ((pc + rtp - rtofst) & ~0x7ffff)) {
463 /* Merge MSB (byte 0) with op-code, ignoring
464 / top 5 bits of address. Then hide the op-code
466 rtval[rtp] = ((rtval[rtp] & 0x07)<<5) | rtval[rtp+3];
470 else if (IS_C24(mode))
473 relv = adw_24(reli, rtp);
477 /* 16 bit address. */
478 relv = adw_w(reli, rtp);
482 * R_BYTE with R_BYT2 offset adjust
491 * Unsigned Byte Checking
493 if (mode & R_USGN && mode & R_BYTE && relv & ~0xFF)
497 * PCR Relocation Error Checking
499 if (mode & R_PCR && mode & R_BYTE) {
501 if (r != (Addr_T) ~0x7F && r != 0)
506 * Page Relocation Error Checking
508 /* if (mode & R_PAG0 && (relv & ~0xFF || paga || pags))
510 if (mode & R_PAG && (relv & ~0xFF))
512 if ((mode & R_BIT) && (relv & ~0x87FF))
519 rerr.aindex = aindex;
521 rerr.rtbase = rtbase + rtp - rtofst - 1;
522 rerr.rindex = rindex;
523 rerr.rval = relv - reli;
524 relerr(errmsg[error-1]);
531 /* JLH: output only if data (beyond two byte address) */
532 if ((oflag == 1) && (rtcnt > 2)) {
533 int extendedAddress = (a[aindex]->a_addr >> 16) & 0xffff;
535 /* Boy, is this a hack: for ABS sections, the
536 * base address is stored as zero, and the T records
537 * indicate the offset from zero.
539 * Since T records can only indicate a 16 bit offset, this
540 * obviously creates a problem for ABS segments located
541 * above 64K (this is only meaningful in flat24 mode).
543 * However, the size of an ABS area is stored as
544 * base address + section size (I suspect this is a bug,
545 * but it's a handy one right now). So the upper 8 bits of
546 * the 24 bit address are stored in the size record.
549 * This is another reason why we can't have areas greater
550 * than 64K yet, even in flat24 mode.
552 // extendedAddress += ((a[aindex]->a_size) >> 16 & 0xffff);
553 // commented out by jr
555 if (lastAreaIndex != aindex) {
556 lastAreaIndex = aindex;
560 if (extendedAddress != lastExtendedAddress)
563 if (lastExtendedAddress!=-1) {
564 printf("output extended linear address record 0x%x 0x%x\n",
565 extendedAddress, lastExtendedAddress);
570 ihxExtendedLinearAddress(extendedAddress);
572 else if (extendedAddress)
574 /* Not allowed to generate extended address records,
575 * but one is called for here...
578 "warning: extended linear address encountered; "
579 "you probably want the -r flag.\n");
581 lastExtendedAddress = extendedAddress;
585 if ((oflag == 2) && (rtcnt > 2)) {
591 "Unsigned Byte error",
592 "Byte PCR relocation error",
593 "Page0 relocation error",
594 "Page Mode relocation error",
595 "Bit-addressable relocation error"
599 /*)Function VOID relp()
601 * The function relp() evaluates a P line read by
602 * the linker. The P line data is combined with the
603 * previous T line data to set the base page address
604 * and test the paging boundary and length.
608 * P 0 0 nn nn n1 n2 xx xx
610 * The P line provides the paging information to the linker as
611 * specified by a .setdp directive. The format of the relocation
612 * information is identical to that of the R line. The correspond-
613 * ing T line has the following information:
614 * T xx xx aa aa bb bb
616 * Where aa aa is the area reference number which specifies the
617 * selected page area and bb bb is the base address of the page.
618 * bb bb will require relocation processing if the 'n1 n2 xx xx' is
619 * specified in the P line. The linker will verify that the base
620 * address is on a 256 byte boundary and that the page length of an
621 * area defined with the PAG type is not larger than 256 bytes.
624 * areax **a pointer to array of area pointers
625 * int aindex area index
626 * int mode relocation mode
627 * Addr_T relv relocation value
628 * int rindex symbol / area index
629 * int rtp index into T data
630 * sym **s pointer to array of symbol pointers
633 * head *hp pointer to the head structure
634 * int lkerr error flag
635 * sdp sdp base page structure
636 * FILE *stderr standard error device
639 * Addr_T adw_w() lkrloc.c
640 * Addr_T evword() lkrloc.c
641 * int eval() lkeval.c
642 * int fprintf() c_library
644 * int symval() lksym.c
647 * The P and T lines are combined to set
648 * the base page address and report any
655 register int aindex, rindex;
662 * Get area and symbol lists
670 if (eval() != (R_WORD | R_AREA) || eval()) {
671 fprintf(stderr, "P input error\n");
679 if (aindex >= hp->h_narea) {
680 fprintf(stderr, "P area error\n");
686 * Do remaining relocations
694 * R_SYM or R_AREA references
697 if (rindex >= hp->h_nglob) {
698 fprintf(stderr, "P symbol error\n");
702 relv = symval(s[rindex]);
704 if (rindex >= hp->h_narea) {
705 fprintf(stderr, "P area error\n");
709 relv = a[rindex]->a_addr;
718 if (aindex >= hp->h_narea) {
719 fprintf(stderr, "P area error\n");
723 sdp.s_areax = a[aindex];
724 sdp.s_area = sdp.s_areax->a_bap;
725 sdp.s_addr = adw_w(0,4);
726 if (sdp.s_area->a_addr & 0xFF || sdp.s_addr & 0xFF)
727 relerp("Page Definition Boundary Error");
730 /*)Function VOID rele()
732 * The function rele() closes all open output files
733 * at the end of the linking process.
739 * int oflag output type flag
740 * int uflag relocation listing flag
744 * VOID lkulist() lklist.c
748 * All open output files are closed.
765 /*)Function Addr_T evword()
767 * The function evword() combines two byte values
768 * into a single word value.
771 * Addr_T v temporary evaluation variable
774 * hilo byte ordering parameter
777 * int eval() lkeval.c
780 * Relocation text line is scanned to combine
781 * two byte values into a single word value.
799 /*)Function Addr_T adb_b(v, i)
801 * int v value to add to byte
802 * int i rtval[] index
804 * The function adb_b() adds the value of v to
805 * the single byte value contained in rtval[i].
806 * The new value of rtval[i] is returned.
818 * The value of rtval[] is changed.
822 Addr_T adb_b(register Addr_T v, register int i)
824 return(rtval[i] += v);
827 /*)Function Addr_T adb_bit(v, i)
829 * int v value to add to byte
830 * int i rtval[] index
832 * The function adb_bit() converts the single
833 * byte address value contained in rtval[i] to bit-
834 * addressable space and adds the value of v to it.
835 * The new value of rtval[i] is returned.
838 * Addr_T j temporary evaluation variable
847 * The value of rtval[] is changed.
851 Addr_T adb_bit(register Addr_T v, register int i)
855 j = adb_lo(v, i) & 0xFF;
856 if ((j >= 0x20) && (j <= 0x2F)) {
858 } else if ((j < 0x80) || ((j & 0x07) != 0)) {
859 return(0x100);//error
863 j = rtval[i+1] = j + (rtval[i] & 0x07);
865 j = rtval[i] = j + (rtval[i+1] & 0x07);
870 /*)Function Addr_T adb_lo(v, i)
872 * int v value to add to byte
873 * int i rtval[] index
875 * The function adb_lo() adds the value of v to the
876 * double byte value contained in rtval[i] and rtval[i+1].
877 * The new value of rtval[i] / rtval[i+1] is returned.
878 * The MSB rtflg[] is cleared.
881 * Addr_T j temporary evaluation variable
884 * hilo byte ordering parameter
890 * The value of rtval[] is changed.
891 * The rtflg[] value corresponding to the
892 * MSB of the word value is cleared to reflect
893 * the fact that the LSB is the selected byte.
897 Addr_T adb_lo(Addr_T v, int i)
913 /*)Function Addr_T adb_hi(v, i)
915 * int v value to add to byte
916 * int i rtval[] index
918 * The function adb_hi() adds the value of v to the
919 * double byte value contained in rtval[i] and rtval[i+1].
920 * The new value of rtval[i] / rtval[i+1] is returned.
921 * The LSB rtflg[] is cleared.
924 * Addr_T j temporary evaluation variable
927 * hilo byte ordering parameter
933 * The value of rtval[] is changed.
934 * The rtflg[] value corresponding to the
935 * LSB of the word value is cleared to reflect
936 * the fact that the MSB is the selected byte.
940 Addr_T adb_hi(Addr_T v, int i)
956 /*)Function Addr_T adb_24_bit(v, i)
958 * int v value to add to byte
959 * int i rtval[] index
961 * The function adb_24_bit() converts the single
962 * byte address value contained in rtval[i] to bit-
963 * addressable space and adds the value of v to it.
964 * The new value of rtval[i] is returned.
967 * Addr_T j temporary evaluation variable
976 * The value of rtval[] is changed.
980 Addr_T adb_24_bit(register Addr_T v, register int i)
984 j = adb_24_lo(v, i) & 0xFF;
985 if ((j >= 0x20) && (j <= 0x2F)) {
987 } else if ((j < 0x80) || ((j & 0x07) != 0)) {
988 return(0x100);//error
992 j = rtval[i+2] = j + (rtval[i+1] & 0x07);
994 j = rtval[i] = j + (rtval[i+1] & 0x07);
999 /*)Function Addr_T adb_24_hi(v, i)
1001 * int v value to add to byte
1002 * int i rtval[] index
1004 * The function adb_24_hi() adds the value of v to the
1005 * 24 bit value contained in rtval[i] - rtval[i+2].
1006 * The new value of rtval[i] / rtval[i+1] is returned.
1007 * The LSB & middle byte rtflg[] is cleared.
1010 * Addr_T j temporary evaluation variable
1013 * hilo byte ordering parameter
1019 * The value of rtval[] is changed.
1020 * The rtflg[] value corresponding to the
1021 * LSB & middle byte of the word value is cleared to
1022 * reflect the fact that the MSB is the selected byte.
1026 Addr_T adb_24_hi(Addr_T v, int i)
1032 /* Remove the lower two bytes. */
1046 /*)Function Addr_T adb_24_mid(v, i)
1048 * int v value to add to byte
1049 * int i rtval[] index
1051 * The function adb_24_mid() adds the value of v to the
1052 * 24 bit value contained in rtval[i] - rtval[i+2].
1053 * The new value of rtval[i] / rtval[i+1] is returned.
1054 * The LSB & MSB byte rtflg[] is cleared.
1057 * Addr_T j temporary evaluation variable
1060 * hilo byte ordering parameter
1066 * The value of rtval[] is changed.
1067 * The rtflg[] value corresponding to the
1068 * LSB & MSB of the 24 bit value is cleared to reflect
1069 * the fact that the middle byte is the selected byte.
1073 Addr_T adb_24_mid(Addr_T v, int i)
1079 /* remove the MSB & LSB. */
1086 /*)Function Addr_T adb_24_lo(v, i)
1088 * int v value to add to byte
1089 * int i rtval[] index
1091 * The function adb_24_lo() adds the value of v to the
1092 * 24 bit value contained in rtval[i] - rtval[i+2].
1093 * The new value of rtval[i] / rtval[i+1] is returned.
1094 * The MSB & middle byte rtflg[] is cleared.
1097 * Addr_T j temporary evaluation variable
1100 * hilo byte ordering parameter
1106 * The value of rtval[] is changed.
1107 * The rtflg[] value corresponding to the
1108 * MSB & middle byte of the word value is cleared to
1109 * reflect the fact that the LSB is the selected byte.
1113 Addr_T adb_24_lo(Addr_T v, int i)
1119 /* Remove the upper two bytes. */
1133 /*)Function Addr_T adw_w(v, i)
1135 * int v value to add to word
1136 * int i rtval[] index
1138 * The function adw_w() adds the value of v to the
1139 * word value contained in rtval[i] and rtval[i+1].
1140 * The new value of rtval[i] / rtval[i+1] is returned.
1143 * Addr_T j temporary evaluation variable
1146 * hilo byte ordering parameter
1152 * The word value of rtval[] is changed.
1156 Addr_T adw_w(register Addr_T v, register int i)
1161 j = v + (rtval[i] << 8) + (rtval[i+1] & 0xff);
1162 rtval[i] = (j >> 8) & 0xff;
1163 rtval[i+1] = j & 0xff;
1165 j = v + (rtval[i] & 0xff) + (rtval[i+1] << 8);
1166 rtval[i] = j & 0xff;
1167 rtval[i+1] = (j >> 8) & 0xff;
1172 /*)Function Addr_T adw_24(v, i)
1174 * int v value to add to word
1175 * int i rtval[] index
1177 * The function adw_w() adds the value of v to the
1178 * 24 bit value contained in rtval[i] - rtval[i+2].
1179 * The new value of rtval[i] - rtval[i+2] is returned.
1182 * Addr_T j temporary evaluation variable
1185 * hilo byte ordering parameter
1191 * The word value of rtval[] is changed.
1194 Addr_T adw_24(Addr_T v, int i)
1199 j = v + ((rtval[i] & 0xff) << 16)
1200 + ((rtval[i+1] & 0xff) << 8)
1201 + (rtval[i+2] & 0xff);
1202 rtval[i] = (j >> 16) & 0xff;
1203 rtval[i+1] = (j >> 8) & 0xff;
1204 rtval[i+2] = j & 0xff;
1206 j = v + (rtval[i] & 0xff)
1207 + ((rtval[i+1] & 0xff) << 8)
1208 + ((rtval[i+2] & 0xff) << 16);
1209 rtval[i] = j & 0xff;
1210 rtval[i+1] = (j >> 8) & 0xff;
1211 rtval[i+2] = (j >> 16) & 0xff;
1216 /*)Function Addr_T adw_lo(v, i)
1218 * int v value to add to byte
1219 * int i rtval[] index
1221 * The function adw_lo() adds the value of v to the
1222 * double byte value contained in rtval[i] and rtval[i+1].
1223 * The new value of rtval[i] / rtval[i+1] is returned.
1224 * The MSB rtval[] is zeroed.
1227 * Addr_T j temporary evaluation variable
1230 * hilo byte ordering parameter
1236 * The value of rtval[] is changed.
1237 * The MSB of the word value is cleared to reflect
1238 * the fact that the LSB is the selected byte.
1242 Addr_T adw_lo(Addr_T v, int i)
1258 /*)Function Addr_T adw_hi(v, i)
1260 * int v value to add to byte
1261 * int i rtval[] index
1263 * The function adw_hi() adds the value of v to the
1264 * double byte value contained in rtval[i] and rtval[i+1].
1265 * The new value of rtval[i] / rtval[i+1] is returned.
1266 * The MSB and LSB values are interchanged.
1267 * The MSB rtval[] is zeroed.
1270 * Addr_T j temporary evaluation variable
1273 * hilo byte ordering parameter
1279 * The value of rtval[] is changed.
1280 * The MSB and LSB values are interchanged and
1281 * then the MSB cleared.
1285 Addr_T adw_hi(Addr_T v, int i)
1291 * LSB = MSB, Clear MSB
1294 rtval[i+1] = rtval[i];
1297 rtval[i] = rtval[i+1];
1303 /*)Function VOID relerr(str)
1305 * char *str error string
1307 * The function relerr() outputs the error string to
1308 * stderr and to the map file (if it is open).
1314 * FILE *mfp handle for the map file
1317 * VOID errdmp() lkrloc.c
1320 * Error message inserted into map file.
1324 VOID relerr(char *str)
1326 errdmp(stderr, str);
1331 /*)Function VOID errdmp(fptr, str)
1333 * FILE *fptr output file handle
1334 * char *str error string
1336 * The function errdmp() outputs the error string str
1337 * to the device specified by fptr. Additional information
1338 * is output about the definition and referencing of
1339 * the symbol / area error.
1342 * int mode error mode
1343 * int aindex area index
1344 * int lkerr error flag
1345 * int rindex error index
1346 * sym **s pointer to array of symbol pointers
1347 * areax **a pointer to array of area pointers
1348 * areax *raxp error area extension pointer
1351 * sdp sdp base page structure
1354 * int fprintf() c_library
1355 * VOID prntval() lkrloc.c
1362 VOID errdmp(FILE *fptr, char *str)
1364 int mode, aindex, rindex;
1373 aindex = rerr.aindex;
1374 rindex = rerr.rindex;
1379 fprintf(fptr, "\n?ASlink-Warning-%s", str);
1383 * Print symbol if symbol based
1386 fprintf(fptr, " for symbol %s\n",
1387 &s[rindex]->s_id[0]);
1389 fprintf(fptr, "\n");
1396 " file module area offset\n");
1398 " Refby %-8.8s %-8.8s %-8.8s ",
1401 &a[aindex]->a_bap->a_id[0]);
1402 prntval(fptr, rerr.rtbase);
1408 raxp = s[rindex]->s_axp;
1413 " Defin %-8.8s %-8.8s %-8.8s ",
1414 raxp->a_bhp->h_lfile->f_idp,
1415 &raxp->a_bhp->m_id[0],
1416 &raxp->a_bap->a_id[0]);
1418 prntval(fptr, s[rindex]->s_addr);
1420 prntval(fptr, rerr.rval);
1424 /*)Function VOID prntval(fptr, v)
1426 * FILE *fptr output file handle
1427 * Addr_T v value to output
1429 * The function prntval() outputs the value v, in the
1430 * currently selected radix, to the device specified
1437 * int xflag current radix
1440 * int fprintf() c_library
1447 VOID prntval(FILE *fptr, Addr_T v)
1450 fprintf(fptr, "%04X\n", v);
1453 fprintf(fptr, "%06o\n", v);
1456 fprintf(fptr, "%05u\n", v);
1460 /*)Function VOID relerp(str)
1462 * char *str error string
1464 * The function relerp() outputs the paging error string to
1465 * stderr and to the map file (if it is open).
1471 * FILE *mfp handle for the map file
1474 * VOID erpdmp() lkrloc.c
1477 * Error message inserted into map file.
1481 VOID relerp(char *str)
1483 erpdmp(stderr, str);
1488 /*)Function VOID erpdmp(fptr, str)
1490 * FILE *fptr output file handle
1491 * char *str error string
1493 * The function erpdmp() outputs the error string str
1494 * to the device specified by fptr.
1497 * head *thp pointer to head structure
1500 * int lkerr error flag
1501 * sdp sdp base page structure
1504 * int fprintf() c_library
1505 * VOID prntval() lkrloc.c
1512 VOID erpdmp(FILE *fptr, char *str)
1514 register struct head *thp;
1516 thp = sdp.s_areax->a_bhp;
1521 fprintf(fptr, "\n?ASlink-Warning-%s\n", str);
1528 " file module pgarea pgoffset\n");
1530 " PgDef %-8.8s %-8.8s %-8.8s ",
1531 thp->h_lfile->f_idp,
1533 &sdp.s_area->a_id[0]);
1534 prntval(fptr, sdp.s_area->a_addr + sdp.s_addr);