|
|
1.1 root 1: # 1 ""
2:
3:
4:
5:
6: # 1 "/usr/include/sys/types.h"
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23: typedef unsigned char u_char;
24: typedef unsigned short u_short;
25: typedef unsigned int u_int;
26: typedef unsigned long u_long;
27:
28: typedef struct _physadr { int r[1]; } *physadr;
29: typedef long daddr_t;
30: typedef char * caddr_t;
31: typedef u_short ino_t;
32: typedef long swblk_t;
33: typedef long size_t;
34: typedef long time_t;
35: typedef long label_t[14];
36: typedef u_short dev_t;
37: typedef long off_t;
38: typedef long portid_t;
39:
40:
41: # 37 "/usr/include/sys/types.h"
42:
43: # 1 "/usr/include/sys/param.h"
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55: # 14 "/usr/include/sys/param.h"
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91: # 1 "/usr/include/signal.h"
92:
93:
94:
95:
96:
97:
98:
99:
100:
101:
102:
103:
104:
105:
106:
107:
108:
109:
110:
111:
112:
113:
114:
115:
116:
117:
118:
119:
120:
121:
122:
123:
124:
125:
126:
127:
128:
129:
130: typedef int (*SIG_TYP)();
131:
132: SIG_TYP signal();
133:
134:
135:
136:
137:
138: # 49 "/usr/include/signal.h"
139:
140:
141:
142:
143:
144:
145:
146:
147:
148:
149:
150: # 50 "/usr/include/sys/param.h"
151:
152:
153:
154:
155:
156:
157:
158:
159:
160:
161:
162:
163:
164:
165:
166:
167:
168:
169:
170:
171:
172:
173:
174:
175:
176:
177:
178:
179:
180:
181:
182:
183:
184:
185:
186:
187:
188:
189:
190:
191:
192:
193:
194:
195:
196:
197: # 106 "/usr/include/sys/param.h"
198:
199:
200:
201:
202:
203:
204:
205:
206:
207:
208:
209:
210:
211:
212:
213:
214:
215:
216:
217:
218: # 135 "/usr/include/sys/param.h"
219:
220:
221:
222:
223:
224:
225:
226:
227:
228:
229:
230:
231:
232:
233:
234:
235:
236:
237:
238:
239:
240:
241:
242:
243:
244:
245:
246:
247:
248:
249:
250:
251:
252:
253:
254: # 1 "/usr/include/sys/types.h"
255:
256:
257:
258:
259: # 52 "/usr/include/sys/types.h"
260:
261: # 171 "/usr/include/sys/param.h"
262: # 173 "/usr/include/sys/param.h"
263:
264:
265:
266:
267:
268:
269:
270:
271:
272:
273:
274:
275:
276:
277: # 39 "/usr/include/sys/types.h"
278:
279:
280:
281:
282:
283:
284:
285: typedef struct fd_set { unsigned long fds_bits[(128+sizeof(int)*8-1)/(sizeof(int)*8)]; } fd_set;
286:
287:
288:
289:
290:
291:
292: # 6 ""
293: # 1 "/usr/include/sys/stat.h"
294: struct stat
295: {
296: dev_t st_dev;
297: ino_t st_ino;
298: unsigned short st_mode;
299: short st_nlink;
300: short st_uid;
301: short st_gid;
302: dev_t st_rdev;
303: off_t st_size;
304: time_t st_atime;
305: time_t st_mtime;
306: time_t st_ctime;
307: };
308:
309:
310:
311:
312:
313:
314:
315:
316:
317:
318:
319:
320:
321:
322:
323: # 7 ""
324: # 1 "/usr/include/a.out.h"
325:
326:
327:
328: struct exec {
329: long a_magic;
330: unsigned long a_text;
331: unsigned long a_data;
332: unsigned long a_bss;
333: unsigned long a_syms;
334: unsigned long a_entry;
335: unsigned long a_trsize;
336: unsigned long a_drsize;
337: };
338:
339:
340:
341:
342:
343:
344:
345:
346:
347:
348:
349:
350:
351:
352:
353:
354:
355:
356:
357:
358:
359:
360: struct relocation_info {
361: int r_address;
362: unsigned int r_symbolnum:24,
363: r_pcrel:1,
364: r_length:2,
365: r_extern:1,
366: r_addsyl:1,
367: :3;
368: };
369:
370:
371:
372:
373:
374:
375: struct nlist {
376: union {
377: char *n_name;
378: long n_strx;
379: } n_un;
380: unsigned char n_type;
381: char n_other;
382: short n_desc;
383: unsigned long n_value;
384: };
385:
386:
387:
388:
389:
390:
391:
392:
393:
394:
395:
396:
397:
398:
399:
400:
401:
402:
403:
404:
405:
406:
407:
408:
409:
410:
411: # 8 ""
412: # 1 "/usr/include/ar.h"
413:
414:
415:
416:
417:
418: struct ar_hdr {
419: char ar_name[16];
420: char ar_date[12];
421: char ar_uid[6];
422: char ar_gid[6];
423: char ar_mode[8];
424: char ar_size[10];
425: char ar_fmag[2];
426: };
427:
428: # 9 ""
429: # 1 "/usr/include/ctype.h"
430:
431:
432:
433:
434:
435:
436:
437:
438:
439: extern char _ctype[];
440:
441:
442:
443:
444:
445:
446:
447:
448:
449:
450:
451:
452:
453:
454:
455:
456: # 10 ""
457: # 1 "/usr/include/pagsiz.h"
458:
459:
460:
461:
462:
463:
464:
465:
466:
467:
468:
469: # 11 ""
470: # 1 "/usr/include/ranlib.h"
471:
472:
473:
474:
475:
476:
477:
478:
479:
480: struct ranlib {
481: union {
482: off_t ran_strx;
483: char *ran_name;
484: } ran_un;
485: off_t ran_off;
486: };
487: # 12 ""
488: # 1 "/usr/include/signal.h"
489: # 59 "/usr/include/signal.h"
490:
491: # 13 ""
492: # 1 "/usr/include/stdio.h"
493:
494:
495:
496: extern struct _iobuf {
497: int _cnt;
498: unsigned char *_ptr;
499: unsigned char *_base;
500: short _flag;
501: char _file;
502: } _iob[120];
503:
504:
505:
506:
507:
508:
509:
510:
511:
512:
513:
514:
515:
516:
517:
518:
519:
520:
521:
522:
523:
524:
525:
526:
527:
528:
529: struct _iobuf *fopen();
530: struct _iobuf *fdopen();
531: struct _iobuf *freopen();
532: struct _iobuf *popen();
533: long ftell();
534: char *fgets();
535:
536:
537: # 1 "/usr/include/tmpnam.h"
538:
539:
540: # 46 "/usr/include/stdio.h"
541:
542: # 14 ""
543:
544:
545:
546:
547:
548:
549:
550:
551:
552:
553:
554:
555:
556:
557:
558:
559:
560:
561:
562:
563:
564:
565:
566:
567:
568:
569:
570:
571:
572:
573:
574:
575:
576:
577:
578:
579:
580:
581:
582:
583:
584:
585:
586:
587:
588:
589:
590:
591:
592:
593:
594:
595:
596:
597:
598:
599:
600:
601:
602:
603: struct symseg {
604: struct nlist *sy_first;
605: struct nlist *sy_last;
606: int sy_used;
607: struct nlist **sy_hfirst;
608: struct nlist **sy_hlast;
609: } symseg[40], *csymseg;
610:
611:
612:
613:
614:
615:
616:
617:
618:
619:
620:
621:
622:
623:
624:
625:
626:
627:
628:
629:
630: struct nlist cursym;
631: struct nlist *lastsym;
632: struct nlist *nextsym;
633: struct nlist *addsym;
634: int nsym;
635:
636:
637: struct nlist **lookup(), **slookup();
638: struct nlist *p_etext, *p_edata, *p_end, *entrypt;
639:
640:
641:
642:
643:
644:
645:
646:
647: off_t li_init[250];
648: struct libseg {
649: off_t *li_first;
650: int li_used;
651: int li_used2;
652: } libseg[40] = {
653: li_init, 0, 0,
654: }, *clibseg = libseg;
655:
656:
657:
658:
659:
660:
661:
662:
663:
664:
665:
666:
667: struct local {
668: int l_index;
669: struct nlist *l_symbol;
670: struct local *l_link;
671: } *lochash[31], lhinit[100];
672: struct locseg {
673: struct local *lo_first;
674: int lo_used;
675: } locseg[40] = {
676: lhinit, 0
677: }, *clocseg;
678:
679:
680:
681:
682:
683:
684:
685:
686:
687:
688:
689:
690:
691: int tnum;
692: int ssiz;
693: struct ranlib *tab;
694: char *tabstr;
695:
696:
697:
698:
699:
700:
701:
702:
703:
704:
705:
706:
707:
708:
709:
710: typedef struct {
711: short *fakeptr;
712: int bno;
713: int nibuf;
714: int nuser;
715: char buff[(1<<12)];
716: } PAGE;
717:
718: PAGE page[2];
719:
720: struct {
721: short *fakeptr;
722: int bno;
723: int nibuf;
724: int nuser;
725: } fpage;
726:
727: typedef struct {
728: char *ptr;
729: int bno;
730: int nibuf;
731: long size;
732: long pos;
733: PAGE *pno;
734: } STREAM;
735:
736: STREAM text;
737: STREAM reloc;
738:
739:
740:
741:
742: struct exec filhdr;
743: struct ar_hdr archdr;
744:
745:
746:
747:
748:
749: int trace;
750: int xflag;
751: int Xflag;
752: int Sflag;
753: int rflag;
754: int arflag;
755: int sflag;
756: int Mflag;
757: int nflag;
758: int dflag;
759: int zflag;
760: long hsize;
761: int Aflag;
762: int Nflag;
763: int funding;
764: int yflag;
765: char **ytab;
766:
767:
768:
769:
770:
771: off_t tsize, dsize, bsize, trsize, drsize, ssize;
772:
773:
774:
775:
776:
777:
778:
779:
780:
781: long ctrel, cdrel, cbrel;
782:
783:
784:
785:
786:
787: long textbase, database;
788:
789:
790:
791:
792:
793: long torigin, dorigin, borigin;
794:
795:
796:
797:
798:
799:
800:
801:
802: int errlev;
803: int delarg = 4;
804:
805:
806:
807:
808:
809:
810:
811:
812:
813: struct biobuf {
814: short b_nleft;
815:
816: char *b_ptr;
817: char b_buf[4096];
818: off_t b_off;
819: struct biobuf *b_link;
820: } *biobufs;
821:
822:
823: int biofd;
824: off_t boffset;
825: struct biobuf *tout, *dout, *trout, *drout, *sout, *strout;
826:
827:
828:
829:
830:
831:
832:
833: off_t offset = sizeof (off_t);
834:
835: int ofilfnd;
836: char *ofilename = "l.out";
837: int ofilemode;
838: int infil;
839: char *filname;
840:
841:
842:
843:
844: char *curstr;
845:
846: char get();
847: int delexit();
848: char *savestr();
849:
850: main(argc, argv)
851: char **argv;
852: {
853: register int c, i;
854: int num;
855: register char *ap, **p;
856: char save;
857:
858: if (signal(2, (SIG_TYP)1) != (SIG_TYP)1) {
859: signal(2, delexit);
860: signal(15, delexit);
861: }
862: if (argc == 1)
863: exit(4);
864: p = argv+1;
865:
866:
867:
868:
869: for (c=1; c<argc; c++) {
870: if (trace)
871: printf("%s:\n", *p);
872: filname = 0;
873: ap = *p++;
874: if (*ap != '-') {
875: load1arg(ap);
876: continue;
877: }
878: for (i=1; ap[i]; i++) switch (ap[i]) {
879:
880: case 'o':
881: if (++c >= argc)
882: error(1, "-o where?");
883: ofilename = *p++;
884: ofilfnd++;
885: continue;
886: case 'u':
887: case 'e':
888: if (++c >= argc)
889: error(1, "-u or -c: arg missing");
890: enter(slookup(*p++));
891: if (ap[i]=='e')
892: entrypt = lastsym;
893: continue;
894: case 'H':
895: if (++c >= argc)
896: error(1, "-H: arg missing");
897: if (tsize!=0)
898: error(1, "-H: too late, some text already loaded");
899: hsize = atoi(*p++);
900: continue;
901: case 'A':
902: if (++c >= argc)
903: error(1, "-A: arg missing");
904: if (Aflag)
905: error(1, "-A: only one base file allowed");
906: Aflag = 1;
907: nflag = 0;
908: funding = 1;
909: load1arg(*p++);
910: trsize = drsize = tsize = dsize = bsize = 0;
911: ctrel = cdrel = cbrel = 0;
912: funding = 0;
913: addsym = nextsym;
914: continue;
915: case 'D':
916: if (++c >= argc)
917: error(1, "-D: arg missing");
918: num = htoi(*p++);
919: if (dsize > num)
920: error(1, "-D: too small");
921: dsize = num;
922: continue;
923: case 'T':
924: if (++c >= argc)
925: error(1, "-T: arg missing");
926: if (tsize!=0)
927: error(1, "-T: too late, some text already loaded");
928: textbase = htoi(*p++);
929: continue;
930: case 'l':
931: save = ap[--i];
932: ap[i]='-';
933: load1arg(&ap[i]);
934: ap[i]=save;
935: goto next;
936: case 'M':
937: Mflag++;
938: continue;
939: case 'x':
940: xflag++;
941: continue;
942: case 'X':
943: Xflag++;
944: continue;
945: case 'S':
946: Sflag++;
947: continue;
948: case 'r':
949: rflag++;
950: arflag++;
951: continue;
952: case 's':
953: sflag++;
954: xflag++;
955: continue;
956: case 'n':
957: nflag++;
958: Nflag = zflag = 0;
959: continue;
960: case 'N':
961: Nflag++;
962: nflag = zflag = 0;
963: continue;
964: case 'd':
965: dflag++;
966: continue;
967: case 'i':
968: printf("ld: -i ignored\n");
969: continue;
970: case 't':
971: trace++;
972: continue;
973: case 'y':
974: if (ap[i+1] == 0)
975: error(1, "-y: symbol name missing");
976: if (yflag == 0) {
977: ytab = (char **)calloc(argc, sizeof (char **));
978: if (ytab == 0)
979: error(1, "ran out of memory (-y)");
980: }
981: ytab[yflag++] = &ap[i+1];
982: goto next;
983: case 'z':
984: zflag++;
985: Nflag = nflag = 0;
986: continue;
987: default:
988: filname = savestr("-x");
989: filname[1] = ap[i];
990: archdr.ar_name[0] = 0;
991: error(1, "bad flag");
992: }
993: next:
994: ;
995: }
996: if (rflag == 0 && Nflag == 0 && nflag == 0)
997: zflag++;
998: endload(argc, argv);
999: exit(0);
1000: }
1001:
1002:
1003:
1004:
1005:
1006: htoi(p)
1007: register char *p;
1008: {
1009: register int c, n;
1010:
1011: n = 0;
1012: while (c = *p++) {
1013: n <<= 4;
1014: if (((_ctype+1)[c]&04))
1015: n += c - '0';
1016: else if (c >= 'a' && c <= 'f')
1017: n += 10 + (c - 'a');
1018: else if (c >= 'A' && c <= 'F')
1019: n += 10 + (c - 'A');
1020: else
1021: error(1, "badly formed hex number");
1022: }
1023: return (n);
1024: }
1025:
1026: delexit()
1027: {
1028:
1029: bflush();
1030: unlink("l.out");
1031: if (delarg==0 && Aflag==0)
1032: chmod(ofilename, ofilemode);
1033: exit (delarg);
1034: }
1035:
1036: endload(argc, argv)
1037: int argc;
1038: char **argv;
1039: {
1040: register int c, i;
1041: long dnum;
1042: register char *ap, **p;
1043:
1044: clibseg = libseg;
1045: filname = 0;
1046: middle();
1047: setupout();
1048: p = argv+1;
1049: for (c=1; c<argc; c++) {
1050: ap = *p++;
1051: if (trace)
1052: printf("%s:\n", ap);
1053: if (*ap != '-') {
1054: load2arg(ap);
1055: continue;
1056: }
1057: for (i=1; ap[i]; i++) switch (ap[i]) {
1058:
1059: case 'D':
1060: dnum = htoi(*p);
1061: if (dorigin < dnum)
1062: while (dorigin < dnum)
1063: (( dout)->b_nleft ? (--( dout)->b_nleft, *( dout)->b_ptr++ = (0)) : bflushc( dout, 0)), dorigin++;
1064:
1065: case 'T':
1066: case 'u':
1067: case 'e':
1068: case 'o':
1069: case 'H':
1070: ++c;
1071: ++p;
1072:
1073: default:
1074: continue;
1075: case 'A':
1076: funding = 1;
1077: load2arg(*p++);
1078: funding = 0;
1079: c++;
1080: continue;
1081: case 'y':
1082: goto next;
1083: case 'l':
1084: ap[--i]='-';
1085: load2arg(&ap[i]);
1086: goto next;
1087: }
1088: next:
1089: ;
1090: }
1091: finishout();
1092: }
1093:
1094:
1095:
1096:
1097: load1arg(cp)
1098: register char *cp;
1099: {
1100: register struct ranlib *tp;
1101: off_t nloc;
1102: int kind;
1103:
1104: kind = getfile(cp);
1105: if (Mflag)
1106: printf("%s\n", filname);
1107: switch (kind) {
1108:
1109:
1110:
1111:
1112: case 0:
1113: load1(0, 0L);
1114: break;
1115:
1116:
1117:
1118:
1119:
1120: case 1:
1121: error(-1,
1122: "warning: archive has no table of contents; add one using ranlib(1)");
1123: nloc = 8;
1124: while (step(nloc))
1125: nloc += sizeof(archdr) +
1126: round(atol(archdr.ar_size), sizeof (short));
1127: break;
1128:
1129:
1130:
1131:
1132:
1133:
1134:
1135:
1136: case 2:
1137: nloc = 8 + sizeof (archdr);
1138: dseek(&text, nloc, sizeof (tnum));
1139: mget((char *)&tnum, sizeof (tnum), &text);
1140: nloc += sizeof (tnum);
1141: tab = (struct ranlib *)malloc(tnum);
1142: if (tab == 0)
1143: error(1, "ran out of memory (toc)");
1144: dseek(&text, nloc, tnum);
1145: mget((char *)tab, tnum, &text);
1146: nloc += tnum;
1147: tnum /= sizeof (struct ranlib);
1148: dseek(&text, nloc, sizeof (ssiz));
1149: mget((char *)&ssiz, sizeof (ssiz), &text);
1150: nloc += sizeof (ssiz);
1151: tabstr = (char *)malloc(ssiz);
1152: if (tabstr == 0)
1153: error(1, "ran out of memory (tocstr)");
1154: dseek(&text, nloc, ssiz);
1155: mget((char *)tabstr, ssiz, &text);
1156: for (tp = &tab[tnum]; --tp >= tab;) {
1157: if (tp->ran_un.ran_strx < 0 ||
1158: tp->ran_un.ran_strx >= ssiz)
1159: error(1, "mangled archive table of contents");
1160: tp->ran_un.ran_name = tabstr + tp->ran_un.ran_strx;
1161: }
1162: while (ldrand())
1163: continue;
1164: cfree((char *)tab);
1165: cfree(tabstr);
1166: nextlibp(-1);
1167: break;
1168:
1169:
1170:
1171:
1172:
1173: case 3:
1174: error(-1,
1175: "warning: table of contents for archive is out of date; rerun ranlib(1)");
1176: nloc = 8;
1177: do
1178: nloc += sizeof(archdr) +
1179: round(atol(archdr.ar_size), sizeof(short));
1180: while (step(nloc));
1181: break;
1182: }
1183: close(infil);
1184: }
1185:
1186:
1187:
1188:
1189:
1190:
1191:
1192: step(nloc)
1193: off_t nloc;
1194: {
1195:
1196: dseek(&text, nloc, (long) sizeof archdr);
1197: if (text.size <= 0) {
1198: nextlibp(-1);
1199: return (0);
1200: }
1201: getarhdr();
1202: if (load1(1, nloc + (sizeof archdr)))
1203: nextlibp(nloc);
1204: return (1);
1205: }
1206:
1207:
1208:
1209:
1210:
1211:
1212: nextlibp(val)
1213: off_t val;
1214: {
1215:
1216: if (clibseg->li_used == 250) {
1217: if (++clibseg == &libseg[40])
1218: error(1, "too many files loaded from libraries");
1219: clibseg->li_first = (off_t *)malloc(250 * sizeof (off_t));
1220: if (clibseg->li_first == 0)
1221: error(1, "ran out of memory (nextlibp)");
1222: }
1223: clibseg->li_first[clibseg->li_used++] = val;
1224: if (val != -1 && Mflag)
1225: printf("\t%s\n", archdr.ar_name);
1226: }
1227:
1228:
1229:
1230:
1231:
1232:
1233:
1234:
1235: ldrand()
1236: {
1237: register struct nlist *sp, **hp;
1238: register struct ranlib *tp, *tplast;
1239: off_t loc;
1240: int nsymt = symx(nextsym);
1241:
1242: tplast = &tab[tnum-1];
1243: for (tp = tab; tp <= tplast; tp++) {
1244: if ((hp = slookup(tp->ran_un.ran_name)) == 0)
1245: continue;
1246: sp = *hp;
1247: if (sp == 0)
1248: continue;
1249: if (sp->n_type != 01+0x0)
1250: continue;
1251: step(tp->ran_off);
1252: loc = tp->ran_off;
1253: while (tp < tplast && (tp+1)->ran_off == loc)
1254: tp++;
1255: }
1256: return (symx(nextsym) != nsymt);
1257: }
1258:
1259:
1260:
1261:
1262: load1(libflg, loc)
1263: off_t loc;
1264: {
1265: register struct nlist *sp;
1266: struct nlist *savnext;
1267: int ndef, nlocal, type, size, nsymt;
1268: register int i;
1269: off_t maxoff;
1270: struct stat stb;
1271:
1272: readhdr(loc);
1273: if (filhdr.a_syms == 0) {
1274: if (filhdr.a_text+filhdr.a_data == 0)
1275: return (0);
1276: error(1, "no namelist");
1277: }
1278: if (libflg)
1279: maxoff = atol(archdr.ar_size);
1280: else {
1281: fstat(infil, &stb);
1282: maxoff = stb.st_size;
1283: }
1284: if (((((filhdr).a_magic==0413 ? 1024 : sizeof (struct exec)) + (filhdr).a_text+(filhdr).a_data + (filhdr).a_trsize+(filhdr).a_drsize) + (filhdr).a_syms) + sizeof (off_t) >= maxoff)
1285: error(1, "too small (old format .o?)");
1286: ctrel = tsize; cdrel += dsize; cbrel += bsize;
1287: ndef = 0;
1288: nlocal = sizeof(cursym);
1289: savnext = nextsym;
1290: loc += (((filhdr).a_magic==0413 ? 1024 : sizeof (struct exec)) + (filhdr).a_text+(filhdr).a_data + (filhdr).a_trsize+(filhdr).a_drsize);
1291: dseek(&text, loc, filhdr.a_syms);
1292: dseek(&reloc, loc + filhdr.a_syms, sizeof(off_t));
1293: mget(&size, sizeof (size), &reloc);
1294: dseek(&reloc, loc + filhdr.a_syms+sizeof (off_t), size-sizeof (off_t));
1295: curstr = (char *)malloc(size);
1296: if (curstr == 0)
1297: error(1, "no space for string table");
1298: mget(curstr+sizeof(off_t), size-sizeof(off_t), &reloc);
1299: while (text.size > 0) {
1300: mget((char *)&cursym, sizeof(struct nlist), &text);
1301: if (cursym.n_un.n_strx) {
1302: if (cursym.n_un.n_strx<sizeof(size) ||
1303: cursym.n_un.n_strx>=size)
1304: error(1, "bad string table index (pass 1)");
1305: cursym.n_un.n_name = curstr + cursym.n_un.n_strx;
1306: }
1307: type = cursym.n_type;
1308: if ((type&01)==0) {
1309: if (Xflag==0 || cursym.n_un.n_name[0]!='L' ||
1310: type & 0xe0)
1311: nlocal += sizeof cursym;
1312: continue;
1313: }
1314: symreloc();
1315: if (enter(lookup()))
1316: continue;
1317: if ((sp = lastsym)->n_type != 01+0x0)
1318: continue;
1319: if (cursym.n_type == 01+0x0) {
1320: if (cursym.n_value > sp->n_value)
1321: sp->n_value = cursym.n_value;
1322: continue;
1323: }
1324: if (sp->n_value != 0 && cursym.n_type == 01+0x4)
1325: continue;
1326: ndef++;
1327: sp->n_type = cursym.n_type;
1328: sp->n_value = cursym.n_value;
1329: }
1330: if (libflg==0 || ndef) {
1331: tsize += filhdr.a_text;
1332: dsize += round(filhdr.a_data, sizeof (long));
1333: bsize += round(filhdr.a_bss, sizeof (long));
1334: ssize += nlocal;
1335: trsize += filhdr.a_trsize;
1336: drsize += filhdr.a_drsize;
1337: if (funding)
1338: textbase = (*slookup("_end"))->n_value;
1339: nsymt = symx(nextsym);
1340: for (i = symx(savnext); i < nsymt; i++) {
1341: sp = (symseg[(i)/1103].sy_first+((i)%1103));
1342: sp->n_un.n_name = savestr(sp->n_un.n_name);
1343: }
1344: free(curstr);
1345: return (1);
1346: }
1347:
1348:
1349:
1350:
1351: symfree(savnext);
1352: free(curstr);
1353: return(0);
1354: }
1355:
1356: middle()
1357: {
1358: register struct nlist *sp;
1359: long csize, t, corigin, ocsize;
1360: int nund, rnd;
1361: char s;
1362: register int i;
1363: int nsymt;
1364:
1365: torigin = 0;
1366: dorigin = 0;
1367: borigin = 0;
1368:
1369: p_etext = *slookup("_etext");
1370: p_edata = *slookup("_edata");
1371: p_end = *slookup("_end");
1372:
1373:
1374:
1375: nsymt = symx(nextsym);
1376: if (rflag==0) {
1377: for (i = 0; i < nsymt; i++) {
1378: sp = (symseg[(i)/1103].sy_first+((i)%1103));
1379: if (sp->n_type==01+0x0 && sp->n_value==0 &&
1380: sp!=p_end && sp!=p_edata && sp!=p_etext) {
1381: rflag++;
1382: dflag = 0;
1383: break;
1384: }
1385: }
1386: }
1387: if (rflag)
1388: sflag = zflag = 0;
1389:
1390:
1391:
1392: csize = 0;
1393: if (!Aflag)
1394: addsym = symseg[0].sy_first;
1395: database = round(tsize+textbase,
1396: (nflag||zflag? (512*2) : sizeof (long)));
1397: database += hsize;
1398: if (dflag || rflag==0) {
1399: ldrsym(p_etext, tsize, 01+0x4);
1400: ldrsym(p_edata, dsize, 01+0x6);
1401: ldrsym(p_end, bsize, 01+0x8);
1402: for (i = symx(addsym); i < nsymt; i++) {
1403: sp = (symseg[(i)/1103].sy_first+((i)%1103));
1404: if ((s=sp->n_type)==01+0x0 &&
1405: (t = sp->n_value)!=0) {
1406: if (t >= sizeof (double))
1407: rnd = sizeof (double);
1408: else if (t >= sizeof (long))
1409: rnd = sizeof (long);
1410: else
1411: rnd = sizeof (short);
1412: csize = round(csize, rnd);
1413: sp->n_value = csize;
1414: sp->n_type = 01+0x12;
1415: ocsize = csize;
1416: csize += t;
1417: }
1418: if (s&01 && (s&0x1e)==0x0 && s&0xe0) {
1419: sp->n_value = ocsize;
1420: sp->n_type = (s&0xe0) | (01+0x12);
1421: }
1422: }
1423: }
1424:
1425:
1426:
1427: csize = round(csize, sizeof (long));
1428: torigin = textbase;
1429: dorigin = database;
1430: corigin = dorigin + dsize;
1431: borigin = corigin + csize;
1432: nund = 0;
1433: nsymt = symx(nextsym);
1434: for (i = symx(addsym); i<nsymt; i++) {
1435: sp = (symseg[(i)/1103].sy_first+((i)%1103));
1436: switch (sp->n_type & (0x1e+01)) {
1437:
1438: case 01+0x0:
1439: if (arflag == 0)
1440: errlev |= 01;
1441: if ((arflag==0 || dflag) && sp->n_value==0) {
1442: if (sp==p_end || sp==p_etext || sp==p_edata)
1443: continue;
1444: if (nund==0)
1445: printf("Undefined:\n");
1446: nund++;
1447: printf("%s\n", sp->n_un.n_name);
1448: }
1449: continue;
1450: case 01+0x2:
1451: default:
1452: continue;
1453: case 01+0x4:
1454: sp->n_value += torigin;
1455: continue;
1456: case 01+0x6:
1457: sp->n_value += dorigin;
1458: continue;
1459: case 01+0x8:
1460: sp->n_value += borigin;
1461: continue;
1462: case 01+0x12:
1463: sp->n_type = (sp->n_type & 0xe0) | (01+0x8);
1464: sp->n_value += corigin;
1465: continue;
1466: }
1467: }
1468: if (sflag || xflag)
1469: ssize = 0;
1470: bsize += csize;
1471: nsym = ssize / (sizeof cursym);
1472: if (Aflag) {
1473: fixspec(p_etext,torigin);
1474: fixspec(p_edata,dorigin);
1475: fixspec(p_end,borigin);
1476: }
1477: }
1478:
1479: fixspec(sym,offset)
1480: struct nlist *sym;
1481: long offset;
1482: {
1483:
1484: if(symx(sym) < symx(addsym) && sym!=0)
1485: sym->n_value += offset;
1486: }
1487:
1488: ldrsym(sp, val, type)
1489: register struct nlist *sp;
1490: long val;
1491: {
1492:
1493: if (sp == 0)
1494: return;
1495: if ((sp->n_type != 01+0x0 || sp->n_value) && !Aflag) {
1496: printf("%s: ", sp->n_un.n_name);
1497: error(0, "user attempt to redefine loader-defined symbol");
1498: return;
1499: }
1500: sp->n_type = type;
1501: sp->n_value = val;
1502: }
1503:
1504: off_t wroff;
1505: struct biobuf toutb;
1506:
1507: setupout()
1508: {
1509: int bss;
1510: extern char *sys_errlist[];
1511: extern int errno;
1512:
1513: ofilemode = 0777 & ~umask(0);
1514: biofd = creat(ofilename, 0666 & ofilemode);
1515: if (biofd < 0) {
1516: filname = ofilename;
1517: archdr.ar_name[0] = 0;
1518: error(1, sys_errlist[errno]);
1519: } else {
1520: struct stat mybuf;
1521: fstat(biofd, &mybuf);
1522: if(mybuf.st_mode & 0111) {
1523: chmod(ofilename, mybuf.st_mode & 0666);
1524: ofilemode = mybuf.st_mode;
1525: }
1526: }
1527: tout = &toutb;
1528: bopen(tout, 0);
1529: filhdr.a_magic = nflag ? 0410 : (zflag ? 0413 : 0407);
1530: filhdr.a_text = nflag ? tsize :
1531: round(tsize, zflag ? (512*2) : sizeof (long));
1532: filhdr.a_data = zflag ? round(dsize, (512*2)) : dsize;
1533: bss = bsize - (filhdr.a_data - dsize);
1534: if (bss < 0)
1535: bss = 0;
1536: filhdr.a_bss = bss;
1537: filhdr.a_trsize = trsize;
1538: filhdr.a_drsize = drsize;
1539: filhdr.a_syms = sflag? 0: (ssize + (sizeof cursym)*symx(nextsym));
1540: if (entrypt) {
1541: if (entrypt->n_type!=01+0x4)
1542: error(0, "entry point not in text");
1543: else
1544: filhdr.a_entry = entrypt->n_value;
1545: } else
1546: filhdr.a_entry = 0;
1547: filhdr.a_trsize = (rflag ? trsize:0);
1548: filhdr.a_drsize = (rflag ? drsize:0);
1549: bwrite((char *)&filhdr, sizeof (filhdr), tout);
1550: if (zflag) {
1551: bflush1(tout);
1552: biobufs = 0;
1553: bopen(tout, (512*2));
1554: }
1555: wroff = ((filhdr).a_magic==0413 ? 1024 : sizeof (struct exec)) + filhdr.a_text;
1556: outb(&dout, filhdr.a_data);
1557: if (rflag) {
1558: outb(&trout, filhdr.a_trsize);
1559: outb(&drout, filhdr.a_drsize);
1560: }
1561: if (sflag==0 || xflag==0) {
1562: outb(&sout, filhdr.a_syms);
1563: wroff += sizeof (offset);
1564: outb(&strout, 0);
1565: }
1566: }
1567:
1568: outb(bp, inc)
1569: register struct biobuf **bp;
1570: {
1571:
1572: *bp = (struct biobuf *)malloc(sizeof (struct biobuf));
1573: if (*bp == 0)
1574: error(1, "ran out of memory (outb)");
1575: bopen(*bp, wroff);
1576: wroff += inc;
1577: }
1578:
1579: load2arg(acp)
1580: char *acp;
1581: {
1582: register char *cp;
1583: off_t loc;
1584:
1585: cp = acp;
1586: if (getfile(cp) == 0) {
1587: while (*cp)
1588: cp++;
1589: while (cp >= acp && *--cp != '/');
1590: mkfsym(++cp);
1591: load2(0L);
1592: } else {
1593: for (;;) {
1594: if (clibseg->li_used2 == clibseg->li_used) {
1595: if (clibseg->li_used < 250)
1596: error(1, "libseg botch");
1597: clibseg++;
1598: }
1599: loc = clibseg->li_first[clibseg->li_used2++];
1600: if (loc == -1)
1601: break;
1602: dseek(&text, loc, (long)sizeof(archdr));
1603: getarhdr();
1604: mkfsym(archdr.ar_name);
1605: load2(loc + (long)sizeof(archdr));
1606: }
1607: }
1608: close(infil);
1609: }
1610:
1611: load2(loc)
1612: long loc;
1613: {
1614: int size;
1615: register struct nlist *sp;
1616: register struct local *lp;
1617: register int symno, i;
1618: int type;
1619:
1620: readhdr(loc);
1621: if (!funding) {
1622: ctrel = torigin;
1623: cdrel += dorigin;
1624: cbrel += borigin;
1625: }
1626:
1627:
1628:
1629:
1630: for (i = 0; i < 31; i++)
1631: lochash[i] = 0;
1632: clocseg = locseg;
1633: clocseg->lo_used = 0;
1634: symno = -1;
1635: loc += ((filhdr).a_magic==0413 ? 1024 : sizeof (struct exec));
1636: dseek(&text, loc+filhdr.a_text+filhdr.a_data+
1637: filhdr.a_trsize+filhdr.a_drsize+filhdr.a_syms, sizeof(off_t));
1638: mget(&size, sizeof(size), &text);
1639: dseek(&text, loc+filhdr.a_text+filhdr.a_data+
1640: filhdr.a_trsize+filhdr.a_drsize+filhdr.a_syms+sizeof(off_t),
1641: size - sizeof(off_t));
1642: curstr = (char *)malloc(size);
1643: if (curstr == 0)
1644: error(1, "out of space reading string table (pass 2)");
1645: mget(curstr+sizeof(off_t), size-sizeof(off_t), &text);
1646: dseek(&text, loc+filhdr.a_text+filhdr.a_data+
1647: filhdr.a_trsize+filhdr.a_drsize, filhdr.a_syms);
1648: while (text.size > 0) {
1649: symno++;
1650: mget((char *)&cursym, sizeof(struct nlist), &text);
1651: if (cursym.n_un.n_strx) {
1652: if (cursym.n_un.n_strx<sizeof(size) ||
1653: cursym.n_un.n_strx>=size)
1654: error(1, "bad string table index (pass 2)");
1655: cursym.n_un.n_name = curstr + cursym.n_un.n_strx;
1656: }
1657:
1658: switch (cursym.n_type & 017) {
1659:
1660: case 0x4:
1661: case 01+0x4:
1662: cursym.n_value += ctrel;
1663: break;
1664: case 0x6:
1665: case 01+0x6:
1666: cursym.n_value += cdrel;
1667: break;
1668: case 0x8:
1669: case 01+0x8:
1670: cursym.n_value += cbrel;
1671: break;
1672: case 01+0x0:
1673: break;
1674: default:
1675: if (cursym.n_type&01)
1676: cursym.n_type = 01+0x2;
1677: }
1678:
1679: type = cursym.n_type;
1680: if (yflag && cursym.n_un.n_name)
1681: for (i = 0; i < yflag; i++)
1682:
1683: if (ytab[i][1] == cursym.n_un.n_name[1] &&
1684: !strcmp(ytab[i], cursym.n_un.n_name)) {
1685: tracesym();
1686: break;
1687: }
1688: if ((type&01) == 0) {
1689: if (!sflag&&!xflag&&
1690: (!Xflag||cursym.n_un.n_name[0]!='L'||type&0xe0))
1691: symwrite(&cursym, sout);
1692: continue;
1693: }
1694: if (funding)
1695: continue;
1696: if ((sp = *lookup()) == 0)
1697: error(1, "internal error: symbol not found");
1698: if (cursym.n_type == 01+0x0) {
1699: if (clocseg->lo_used == 100) {
1700: if (++clocseg == &locseg[40])
1701: error(1, "local symbol overflow");
1702: clocseg->lo_used = 0;
1703: }
1704: if (clocseg->lo_first == 0) {
1705: clocseg->lo_first = (struct local *)
1706: malloc(100 * sizeof (struct local));
1707: if (clocseg->lo_first == 0)
1708: error(1, "out of memory (clocseg)");
1709: }
1710: lp = &clocseg->lo_first[clocseg->lo_used++];
1711: lp->l_index = symno;
1712: lp->l_symbol = sp;
1713: lp->l_link = lochash[symno % 31];
1714: lochash[symno % 31] = lp;
1715: continue;
1716: }
1717: if (cursym.n_type & 0xe0)
1718: continue;
1719: if (cursym.n_type!=sp->n_type || cursym.n_value!=sp->n_value) {
1720: printf("%s: ", cursym.n_un.n_name);
1721: error(0, "multiply defined");
1722: }
1723: }
1724: if (funding)
1725: return;
1726: dseek(&text, loc, filhdr.a_text);
1727: dseek(&reloc, loc+filhdr.a_text+filhdr.a_data, filhdr.a_trsize);
1728: load2td(ctrel, torigin - textbase, tout, trout);
1729: dseek(&text, loc+filhdr.a_text, filhdr.a_data);
1730: dseek(&reloc, loc+filhdr.a_text+filhdr.a_data+filhdr.a_trsize,
1731: filhdr.a_drsize);
1732: load2td(cdrel, dorigin - database, dout, drout);
1733: while (filhdr.a_data & (sizeof(long)-1)) {
1734: (( dout)->b_nleft ? (--( dout)->b_nleft, *( dout)->b_ptr++ = (0)) : bflushc( dout, 0));
1735: filhdr.a_data++;
1736: }
1737: torigin += filhdr.a_text;
1738: dorigin += round(filhdr.a_data, sizeof (long));
1739: borigin += round(filhdr.a_bss, sizeof (long));
1740: free(curstr);
1741: }
1742:
1743: struct tynames {
1744: int ty_value;
1745: char *ty_name;
1746: } tynames[] = {
1747: 0x0, "undefined",
1748: 0x2, "absolute",
1749: 0x4, "text",
1750: 0x6, "data",
1751: 0x8, "bss",
1752: 0x12, "common",
1753: 0, 0,
1754: };
1755:
1756: tracesym()
1757: {
1758: register struct tynames *tp;
1759:
1760: if (cursym.n_type & 0xe0)
1761: return;
1762: printf("%s", filname);
1763: if (archdr.ar_name[0])
1764: printf("(%s)", archdr.ar_name);
1765: printf(": ");
1766: if ((cursym.n_type&0x1e) == 0x0 && cursym.n_value) {
1767: printf("definition of common %s size %d\n",
1768: cursym.n_un.n_name, cursym.n_value);
1769: return;
1770: }
1771: for (tp = tynames; tp->ty_name; tp++)
1772: if (tp->ty_value == (cursym.n_type&0x1e))
1773: break;
1774: printf((cursym.n_type&0x1e) ? "definition of" : "reference to");
1775: if (cursym.n_type&01)
1776: printf(" external");
1777: if (tp->ty_name)
1778: printf(" %s", tp->ty_name);
1779: printf(" %s\n", cursym.n_un.n_name);
1780: }
1781:
1782:
1783:
1784:
1785:
1786:
1787:
1788:
1789:
1790:
1791:
1792:
1793:
1794:
1795: load2td(creloc, position, b1, b2)
1796: long creloc, offset;
1797: struct biobuf *b1, *b2;
1798: {
1799: register struct nlist *sp;
1800: register struct local *lp;
1801: long tw;
1802: register struct relocation_info *rp, *rpend;
1803: struct relocation_info *relp;
1804: char *codep;
1805: register char *cp;
1806: int relsz, codesz;
1807:
1808: relsz = reloc.size;
1809: relp = (struct relocation_info *)malloc(relsz);
1810: codesz = text.size;
1811: codep = (char *)malloc(codesz);
1812: if (relp == 0 || codep == 0)
1813: error(1, "out of memory (load2td)");
1814: mget((char *)relp, relsz, &reloc);
1815: rpend = &relp[relsz / sizeof (struct relocation_info)];
1816: mget(codep, codesz, &text);
1817: for (rp = relp; rp < rpend; rp++) {
1818: cp = codep + rp->r_address;
1819:
1820:
1821:
1822: switch (rp->r_length) {
1823:
1824: case 0:
1825: tw = *cp;
1826: break;
1827:
1828: case 1:
1829: tw = *(short *)cp;
1830: break;
1831:
1832: case 2:
1833: tw = *(long *)cp;
1834: break;
1835:
1836: default:
1837: error(1, "load2td botch: bad length");
1838: }
1839:
1840:
1841:
1842:
1843:
1844:
1845:
1846: if (rp->r_extern) {
1847:
1848:
1849:
1850:
1851:
1852: lp = lochash[rp->r_symbolnum % 31];
1853: while (lp->l_index != rp->r_symbolnum) {
1854: lp = lp->l_link;
1855: if (lp == 0)
1856: error(1, "local symbol botch");
1857: }
1858: sp = lp->l_symbol;
1859: if (sp->n_type == 01+0x0)
1860: rp->r_symbolnum = nsym+symx(sp);
1861: else {
1862: rp->r_symbolnum = sp->n_type & 0x1e;
1863: tw += sp->n_value;
1864: rp->r_extern = 0;
1865: }
1866: } else switch (rp->r_symbolnum & 0x1e) {
1867:
1868:
1869:
1870:
1871:
1872: case 0x4:
1873: tw += ctrel;
1874: break;
1875: case 0x6:
1876: tw += cdrel;
1877: break;
1878: case 0x8:
1879: tw += cbrel;
1880: break;
1881: case 0x2:
1882: break;
1883: default:
1884: error(1, "relocation format botch (symbol type))");
1885: }
1886:
1887:
1888:
1889:
1890:
1891:
1892:
1893:
1894:
1895: if (rp->r_pcrel)
1896: tw -= creloc;
1897:
1898:
1899:
1900:
1901: switch (rp->r_length) {
1902:
1903: case 0:
1904: if (tw < -128 || tw > 127)
1905: error(0, "byte displacement overflow");
1906: *cp = tw;
1907: break;
1908: case 1:
1909: if (tw < -32768 || tw > 32767)
1910: error(0, "word displacement overflow");
1911: *(short *)cp = tw;
1912: break;
1913: case 2:
1914: *(long *)cp = tw;
1915: break;
1916: }
1917:
1918:
1919:
1920:
1921:
1922:
1923:
1924: if (rflag)
1925: rp->r_address += position;
1926: }
1927: bwrite(codep, codesz, b1);
1928: if (rflag)
1929: bwrite(relp, relsz, b2);
1930: cfree((char *)relp);
1931: cfree(codep);
1932: }
1933:
1934: finishout()
1935: {
1936: register int i;
1937: int nsymt;
1938:
1939: if (sflag==0) {
1940: nsymt = symx(nextsym);
1941: for (i = 0; i < nsymt; i++)
1942: symwrite((symseg[(i)/1103].sy_first+((i)%1103)), sout);
1943: bwrite(&offset, sizeof offset, sout);
1944: }
1945: if (!ofilfnd) {
1946: unlink("a.out");
1947: if (link("l.out", "a.out") < 0)
1948: error(1, "cannot move l.out to a.out");
1949: ofilename = "a.out";
1950: }
1951: delarg = errlev;
1952: delexit();
1953: }
1954:
1955: mkfsym(s)
1956: char *s;
1957: {
1958:
1959: if (sflag || xflag)
1960: return;
1961: cursym.n_un.n_name = s;
1962: cursym.n_type = 0x4;
1963: cursym.n_value = torigin;
1964: symwrite(&cursym, sout);
1965: }
1966:
1967: getarhdr()
1968: {
1969: register char *cp;
1970:
1971: mget((char *)&archdr, sizeof archdr, &text);
1972: for (cp=archdr.ar_name; cp<&archdr.ar_name[sizeof(archdr.ar_name)];)
1973: if (*cp++ == ' ') {
1974: cp[-1] = 0;
1975: return;
1976: }
1977: }
1978:
1979: mget(loc, n, sp)
1980: register STREAM *sp;
1981: register char *loc;
1982: {
1983: register char *p;
1984: register int take;
1985:
1986: top:
1987: if (n == 0)
1988: return;
1989: if (sp->size && sp->nibuf) {
1990: p = sp->ptr;
1991: take = sp->size;
1992: if (take > sp->nibuf)
1993: take = sp->nibuf;
1994: if (take > n)
1995: take = n;
1996: n -= take;
1997: sp->size -= take;
1998: sp->nibuf -= take;
1999: sp->pos += take;
2000: do
2001: *loc++ = *p++;
2002: while (--take > 0);
2003: sp->ptr = p;
2004: goto top;
2005: }
2006: if (n > 4096) {
2007: take = n - n % (1<<12);
2008: lseek(infil, (sp->bno+1)*(1<<12), 0);
2009: if (take > sp->size || read(infil, loc, take) != take)
2010: error(1, "premature EOF");
2011: loc += take;
2012: n -= take;
2013: sp->size -= take;
2014: sp->pos += take;
2015: dseek(sp, (sp->bno+1+take/(1<<12))*(1<<12), -1);
2016: goto top;
2017: }
2018: *loc++ = get(sp);
2019: --n;
2020: goto top;
2021: }
2022:
2023: symwrite(sp, bp)
2024: struct nlist *sp;
2025: struct biobuf *bp;
2026: {
2027: register int len;
2028: register char *str;
2029:
2030: str = sp->n_un.n_name;
2031: if (str) {
2032: sp->n_un.n_strx = offset;
2033: len = strlen(str) + 1;
2034: bwrite(str, len, strout);
2035: offset += len;
2036: }
2037: bwrite(sp, sizeof (*sp), bp);
2038: sp->n_un.n_name = str;
2039: }
2040:
2041: dseek(sp, loc, s)
2042: register STREAM *sp;
2043: long loc, s;
2044: {
2045: register PAGE *p;
2046: register b, o;
2047: int n;
2048:
2049: b = loc>>12;
2050: o = loc&((1<<12)-1);
2051: if (o&01)
2052: error(1, "loader error; odd offset");
2053: --sp->pno->nuser;
2054: if ((p = &page[0])->bno!=b && (p = &page[1])->bno!=b)
2055: if (p->nuser==0 || (p = &page[0])->nuser==0) {
2056: if (page[0].nuser==0 && page[1].nuser==0)
2057: if (page[0].bno < page[1].bno)
2058: p = &page[0];
2059: p->bno = b;
2060: lseek(infil, loc & ~(long)((1<<12)-1), 0);
2061: if ((n = read(infil, p->buff, sizeof(p->buff))) < 0)
2062: n = 0;
2063: p->nibuf = n;
2064: } else
2065: error(1, "botch: no pages");
2066: ++p->nuser;
2067: sp->bno = b;
2068: sp->pno = p;
2069: if (s != -1) {sp->size = s; sp->pos = 0;}
2070: sp->ptr = (char *)(p->buff + o);
2071: if ((sp->nibuf = p->nibuf-o) <= 0)
2072: sp->size = 0;
2073: }
2074:
2075: char
2076: get(asp)
2077: STREAM *asp;
2078: {
2079: register STREAM *sp;
2080:
2081: sp = asp;
2082: if ((sp->nibuf -= sizeof(char)) < 0) {
2083: dseek(sp, ((long)(sp->bno+1)<<12), (long)-1);
2084: sp->nibuf -= sizeof(char);
2085: }
2086: if ((sp->size -= sizeof(char)) <= 0) {
2087: if (sp->size < 0)
2088: error(1, "premature EOF");
2089: ++fpage.nuser;
2090: --sp->pno->nuser;
2091: sp->pno = (PAGE *) &fpage;
2092: }
2093: sp->pos += sizeof(char);
2094: return(*sp->ptr++);
2095: }
2096:
2097: getfile(acp)
2098: char *acp;
2099: {
2100: register char *cp;
2101: register int c;
2102: char arcmag[8+1];
2103: struct stat stb;
2104:
2105: cp = acp;
2106: infil = -1;
2107: archdr.ar_name[0] = '\0';
2108: filname = cp;
2109: if (cp[0]=='-' && cp[1]=='l') {
2110: char *locfilname = "/usr/local/lib/libxxxxxxxxxxxxxxx";
2111: if(cp[2] == '\0')
2112: cp = "-la";
2113: filname = "/usr/lib/libxxxxxxxxxxxxxxx";
2114: for(c=0; cp[c+2]; c++) {
2115: filname[c+12] = cp[c+2];
2116: locfilname[c+18] = cp[c+2];
2117: }
2118: filname[c+12] = locfilname[c+18] = '.';
2119: filname[c+13] = locfilname[c+19] = 'a';
2120: filname[c+14] = locfilname[c+20] = '\0';
2121: if ((infil = open(filname+4, 0)) >= 0) {
2122: filname += 4;
2123: } else if ((infil = open(filname, 0)) < 0) {
2124: filname = locfilname;
2125: }
2126: }
2127: if (infil == -1 && (infil = open(filname, 0)) < 0)
2128: error(1, "cannot open");
2129: page[0].bno = page[1].bno = -1;
2130: page[0].nuser = page[1].nuser = 0;
2131: text.pno = reloc.pno = (PAGE *) &fpage;
2132: fpage.nuser = 2;
2133: dseek(&text, 0L, 8);
2134: if (text.size <= 0)
2135: error(1, "premature EOF");
2136: mget((char *)arcmag, 8, &text);
2137: arcmag[8] = 0;
2138: if (strcmp(arcmag, "!<arch>\n"))
2139: return (0);
2140: dseek(&text, 8, sizeof archdr);
2141: if(text.size <= 0)
2142: return (1);
2143: getarhdr();
2144: if (strncmp(archdr.ar_name, "__.SYMDEF", sizeof(archdr.ar_name)) != 0)
2145: return (1);
2146: fstat(infil, &stb);
2147: return (stb.st_mtime > atol(archdr.ar_date) ? 3 : 2);
2148: }
2149:
2150: struct nlist **
2151: lookup()
2152: {
2153: register int sh;
2154: register struct nlist **hp;
2155: register char *cp, *cp1;
2156: register struct symseg *gp;
2157: register int i;
2158:
2159: sh = 0;
2160: for (cp = cursym.n_un.n_name; *cp;)
2161: sh = (sh<<1) + *cp++;
2162: sh = (sh & 0x7fffffff) % (1103*2);
2163: for (gp = symseg; gp < &symseg[40]; gp++) {
2164: if (gp->sy_first == 0) {
2165: gp->sy_first = (struct nlist *)
2166: calloc(1103, sizeof (struct nlist));
2167: gp->sy_hfirst = (struct nlist **)
2168: calloc((1103*2), sizeof (struct nlist *));
2169: if (gp->sy_first == 0 || gp->sy_hfirst == 0)
2170: error(1, "ran out of space for symbol table");
2171: gp->sy_last = gp->sy_first + 1103;
2172: gp->sy_hlast = gp->sy_hfirst + (1103*2);
2173: }
2174: if (gp > csymseg)
2175: csymseg = gp;
2176: hp = gp->sy_hfirst + sh;
2177: i = 1;
2178: do {
2179: if (*hp == 0) {
2180: if (gp->sy_used == 1103)
2181: break;
2182: return (hp);
2183: }
2184: cp1 = (*hp)->n_un.n_name;
2185: for (cp = cursym.n_un.n_name; *cp == *cp1++;)
2186: if (*cp++ == 0)
2187: return (hp);
2188: hp += i;
2189: i += 2;
2190: if (hp >= gp->sy_hlast)
2191: hp -= (1103*2);
2192: } while (i < (1103*2));
2193: if (i > (1103*2))
2194: error(1, "hash table botch");
2195: }
2196: error(1, "symbol table overflow");
2197:
2198: }
2199:
2200: symfree(saved)
2201: struct nlist *saved;
2202: {
2203: register struct symseg *gp;
2204: register struct nlist *sp;
2205:
2206: for (gp = csymseg; gp >= symseg; gp--, csymseg--) {
2207: sp = gp->sy_first + gp->sy_used;
2208: if (sp == saved) {
2209: nextsym = sp;
2210: return;
2211: }
2212: for (sp--; sp >= gp->sy_first; sp--) {
2213: gp->sy_hfirst[sp->n_desc] = 0;
2214: gp->sy_used--;
2215: if (sp == saved) {
2216: nextsym = sp;
2217: return;
2218: }
2219: }
2220: }
2221: if (saved == 0)
2222: return;
2223: error(1, "symfree botch");
2224: }
2225:
2226: struct nlist **
2227: slookup(s)
2228: char *s;
2229: {
2230:
2231: cursym.n_un.n_name = s;
2232: cursym.n_type = 01+0x0;
2233: cursym.n_value = 0;
2234: return (lookup());
2235: }
2236:
2237: enter(hp)
2238: register struct nlist **hp;
2239: {
2240: register struct nlist *sp;
2241:
2242: if (*hp==0) {
2243: if (hp < csymseg->sy_hfirst || hp >= csymseg->sy_hlast)
2244: error(1, "enter botch");
2245: *hp = lastsym = sp = csymseg->sy_first + csymseg->sy_used;
2246: csymseg->sy_used++;
2247: sp->n_un.n_name = cursym.n_un.n_name;
2248: sp->n_type = cursym.n_type;
2249: sp->n_desc = hp - csymseg->sy_hfirst;
2250: sp->n_value = cursym.n_value;
2251: nextsym = lastsym + 1;
2252: return(1);
2253: } else {
2254: lastsym = *hp;
2255: return(0);
2256: }
2257: }
2258:
2259: symx(sp)
2260: struct nlist *sp;
2261: {
2262: register struct symseg *gp;
2263:
2264: if (sp == 0)
2265: return (0);
2266: for (gp = csymseg; gp >= symseg; gp--)
2267:
2268: if (sp >= gp->sy_first && sp <= gp->sy_last)
2269: return ((gp - symseg) * 1103 + sp - gp->sy_first);
2270: error(1, "symx botch");
2271:
2272: }
2273:
2274: symreloc()
2275: {
2276: if(funding) return;
2277: switch (cursym.n_type & 017) {
2278:
2279: case 0x4:
2280: case 01+0x4:
2281: cursym.n_value += ctrel;
2282: return;
2283:
2284: case 0x6:
2285: case 01+0x6:
2286: cursym.n_value += cdrel;
2287: return;
2288:
2289: case 0x8:
2290: case 01+0x8:
2291: cursym.n_value += cbrel;
2292: return;
2293:
2294: case 01+0x0:
2295: return;
2296:
2297: default:
2298: if (cursym.n_type&01)
2299: cursym.n_type = 01+0x2;
2300: return;
2301: }
2302: }
2303:
2304: error(n, s)
2305: char *s;
2306: {
2307:
2308: if (errlev==0)
2309: printf("ld:");
2310: if (filname) {
2311: printf("%s", filname);
2312: if (n != -1 && archdr.ar_name[0])
2313: printf("(%s)", archdr.ar_name);
2314: printf(": ");
2315: }
2316: printf("%s\n", s);
2317: if (n == -1)
2318: return;
2319: if (n)
2320: delexit();
2321: errlev = 2;
2322: }
2323:
2324: readhdr(loc)
2325: off_t loc;
2326: {
2327:
2328: dseek(&text, loc, (long)sizeof(filhdr));
2329: mget((short *)&filhdr, sizeof(filhdr), &text);
2330: if ((((filhdr).a_magic)!=0407 && ((filhdr).a_magic)!=0410 && ((filhdr).a_magic)!=0413)) {
2331: if (filhdr.a_magic == 0177545)
2332: error(1, "old archive");
2333: error(1, "bad magic number");
2334: }
2335: if (filhdr.a_text&01 || filhdr.a_data&01)
2336: error(1, "text/data size odd");
2337: if (filhdr.a_magic == 0410 || filhdr.a_magic == 0413) {
2338: cdrel = -round(filhdr.a_text, (512*2));
2339: cbrel = cdrel - filhdr.a_data;
2340: } else if (filhdr.a_magic == 0407) {
2341: cdrel = -filhdr.a_text;
2342: cbrel = cdrel - filhdr.a_data;
2343: } else
2344: error(1, "bad format");
2345: }
2346:
2347: round(v, r)
2348: int v;
2349: u_long r;
2350: {
2351:
2352: r--;
2353: v += r;
2354: v &= ~(long)r;
2355: return(v);
2356: }
2357:
2358:
2359: char *savetab;
2360: int saveleft;
2361:
2362: char *
2363: savestr(cp)
2364: register char *cp;
2365: {
2366: register int len;
2367:
2368: len = strlen(cp) + 1;
2369: if (len > saveleft) {
2370: saveleft = 8192;
2371: if (len > saveleft)
2372: saveleft = len;
2373: savetab = (char *)malloc(saveleft);
2374: if (savetab == 0)
2375: error(1, "ran out of memory (savestr)");
2376: }
2377: strncpy(savetab, cp, len);
2378: cp = savetab;
2379: savetab += len;
2380: saveleft -= len;
2381: return (cp);
2382: }
2383:
2384: bopen(bp, off)
2385: struct biobuf *bp;
2386: {
2387:
2388: bp->b_ptr = bp->b_buf;
2389: bp->b_nleft = 4096 - off % 4096;
2390: bp->b_off = off;
2391: bp->b_link = biobufs;
2392: biobufs = bp;
2393: }
2394:
2395: int bwrerror;
2396:
2397: bwrite(p, cnt, bp)
2398: register char *p;
2399: register int cnt;
2400: register struct biobuf *bp;
2401: {
2402: register int put;
2403: register char *to;
2404:
2405: top:
2406: if (cnt == 0)
2407: return;
2408: if (bp->b_nleft) {
2409: put = bp->b_nleft;
2410: if (put > cnt)
2411: put = cnt;
2412: bp->b_nleft -= put;
2413: to = bp->b_ptr;
2414: asm("movc3 r8,(r11),(r7)");
2415: bp->b_ptr += put;
2416: p += put;
2417: cnt -= put;
2418: goto top;
2419: }
2420: if (cnt >= 4096) {
2421: if (bp->b_ptr != bp->b_buf)
2422: bflush1(bp);
2423: put = cnt - cnt % 4096;
2424: if (boffset != bp->b_off)
2425: lseek(biofd, bp->b_off, 0);
2426: if (write(biofd, p, put) != put) {
2427: bwrerror = 1;
2428: error(1, "output write error");
2429: }
2430: bp->b_off += put;
2431: boffset = bp->b_off;
2432: p += put;
2433: cnt -= put;
2434: goto top;
2435: }
2436: bflush1(bp);
2437: goto top;
2438: }
2439:
2440: bflush()
2441: {
2442: register struct biobuf *bp;
2443:
2444: if (bwrerror)
2445: return;
2446: for (bp = biobufs; bp; bp = bp->b_link)
2447: bflush1(bp);
2448: }
2449:
2450: bflush1(bp)
2451: register struct biobuf *bp;
2452: {
2453: register int cnt = bp->b_ptr - bp->b_buf;
2454:
2455: if (cnt == 0)
2456: return;
2457: if (boffset != bp->b_off)
2458: lseek(biofd, bp->b_off, 0);
2459: if (write(biofd, bp->b_buf, cnt) != cnt) {
2460: bwrerror = 1;
2461: error(1, "output write error");
2462: }
2463: bp->b_off += cnt;
2464: boffset = bp->b_off;
2465: bp->b_ptr = bp->b_buf;
2466: bp->b_nleft = 4096;
2467: }
2468:
2469: bflushc(bp, c)
2470: register struct biobuf *bp;
2471: {
2472:
2473: bflush1(bp);
2474: (( bp)->b_nleft ? (--( bp)->b_nleft, *( bp)->b_ptr++ = (c)) : bflushc( bp, c));
2475: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.