1: /* 2: * link editor 3: * modified to be a overlayed segmentation register loader by wnj 6/79 4: * touched up by bill jolitz 9/79. 5: * working with emt trap thunk fmt 5/80 bill jolitz. 6: * 8-byte thunks, more touch-ups, mjk 9/81. 7: */ 8: 9: #include <stdio.h> 10: #include <signal.h> 11: #include <sys/types.h> 12: #include <sys/stat.h> 13: 14: /* Layout of a.out file : 15: * 16: * header of 8 words magic number 405, 407, 410, 411 17: * text size ) 18: * data size ) in bytes but even 19: * bss size ) 20: * symbol table size 21: * entry point 22: * {unused} 23: * flag set if no relocation 24: * 25: * 26: * header: 0 27: * text: 16 28: * data: 16+textsize 29: * relocation: 16+textsize+datasize 30: * symbol table: 16+2*(textsize+datasize) or 16+textsize+datasize 31: * 32: */ 33: #define TRUE 1 34: #define FALSE 0 35: 36: 37: #define ARCMAGIC 0177545 38: #define OMAGIC 0405 39: #define FMAGIC 0407 40: #define NMAGIC 0410 41: #define IMAGIC 0411 42: 43: #define EXTERN 040 44: #define UNDEF 00 45: #define ABS 01 46: #define TEXT 02 47: #define DATA 03 48: #define BSS 04 49: #define COMM 05 /* internal use only */ 50: 51: #define RABS 00 52: #define RTEXT 02 53: #define RDATA 04 54: #define RBSS 06 55: #define REXT 010 56: 57: #define NOVLY 16 58: #define RELFLG 01 59: #define NROUT 256 60: #define NSYM 1103 61: #define NSYMPR 1000 62: 63: char premeof[] = "Premature EOF"; 64: char goodnm[] = "__.SYMDEF"; 65: 66: /* table of contents stuff */ 67: #define TABSZ 700 68: struct tab 69: { char cname[8]; 70: long cloc; 71: } tab[TABSZ]; 72: int tnum; 73: 74: 75: /* overlay management */ 76: int vindex; 77: struct overlay { 78: int argsav; 79: int symsav; 80: struct liblist *libsav; 81: char *vname; 82: int ctsav, cdsav, cbsav; 83: int offt, offd, offb, offs; 84: } vnodes[NOVLY]; 85: 86: /* input management */ 87: struct page { 88: int nuser; 89: int bno; 90: int nibuf; 91: int buff[256]; 92: } page[2]; 93: 94: struct { 95: int nuser; 96: int bno; 97: } fpage; 98: 99: struct stream { 100: int *ptr; 101: int bno; 102: int nibuf; 103: int size; 104: struct page *pno; 105: }; 106: 107: struct stream text; 108: struct stream reloc; 109: 110: struct { 111: char aname[14]; 112: long atime; 113: char auid, agid; 114: int amode; 115: long asize; 116: } archdr; 117: 118: struct { 119: int fmagic; 120: int tsize; 121: int dsize; 122: int bsize; 123: int ssize; 124: int entry; 125: int pad; 126: int relflg; 127: } filhdr; 128: 129: 130: /* one entry for each archive member referenced; 131: * set in first pass; needs restoring for overlays 132: */ 133: struct liblist { 134: long loc; 135: }; 136: 137: struct liblist liblist[NROUT]; 138: struct liblist *libp = liblist; 139: 140: 141: /* symbol management */ 142: struct symbol { 143: char sname[8]; 144: char stype; 145: char sovly; 146: int svalue; 147: int sovalue; 148: }; 149: 150: struct xsymbol { 151: char sname[8]; 152: char stype; 153: char sovly; 154: int svalue; 155: }; 156: struct local { 157: int locindex; /* index to symbol in file */ 158: struct symbol *locsymbol; /* ptr to symbol table */ 159: }; 160: 161: struct xsymbol cursym; /* current symbol */ 162: struct symbol symtab[NSYM]; /* actual symbols */ 163: struct symbol **symhash[NSYM]; /* ptr to hash table entry */ 164: struct symbol *lastsym; /* last symbol entered */ 165: int symindex; /* next available symbol table entry */ 166: struct symbol *hshtab[NSYM+2]; /* hash table for symbols */ 167: struct local local[NSYMPR]; 168: 169: /* internal symbols */ 170: struct symbol *p_etext; 171: struct symbol *p_edata; 172: struct symbol *p_end; 173: struct symbol *entrypt; 174: 175: int trace; 176: /* flags */ 177: int xflag; /* discard local symbols */ 178: int Xflag; /* discard locals starting with 'L' */ 179: int Sflag; /* discard all except locals and globals*/ 180: int rflag; /* preserve relocation bits, don't define common */ 181: int arflag; /* original copy of rflag */ 182: int sflag; /* discard all symbols */ 183: int nflag; /* pure procedure */ 184: int Oflag; /* set magic # to 0405 (overlay) */ 185: int dflag; /* define common even with rflag */ 186: int iflag; /* I/D space separated */ 187: int vflag; /* overlays used */ 188: 189: int ofilfnd; 190: char *ofilename = "l.out"; 191: int infil; 192: char *filname; 193: 194: /* cumulative sizes set in pass 1 */ 195: int tsize; 196: int dsize; 197: int bsize; 198: int ssize; 199: 200: /* symbol relocation; both passes */ 201: int ctrel; 202: int cdrel; 203: int cbrel; 204: 205: int errlev; 206: int delarg = 4; 207: char tfname[] = "/tmp/ldaXXXXX"; 208: 209: 210: /* output management */ 211: struct buf { 212: int fildes; 213: int nleft; 214: int *xnext; 215: int iobuf[256]; 216: }; 217: struct buf toutb; 218: struct buf doutb; 219: struct buf troutb; 220: struct buf droutb; 221: struct buf soutb; 222: 223: /* wnj added for text overlay register */ 224: 225: #define NOVL 7 /* max number of overlays; this defines 226: * the header format and must agree with 227: * the kernel limit. */ 228: #define THUNKSIZ 8 229: 230: int torgwas; /* Saves torigin while doing overlays */ 231: int tsizwas; /* Saves tsize while doing overlays */ 232: int numov; /* Total number of overlays */ 233: int curov; /* Overlay being worked on just now */ 234: int inov; /* 1 if working on an overlay */ 235: int ovsize[NOVL+1]; /* The sizes of the overlays */ 236: 237: #define max ovsize[0] 238: 239: struct buf voutb; /* Overlay text goes here */ 240: /* 241: struct buf dummyb; 242: */ 243: 244: /* Kernel overlays have a special 245: subroutine to do the switch */ 246: struct xsymbol ovhndlr = 247: { "ovhndlr1", EXTERN+UNDEF, 0, 0 }; 248: #define HNDLR_NUM 7 /* position of ov number in ovhndlr.sname[] */ 249: int ovbase; /* The base address of the overlays */ 250: /* end overlay stuff */ 251: 252: struct symbol **lookup(); 253: struct symbol **slookup(); 254: struct symbol *lookloc(); 255: 256: delexit() 257: { 258: unlink("l.out"); 259: if (delarg==0) 260: chmod(ofilename, 0777 & ~umask(0)); 261: exit(delarg); 262: } 263: 264: main(argc, argv) 265: char **argv; 266: { 267: register int c, i; 268: int num; 269: register char *ap, **p; 270: int found; 271: int vscan; 272: char save; 273: 274: if (signal(SIGINT, SIG_IGN) != SIG_IGN) 275: signal(SIGINT, delexit); 276: if (signal(SIGTERM, SIG_IGN) != SIG_IGN) 277: signal(SIGTERM, delexit); 278: if (argc == 1) 279: exit(4); 280: p = argv+1; 281: 282: /* scan files once to find symdefs */ 283: for (c=1; c<argc; c++) { 284: if (trace) printf("%s:\n", *p); 285: filname = 0; 286: ap = *p++; 287: 288: if (*ap == '-') { 289: for (i=1; ap[i]; i++) { 290: switch (ap[i]) { 291: case 'o': 292: if (++c >= argc) 293: error(2, "Bad output file"); 294: ofilename = *p++; 295: ofilfnd++; 296: continue; 297: 298: case 'u': 299: case 'e': 300: if (++c >= argc) 301: error(2, "Bad 'use' or 'entry'"); 302: enter(slookup(*p++)); 303: if (ap[i]=='e') 304: entrypt = lastsym; 305: continue; 306: 307: case 'v': 308: if (++c >= argc) 309: error(2, "-v: arg missing"); 310: vflag=TRUE; 311: vscan = vindex; 312: found=FALSE; 313: while (--vscan>=0 && found==FALSE) 314: found = eq(vnodes[vscan].vname, *p); 315: if (found) { 316: endload(c, argv); 317: restore(vscan); 318: } else 319: record(c, *p); 320: p++; 321: continue; 322: 323: case 'D': 324: if (++c >= argc) 325: error(2, "-D: arg missing"); 326: num = atoi(*p++); 327: if (dsize>num) 328: error(2, "-D: too small"); 329: dsize = num; 330: continue; 331: 332: case 'l': 333: save = ap[--i]; 334: ap[i]='-'; 335: load1arg(&ap[i]); 336: ap[i]=save; 337: break; 338: 339: case 'x': 340: xflag++; 341: continue; 342: 343: case 'X': 344: Xflag++; 345: continue; 346: 347: case 'S': 348: Sflag++; 349: continue; 350: 351: case 'r': 352: rflag++; 353: arflag++; 354: continue; 355: 356: case 's': 357: sflag++; 358: xflag++; 359: continue; 360: 361: case 'n': 362: nflag++; 363: continue; 364: 365: case 'd': 366: dflag++; 367: continue; 368: 369: case 'i': 370: iflag++; 371: continue; 372: 373: case 'O': 374: Oflag++; 375: continue; 376: 377: case 't': 378: trace++; 379: continue; 380: 381: /* wnj added for overlay text registers */ 382: case 'Z': 383: if (!inov) { 384: tsizwas = tsize; 385: if (numov == 0) { 386: cursym = ovhndlr; 387: enter(lookup()); 388: } 389: } else { 390: ovsize[curov] = tsize; 391: if (trace) 392: printf("overlay %d size %d\n", curov, ovsize[curov]); 393: } 394: tsize = 0; 395: inov = 1; 396: numov++; 397: if (numov > NOVL) 398: error(2, "Too many overlays, limit 7"); 399: curov++; 400: continue; 401: 402: case 'L': 403: if (inov == 0) 404: error(2, "-L: Not in overlay"); 405: ovsize[curov] = tsize; 406: if (trace) 407: printf("overlay %d size %d\n", curov, ovsize[curov]); 408: curov = inov = 0; 409: tsize = tsizwas; 410: continue; 411: /* end overlay text addition */ 412: 413: default: 414: error(2, "bad flag"); 415: } /*endsw*/ 416: break; 417: } /*endfor*/ 418: } else 419: load1arg(ap); 420: } 421: endload(argc, argv); 422: } 423: 424: /* used after pass 1 */ 425: int nsym; 426: int torigin; 427: int dorigin; 428: int borigin; 429: 430: endload(argc, argv) 431: int argc; 432: char **argv; 433: { 434: register int c, i; 435: int dnum; 436: register char *ap, **p; 437: 438: if (numov) 439: rflag = 0; 440: filname = 0; 441: middle(); 442: setupout(); 443: p = argv+1; 444: libp = liblist; 445: for (c=1; c<argc; c++) { 446: ap = *p++; 447: if (trace) printf("%s:\n", ap); 448: if (*ap == '-') { 449: for (i=1; ap[i]; i++) { 450: switch (ap[i]) { 451: case 'D': 452: for (dnum = atoi(*p); dorigin<dnum; dorigin += 2) { 453: putw(0, &doutb); 454: if (rflag) 455: putw(0, &droutb); 456: } 457: case 'u': 458: case 'e': 459: case 'o': 460: case 'v': 461: ++c; 462: ++p; 463: 464: default: 465: continue; 466: 467: case 'l': 468: ap[--i]='-'; 469: load2arg(&ap[i]); 470: break; 471: 472: /* wnj added for overlay text segmentation registers */ 473: case 'Z': 474: if (inov == 0) 475: torgwas = torigin; 476: else 477: roundov(); 478: torigin = ovbase; 479: inov = 1; 480: curov++; 481: continue; 482: 483: case 'L': 484: roundov(); 485: inov = 0; 486: if (trace) 487: printf("end overlay generation\n"); 488: torigin = torgwas; 489: continue; 490: /* end wnj added for text overlay registers */ 491: } /*endsw*/ 492: break; 493: } /*endfor*/ 494: } else 495: load2arg(ap); 496: } 497: finishout(); 498: } 499: 500: roundov() 501: { 502: 503: while (torigin & 077) { 504: putw(0, &voutb); 505: torigin += sizeof (int); 506: } 507: } 508: 509: record(c, nam) 510: int c; 511: char *nam; 512: { 513: register struct overlay *v; 514: 515: v = &vnodes[vindex++]; 516: v->argsav = c; 517: v->symsav = symindex; 518: v->libsav = libp; 519: v->vname = nam; 520: v->offt = tsize; 521: v->offd = dsize; 522: v->offb = bsize; 523: v->offs = ssize; 524: v->ctsav = ctrel; 525: v->cdsav = cdrel; 526: v->cbsav = cbrel; 527: } 528: 529: restore(vscan) 530: int vscan; 531: { 532: register struct overlay *v; 533: register int saved; 534: 535: v = &vnodes[vscan]; 536: vindex = vscan+1; 537: libp = v->libsav; 538: ctrel = v->ctsav; 539: cdrel = v->cdsav; 540: cbrel = v->cbsav; 541: tsize = v->offt; 542: dsize = v->offd; 543: bsize = v->offb; 544: ssize = v->offs; 545: saved = v->symsav; 546: while (symindex>saved) 547: *symhash[--symindex]=0; 548: } 549: 550: /* scan file to find defined symbols */ 551: load1arg(acp) 552: char *acp; 553: { 554: register char *cp; 555: long nloc; 556: 557: cp = acp; 558: switch ( getfile(cp)) { 559: case 0: 560: load1(0, 0L); 561: break; 562: 563: /* regular archive */ 564: case 1: 565: nloc = 1; 566: while ( step(nloc)) 567: nloc += (archdr.asize + sizeof(archdr) + 1) >> 1; 568: break; 569: 570: /* table of contents */ 571: case 2: 572: tnum = archdr.asize / sizeof(struct tab); 573: if (tnum >= TABSZ) { 574: error(2, "fast load buffer too small"); 575: } 576: lseek(infil, (long)(sizeof(filhdr.fmagic)+sizeof(archdr)), 0); 577: read(infil, (char *)tab, tnum * sizeof(struct tab)); 578: while (ldrand()); 579: libp->loc = -1; 580: libp++; 581: break; 582: /* out of date table of contents */ 583: case 3: 584: error(0, "out of date (warning)"); 585: for(nloc = 1+((archdr.asize+sizeof(archdr)+1) >> 1); step(nloc); 586: nloc += (archdr.asize + sizeof(archdr) + 1) >> 1); 587: break; 588: } 589: close(infil); 590: } 591: 592: step(nloc) 593: long nloc; 594: { 595: dseek(&text, nloc, sizeof archdr); 596: if (text.size <= 0) { 597: libp->loc = -1; 598: libp++; 599: return(0); 600: } 601: mget((int *)&archdr, sizeof archdr); 602: if (load1(1, nloc + (sizeof archdr) / 2)) { 603: libp->loc = nloc; 604: libp++; 605: } 606: return(1); 607: } 608: 609: ldrand() 610: { 611: int i; 612: struct symbol *sp, **pp; 613: struct liblist *oldp = libp; 614: for(i = 0; i<tnum; i++) { 615: if ((pp = slookup(tab[i].cname)) == 0) 616: continue; 617: sp = *pp; 618: if (sp->stype != EXTERN+UNDEF) 619: continue; 620: step(tab[i].cloc >> 1); 621: } 622: return(oldp != libp); 623: } 624: 625: add(a,b,s) 626: int a, b; 627: char *s; 628: { 629: long r; 630: 631: r = (long)(unsigned)a + (unsigned)b; 632: if (r >= 0200000) 633: error(1,s); 634: return(r); 635: } 636: 637: 638: /* single file or archive member */ 639: load1(libflg, loc) 640: long loc; 641: { 642: register struct symbol *sp; 643: int savindex; 644: int ndef, nloc, type, mtype; 645: 646: readhdr(loc); 647: ctrel = tsize; 648: cdrel += dsize; 649: cbrel += bsize; 650: ndef = 0; 651: nloc = sizeof cursym; 652: savindex = symindex; 653: if ((filhdr.relflg&RELFLG)==1) { 654: error(1, "No relocation bits"); 655: return(0); 656: } 657: loc += (sizeof filhdr)/2 + filhdr.tsize + filhdr.dsize; 658: dseek(&text, loc, filhdr.ssize); 659: while (text.size > 0) { 660: mget((int *)&cursym, sizeof cursym); 661: type = cursym.stype; 662: if (Sflag) { 663: mtype = type&037; 664: if (mtype==1 || mtype>4) { 665: continue; 666: } 667: } 668: if ((type&EXTERN)==0) { 669: if (Xflag==0 || cursym.sname[0]!='L') 670: nloc += sizeof cursym; 671: continue; 672: } 673: symreloc(); 674: if (enter(lookup())) 675: continue; 676: if ((sp = lastsym)->stype != EXTERN+UNDEF) 677: continue; 678: if (cursym.stype == EXTERN+UNDEF) { 679: if (cursym.svalue > sp->svalue) 680: sp->svalue = cursym.svalue; 681: continue; 682: } 683: if (sp->svalue != 0 && cursym.stype == EXTERN+TEXT) 684: continue; 685: ndef++; 686: sp->stype = cursym.stype; 687: sp->svalue = cursym.svalue; 688: if ((sp->stype &~ EXTERN) == TEXT) 689: sp->sovly = curov; 690: if (trace) 691: printf("found %8.8s in overlay %d at %d\n", sp->sname, sp->sovly, sp->svalue); 692: } 693: if (libflg==0 || ndef) { 694: tsize = add(tsize,filhdr.tsize,"text overflow"); 695: dsize = add(dsize,filhdr.dsize,"data overflow"); 696: bsize = add(bsize,filhdr.bsize,"bss overflow"); 697: ssize = add(ssize,nloc,"symbol table overflow"); 698: return(1); 699: } 700: /* 701: * No symbols defined by this library member. 702: * Rip out the hash table entries and reset the symbol table. 703: */ 704: while (symindex>savindex) 705: *symhash[--symindex]=0; 706: return(0); 707: } 708: 709: middle() 710: { 711: register struct symbol *sp, *symp; 712: register t, csize; 713: int nund, corigin; 714: int ttsize; 715: 716: torigin=0; 717: dorigin=0; 718: borigin=0; 719: 720: p_etext = *slookup("_etext"); 721: p_edata = *slookup("_edata"); 722: p_end = *slookup("_end"); 723: /* 724: * If there are any undefined symbols, save the relocation bits. 725: * (Unless we are overlaying.) 726: */ 727: symp = &symtab[symindex]; 728: if (rflag==0 && !numov) { 729: for (sp = symtab; sp<symp; sp++) 730: if (sp->stype==EXTERN+UNDEF && sp->svalue==0 731: && sp!=p_end && sp!=p_edata && sp!=p_etext) { 732: rflag++; 733: dflag = 0; 734: break; 735: } 736: } 737: if (rflag) 738: nflag = sflag = iflag = Oflag = 0; 739: /* 740: * Assign common locations. 741: */ 742: csize = 0; 743: if (dflag || rflag==0) { 744: ldrsym(p_etext, tsize, EXTERN+TEXT); 745: ldrsym(p_edata, dsize, EXTERN+DATA); 746: ldrsym(p_end, bsize, EXTERN+BSS); 747: for (sp = symtab; sp<symp; sp++) 748: if (sp->stype==EXTERN+UNDEF && (t = sp->svalue)!=0) { 749: t = (t+1) & ~01; 750: sp->svalue = csize; 751: sp->stype = EXTERN+COMM; 752: csize = add(csize, t, "bss overflow"); 753: } 754: } 755: /* wnj added for overlay text */ 756: if (numov) { 757: for (sp = symtab; sp < symp; sp++) { 758: if (trace) 759: printf("%8.8s stype %o svalue %o sovalue %o sovly %d\n", 760: sp->sname, sp->stype, sp->svalue, sp->sovalue, sp->sovly); 761: if (sp->sovly && sp->stype == EXTERN+TEXT) { 762: sp->sovalue = sp->svalue; 763: sp->svalue = tsize; 764: tsize += THUNKSIZ; 765: if (trace) 766: printf("relocating %s in overlay %d from %o to %o\n", 767: sp->sname, sp->sovly, 768: sp->sovalue, sp->svalue); 769: } 770: } 771: } 772: /* end wnj added */ 773: /* 774: * Now set symbols to their final value 775: */ 776: if (nflag || iflag) 777: tsize = (tsize + 077) & ~077; 778: /* wnj added */ 779: ttsize = tsize; 780: if (numov) { 781: register int i; 782: 783: ovbase = (tsize + 017777) &~ 017777; 784: if (trace) 785: printf("overlay base is %d.\n", ovbase); 786: for (sp = symtab; sp < symp; sp++) 787: if (sp->sovly && sp->stype == EXTERN+TEXT) { 788: sp->sovalue += ovbase; 789: if (trace) 790: printf("%.8s at %d overlay %d\n", sp->sname, sp->sovalue, sp->sovly); 791: } 792: for (i = 1; i < 8; i++) { 793: ovsize[i] = (ovsize[i] + 077) &~ 077; 794: if (ovsize[i] > max) 795: max = ovsize[i]; 796: } 797: if (trace) 798: printf("maximum overlay size is %d.\n", max); 799: ttsize = ovbase + max; 800: ttsize = (ttsize + 017777) &~ 017777; 801: if (trace) 802: printf("overlays end before %u.\n", ttsize); 803: } 804: /* end wnj added */ 805: dorigin = ttsize; 806: if (nflag) 807: dorigin = (ttsize+017777) & ~017777; 808: if (iflag) 809: dorigin = 0; 810: corigin = dorigin + dsize; 811: borigin = corigin + csize; 812: nund = 0; 813: for (sp = symtab; sp<symp; sp++) switch (sp->stype) { 814: case EXTERN+UNDEF: 815: errlev |= 01; 816: if (arflag==0 && sp->svalue==0) { 817: if (nund==0) 818: printf("Undefined:\n"); 819: nund++; 820: printf("%.8s\n", sp->sname); 821: } 822: continue; 823: 824: case EXTERN+ABS: 825: default: 826: continue; 827: 828: case EXTERN+TEXT: 829: sp->svalue += torigin; 830: continue; 831: 832: case EXTERN+DATA: 833: sp->svalue += dorigin; 834: continue; 835: 836: case EXTERN+BSS: 837: sp->svalue += borigin; 838: continue; 839: 840: case EXTERN+COMM: 841: sp->stype = EXTERN+BSS; 842: sp->svalue += corigin; 843: continue; 844: } 845: if (sflag || xflag) 846: ssize = 0; 847: bsize = add(bsize, csize, "bss overflow"); 848: nsym = ssize / (sizeof cursym); 849: } 850: 851: ldrsym(asp, val, type) 852: struct symbol *asp; 853: { 854: register struct symbol *sp; 855: 856: if ((sp = asp) == 0) 857: return; 858: if (sp->stype != EXTERN+UNDEF || sp->svalue) { 859: printf("%.8s: ", sp->sname); 860: /* if (trace) */ 861: printf("svalue %o ", sp->svalue); 862: error(1, "Multiply defined"); 863: return; 864: } 865: sp->stype = type; 866: sp->svalue = val; 867: } 868: 869: setupout() 870: { 871: tcreat(&toutb, 0); 872: mktemp(tfname); 873: tcreat(&doutb, 1); 874: if (sflag==0 || xflag==0) 875: tcreat(&soutb, 1); 876: if (rflag) { 877: tcreat(&troutb, 1); 878: tcreat(&droutb, 1); 879: } 880: /* wnj added */ 881: if (numov) 882: tcreat(&voutb, 1); 883: /* end wnj added */ 884: filhdr.fmagic = (Oflag ? OMAGIC :( iflag ? IMAGIC : ( nflag ? NMAGIC : FMAGIC ))); 885: if (numov) { 886: if (filhdr.fmagic == FMAGIC) 887: error(2, "-n or -i must be used for overlays"); 888: filhdr.fmagic |= 020; 889: } 890: filhdr.tsize = tsize; 891: filhdr.dsize = dsize; 892: filhdr.bsize = bsize; 893: filhdr.ssize = sflag? 0: (ssize + (sizeof cursym)*symindex); 894: if (entrypt) { 895: if (entrypt->stype!=EXTERN+TEXT) 896: error(1, "Entry point not in text"); 897: else if (entrypt->sovly) 898: error(1, "Entry point in overlay"); 899: else 900: filhdr.entry = entrypt->svalue | 01; 901: } else 902: filhdr.entry=0; 903: filhdr.pad = 0; 904: filhdr.relflg = (rflag==0); 905: mput(&toutb, (int *)&filhdr, sizeof filhdr); 906: /* wnj added */ 907: if (numov) { 908: register int i; 909: for (i = 0; i < 8; i++) 910: putw(ovsize[i], &toutb); 911: } 912: /* end wnj */ 913: } 914: 915: tcreat(buf, tempflg) 916: struct buf *buf; 917: { 918: register int ufd; 919: char *nam; 920: nam = (tempflg ? tfname : ofilename); 921: if ((ufd = creat(nam, 0666)) < 0) 922: error(2, tempflg?"cannot create temp":"cannot create output"); 923: close(ufd); 924: buf->fildes = open(nam, 2); 925: if (tempflg) 926: unlink(tfname); 927: buf->nleft = sizeof(buf->iobuf)/sizeof(int); 928: buf->xnext = buf->iobuf; 929: } 930: 931: load2arg(acp) 932: char *acp; 933: { 934: register char *cp; 935: register struct liblist *lp; 936: 937: cp = acp; 938: if (getfile(cp) == 0) { 939: while (*cp) 940: cp++; 941: while (cp >= acp && *--cp != '/'); 942: mkfsym(++cp); 943: load2(0L); 944: } else { /* scan archive members referenced */ 945: for (lp = libp; lp->loc != -1; lp++) { 946: dseek(&text, lp->loc, sizeof archdr); 947: mget((int *)&archdr, sizeof archdr); 948: mkfsym(archdr.aname); 949: load2(lp->loc + (sizeof archdr) / 2); 950: } 951: libp = ++lp; 952: } 953: close(infil); 954: } 955: 956: load2(loc) 957: long loc; 958: { 959: register struct symbol *sp; 960: register struct local *lp; 961: register int symno; 962: int type, mtype; 963: 964: readhdr(loc); 965: ctrel = torigin; 966: cdrel += dorigin; 967: cbrel += borigin; 968: /* 969: * Reread the symbol table, recording the numbering 970: * of symbols for fixing external references. 971: */ 972: lp = local; 973: symno = -1; 974: loc += (sizeof filhdr)/2; 975: dseek(&text, loc + filhdr.tsize + filhdr.dsize, filhdr.ssize); 976: while (text.size > 0) { 977: symno++; 978: mget((int *)&cursym, sizeof cursym); 979: symreloc(); 980: type = cursym.stype; 981: if (Sflag) { 982: mtype = type&037; 983: if (mtype==1 || mtype>4) continue; 984: } 985: if ((type&EXTERN) == 0) { 986: if (!sflag&&!xflag&&(!Xflag||cursym.sname[0]!='L')) { 987: /* preserve overlay number for locals */ 988: /* mostly for adb. mjk 7/81 */ 989: if ((type==TEXT) && inov) 990: cursym.sovly = curov; 991: mput(&soutb, (int *)&cursym, sizeof cursym); 992: } 993: continue; 994: } 995: if ((sp = *lookup()) == 0) 996: error(2, "internal error: symbol not found"); 997: /* 998: * Bill Shannon's fix to the 'local symbol botch' 999: * message. -wfj 5/80 1000: */ 1001: if (cursym.stype == EXTERN+UNDEF || cursym.stype == EXTERN+TEXT) 1002: { 1003: /* 1004: if (cursym.stype == EXTERN+UNDEF) { 1005: */ 1006: if (lp >= &local[NSYMPR]) 1007: error(2, "Local symbol overflow"); 1008: lp->locindex = symno; 1009: lp++->locsymbol = sp; 1010: continue; 1011: } 1012: if (cursym.stype!=sp->stype 1013: || cursym.svalue!=sp->svalue && !sp->sovly 1014: || sp->sovly && cursym.svalue!=sp->sovalue) { 1015: printf("%.8s: ", cursym.sname); 1016: if (trace) { 1017: printf(" sovly %d sovalue %o ", sp->sovly, sp->sovalue); 1018: printf("new %o hav %o ", cursym.svalue, sp->svalue); 1019: } 1020: error(1, "Multiply defined"); 1021: } 1022: } 1023: dseek(&text, loc, filhdr.tsize); 1024: dseek(&reloc, loc + half(filhdr.tsize + filhdr.dsize), filhdr.tsize); 1025: load2td(lp, ctrel, inov ? &voutb : &toutb, &troutb); 1026: dseek(&text, loc+half(filhdr.tsize), filhdr.dsize); 1027: dseek(&reloc, loc+filhdr.tsize+half(filhdr.dsize), filhdr.dsize); 1028: load2td(lp, cdrel, &doutb, &droutb); 1029: torigin += filhdr.tsize; 1030: dorigin += filhdr.dsize; 1031: borigin += filhdr.bsize; 1032: } 1033: 1034: load2td(lp, creloc, b1, b2) 1035: struct local *lp; 1036: struct buf *b1, *b2; 1037: { 1038: register r, t; 1039: register struct symbol *sp; 1040: 1041: for (;;) { 1042: /* 1043: * The pickup code is copied from "get" for speed. 1044: */ 1045: 1046: /* next text or data word */ 1047: if (--text.size <= 0) { 1048: if (text.size < 0) 1049: break; 1050: text.size++; 1051: t = get(&text); 1052: } else if (--text.nibuf < 0) { 1053: text.nibuf++; 1054: text.size++; 1055: t = get(&text); 1056: } else 1057: t = *text.ptr++; 1058: 1059: /* next relocation word */ 1060: if (--reloc.size <= 0) { 1061: if (reloc.size < 0) 1062: error(2, "Relocation error"); 1063: reloc.size++; 1064: r = get(&reloc); 1065: } else if (--reloc.nibuf < 0) { 1066: reloc.nibuf++; 1067: reloc.size++; 1068: r = get(&reloc); 1069: } else 1070: r = *reloc.ptr++; 1071: 1072: switch (r&016) { 1073: 1074: case RTEXT: 1075: t += ctrel; 1076: break; 1077: 1078: case RDATA: 1079: t += cdrel; 1080: break; 1081: 1082: case RBSS: 1083: t += cbrel; 1084: break; 1085: 1086: case REXT: 1087: sp = lookloc(lp, r); 1088: if (sp->stype==EXTERN+UNDEF) { 1089: r = (r&01) + ((nsym+(sp-symtab))<<4) + REXT; 1090: break; 1091: } 1092: t += sp->svalue; 1093: r = (r&01) + ((sp->stype-(EXTERN+ABS))<<1); 1094: break; 1095: } 1096: if (r&01) 1097: t -= creloc; 1098: putw(t, b1); 1099: if (rflag) 1100: putw(r, b2); 1101: } 1102: } 1103: 1104: finishout() 1105: { 1106: register n, *p; 1107: register struct symbol *sp, *symp; 1108: 1109: /* wnj added */ 1110: if (numov) { 1111: int aovno = adrof("__ovno"); 1112: int aovhndlr[NOVL+1]; 1113: for (n=1; n<=numov; n++) { 1114: ovhndlr.sname[HNDLR_NUM] = '0' + n; 1115: aovhndlr[n] = adrof(ovhndlr.sname); 1116: } 1117: symp = &symtab[symindex]; 1118: for (sp = symtab; sp < symp; sp++) 1119: if (sp->sovly && (sp->stype & (EXTERN+TEXT))) { 1120: putw(012701, &toutb); /* mov $~foo+4, r1*/ 1121: putw(sp->sovalue+4, &toutb); 1122: putw(04537, &toutb); /* jsr r5,ovhndlrx */ 1123: putw(aovhndlr[sp->sovly], &toutb); 1124: torigin += THUNKSIZ; 1125: } 1126: } 1127: /* end wnj */ 1128: if (nflag||iflag) { 1129: n = torigin; 1130: while (n&077) { 1131: n += 2; 1132: putw(0, &toutb); 1133: if (rflag) 1134: putw(0, &troutb); 1135: } 1136: } 1137: if (numov) 1138: copy(&voutb); 1139: copy(&doutb); 1140: if (rflag) { 1141: copy(&troutb); 1142: copy(&droutb); 1143: } 1144: if (sflag==0) { 1145: if (xflag==0) 1146: copy(&soutb); 1147: for (p = (int *)symtab; p < (int *)&symtab[symindex];) { 1148: /* wnj changed.... this is bad machine dependent code... */ 1149: /* this does the symbol */ 1150: putw(*p++, &toutb); putw(*p++, &toutb); 1151: putw(*p++, &toutb); putw(*p++, &toutb); 1152: /* these do the flags and value */ 1153: putw(*p++, &toutb); putw(*p++, &toutb); 1154: /* skip sovalue */ 1155: p++; 1156: } 1157: /* end wnj changed */ 1158: } 1159: flush(&toutb); 1160: close(toutb.fildes); 1161: if (!ofilfnd) { 1162: unlink("a.out"); 1163: link("l.out", "a.out"); 1164: ofilename = "a.out"; 1165: } 1166: delarg = errlev; 1167: delexit(); 1168: } 1169: 1170: /* wnj added for overlay txt regs */ 1171: adrof(s) 1172: char *s; 1173: { 1174: register struct symbol **p = slookup(s); 1175: 1176: if (*p == 0) { 1177: printf("%.8s: ", s); 1178: error(1, "Undefined!"); 1179: return (0); 1180: } 1181: return ((*p)->svalue); 1182: } 1183: /* end wnj added */ 1184: 1185: copy(buf) 1186: struct buf *buf; 1187: { 1188: register f, *p, n; 1189: 1190: flush(buf); 1191: lseek(f = buf->fildes, (long)0, 0); 1192: while ((n = read(f, (char *)buf->iobuf, sizeof(buf->iobuf))) > 1) { 1193: n >>= 1; 1194: p = (int *)buf->iobuf; 1195: do 1196: putw(*p++, &toutb); 1197: while (--n); 1198: } 1199: close(f); 1200: } 1201: 1202: mkfsym(s) 1203: char *s; 1204: { 1205: 1206: if (sflag || xflag) 1207: return; 1208: cp8c(s, cursym.sname); 1209: cursym.stype = 037; 1210: cursym.svalue = torigin; 1211: mput(&soutb, (int *)&cursym, sizeof cursym); 1212: } 1213: 1214: mget(aloc, an) 1215: int *aloc; 1216: { 1217: register *loc, n; 1218: register *p; 1219: 1220: n = an; 1221: n >>= 1; 1222: loc = aloc; 1223: if ((text.nibuf -= n) >= 0) { 1224: if ((text.size -= n) > 0) { 1225: p = text.ptr; 1226: do 1227: *loc++ = *p++; 1228: while (--n); 1229: text.ptr = p; 1230: return; 1231: } else 1232: text.size += n; 1233: } 1234: text.nibuf += n; 1235: do { 1236: *loc++ = get(&text); 1237: } 1238: while (--n); 1239: } 1240: 1241: mput(buf, aloc, an) 1242: struct buf *buf; 1243: int *aloc; 1244: { 1245: register *loc; 1246: register n; 1247: 1248: loc = aloc; 1249: n = an>>1; 1250: do { 1251: putw(*loc++, buf); 1252: } 1253: while (--n); 1254: } 1255: 1256: dseek(asp, aloc, s) 1257: long aloc; 1258: struct stream *asp; 1259: { 1260: register struct stream *sp; 1261: register struct page *p; 1262: /* register */ long b, o; 1263: int n; 1264: 1265: b = aloc >> 8; 1266: o = aloc & 0377; 1267: sp = asp; 1268: --sp->pno->nuser; 1269: if ((p = &page[0])->bno!=b && (p = &page[1])->bno!=b) 1270: if (p->nuser==0 || (p = &page[0])->nuser==0) { 1271: if (page[0].nuser==0 && page[1].nuser==0) 1272: if (page[0].bno < page[1].bno) 1273: p = &page[0]; 1274: p->bno = b; 1275: lseek(infil, (aloc & ~0377L) << 1, 0); 1276: if ((n = read(infil, (char *)p->buff, 512)>>1) < 0) 1277: n = 0; 1278: p->nibuf = n; 1279: } else 1280: error(2, "No pages"); 1281: ++p->nuser; 1282: sp->bno = b; 1283: sp->pno = p; 1284: sp->ptr = p->buff + o; 1285: if (s != -1) 1286: sp->size = half(s); 1287: if ((sp->nibuf = p->nibuf-o) <= 0) 1288: sp->size = 0; 1289: } 1290: 1291: half(i) 1292: { 1293: return((i>>1)&077777); 1294: } 1295: 1296: get(asp) 1297: struct stream *asp; 1298: { 1299: register struct stream *sp; 1300: 1301: sp = asp; 1302: if (--sp->nibuf < 0) { 1303: dseek(sp, (long)(sp->bno + 1) << 8, -1); 1304: --sp->nibuf; 1305: } 1306: if (--sp->size <= 0) { 1307: if (sp->size < 0) 1308: error(2, premeof); 1309: ++fpage.nuser; 1310: --sp->pno->nuser; 1311: sp->pno = (struct page *)&fpage; 1312: } 1313: return(*sp->ptr++); 1314: } 1315: 1316: getfile(acp) 1317: char *acp; 1318: { 1319: register char *cp; 1320: register int c; 1321: struct stat x; 1322: 1323: cp = acp; 1324: infil = -1; 1325: archdr.aname[0] = '\0'; 1326: filname = cp; 1327: if (cp[0]=='-' && cp[1]=='l') { 1328: if(cp[2] == '\0') 1329: cp = "-la"; 1330: filname = "/usr/lib/libxxxxxxxxxxxxxxx"; 1331: for(c=0; cp[c+2]; c++) 1332: filname[c+12] = cp[c+2]; 1333: filname[c+12] = '.'; 1334: filname[c+13] = 'a'; 1335: filname[c+14] = '\0'; 1336: if ((infil = open(filname+4, 0)) >= 0) { 1337: filname += 4; 1338: } 1339: } 1340: if (infil == -1 && (infil = open(filname, 0)) < 0) 1341: error(2, "cannot open"); 1342: page[0].bno = page[1].bno = -1; 1343: page[0].nuser = page[1].nuser = 0; 1344: text.pno = reloc.pno = (struct page *)&fpage; 1345: fpage.nuser = 2; 1346: dseek(&text, 0L, 2); 1347: if (text.size <= 0) 1348: error(2, premeof); 1349: if(get(&text) != ARCMAGIC) 1350: return(0); /* regualr file */ 1351: dseek(&text, 1L, sizeof archdr); /* word addressing */ 1352: if(text.size <= 0) 1353: return(1); /* regular archive */ 1354: mget((int *)&archdr, sizeof archdr); 1355: if(strncmp(archdr.aname, goodnm, 14) != 0) 1356: return(1); /* regular archive */ 1357: else { 1358: fstat(infil, &x); 1359: if(x.st_mtime > archdr.atime) 1360: { 1361: return(3); 1362: } 1363: else return(2); 1364: } 1365: } 1366: 1367: struct symbol **lookup() 1368: { 1369: int i; 1370: int clash; 1371: register struct symbol **hp; 1372: register char *cp, *cp1; 1373: 1374: i = 0; 1375: for (cp = cursym.sname; cp < &cursym.sname[8];) 1376: i = (i<<1) + *cp++; 1377: for (hp = &hshtab[(i&077777)%NSYM+2]; *hp!=0;) { 1378: cp1 = (*hp)->sname; 1379: clash=FALSE; 1380: for (cp = cursym.sname; cp < &cursym.sname[8];) 1381: if (*cp++ != *cp1++) { 1382: clash=TRUE; 1383: break; 1384: } 1385: if (clash) { 1386: if (++hp >= &hshtab[NSYM+2]) 1387: hp = hshtab; 1388: } else 1389: break; 1390: } 1391: return(hp); 1392: } 1393: 1394: struct symbol **slookup(s) 1395: char *s; 1396: { 1397: cp8c(s, cursym.sname); 1398: cursym.stype = EXTERN+UNDEF; 1399: cursym.svalue = 0; 1400: return(lookup()); 1401: } 1402: 1403: enter(hp) 1404: struct symbol **hp; 1405: { 1406: register struct symbol *sp; 1407: 1408: if (*hp==0) { 1409: if (symindex>=NSYM) 1410: error(2, "Symbol table overflow"); 1411: symhash[symindex] = hp; 1412: *hp = lastsym = sp = &symtab[symindex++]; 1413: cp8c(cursym.sname, sp->sname); 1414: sp->stype = cursym.stype; 1415: sp->svalue = cursym.svalue; 1416: if (sp->stype == EXTERN+TEXT) { 1417: sp->sovly = curov; 1418: if (trace) 1419: printf("found %8.8s in overlay %d at %d\n", 1420: sp->sname, sp->sovly, sp->svalue); 1421: } 1422: return(1); 1423: } else { 1424: lastsym = *hp; 1425: return(0); 1426: } 1427: } 1428: 1429: symreloc() 1430: { 1431: switch (cursym.stype) { 1432: 1433: case TEXT: 1434: case EXTERN+TEXT: 1435: cursym.svalue += ctrel; 1436: return; 1437: 1438: case DATA: 1439: case EXTERN+DATA: 1440: cursym.svalue += cdrel; 1441: return; 1442: 1443: case BSS: 1444: case EXTERN+BSS: 1445: cursym.svalue += cbrel; 1446: return; 1447: 1448: case EXTERN+UNDEF: 1449: return; 1450: } 1451: if (cursym.stype&EXTERN) 1452: cursym.stype = EXTERN+ABS; 1453: } 1454: 1455: error(n, s) 1456: char *s; 1457: { 1458: if (errlev==0) 1459: printf("ld:"); 1460: if (filname) { 1461: printf("%s", filname); 1462: if (archdr.aname[0]) 1463: printf("(%.14s)", archdr.aname); 1464: printf(": "); 1465: } 1466: printf("%s\n", s); 1467: if (n > 1) 1468: delexit(); 1469: errlev = n; 1470: } 1471: 1472: struct symbol * 1473: lookloc(alp, r) 1474: struct local *alp; 1475: { 1476: register struct local *clp, *lp; 1477: register sn; 1478: 1479: lp = alp; 1480: sn = (r>>4) & 07777; 1481: for (clp = local; clp<lp; clp++) 1482: if (clp->locindex == sn) 1483: return(clp->locsymbol); 1484: error(2, "Local symbol botch"); 1485: } 1486: 1487: readhdr(loc) 1488: long loc; 1489: { 1490: register st, sd; 1491: 1492: dseek(&text, loc, sizeof filhdr); 1493: mget((int *)&filhdr, sizeof filhdr); 1494: if (filhdr.fmagic != FMAGIC) 1495: error(2, "Bad format"); 1496: st = (filhdr.tsize+01) & ~01; 1497: filhdr.tsize = st; 1498: cdrel = -st; 1499: sd = (filhdr.dsize+01) & ~01; 1500: cbrel = - (st+sd); 1501: filhdr.bsize = (filhdr.bsize+01) & ~01; 1502: } 1503: 1504: cp8c(from, to) 1505: char *from, *to; 1506: { 1507: register char *f, *t, *te; 1508: 1509: f = from; 1510: t = to; 1511: te = t+8; 1512: while ((*t++ = *f++) && t<te); 1513: while (t<te) 1514: *t++ = 0; 1515: } 1516: 1517: eq(s1, s2) 1518: char *s1; 1519: char *s2; 1520: { 1521: while (*s1==*s2++) 1522: if ((*s1++)==0) 1523: return(TRUE); 1524: return(FALSE); 1525: } 1526: 1527: putw(w, b) 1528: register struct buf *b; 1529: { 1530: *(b->xnext)++ = w; 1531: if (--b->nleft <= 0) 1532: flush(b); 1533: } 1534: 1535: flush(b) 1536: register struct buf *b; 1537: { 1538: register n; 1539: 1540: if ((n = (char *)b->xnext - (char *)b->iobuf) > 0) 1541: if (write(b->fildes, (char *)b->iobuf, n) != n) 1542: error(2, "output error"); 1543: b->xnext = b->iobuf; 1544: b->nleft = sizeof(b->iobuf)/sizeof(int); 1545: }