1 /* lkrloc3.c */
2
3 /*
4 * Copyright (C) 1989-2010 Alan R. Baldwin
5 *
6 * This program is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
10 *
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.
15 *
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/>.
18 *
19 *
20 * Alan R. Baldwin
21 * 721 Berkeley St.
22 * Kent, Ohio 44240
23 *
24 * With enhancements from:
25 *
26 * John L. Hartman (JLH)
27 * jhartman@compuserve.com
28 *
29 * Bill McKinnon (BM)
30 * w_mckinnon@conknet.com
31 */
32
33 #include "aslink.h"
34
35 /*)Module lkrloc3.c
36 *
37 * The module lkrloc3.c contains the functions which
38 * perform the version 3 relocation calculations.
39 *
40 * lkrloc3.c contains the following functions:
41 * a_uint adb_lo()
42 * a_uint adb_hi()
43 * VOID erpdmp3()
44 * VOID errdmp3()
45 * VOID rele3()
46 * VOID relerr3()
47 * VOID relerp3()
48 * VOID reloc3()
49 * VOID relp3()
50 * VOID relr3()
51 * VOID relt3()
52 *
53 * lkrloc3.c the local variable errmsg3[].
54 *
55 */
56
57 /*)Function VOID reloc3(c)
58 *
59 * int c process code
60 *
61 * The function reloc3() calls a particular relocation
62 * function determined by the process code.
63 *
64 * local variable:
65 * none
66 *
67 * global variables:
68 * int lkerr error flag
69 *
70 * called functions:
71 * int fprintf() c_library
72 * VOID rele3() lkrloc3.c
73 * VOID relp3() lkrloc3.c
74 * VOID relr3() lkrloc3.c
75 * VOId relt3() lkrloc3.c
76 *
77 * side effects:
78 * Refer to the called relocation functions.
79 *
80 */
81
82 VOID
reloc3(int c)83 reloc3(int c)
84 {
85 switch(c) {
86
87 case 'T':
88 relt3();
89 break;
90
91 case 'R':
92 relr3();
93 break;
94
95 case 'P':
96 relp3();
97 break;
98
99 case 'E':
100 rele3();
101 break;
102
103 default:
104 fprintf(stderr, "Undefined Relocation Operation\n");
105 lkerr++;
106 break;
107
108 }
109 }
110
111
112 /*)Function VOID relt3()
113 *
114 * The function relt3() evaluates a T line read by
115 * the linker. Each byte value read is saved in the
116 * rtval[] array, rtflg[] is set, and the number of
117 * evaluations is maintained in rtcnt.
118 *
119 * T Line
120 *
121 * T xx xx nn nn nn nn nn ...
122 *
123 *
124 * In: "T n0 n1 n2 n3 ... nn"
125 *
126 * Out: 0 1 2 .. rtcnt
127 * +----+----+----+----+----+
128 * rtval | n0 | n1 | n2 | .. | nn |
129 * +----+----+----+----+----+
130 * rtflag| 1 | 1 | 1 | 1 | 1 |
131 * +----+----+----+----+----+
132 *
133 * The T line contains the assembled code output by the assem-
134 * bler with xx xx being the offset address from the current area
135 * base address and nn being the assembled instructions and data in
136 * byte format.
137 *
138 * local variable:
139 * none
140 *
141 * global variables:
142 * int rtcnt number of values evaluated
143 * int rtflg[] array of evaluation flags
144 * int rtval[] array of evaluation values
145 *
146 * called functions:
147 * int eval() lkeval.c
148 * int more() lklex.c
149 *
150 * side effects:
151 * Linker input T line evaluated.
152 *
153 */
154
155 VOID
relt3(void)156 relt3(void)
157 {
158 rtcnt = 0;
159 while (more()) {
160 if (rtcnt < NTXT) {
161 rtval[rtcnt] = eval();
162 rtflg[rtcnt] = 1;
163 rterr[rtcnt] = 0;
164 rtcnt++;
165 }
166 }
167 }
168
169 /*)Function VOID relr3()
170 *
171 * The function relr3() 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
176 * performed.
177 *
178 * R Line
179 *
180 * R 0 0 nn nn n1 n2 xx xx ...
181 *
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:
186 *
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) byte data
192 * 5. bit 4 signed(0x00)/unsigned(0x10) byte data
193 * 6. bit 5 normal(0x00)/page '0'(0x20) reference
194 * 7. bit 6 normal(0x00)/page 'nnn'(0x40) reference
195 *
196 * 2. n2 is a byte index into the corresponding (i.e. pre-
197 * ceeding) T line data (i.e. a pointer to the data to be
198 * updated by the relocation). The T line data may be
199 * 1-byte or 2-byte byte data format or 2-byte word
200 * format.
201 *
202 * 3. xx xx is the area/symbol index for the area/symbol be-
203 * ing referenced. the corresponding area/symbol is found
204 * in the header area/symbol lists.
205 *
206 * The groups of 4 bytes are repeated for each item requiring relo-
207 * cation in the preceeding T line.
208 *
209 * local variable:
210 * areax **a pointer to array of area pointers
211 * int aindex area index
212 * char *errmsg3[] array of pointers to error strings
213 * int error error code
214 * int mode relocation mode
215 * adrr_t paga paging base area address
216 * a_uint pags paging symbol address
217 * a_uint r PCR relocation value
218 * a_uint reli relocation initial value
219 * a_uint relv relocation final value
220 * int rindex symbol / area index
221 * a_uint rtbase base code address
222 * a_uint rtofst rtval[] index offset
223 * int rtp index into T data
224 * sym **s pointer to array of symbol pointers
225 *
226 * global variables:
227 * head *hp pointer to the head structure
228 * int lkerr error flag
229 * a_uint pc relocated base address
230 * int pcb bytes per instruction word
231 * rerr rerr linker error structure
232 * FILE *stderr standard error device
233 *
234 * called functions:
235 * a_uint adb_1b() lkrloc.c
236 * a_uint adb_2b() lkrloc.c
237 * a_uint adb_lo() lkrloc3.c
238 * a_uint adb_hi() lkrloc3.c
239 * sdld specific
240 * VOID elf() lkelf.c
241 * VOID gb() lkgb.c
242 * end sdld specific
243 * a_uint evword() lkrloc.c
244 * int eval() lkeval.c
245 * int fprintf() c_library
246 * VOID ihx() lkihx.c
247 * VOID s19() lks19.c
248 * VOID lkulist lklist.c
249 * int more() lklex.c
250 * VOID relerr3() lkrloc3.c
251 * int symval() lksym.c
252 *
253 * side effects:
254 * The R and T lines are combined to produce
255 * relocated code and data. Output Sxx / Ixx
256 * and relocated listing files may be produced.
257 *
258 */
259
260 VOID
relr3(void)261 relr3(void)
262 {
263 int mode;
264 a_uint reli, relv;
265 int aindex, rindex, rtp, error, i;
266 a_uint r, rtbase, rtofst, paga = 0, pags = 0;
267 struct areax **a;
268 struct sym **s;
269
270 /*
271 * Get area and symbol lists
272 */
273 a = hp->a_list;
274 s = hp->s_list;
275
276 /*
277 * Verify Area Mode
278 */
279 if (eval() != (R3_WORD | R3_AREA) || eval()) {
280 fprintf(stderr, "R input error\n");
281 lkerr++;
282 return;
283 }
284
285 /*
286 * Get area pointer
287 */
288 aindex = (int) evword();
289 if (aindex >= hp->h_narea) {
290 fprintf(stderr, "R area error\n");
291 lkerr++;
292 return;
293 }
294
295 /*
296 * Select Output File
297 */
298 if (oflag != 0) {
299 ap = a[aindex]->a_bap;
300 if (ofp != NULL) {
301 rtabnk->b_rtaflg = rtaflg;
302 if (ofp != ap->a_ofp) {
303 lkflush();
304 }
305 }
306 ofp = ap->a_ofp;
307 rtabnk = ap->a_bp;
308 rtaflg = rtabnk->b_rtaflg;
309 }
310
311 /*
312 * Base values
313 */
314 rtbase = adb_xb(0, 0);
315 rtofst = a_bytes;
316
317 /*
318 * Relocate address
319 */
320 pc = adb_xb(a[aindex]->a_addr, 0);
321
322 /*
323 * Number of 'bytes' per PC address
324 */
325 pcb = 1;
326
327 #if 0
328 printf("area %d base address: 0x%x size: 0x%x rtbase: 0x%x\n", aindex,
329 a[aindex]->a_addr, a[aindex]->a_size, rtbase);
330 #endif
331 /*
332 * Do remaining relocations
333 */
334 while (more()) {
335 error = 0;
336 mode = (int) eval();
337
338 if ((mode & R_ESCAPE_MASK) == R_ESCAPE_MASK)
339 {
340 mode = ((mode & ~R_ESCAPE_MASK) << 8) | eval();
341 /* printf("unescaping rmode\n"); */
342 }
343
344 rtp = (int) eval();
345 rindex = (int) evword();
346
347 /*
348 * R3_SYM or R3_AREA references
349 */
350 if (mode & R3_SYM) {
351 if (rindex >= hp->h_nsym) {
352 fprintf(stderr, "R symbol error\n");
353 lkerr++;
354 return;
355 }
356 reli = symval(s[rindex]);
357 }
358 /* sdld specific */
359 else if ((IS_R_J11(mode) || IS_R_J19(mode)) && (rindex == 0xFFFF)) {
360 /* absolute acall/ajmp address */
361 reli = 0;
362 }
363 /* end sdld specific */
364 else {
365 if (rindex >= hp->h_narea) {
366 fprintf(stderr, "R area error\n");
367 lkerr++;
368 return;
369 }
370 reli = a[rindex]->a_addr;
371 }
372
373 /*
374 * R3_PCR addressing
375 */
376 if (mode & R3_PCR) {
377 if (mode & R3_BYTE) {
378 reli -= (pc + (rtp-rtofst) + 1);
379 } else {
380 reli -= (pc + (rtp-rtofst) + 2);
381 }
382 }
383
384 /*
385 * R3_PAG0 or R3_PAG addressing
386 */
387 if (mode & (R3_PAG0 | R3_PAG)) {
388 paga = sdp.s_area->a_addr;
389 pags = sdp.s_addr;
390 reli -= paga + pags;
391 }
392
393
394 /* pdk instruction fusion */
395 if (TARGET_IS_PDK) {
396 relv = adb_3b(reli, rtp);
397
398 /* pdk addresses in words, not in bytes,
399 * for goto/call instructions and byte selections.
400 */
401 int jump = 1, mask = 0;
402 if (rtval[rtp + 4] == 15) {
403 jump = rtval[rtp + 3] & 0x70;
404 mask = 0x40;
405 if (get_sdld_target() == TARGET_ID_PDK) {
406 set_sdld_target(TARGET_ID_PDK15);
407 } else if (get_sdld_target() != TARGET_ID_PDK15) {
408 error = 12;
409 }
410 } else if (rtval[rtp + 4] == 14) {
411 jump = rtval[rtp + 3] & 0x38;
412 mask = 0x20;
413 if (get_sdld_target() == TARGET_ID_PDK) {
414 set_sdld_target(TARGET_ID_PDK14);
415 } else if (get_sdld_target() != TARGET_ID_PDK14) {
416 error = 13;
417 }
418 } else if (rtval[rtp + 4] == 13) {
419 jump = rtval[rtp + 3] & 0x1C;
420 mask = 0x10;
421 if (get_sdld_target() == TARGET_ID_PDK) {
422 set_sdld_target(TARGET_ID_PDK13);
423 } else if (get_sdld_target() != TARGET_ID_PDK13) {
424 error = 14;
425 }
426
427 /* T*SN and SET* instructions for PDK13 needed to
428 * be handled specially since their address is
429 * in between the opcode.
430 */
431 if ((rtval[rtp + 3] & 0x1F00) == 0x300 ||
432 (rtval[rtp + 3] & 0x1F00) == 0x200) {
433 rtval[rtp] <<= 1;
434 }
435 }
436
437 const int icall =
438 (mask >> 0) | (mask >> 1) | (mask >> 2);
439 const int igoto = (mask >> 0) | (mask >> 1);
440 if (((mode & R3_BYTE) && !(mode & R3_USGN)) ||
441 jump == icall || jump == igoto) {
442 /* Addresses cannot be bigger than N - 1 bits.
443 * Any bits that are set past that point are
444 * marker bits that should be not shifted.
445 */
446 int marker = rtval[rtp + 1] & 0x80;
447 rtval[rtp + 1] &= ~0x80;
448
449 rtval[rtp] /= 2;
450 rtval[rtp] |= (rtval[rtp + 1] & 1) << 7;
451 rtval[rtp + 1] /= 2;
452 rtval[rtp + 1] |= marker;
453 }
454
455 const int inst = (rtval[rtp + 3] << 8) | rtval[rtp + 2];
456
457 /* Do the actual opcode fusion and ignore the two
458 * bytes taken for the opcode by the assembler.
459 */
460 if (IS_R_J11(mode)) {
461 rtval[rtp + 2] |= rtval[rtp];
462 rtval[rtp + 3] |= rtval[rtp + 1];
463 } else if (mode & R3_MSB) {
464 rtval[rtp + 2] |= rtval[rtp + 1];
465 rtval[rtp] = rtval[rtp + 1];
466 rtval[rtp + 1] = 0;
467 } else {
468 rtval[rtp + 2] |= rtval[rtp];
469 rtval[rtp + 1] = 0;
470 }
471
472 const int addr = (rtval[rtp + 1] << 8) | rtval[rtp];
473 static int errorCount = 0;
474 if (vpdkinst(inst, addr, rtval[rtp + 4])) {
475 if (errorCount < 3) {
476 error = 11;
477 } else if (errorCount == 3) {
478 puts("?ASlink-Warning-More instruction address errors omitted");
479 }
480 ++errorCount;
481 }
482
483 mode &= ~R3_USGN;
484 rtflg[rtp] = 0;
485 rtflg[rtp + 1] = 0;
486 rtflg[rtp + 4] = 0;
487 rtofst += 3;
488 }
489
490 /*
491 * R3_BYTE or R3_WORD operation
492 */
493 else if (mode & R3_BYTE) {
494 if (mode & R_BYT3)
495 {
496 /* This is a three byte address, of which
497 * we will select one byte.
498 */
499 /* sdld specific */
500 if (mode & R_BIT)
501 {
502 relv = adb_24_bit(reli, rtp);
503 }
504 /* sdld specific */
505 else if (mode & R_HIB)
506 {
507 /* printf("24 bit address selecting hi byte.\n"); */
508 relv = adb_24_hi(reli, rtp);
509 }
510 else if (mode & R3_MSB)
511 {
512 /* Note that in 24 bit mode, R3_MSB
513 * is really the middle byte, not
514 * the most significant byte.
515 *
516 * This is ugly and I can only apologize
517 * for any confusion.
518 */
519 /* printf("24 bit address selecting middle byte.\n"); */
520 relv = adb_24_mid(reli, rtp);
521 }
522 else
523 {
524 /* printf("24 bit address selecting lo byte.\n"); */
525 relv = adb_24_lo(reli, rtp);
526 }
527 }
528 else if (mode & R3_BYTX) {
529 /* This is a two byte address, of
530 * which we will select one byte.
531 */
532 if (mode & R_BIT) {
533 relv = adb_bit(reli, rtp);
534 } else if (mode & R3_MSB) {
535 relv = adb_hi(reli, rtp);
536 } else {
537 relv = adb_lo(reli, rtp);
538 }
539 } else {
540 relv = adb_1b(reli, rtp);
541 }
542 } else if (IS_R_J11(mode)) {
543 /*
544 * JLH: 11 bit jump destination for 8051.
545 * Forms two byte instruction with
546 * op-code bits in the MIDDLE!
547 * rtp points at 3 byte locus:
548 * first two will get the address,
549 * third one has raw op-code
550 */
551
552 /*
553 * Calculate absolute destination
554 * relv must be on same 2K page as pc
555 */
556 relv = adb_2b(reli, rtp);
557
558 if ((relv & ~((a_uint) 0x000007FF)) !=
559 ((pc + rtp - rtofst) & ~((a_uint) 0x000007FF))) {
560 error = 6;
561 }
562
563 /*
564 * Merge MSB with op-code,
565 * ignoring top 5 bits of address.
566 * Then hide the op-code.
567 */
568 rtval[rtp] = ((rtval[rtp] & 0x07)<<5) | rtval[rtp+2];
569 rtflg[rtp + 2] = 0;
570 rtofst += 1;
571 }
572 else if (IS_R_J19(mode)) {
573 /*
574 * BK: 19 bit jump destination for DS80C390.
575 * Forms four byte instruction with
576 * op-code bits in the MIDDLE!
577 * rtp points at 4 byte locus:
578 * first three will get the address,
579 * fourth one has raw op-code
580 */
581 relv = adb_3b(reli, rtp);
582
583 /*
584 * Calculate absolute destination
585 * relv must be on same 512K page as pc
586 */
587 if ((relv & ~((a_uint) 0x0007FFFF)) !=
588 ((pc + rtp - rtofst) & ~((a_uint) 0x0007FFFF))) {
589 error = 7;
590 }
591
592 /*
593 * Merge MSB with op-code,
594 * ignoring top 5 bits of address.
595 * Then hide the op-code.
596 */
597 rtval[rtp] = ((rtval[rtp] & 0x07)<<5) | rtval[rtp+3];
598 rtflg[rtp + 3] = 0;
599 rtofst += 1;
600 }
601 else if (IS_C24(mode))
602 {
603 /*
604 * 24 bit destination
605 */
606 relv = adb_3b(reli, rtp);
607 }
608 else
609 {
610 /* 16 bit address. */
611 relv = adb_2b(reli, rtp);
612 }
613
614 /*
615 * R3_BYTE with R3_BYTX offset adjust
616 */
617 if (mode & R3_BYTE) {
618 if (mode & R3_BYTX) {
619 rtofst += (a_bytes - 1);
620 }
621 }
622
623 /*
624 * Unsigned Byte Checking
625 */
626 if (mode & R3_USGN && mode & R3_BYTE && relv & ~((a_uint) 0x000000FF))
627 error = 1;
628
629 /*
630 * PCR Relocation Error Checking
631 */
632 if (mode & R3_PCR && mode & R3_BYTE) {
633 r = relv & ~0x7F;
634 if (r != (a_uint) ~0x7F && r != 0)
635 error = 2;
636 }
637
638 /*
639 * Page Relocation Error Checking
640 */
641 if ((TARGET_IS_GB || TARGET_IS_Z80) &&
642 mode & R3_PAG0 && (relv & ~0xFF || paga || pags))
643 error = 4;
644 if (mode & R3_PAG && (relv & ~0xFF))
645 error = 5;
646 /* sdld specific */
647 if ((mode & R_BIT) && (relv & ~0x87FF))
648 error = 10;
649 /* end sdld specific */
650
651 /*
652 * Error Processing
653 */
654 if (error) {
655 rerr.aindex = aindex;
656 rerr.mode = mode;
657 rerr.rtbase = rtbase + rtp - rtofst - 1;
658 rerr.rindex = rindex;
659 rerr.rval = relv - reli;
660 relerr3(errmsg3[error]);
661
662 for (i=rtp; i<rtp+a_bytes; i++) {
663 if (rtflg[i]) {
664 rterr[i] = error;
665 break;
666 }
667 }
668 }
669 }
670 if (uflag != 0) {
671 lkulist(1);
672 }
673 if (oflag != 0) {
674 lkout(1);
675 }
676 }
677
678 char *errmsg3[] = {
679 /* 0 */ "LKRLOC3 Error List",
680 /* 1 */ "Unsigned Byte error",
681 /* 2 */ "Byte PCR relocation error",
682 /* 3 */ "",
683 /* 4 */ "Page0 relocation error",
684 /* 5 */ "Page Mode relocation error",
685 /* 6 */ "2K Page relocation error",
686 /* 7 */ "512K Page relocation error",
687 /* 8 */ "",
688 /* 9 */ "",
689 /* sdld specific */
690 /* 10 */ "Bit-addressable relocation error",
691 /* 11 */ "Invalid address for instruction",
692 /* 12 */ "mismatched pdk targets; expected pdk15",
693 /* 13 */ "mismatched pdk targets; expected pdk14",
694 /* 14 */ "mismatched pdk targets; expected pdk13"
695 /* end sdld specific */
696 };
697
698
699 /*)Function VOID relp3()
700 *
701 * The function relp3() evaluates a P line read by
702 * the linker. The P line data is combined with the
703 * previous T line data to set the base page address
704 * and test the paging boundary and length.
705 *
706 * P Line
707 *
708 * P 0 0 nn nn n1 n2 xx xx
709 *
710 * The P line provides the paging information to the linker as
711 * specified by a .setdp directive. The format of the relocation
712 * information is identical to that of the R line. The correspond-
713 * ing T line has the following information:
714 * T xx xx aa aa bb bb
715 *
716 * Where aa aa is the area reference number which specifies the
717 * selected page area and bb bb is the base address of the page.
718 * bb bb will require relocation processing if the 'n1 n2 xx xx' is
719 * specified in the P line. The linker will verify that the base
720 * address is on a 256 byte boundary and that the page length of an
721 * area defined with the PAG type is not larger than 256 bytes.
722 *
723 * local variable:
724 * areax **a pointer to array of area pointers
725 * int aindex area index
726 * int mode relocation mode
727 * a_uint relv relocation value
728 * int rindex symbol / area index
729 * int rtp index into T data
730 * sym **s pointer to array of symbol pointers
731 *
732 * global variables:
733 * head *hp pointer to the head structure
734 * int lkerr error flag
735 * sdp sdp base page structure
736 * FILE *stderr standard error device
737 *
738 * called functions:
739 * a_uint adb_2b() lkrloc.c
740 * a_uint evword() lkrloc.c
741 * int eval() lkeval.c
742 * int fprintf() c_library
743 * int more() lklex.c
744 * int symval() lksym.c
745 *
746 * side effects:
747 * The P and T lines are combined to set
748 * the base page address and report any
749 * paging errors.
750 *
751 */
752
753 VOID
relp3()754 relp3()
755 {
756 int aindex, rindex;
757 int mode, rtp;
758 a_uint relv;
759 struct areax **a;
760 struct sym **s;
761
762 /*
763 * Get area and symbol lists
764 */
765 a = hp->a_list;
766 s = hp->s_list;
767
768 /*
769 * Verify Area Mode
770 */
771 if (eval() != (R3_WORD | R3_AREA) || eval()) {
772 fprintf(stderr, "P input error\n");
773 lkerr++;
774 }
775
776 /*
777 * Get area pointer
778 */
779 aindex = (int) evword();
780 if (aindex >= hp->h_narea) {
781 fprintf(stderr, "P area error\n");
782 lkerr++;
783 return;
784 }
785
786 /*
787 * Do remaining relocations
788 */
789 while (more()) {
790 mode = (int) eval();
791 rtp = (int) eval();
792 rindex = (int) evword();
793
794 /*
795 * R3_SYM or R3_AREA references
796 */
797 if (mode & R3_SYM) {
798 if (rindex >= hp->h_nsym) {
799 fprintf(stderr, "P symbol error\n");
800 lkerr++;
801 return;
802 }
803 relv = symval(s[rindex]);
804 } else {
805 if (rindex >= hp->h_narea) {
806 fprintf(stderr, "P area error\n");
807 lkerr++;
808 return;
809 }
810 relv = a[rindex]->a_addr;
811 }
812 adb_2b(relv, rtp);
813 }
814
815 /*
816 * Paged values
817 */
818 aindex = (int) adb_2b(0, 2);
819 if (aindex >= hp->h_narea) {
820 fprintf(stderr, "P area error\n");
821 lkerr++;
822 return;
823 }
824 sdp.s_areax = a[aindex];
825 sdp.s_area = sdp.s_areax->a_bap;
826 sdp.s_addr = adb_2b(0, 4);
827 if (sdp.s_area->a_addr & 0xFF || sdp.s_addr & 0xFF)
828 relerp3("Page Definition Boundary Error");
829 }
830
831 /*)Function VOID rele3()
832 *
833 * The function rele3() closes all open output files
834 * at the end of the linking process.
835 *
836 * local variable:
837 * none
838 *
839 * global variables:
840 * int oflag output type flag
841 * int uflag relocation listing flag
842 *
843 * called functions:
844 * VOID lkfclose() lkbank.c
845 * VOID lkflush() lkout.c
846 * VOID lkulist() lklist.c
847 *
848 * side effects:
849 * All open output files are closed.
850 *
851 */
852
853 VOID
rele3()854 rele3()
855 {
856 if (uflag != 0) {
857 lkulist(0);
858 }
859 if (oflag != 0) {
860 lkflush();
861 lkfclose();
862 }
863 }
864
865 /*)Function VOID relerr3(str)
866 *
867 * char *str error string
868 *
869 * The function relerr3() outputs the error string to
870 * stderr and to the map file (if it is open).
871 *
872 * local variable:
873 * none
874 *
875 * global variables:
876 * FILE *mfp handle for the map file
877 *
878 * called functions:
879 * VOID errdmp3() lkrloc3.c
880 *
881 * side effects:
882 * Error message inserted into map file.
883 *
884 */
885
886 VOID
relerr3(char * str)887 relerr3(char *str)
888 {
889 errdmp3(stderr, str);
890 if (mfp)
891 errdmp3(mfp, str);
892 }
893
894 /*)Function VOID errdmp3(fptr, str)
895 *
896 * FILE *fptr output file handle
897 * char *str error string
898 *
899 * The function errdmp3() outputs the error string str
900 * to the device specified by fptr. Additional information
901 * is output about the definition and referencing of
902 * the symbol / area error.
903 *
904 * local variable:
905 * int mode error mode
906 * int aindex area index
907 * int lkerr error flag
908 * int rindex error index
909 * sym **s pointer to array of symbol pointers
910 * areax **a pointer to array of area pointers
911 * areax *raxp error area extension pointer
912 *
913 * global variables:
914 * sdp sdp base page structure
915 *
916 * called functions:
917 * int fprintf() c_library
918 * VOID prntval() lkrloc.c
919 *
920 * side effects:
921 * Error reported.
922 *
923 */
924
925 const char errdmp3_null_srcname[] = "<missing>";
926
927 VOID
errdmp3(FILE * fptr,char * str)928 errdmp3(FILE *fptr, char *str)
929 {
930 int mode, aindex, rindex;
931 struct sym **s;
932 struct areax **a;
933 struct areax *raxp;
934
935 a = hp->a_list;
936 s = hp->s_list;
937
938 mode = rerr.mode;
939 aindex = rerr.aindex;
940 rindex = rerr.rindex;
941
942 /*
943 * Print Error
944 */
945 fprintf(fptr, "\n?ASlink-Warning-%s", str);
946 lkerr++;
947
948 /*
949 * Print symbol if symbol based
950 */
951 if (mode & R3_SYM) {
952 fprintf(fptr, " for symbol %s\n",
953 &s[rindex]->s_id[0]);
954 } else {
955 fprintf(fptr, "\n");
956 }
957
958 /*
959 * Print Ref Info
960 */
961 /* 11111111112222222222333333333344444444445555555555666666666677777*/
962 /*12345678901234567890123456789012345678901234567890123456789012345678901234*/
963 /* | | | | */
964 fprintf(fptr,
965 " file module area offset\n");
966 fprintf(fptr,
967 " Refby %-14.14s %-14.14s %-14.14s ",
968 (hp->h_lfile && hp->h_lfile->f_idp) ? hp->h_lfile->f_idp : errdmp3_null_srcname,
969 &hp->m_id[0],
970 &a[aindex]->a_bap->a_id[0]);
971 prntval(fptr, rerr.rtbase);
972
973 /*
974 * Print Def Info
975 */
976 if (mode & R3_SYM) {
977 raxp = s[rindex]->s_axp;
978 } else {
979 raxp = a[rindex];
980 }
981 /* 11111111112222222222333333333344444444445555555555666666666677777*/
982 /*12345678901234567890123456789012345678901234567890123456789012345678901234*/
983 /* | | | | */
984 fprintf(fptr,
985 " Defin %-14.14s %-14.14s %-14.14s ",
986 (raxp->a_bhp->h_lfile && raxp->a_bhp->h_lfile->f_idp) ? raxp->a_bhp->h_lfile->f_idp : errdmp3_null_srcname,
987 &raxp->a_bhp->m_id[0],
988 &raxp->a_bap->a_id[0]);
989 if (mode & R3_SYM) {
990 prntval(fptr, s[rindex]->s_addr);
991 } else {
992 prntval(fptr, rerr.rval);
993 }
994 }
995
996 /*)Function VOID relerp3(str)
997 *
998 * char *str error string
999 *
1000 * The function relerp3() outputs the paging error string to
1001 * stderr and to the map file (if it is open).
1002 *
1003 * local variable:
1004 * none
1005 *
1006 * global variables:
1007 * FILE *mfp handle for the map file
1008 *
1009 * called functions:
1010 * VOID erpdmp3() lkrloc3.c
1011 *
1012 * side effects:
1013 * Error message inserted into map file.
1014 *
1015 */
1016
1017 VOID
relerp3(char * str)1018 relerp3(char *str)
1019 {
1020 erpdmp3(stderr, str);
1021 if (mfp)
1022 erpdmp3(mfp, str);
1023 }
1024
1025 /*)Function VOID erpdmp3(fptr, str)
1026 *
1027 * FILE *fptr output file handle
1028 * char *str error string
1029 *
1030 * The function erpdmp3() outputs the error string str
1031 * to the device specified by fptr.
1032 *
1033 * local variable:
1034 * head *thp pointer to head structure
1035 *
1036 * global variables:
1037 * int lkerr error flag
1038 * sdp sdp base page structure
1039 *
1040 * called functions:
1041 * int fprintf() c_library
1042 * VOID prntval() lkrloc.c
1043 *
1044 * side effects:
1045 * Error reported.
1046 *
1047 */
1048
1049 VOID
erpdmp3(FILE * fptr,char * str)1050 erpdmp3(FILE *fptr, char *str)
1051 {
1052 struct head *thp;
1053
1054 thp = sdp.s_areax->a_bhp;
1055
1056 /*
1057 * Print Error
1058 */
1059 fprintf(fptr, "\n?ASlink-Warning-%s\n", str);
1060 lkerr++;
1061
1062 /*
1063 * Print PgDef Info
1064 */
1065 /* 111111111122222222223333333333444444444455555555556666666666777*/
1066 /*123456789012345678901234567890123456789012345678901234567890123456789012*/
1067 fprintf(fptr,
1068 " file module pgarea pgoffset\n");
1069 fprintf(fptr,
1070 " PgDef %-14.14s %-14.14s %-14.14s ",
1071 thp->h_lfile->f_idp,
1072 &thp->m_id[0],
1073 &sdp.s_area->a_id[0]);
1074 prntval(fptr, sdp.s_area->a_addr + sdp.s_addr);
1075 }
1076
1077 /* sdld specific */
1078 /*)Function a_uint adb_bit(v, i)
1079 *
1080 * a_uint v value to add to byte
1081 * int i rtval[] index
1082 *
1083 * The function adb_bit() converts the single
1084 * byte address value contained in rtval[i] to bit-
1085 * addressable space and adds the value of v to it.
1086 * The new value of rtval[i] is returned.
1087 *
1088 * local variable:
1089 * a_uint j temporary evaluation variable
1090 *
1091 * global variables:
1092 * none
1093 *
1094 * called functions:
1095 * none
1096 *
1097 * side effects:
1098 * The value of rtval[] is changed.
1099 *
1100 */
1101
1102 a_uint
adb_bit(a_uint v,int i)1103 adb_bit(a_uint v, int i)
1104 {
1105 a_uint j;
1106
1107 j = adb_lo(v, i) & 0xFF;
1108 if ((j >= 0x20) && (j <= 0x2F)) {
1109 j = (j - 0x20) * 8;
1110 } else if ((j < 0x80) || ((j & 0x07) != 0)) {
1111 return(0x100);//error
1112 }
1113
1114 if (hilo) {
1115 j = rtval[i+1] = j + (rtval[i] & 0x07);
1116 } else {
1117 j = rtval[i] = j + (rtval[i+1] & 0x07);
1118 }
1119 return(j);
1120 }
1121 /* end sdld specific */
1122
1123 /*)Function a_uint adb_lo(v, i)
1124 *
1125 * int v value to add to byte
1126 * int i rtval[] index
1127 *
1128 * The function adb_lo() adds the value of v to the
1129 * value contained in rtval[i] through rtval[i + a_bytes - 1].
1130 * The new value of rtval[i] ... is returned.
1131 * The rtflg[] flags are cleared for all rtval[i] ... except
1132 * the LSB.
1133 *
1134 * local variable:
1135 * a_uint j temporary evaluation variable
1136 *
1137 * global variables:
1138 * hilo byte ordering parameter
1139 *
1140 * called functions:
1141 * none
1142 *
1143 * side effects:
1144 * The value of rtval[] is changed.
1145 * The rtflg[] values corresponding to all bytes
1146 * except the LSB of the value are cleared to reflect
1147 * the fact that the LSB is the selected byte.
1148 *
1149 */
1150
1151 a_uint
adb_lo(v,i)1152 adb_lo(v, i)
1153 a_uint v;
1154 int i;
1155 {
1156 a_uint j;
1157 int m, n;
1158
1159 j = adb_xb(v, i);
1160 /*
1161 * LSB is lowest order byte of data
1162 */
1163 m = (hilo ? a_bytes-1 : 0);
1164 for (n=0; n<a_bytes; n++) {
1165 if(n != m) rtflg[i+n] = 0;
1166 }
1167 return (j);
1168 }
1169
1170 /*)Function a_uint adb_hi(v, i)
1171 *
1172 * int v value to add to byte
1173 * int i rtval[] index
1174 *
1175 * The function adb_hi() adds the value of v to the
1176 * value contained in rtval[i] through rtval[i + a_bytes - 1].
1177 * The new value of rtval[i] .... is returned.
1178 * The LSB rtflg[] is cleared.
1179 *
1180 * local variable:
1181 * a_uint j temporary evaluation variable
1182 *
1183 * global variables:
1184 * hilo byte ordering parameter
1185 *
1186 * called functions:
1187 * none
1188 *
1189 * side effects:
1190 * The value of rtval[] is changed.
1191 * The rtflg[] values corresponding to all bytes
1192 * except the 2nd byte (MSB) are cleared to reflect
1193 * the fact that the MSB is the selected byte.
1194 *
1195 */
1196
1197 a_uint
adb_hi(v,i)1198 adb_hi(v, i)
1199 a_uint v;
1200 int i;
1201 {
1202 a_uint j;
1203 int m, n;
1204
1205 j = adb_xb(v, i);
1206 /*
1207 * MSB is next lowest order byte of data
1208 */
1209 m = (hilo ? a_bytes-2 : 1);
1210 for (n=0; n<a_bytes; n++) {
1211 if(n != m) rtflg[i+n] = 0;
1212 }
1213 return (j);
1214 }
1215
1216 /* sdld specific */
1217 /*)Function a_uint adb_24_bit(v, i)
1218 *
1219 * a_uint v value to add to byte
1220 * int i rtval[] index
1221 *
1222 * The function adb_24_bit() converts the single
1223 * byte address value contained in rtval[i] to bit-
1224 * addressable space and adds the value of v to it.
1225 * The new value of rtval[i] is returned.
1226 *
1227 * local variable:
1228 * a_uint j temporary evaluation variable
1229 *
1230 * global variables:
1231 * none
1232 *
1233 * called functions:
1234 * none
1235 *
1236 * side effects:
1237 * The value of rtval[] is changed.
1238 *
1239 */
1240
1241 a_uint
adb_24_bit(v,i)1242 adb_24_bit(v, i)
1243 a_uint v;
1244 int i;
1245 {
1246 a_uint j;
1247
1248 j = adb_24_lo(v, i) & 0xFF;
1249 if ((j >= 0x20) && (j <= 0x2F)) {
1250 j = (j - 0x20) * 8;
1251 } else if ((j < 0x80) || ((j & 0x07) != 0)) {
1252 return(0x100);//error
1253 }
1254
1255 if (hilo) {
1256 j = rtval[i+2] = j + (rtval[i+1] & 0x07);
1257 } else {
1258 j = rtval[i] = j + (rtval[i+1] & 0x07);
1259 }
1260 return(j);
1261 }
1262
1263 /*)Function a_uint adb_24_hi(v, i)
1264 *
1265 * a_uint v value to add to byte
1266 * int i rtval[] index
1267 *
1268 * The function adb_24_hi() adds the value of v to the
1269 * 24 bit value contained in rtval[i] - rtval[i+2].
1270 * The new value of rtval[i] / rtval[i+1] is returned.
1271 * The LSB & middle byte rtflg[] is cleared.
1272 *
1273 * local variable:
1274 * a_uint j temporary evaluation variable
1275 *
1276 * global variables:
1277 * hilo byte ordering parameter
1278 *
1279 * called functions:
1280 * none
1281 *
1282 * side effects:
1283 * The value of rtval[] is changed.
1284 * The rtflg[] value corresponding to the
1285 * LSB & middle byte of the word value is cleared to
1286 * reflect the fact that the MSB is the selected byte.
1287 *
1288 */
1289
1290 a_uint
adb_24_hi(v,i)1291 adb_24_hi(v, i)
1292 a_uint v;
1293 int i;
1294 {
1295 a_uint j;
1296
1297 j = adb_3b(v, i);
1298
1299 /* Remove the lower two bytes. */
1300 if (hilo)
1301 {
1302 rtflg[i+2] = 0;
1303 }
1304 else
1305 {
1306 rtflg[i] = 0;
1307 }
1308 rtflg[i+1] = 0;
1309
1310 return (j);
1311 }
1312
1313 /*)Function a_uint adb_24_mid(v, i)
1314 *
1315 * a_uint v value to add to byte
1316 * int i rtval[] index
1317 *
1318 * The function adb_24_mid() adds the value of v to the
1319 * 24 bit value contained in rtval[i] - rtval[i+2].
1320 * The new value of rtval[i] / rtval[i+1] is returned.
1321 * The LSB & MSB byte rtflg[] is cleared.
1322 *
1323 * local variable:
1324 * a_uint j temporary evaluation variable
1325 *
1326 * global variables:
1327 * hilo byte ordering parameter
1328 *
1329 * called functions:
1330 * none
1331 *
1332 * side effects:
1333 * The value of rtval[] is changed.
1334 * The rtflg[] value corresponding to the
1335 * LSB & MSB of the 24 bit value is cleared to reflect
1336 * the fact that the middle byte is the selected byte.
1337 *
1338 */
1339
1340 a_uint
adb_24_mid(v,i)1341 adb_24_mid(v, i)
1342 a_uint v;
1343 int i;
1344 {
1345 a_uint j;
1346
1347 j = adb_3b(v, i);
1348
1349 /* remove the MSB & LSB. */
1350 rtflg[i+2] = 0;
1351 rtflg[i] = 0;
1352
1353 return (j);
1354 }
1355
1356 /*)Function a_uint adb_24_lo(v, i)
1357 *
1358 * a_uint v value to add to byte
1359 * int i rtval[] index
1360 *
1361 * The function adb_24_lo() adds the value of v to the
1362 * 24 bit value contained in rtval[i] - rtval[i+2].
1363 * The new value of rtval[i] / rtval[i+1] is returned.
1364 * The MSB & middle byte rtflg[] is cleared.
1365 *
1366 * local variable:
1367 * a_uint j temporary evaluation variable
1368 *
1369 * global variables:
1370 * hilo byte ordering parameter
1371 *
1372 * called functions:
1373 * none
1374 *
1375 * side effects:
1376 * The value of rtval[] is changed.
1377 * The rtflg[] value corresponding to the
1378 * MSB & middle byte of the word value is cleared to
1379 * reflect the fact that the LSB is the selected byte.
1380 *
1381 */
1382
1383 a_uint
adb_24_lo(v,i)1384 adb_24_lo(v, i)
1385 a_uint v;
1386 int i;
1387 {
1388 a_uint j;
1389
1390 j = adb_3b(v, i);
1391
1392 /* Remove the upper two bytes. */
1393 if (hilo)
1394 {
1395 rtflg[i] = 0;
1396 }
1397 else
1398 {
1399 rtflg[i+2] = 0;
1400 }
1401 rtflg[i+1] = 0;
1402
1403 return (j);
1404 }
1405
1406 /*)Function VOID vpdkinst(inst, addr, ver)
1407 *
1408 * int inst instruction
1409 * int addr address
1410 * int ver PDK version
1411 *
1412 * The function vpdkinst() tests whether the address
1413 * does not exceed the allowed maximum size of the
1414 * instruction.
1415 *
1416 * local variable:
1417 * a_uint j temporary evaluation variable
1418 *
1419 * global variables:
1420 * hilo byte ordering parameter
1421 *
1422 * called functions:
1423 * none
1424 *
1425 * side effects:
1426 * The value of rtval[] is changed.
1427 * The rtflg[] value corresponding to the
1428 * MSB & middle byte of the word value is cleared to
1429 * reflect the fact that the LSB is the selected byte.
1430 *
1431 */
1432
1433 int
vpdkinst(inst,addr,ver)1434 vpdkinst(inst, addr, ver)
1435 int inst;
1436 int addr;
1437 int ver;
1438 {
1439 switch (ver) {
1440 case 13: /* PDK 13 */
1441 switch (inst & 0x1C00) {
1442 case 0x1800:
1443 case 0x1C00:
1444 if (addr > 0x3FF) {
1445 return 1;
1446 }
1447 break;
1448 case 0x1000:
1449 case 0x1400:
1450 if (addr > 0xFF) {
1451 return 1;
1452 }
1453 break;
1454 case 0x0C00:
1455 case 0x2000:
1456 if (addr > 0x1F) {
1457 return 1;
1458 }
1459 break;
1460 case 0x800:
1461 case 0x400:
1462 if (addr > 0x3F) {
1463 return 1;
1464 }
1465 break;
1466 case 0x0:
1467 if (inst & 0x200) {
1468 /* Address was right shifted to fit into the
1469 * opcode.
1470 */
1471 if ((addr >> 1) > 0xF) {
1472 return 1;
1473 }
1474 } else if (inst & 0x100) {
1475 if (addr > 0xFF) {
1476 return 1;
1477 }
1478 } else if (addr > 0x1F) {
1479 return 1;
1480 }
1481 break;
1482 }
1483 break;
1484 case 14: /* PDK 14 */
1485 switch (inst & 0x3800) {
1486 case 0x3000:
1487 case 0x3800:
1488 if (addr > 0x7FF) {
1489 return 1;
1490 }
1491 break;
1492 case 0x2800:
1493 if (addr > 0xFF) {
1494 return 1;
1495 }
1496 break;
1497 case 0x1800:
1498 case 0x2000:
1499 if (addr > 0x3F) {
1500 return 1;
1501 }
1502 break;
1503 case 0x800:
1504 case 0x1000:
1505 if (addr > 0x7F) {
1506 return 1;
1507 }
1508 break;
1509 case 0x0:
1510 if (inst & 0x400) {
1511 if (addr > 0x3F) {
1512 return 1;
1513 }
1514 } else if ((inst & 0x300) == 0x300) {
1515 if (addr & 0x1) {
1516 return 1;
1517 }
1518 } else if ((inst & 0x300) == 0x200 && addr > 0xFF) {
1519 return 1;
1520 } else if ((inst & 0x300) == 0x100 && addr > 0x3F) {
1521 return 1;
1522 }
1523 break;
1524 }
1525 break;
1526 case 15: /* PDK 15 */
1527 switch (inst & 0x7000) {
1528 case 0x6000:
1529 case 0x7000:
1530 if (addr > 0xFFF) {
1531 return 1;
1532 }
1533 break;
1534 case 0x5000:
1535 if (inst & 0x800) {
1536 if (addr > 0x7F) {
1537 return 1;
1538 }
1539 break;
1540 }
1541 case 0x1000:
1542 case 0x2000:
1543 if (addr > 0xFF) {
1544 return 1;
1545 }
1546 break;
1547 case 0x3000:
1548 case 0x4000:
1549 if (addr > 0x7F) {
1550 return 1;
1551 }
1552 break;
1553 case 0x0:
1554 switch (inst & 0xC00) {
1555 case 0xC00:
1556 if (addr > 0xFF) {
1557 return 1;
1558 }
1559 break;
1560 case 0x400:
1561 if (addr > 0xFF || (addr & 0x1)) {
1562 return 1;
1563 }
1564 break;
1565 case 0x0:
1566 if ((inst & 0x200) && addr > 0xFF) {
1567 return 1;
1568 } else if (!(inst & 0x200) && addr > 0x7F) {
1569 return 1;
1570 }
1571 break;
1572 }
1573 break;
1574 }
1575 break;
1576 }
1577 return 0;
1578 #undef MASK
1579 }
1580
1581 /* end sdld specific */
1582