|
|
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.