|
|
1.1 ! root 1: # ! 2: /* ! 3: * link editor for VAX ! 4: * ! 5: * Written by J. Reiser, modified by K. sklower to have an incremental ! 6: * loading facility ! 7: */ ! 8: ! 9: /* layout of a.out file: ! 10: * ! 11: * header of 8 words magic number 0410: ! 12: data starts at 1st 0777 ! 13: boundary above text ! 14: magic number 0407: ! 15: data starts immediately after ! 16: text ! 17: * text size ) ! 18: * data size ) in bytes ! 19: * bss size ) ! 20: * symbol table size ! 21: * entry point ! 22: * size of text relocation info ! 23: * size of data relocation info ! 24: * ! 25: * 'segment' origin comments ! 26: * header: 0 ! 27: * text: 32 0 padded to multiple of 4 bytes ! 28: * data: 32+textsize 0 padded to multiple of 4 bytes ! 29: * text relocation: 32+textsize+datasize ! 30: * data relocation: 32+textsize+datasize+textrelocationsize ! 31: * symbol table: 32+textsize+datasize+textrelocationsize+datarelocationsize ! 32: * ! 33: */ ! 34: #include <signal.h> ! 35: #include <stdio.h> ! 36: #include <ar.h> ! 37: #include <a.out.h> ! 38: ! 39: typedef struct {short hiword; short loword;} *bless; /* stupid fp-11 */ ! 40: fixl(p) register long *p;{ ! 41: register short t; ! 42: t=((bless) p)->hiword; ((bless) p)->hiword=((bless) p)->loword; ((bless) p)->loword=t; ! 43: } ! 44: ! 45: writel(p,n,f) long *p; FILE *f; { ! 46: #ifdef vax ! 47: fwrite(p,sizeof(*p),n,f); ! 48: #else ! 49: while (n--) { ! 50: fwrite(&(*p).loword,2,1,f); ! 51: fwrite(&(*p).hiword,2,1,f); ! 52: p++; ! 53: } ! 54: #endif ! 55: } ! 56: ! 57: long htoi(p) register char *p; {/* hex to integer conversion */ ! 58: register long n = 0; ! 59: while (*p) { ! 60: n <<= 4; ! 61: if (*p<='9' && *p>='0') n += *p - '0'; ! 62: else if (*p<='f' && *p>='a') n += *p -'a' +10; ! 63: else if (*p<='F' && *p>='A') n += *p -'A' +10; ! 64: p++; ! 65: } ! 66: return(n); ! 67: } ! 68: ! 69: typedef char *STRING; ! 70: typedef int BOOL; ! 71: #define TRUE 1 ! 72: #define FALSE 0 ! 73: ! 74: #define OMAGIC 0407 ! 75: #define NMAGIC 0410 ! 76: ! 77: /* ! 78: * Symbol types ! 79: */ ! 80: #define UNDEF 0x0 ! 81: #define ABS 0x2 ! 82: #define TEXT 0x4 ! 83: #define DATA 0x6 ! 84: #define BSS 0x8 ! 85: #define DATAO 0xA ! 86: #define BSSO 0xC ! 87: #define TEXTO 0xE ! 88: #define ABSO 0x10 ! 89: ! 90: #define COMM 0x12 /* for internal use only */ ! 91: ! 92: #define EXTERN 0x1 ! 93: #define TYPE 0x1E ! 94: #define STABTYPS 0xE0 ! 95: /* ! 96: * address reference types ! 97: */ ! 98: #define PCREL 1 ! 99: #define LEN1 0 ! 100: #define LEN2 2 ! 101: #define LEN4 4 ! 102: ! 103: #define HW 01 ! 104: #define FW 03 ! 105: #define DW 07 ! 106: ! 107: #define PAGRND 0777 ! 108: ! 109: #define TYPMASK 0x1E ! 110: #define TYMASK (0x1E) ! 111: #define TMASK 0x1F ! 112: ! 113: #define RABS (ABS) ! 114: #define RTEXT TEXT ! 115: #define RDATA DATA ! 116: #define RBSS BSS ! 117: #define RDATAO DATAO ! 118: #define RBSSO BSSO ! 119: #define RTEXTO TEXTO ! 120: #define RABSO ABSO ! 121: #define REXT (01<<3) ! 122: #define ROFF (02<<3) ! 123: #define REFMASK 0x7 ! 124: ! 125: #define NOVLY 1 ! 126: #define RELFLG 01 ! 127: #define NROUT 256 ! 128: #define NSYM 1103 ! 129: #define NSYMPR 500 ! 130: ! 131: char premeof[] = "Premature EOF"; ! 132: ! 133: typedef struct { ! 134: long loc; ! 135: } LIBLIST; ! 136: ! 137: /* overlay management */ ! 138: int vindex; ! 139: typedef struct { ! 140: int argsav; ! 141: int symsav; ! 142: LIBLIST *libsav; ! 143: STRING vname; ! 144: long ctsav, cdsav, cbsav; ! 145: long offt, offd, offb, offtr, offdr, offs; ! 146: } OVERLAY; ! 147: OVERLAY vnodes[NOVLY]; ! 148: ! 149: /* input management */ ! 150: typedef struct { ! 151: short *fakeptr; ! 152: int bno; ! 153: int nibuf; ! 154: int nuser; ! 155: char buff[512]; ! 156: } PAGE; ! 157: ! 158: PAGE page[2]; ! 159: ! 160: struct { ! 161: short *fakeptr; ! 162: int bno; ! 163: int nibuf; ! 164: int nuser; ! 165: } fpage; ! 166: ! 167: typedef struct { ! 168: char *ptr; ! 169: int bno; ! 170: int nibuf; ! 171: long size; ! 172: long pos; ! 173: PAGE *pno; ! 174: } STREAM; ! 175: ! 176: STREAM text; ! 177: STREAM reloc; ! 178: ! 179: struct ar_hdr archdr; ! 180: ! 181: struct exec filhdr; ! 182: ! 183: /* one entry for each archive member referenced; ! 184: * set in first pass; needs restoring for overlays ! 185: */ ! 186: ! 187: LIBLIST liblist[NROUT]; ! 188: LIBLIST *libp = liblist; ! 189: ! 190: ! 191: /* symbol management */ ! 192: typedef struct { ! 193: char sname[8]; ! 194: char stype; ! 195: char spare; ! 196: short symhash; /* index of hash table entry pointing to this symbol */ ! 197: long svalue; ! 198: } SYMBOL; ! 199: ! 200: typedef struct { ! 201: int locindex; /* index to symbol in file */ ! 202: SYMBOL *locsymbol; /* ptr to symbol table */ ! 203: } LOCAL; ! 204: ! 205: SYMBOL cursym; /* current symbol */ ! 206: SYMBOL *symtab; /* actual symbols */ ! 207: SYMBOL *lastsym; /* last symbol entered */ ! 208: SYMBOL *nextsym; /* next available symbol table entry */ ! 209: SYMBOL *addsym; /* first symbol defined during incremental ! 210: load */ ! 211: int nsym; /* number of symbols allocated in symtab */ ! 212: SYMBOL *hshtab[NSYM+2]; /* hash table for symbols */ ! 213: LOCAL *local; ! 214: ! 215: /* internal symbols */ ! 216: SYMBOL *p_data; ! 217: SYMBOL *p_etext; ! 218: SYMBOL *p_edata; ! 219: SYMBOL *p_end; ! 220: SYMBOL *entrypt; ! 221: ! 222: int trace; ! 223: /* flags */ ! 224: int xflag; /* discard local symbols */ ! 225: int Xflag; /* discard locals starting with 'L' */ ! 226: int Sflag; /* discard all except locals and globals*/ ! 227: int rflag; /* preserve relocation bits, don't define common */ ! 228: int arflag; /* original copy of rflag */ ! 229: int sflag; /* discard all symbols */ ! 230: int nflag = 1; /* pure procedure */ ! 231: int dflag; /* define common even with rflag */ ! 232: int iflag; /* I/D space separated */ ! 233: BOOL vflag; /* overlays used */ ! 234: int Aflag; /* doing incremental load */ ! 235: int RFflag; /* used to escape while reading fundament file*/ ! 236: ! 237: int ofilfnd; ! 238: char *ofilename = "l.out"; ! 239: int infil; ! 240: char *filname; ! 241: ! 242: long textbase; ! 243: /* cumulative sizes set in pass 1 */ ! 244: long tsize; ! 245: long dsize; ! 246: long bsize; ! 247: long trsize; ! 248: long drsize; ! 249: long ssize; ! 250: ! 251: /* symbol relocation; both passes */ ! 252: long ctrel; ! 253: long cdrel; ! 254: long cbrel; ! 255: long ctorel; ! 256: long cdorel; ! 257: long cborel; ! 258: ! 259: int errlev; ! 260: int delarg = 4; ! 261: ! 262: ! 263: FILE *tout; ! 264: FILE *dout; ! 265: char *doutn = ""; ! 266: FILE *trout; ! 267: char *troutn = ""; ! 268: FILE *drout; ! 269: char *droutn = ""; ! 270: FILE *sout; ! 271: char *soutn = ""; ! 272: ! 273: char *mktemp(); ! 274: char get(); ! 275: char getb(); ! 276: short gets(); ! 277: long get3(); ! 278: long getl(); ! 279: SYMBOL **lookup(); ! 280: FILE *tcreat(); ! 281: long round(); ! 282: SYMBOL **slookup(); ! 283: SYMBOL *lookloc(); ! 284: ! 285: symwrite(sp,n,f) SYMBOL *sp; FILE *f; { ! 286: #ifdef vax ! 287: fwrite(sp,sizeof(*symtab),n,f); ! 288: #else ! 289: while (n--) { ! 290: fwrite(sp,sizeof(*symtab)-sizeof(sp->svalue),1,f); ! 291: writel(&(sp->svalue),1,f); sp++; ! 292: } ! 293: #endif ! 294: } ! 295: ! 296: delexit() ! 297: { ! 298: unlink("l.out"); ! 299: unlink(doutn); ! 300: unlink(troutn); ! 301: unlink(droutn); ! 302: unlink(soutn); ! 303: if (delarg==0) ! 304: chmod(ofilename, 0777); ! 305: exit(delarg); ! 306: } ! 307: ! 308: main(argc, argv) ! 309: char **argv; ! 310: { ! 311: register int c, i; ! 312: int num; ! 313: register char *ap, **p; ! 314: BOOL found; ! 315: int vscan; ! 316: char save; ! 317: ! 318: if (signal(SIGINT, SIG_IGN) != SIG_IGN) ! 319: signal(SIGINT, delexit); ! 320: if (argc == 1) ! 321: exit(4); ! 322: p = argv+1; ! 323: ! 324: nextsym=symtab=(SYMBOL *)sbrk(0); nsym=0; ! 325: /* scan files once to find symdefs */ ! 326: for (c=1; c<argc; c++) { ! 327: if (trace) printf("%s:\n", *p); ! 328: filname = 0; ! 329: ap = *p++; ! 330: ! 331: if (*ap == '-') { ! 332: for (i=1; ap[i]; i++) { ! 333: switch (ap[i]) { ! 334: case 'o': ! 335: if (++c >= argc) ! 336: error(1, "Bad output file"); ! 337: ofilename = *p++; ! 338: ofilfnd++; ! 339: continue; ! 340: ! 341: case 'u': ! 342: case 'e': ! 343: if (++c >= argc) ! 344: error(1, "Bad 'use' or 'entry'"); ! 345: enter(slookup(*p++)); ! 346: if (ap[i]=='e') ! 347: entrypt = lastsym; ! 348: continue; ! 349: ! 350: case 'A': ! 351: if (++c >= argc) ! 352: error(1, "-A: arg missing"); ! 353: if (Aflag) ! 354: error(2, "-A: Only one fundament file allowed"); ! 355: Aflag = TRUE; ! 356: nflag = FALSE; ! 357: fundament(*p++); ! 358: continue; ! 359: ! 360: case 'v': ! 361: if (++c >= argc) ! 362: error(1, "-v: arg missing"); ! 363: vflag=TRUE; ! 364: vscan = vindex; ! 365: found=FALSE; ! 366: while (--vscan>=0 && found==FALSE) ! 367: found = eq(vnodes[vscan].vname, *p); ! 368: if (found) { ! 369: endload(c, argv); ! 370: restore(vscan); ! 371: } else ! 372: record(c, *p); ! 373: p++; ! 374: continue; ! 375: ! 376: case 'D': ! 377: if (++c >= argc) ! 378: error(1, "-D: arg missing"); ! 379: num = htoi(*p++); ! 380: if (dsize>num) ! 381: error(1, "-D: too small"); ! 382: dsize = num; ! 383: continue; ! 384: ! 385: case 'T': ! 386: if (++c >= argc) ! 387: error(1, "-T: arg missing"); ! 388: if (tsize!=0 && !Aflag) ! 389: error(1, "-T: too late, some text already loaded"); ! 390: textbase = htoi(*p++); ! 391: continue; ! 392: ! 393: case 'l': ! 394: save = ap[--i]; ! 395: ap[i]='-'; ! 396: load1arg(&ap[i]); ! 397: ap[i]=save; ! 398: break; ! 399: ! 400: case 'x': ! 401: xflag++; ! 402: continue; ! 403: ! 404: case 'X': ! 405: Xflag++; ! 406: continue; ! 407: ! 408: case 'S': ! 409: Sflag++; ! 410: continue; ! 411: ! 412: case 'r': ! 413: rflag++; ! 414: arflag++; ! 415: continue; ! 416: ! 417: case 's': ! 418: sflag++; ! 419: xflag++; ! 420: continue; ! 421: ! 422: case 'n': ! 423: nflag++; ! 424: continue; ! 425: ! 426: case 'N': ! 427: nflag = 0; ! 428: continue; ! 429: ! 430: case 'd': ! 431: dflag++; ! 432: continue; ! 433: ! 434: case 'i': ! 435: iflag++; ! 436: continue; ! 437: ! 438: case 't': ! 439: trace++; ! 440: continue; ! 441: ! 442: default: ! 443: error(1, "bad flag"); ! 444: } /*endsw*/ ! 445: break; ! 446: } /*endfor*/ ! 447: } else ! 448: load1arg(ap); ! 449: } ! 450: endload(argc, argv); ! 451: exit(0); ! 452: } ! 453: ! 454: /* used after pass 1 */ ! 455: long torigin; ! 456: long dorigin; ! 457: long borigin; ! 458: long database; ! 459: ! 460: endload(argc, argv) ! 461: int argc; ! 462: char **argv; ! 463: { ! 464: register int c, i; ! 465: long dnum; ! 466: register char *ap, **p; ! 467: ! 468: brk(nextsym); ! 469: filname = 0; ! 470: middle(); ! 471: setupout(); ! 472: if ((LOCAL *)-1==(local=(LOCAL *)sbrk(NSYMPR*sizeof(*local)))) error(1,"Memory overflow"); ! 473: p = argv+1; ! 474: libp = liblist; ! 475: for (c=1; c<argc; c++) { ! 476: ap = *p++; ! 477: if (trace) printf("%s:\n", ap); ! 478: if (*ap == '-') { ! 479: for (i=1; ap[i]; i++) { ! 480: switch (ap[i]) { ! 481: case 'D': ! 482: for (dnum = htoi(*p); dorigin<dnum; dorigin++) putc(0, dout); ! 483: case 'T': ! 484: case 'u': ! 485: case 'e': ! 486: case 'o': ! 487: case 'v': ! 488: ++c; ! 489: ++p; ! 490: ! 491: default: ! 492: continue; ! 493: ! 494: case 'A': ! 495: fund2(*p++); ! 496: c++; ! 497: continue; ! 498: ! 499: case 'l': ! 500: ap[--i]='-'; ! 501: load2arg(&ap[i]); ! 502: break; ! 503: } /*endsw*/ ! 504: break; ! 505: } /*endfor*/ ! 506: } else ! 507: load2arg(ap); ! 508: } ! 509: finishout(); ! 510: } ! 511: ! 512: record(c, nam) ! 513: int c; ! 514: STRING nam; ! 515: { ! 516: register OVERLAY *v; ! 517: ! 518: v = &vnodes[vindex++]; ! 519: v->argsav = c; ! 520: v->symsav = nextsym-symtab; ! 521: v->libsav = libp; ! 522: v->vname = nam; ! 523: v->offt = tsize; ! 524: v->offd = dsize; ! 525: v->offb = bsize; ! 526: v->offtr = trsize; ! 527: v->offdr = drsize; ! 528: v->offs = ssize; ! 529: v->ctsav = ctrel; ! 530: v->cdsav = cdrel; ! 531: v->cbsav = cbrel; ! 532: } ! 533: ! 534: restore(vscan) ! 535: int vscan; ! 536: { ! 537: register OVERLAY *v; ! 538: register SYMBOL *saved,*sp; ! 539: ! 540: v = &vnodes[vscan]; ! 541: vindex = vscan+1; ! 542: libp = v->libsav; ! 543: ctrel = v->ctsav; ! 544: cdrel = v->cdsav; ! 545: cbrel = v->cbsav; ! 546: tsize = v->offt; ! 547: dsize = v->offd; ! 548: bsize = v->offb; ! 549: trsize = v->offtr; ! 550: drsize = v->offdr; ! 551: ssize = v->offs; ! 552: saved = symtab + v->symsav; ! 553: sp = nextsym; ! 554: while (sp>saved) ! 555: hshtab[(--sp)->symhash]=0; ! 556: nextsym = saved; ! 557: } ! 558: ! 559: /* scan file to find defined symbols */ ! 560: load1arg(cp) ! 561: register char *cp; ! 562: { ! 563: long loc; ! 564: ! 565: if (getfile(cp)==0) ! 566: load1(0, 0L); ! 567: else { ! 568: loc = sizeof(int); ! 569: for (;;) { ! 570: dseek(&text, loc, (long)sizeof(archdr)); ! 571: if (text.size <= 0) { ! 572: libp->loc = -1; ! 573: if( ++libp >= liblist + NROUT) ! 574: error(1,"liblist overflow"); ! 575: /* thanks to Dennis Wasley */ ! 576: return; ! 577: } ! 578: mget((short *)&archdr, sizeof archdr, &text); ! 579: if (load1(1, loc+sizeof(archdr))) { ! 580: libp->loc = loc; ! 581: libp++; ! 582: } ! 583: #ifndef vax ! 584: if (archdr.ar_size.loword==0) fixl(&archdr.ar_size); ! 585: #endif ! 586: loc += round(archdr.ar_size, 1) + sizeof(archdr); ! 587: } ! 588: } ! 589: close(infil); ! 590: } ! 591: ! 592: /* single file or archive member */ ! 593: load1(libflg, loc) ! 594: long loc; ! 595: { ! 596: register SYMBOL *sp; ! 597: SYMBOL *savnext; ! 598: int ndef, nlocal, type; ! 599: ! 600: readhdr(loc); ! 601: ctrel = tsize; ! 602: cdrel += dsize; ! 603: cbrel += bsize; ! 604: ndef = 0; ! 605: nlocal = sizeof(cursym); ! 606: savnext = nextsym; ! 607: /* if (filhdr.a_trsize+filhdr.a_drsize==0) { ! 608: /* error(0, "No relocation bits"); ! 609: /* return(0); ! 610: /* } ! 611: */ ! 612: loc += filhdr.a_text + filhdr.a_data + ! 613: filhdr.a_trsize + filhdr.a_drsize + sizeof(filhdr); ! 614: dseek(&text, loc, filhdr.a_syms); ! 615: while (text.size > 0) { ! 616: symget(&cursym, &text); ! 617: type = cursym.stype; ! 618: if ((type&EXTERN)==0) { ! 619: if (Xflag==0 || cursym.sname[0]!='L' || type & STABTYPS) ! 620: nlocal += sizeof cursym; ! 621: continue; ! 622: } ! 623: symreloc(); ! 624: if (enter(lookup())) ! 625: continue; ! 626: if ((sp = lastsym)->stype != EXTERN+UNDEF) ! 627: continue; ! 628: if (cursym.stype == EXTERN+UNDEF) { ! 629: if (cursym.svalue > sp->svalue) ! 630: sp->svalue = cursym.svalue; ! 631: continue; ! 632: } ! 633: if (sp->svalue != 0 && cursym.stype == EXTERN+TEXT) ! 634: continue; ! 635: ndef++; ! 636: sp->stype = cursym.stype; ! 637: sp->svalue = cursym.svalue; ! 638: } ! 639: if (libflg==0 || ndef) { ! 640: tsize += filhdr.a_text; ! 641: dsize += round(filhdr.a_data, FW); ! 642: bsize += round(filhdr.a_bss, FW); ! 643: ssize += nlocal; ! 644: trsize += filhdr.a_trsize; ! 645: drsize += filhdr.a_drsize; ! 646: if (RFflag) textbase = (*slookup("_end"))->svalue; ! 647: return(1); ! 648: } ! 649: /* ! 650: * No symbols defined by this library member. ! 651: * Rip out the hash table entries and reset the symbol table. ! 652: */ ! 653: while (nextsym>savnext) ! 654: hshtab[(--nextsym)->symhash]=0; ! 655: return(0); ! 656: } ! 657: ! 658: middle() ! 659: { ! 660: register SYMBOL *sp, *symp; ! 661: long csize, t, corigin, ocsize; ! 662: int nund, rnd; ! 663: char s; ! 664: ! 665: torigin = 0; ! 666: dorigin = 0; ! 667: borigin = 0; ! 668: ! 669: p_data = *slookup("_data"); ! 670: p_etext = *slookup("_etext"); ! 671: p_edata = *slookup("_edata"); ! 672: p_end = *slookup("_end"); ! 673: /* ! 674: * If there are any undefined symbols, save the relocation bits. ! 675: */ ! 676: symp = nextsym; ! 677: if (rflag==0) { ! 678: for (sp = symtab; sp<symp; sp++) ! 679: if (sp->stype==EXTERN+UNDEF && sp->svalue==0 ! 680: && sp!=p_end && sp!=p_edata && sp!=p_etext ! 681: && sp!=p_data) { ! 682: rflag++; ! 683: dflag = 0; ! 684: break; ! 685: } ! 686: } ! 687: if (rflag) ! 688: sflag = iflag = 0; ! 689: /* ! 690: * Assign common locations. ! 691: */ ! 692: csize = 0; ! 693: if(!Aflag) addsym = symtab; ! 694: database = round(tsize+textbase, (nflag? PAGRND:FW)); ! 695: if (dflag || rflag==0) { ! 696: ldrsym(p_data, (long)0 , EXTERN+DATA); ! 697: ldrsym(p_etext, tsize, EXTERN+TEXT); ! 698: ldrsym(p_edata, dsize, EXTERN+DATA); ! 699: ldrsym(p_end, bsize, EXTERN+BSS); ! 700: for (sp = addsym; sp<symp; sp++) { ! 701: if ((s=sp->stype)==EXTERN+UNDEF && (t = sp->svalue)!=0) { ! 702: if (t>DW) ! 703: rnd = DW; ! 704: else if (t>FW) ! 705: rnd = FW; ! 706: else ! 707: rnd = HW; ! 708: csize = round(csize, rnd); ! 709: sp->svalue = csize; ! 710: sp->stype = EXTERN+COMM; ! 711: ocsize = csize; ! 712: csize += t; ! 713: } ! 714: if (((s&TMASK) == EXTERN+UNDEF) && (s & STABTYPS)) { ! 715: sp->svalue = ocsize; ! 716: sp->stype = (s & STABTYPS) | (EXTERN+COMM); ! 717: } ! 718: } ! 719: } ! 720: /* ! 721: * Now set symbols to their final value ! 722: */ ! 723: csize = round(csize, FW); ! 724: torigin = textbase; ! 725: dorigin = database; ! 726: corigin = dorigin + dsize; ! 727: borigin = corigin + csize; ! 728: cdorel = 0; ! 729: cborel = dsize+csize; ! 730: nund = 0; ! 731: for (sp = addsym; sp<symp; sp++) switch (sp->stype & TMASK) { ! 732: case EXTERN+UNDEF: ! 733: errlev |= 01; ! 734: if ((arflag==0 || dflag) && sp->svalue==0) { ! 735: if (nund==0) ! 736: printf("Undefined:\n"); ! 737: nund++; ! 738: printf("%.8s\n", sp->sname); ! 739: } ! 740: continue; ! 741: ! 742: case EXTERN+ABS: ! 743: default: ! 744: continue; ! 745: ! 746: case EXTERN+TEXT: ! 747: sp->svalue += torigin; ! 748: continue; ! 749: ! 750: case EXTERN+DATA: ! 751: sp->svalue += dorigin; ! 752: continue; ! 753: ! 754: case EXTERN+BSS: ! 755: sp->svalue += borigin; ! 756: continue; ! 757: ! 758: case EXTERN+COMM: ! 759: sp->stype = (sp->stype & STABTYPS) | (EXTERN+BSS); ! 760: sp->svalue += corigin; ! 761: continue; ! 762: } ! 763: if (sflag || xflag) ! 764: ssize = 0; ! 765: bsize += csize; ! 766: nsym = ssize / (sizeof cursym); ! 767: if (Aflag) { ! 768: fixspec(p_data,dorigin); ! 769: fixspec(p_etext,torigin); ! 770: fixspec(p_edata,dorigin); ! 771: fixspec(p_end,borigin); ! 772: } ! 773: } ! 774: fixspec(sym,offset) ! 775: SYMBOL *sym; long offset; ! 776: { ! 777: if(sym < addsym && sym!=0) ! 778: sym->svalue += offset; ! 779: } ! 780: ! 781: ! 782: ldrsym(asp, val, type) ! 783: long val; ! 784: SYMBOL *asp; ! 785: { ! 786: register SYMBOL *sp; ! 787: ! 788: if ((sp = asp) == 0) ! 789: return; ! 790: if ((sp->stype != EXTERN+UNDEF || sp->svalue) && !Aflag) { ! 791: printf("%.8s: ", sp->sname); ! 792: error(0, "Multiply defined (internal)"); ! 793: return; ! 794: } ! 795: sp->stype = type; ! 796: sp->svalue = val; ! 797: } ! 798: ! 799: extern char _sibuf[BUFSIZ]; /* the space is forced upon us; might as well use it */ ! 800: ! 801: setupout() ! 802: { ! 803: tout = fopen(ofilename, "w"); ! 804: if (tout==NULL) ! 805: error(1, "cannot create output"); ! 806: setbuf(tout,_sibuf); ! 807: dout = tcreat(&doutn, "/tmp/ldaaXXXXX"); ! 808: if (sflag==0 || xflag==0) ! 809: sout = tcreat(&soutn, "/tmp/ldbaXXXXX"); ! 810: if (rflag) { ! 811: trout = tcreat(&troutn, "/tmp/ldcaXXXXX"); ! 812: drout = tcreat(&droutn, "/tmp/lddaXXXXX"); ! 813: } ! 814: filhdr.a_magic = nflag? NMAGIC:OMAGIC; ! 815: filhdr.a_text = nflag? tsize:round(tsize, FW); ! 816: filhdr.a_data = dsize; ! 817: filhdr.a_bss = bsize; ! 818: filhdr.a_trsize = trsize; ! 819: filhdr.a_drsize = drsize; ! 820: filhdr.a_syms = sflag? 0: (ssize + (sizeof cursym)*(nextsym-symtab)); ! 821: if (entrypt) { ! 822: if (entrypt->stype!=EXTERN+TEXT) ! 823: error(0, "Entry point not in text"); ! 824: else ! 825: filhdr.a_entry = entrypt->svalue; ! 826: } else ! 827: filhdr.a_entry=0; ! 828: filhdr.a_trsize = (rflag ? trsize:0); ! 829: filhdr.a_drsize = (rflag ? drsize:0); ! 830: writel(&filhdr,8,tout); ! 831: } ! 832: ! 833: FILE * ! 834: tcreat(namep, name) ! 835: char **namep, *name; ! 836: { ! 837: register FILE *fp; ! 838: register char *tnm; ! 839: ! 840: tnm = mktemp(name); ! 841: if ((fp = fopen(tnm, "w")) == NULL) ! 842: error(1, "Cannot create temp file"); ! 843: chmod(tnm, 0600); ! 844: *namep = tnm; ! 845: return(fp); ! 846: } ! 847: ! 848: load2arg(acp) ! 849: char *acp; ! 850: { ! 851: register char *cp; ! 852: register LIBLIST *lp; ! 853: ! 854: cp = acp; ! 855: if (getfile(cp) == 0) { ! 856: while (*cp) ! 857: cp++; ! 858: while (cp >= acp && *--cp != '/'); ! 859: mkfsym(++cp); ! 860: load2(0L); ! 861: } else { /* scan archive members referenced */ ! 862: for (lp = libp; lp->loc != -1; lp++) { ! 863: dseek(&text, lp->loc, (long)sizeof(archdr)); ! 864: mget((short *)&archdr, sizeof(archdr), &text); ! 865: mkfsym(archdr.ar_name); ! 866: load2(lp->loc + (long)sizeof(archdr)); ! 867: } ! 868: libp = ++lp; ! 869: } ! 870: close(infil); ! 871: } ! 872: ! 873: load2(loc) ! 874: long loc; ! 875: { ! 876: register SYMBOL *sp; ! 877: register LOCAL *lp; ! 878: register int symno; ! 879: int type; ! 880: ! 881: readhdr(loc); ! 882: if(!RFflag) { ! 883: ctrel = torigin; ! 884: cdrel += dorigin; ! 885: cbrel += borigin; ! 886: } ! 887: /* ! 888: * Reread the symbol table, recording the numbering ! 889: * of symbols for fixing external references. ! 890: */ ! 891: lp = local; ! 892: symno = -1; ! 893: loc += sizeof(filhdr); ! 894: dseek(&text, loc+filhdr.a_text+filhdr.a_data+ ! 895: filhdr.a_trsize+filhdr.a_drsize, filhdr.a_syms); ! 896: while (text.size > 0) { ! 897: symno++; ! 898: symget(&cursym, &text); ! 899: symreloc(); ! 900: type = cursym.stype; ! 901: if ((type&EXTERN) == 0) { ! 902: if (!sflag&&!xflag&& ! 903: (!Xflag||cursym.sname[0]!='L'||type&STABTYPS)) ! 904: symwrite(&cursym, 1, sout); ! 905: continue; ! 906: } ! 907: if (RFflag) continue; ! 908: if ((sp = *lookup()) == 0) ! 909: error(1, "internal error: symbol not found"); ! 910: if (cursym.stype == EXTERN+UNDEF) { ! 911: if (lp >= local+NSYMPR) ! 912: error(1, "Local symbol overflow"); ! 913: lp->locindex = symno; ! 914: lp++->locsymbol = sp; ! 915: continue; ! 916: } ! 917: if(cursym.stype & STABTYPS) continue; ! 918: if (cursym.stype!=sp->stype || cursym.svalue!=sp->svalue) { ! 919: printf("%.8s: ", cursym.sname); ! 920: error(0, "Multiply defined"); ! 921: } ! 922: } ! 923: if(RFflag) return; ! 924: dseek(&text, loc, filhdr.a_text); ! 925: dseek(&reloc, loc+filhdr.a_text+filhdr.a_data, filhdr.a_trsize); ! 926: load2td(lp, ctrel, tout, trout); ! 927: dseek(&text, loc+filhdr.a_text, filhdr.a_data); ! 928: dseek(&reloc, loc+filhdr.a_text+filhdr.a_data+filhdr.a_trsize, filhdr.a_drsize); ! 929: load2td(lp, cdrel, dout, drout); ! 930: while (filhdr.a_data&FW) { ! 931: putc(0, dout); filhdr.a_data++; ! 932: } ! 933: torigin += filhdr.a_text; ! 934: dorigin += filhdr.a_data; ! 935: borigin += filhdr.a_bss; ! 936: cdorel += filhdr.a_data; ! 937: cborel += filhdr.a_bss; ! 938: } ! 939: ! 940: load2td(lp, creloc, b1, b2) ! 941: LOCAL *lp; ! 942: long creloc; ! 943: FILE *b1, *b2; ! 944: { ! 945: register r1; ! 946: register char r2; ! 947: register long t; ! 948: register SYMBOL *sp; ! 949: long tw,u,l; ! 950: ! 951: for (;;) { ! 952: if (reloc.size==0) {while (text.size) putc(get(&text),b1); break;} ! 953: t=getl(&reloc); /* position of relocatable stuff */ ! 954: if (rflag) putl(t+creloc,b2); /* remember for subsequent link editing */ ! 955: while (text.pos<t) putc(get(&text),b1); /* advance to proper position */ ! 956: r1=get3(&reloc); /* kind of relocation */ ! 957: r2 = getb(&reloc); ! 958: switch (r2&06) {/* read raw datum according to its length */ ! 959: case LEN1: tw=get(&text); break; ! 960: case LEN2: tw=gets(&text); break; ! 961: case LEN4: tw=getl(&text); break; ! 962: } ! 963: if (r2&REXT) { ! 964: sp=lookloc(lp,r1); /* find the symbol */ ! 965: if (sp->stype==EXTERN+UNDEF) { /* still undefined */ ! 966: r2=(r2&(REFMASK+REXT+ROFF)); ! 967: r1 = nsym+(sp-symtab); /* new reloc */ ! 968: } ! 969: else { ! 970: if (sp->stype==EXTERN+DATA && r2&ROFF) { ! 971: r1=RDATAO; ! 972: r2&=REFMASK; ! 973: } ! 974: else if (sp->stype==EXTERN+BSS && r2&ROFF) { ! 975: r1=RBSSO; ! 976: r2&=REFMASK; ! 977: } ! 978: else if (sp->stype==EXTERN+ABS && r2&ROFF) { ! 979: r1=RABSO; ! 980: r2&=REFMASK; ! 981: } ! 982: else if (sp->stype==EXTERN+TEXT && r2&ROFF) { ! 983: r1=RTEXTO; ! 984: r2&=REFMASK; ! 985: } ! 986: else {if (r2&ROFF) {if (rflag) {error(0,"!-r; see JFR"); rflag=0;}} ! 987: else tw += database; ! 988: r1=sp->stype&TYPE; ! 989: r2&=REFMASK; ! 990: } ! 991: tw += sp->svalue - database; ! 992: } ! 993: } else switch (r1&TYMASK) { ! 994: case RTEXT: tw += ctrel; break; ! 995: case RTEXTO:tw += round(filhdr.a_text,PAGRND)+ctrel-database; break; ! 996: case RDATA: tw += cdrel; break; ! 997: case RDATAO:tw += cdorel; break; ! 998: case RBSS: tw += cbrel; break; ! 999: case RBSSO: tw += cborel-filhdr.a_data; break; ! 1000: case RABSO: tw += round(filhdr.a_text,PAGRND)-database; break; ! 1001: } ! 1002: if (rflag) { /* remember for subsequent link editing */ ! 1003: put3(r1,b2); ! 1004: putb(r2,b2); ! 1005: } ! 1006: if (r2&PCREL) tw -= creloc; /* assembler already subtracted text.pos */ ! 1007: switch (r2&06) {/* output relocated datum according to its length */ ! 1008: case LEN1: l= -128; u=127; putc((char)tw,b1); break; ! 1009: case LEN2: l= -32768; u=32767; puts((short)tw,b1); break; ! 1010: case LEN4: l=0x80000000; u=0x7FFFFFFF; putl(tw,b1); break; ! 1011: } ! 1012: if (tw<l || u<tw) error(0,"Displacement overflow"); ! 1013: } ! 1014: } ! 1015: ! 1016: finishout() ! 1017: { ! 1018: ! 1019: if (!nflag) ! 1020: while (tsize&FW) { ! 1021: putc(0, tout); tsize++; ! 1022: } ! 1023: fclose(dout); ! 1024: copy(doutn); ! 1025: if (rflag) { ! 1026: fclose(trout); ! 1027: copy(troutn); ! 1028: fclose(drout); ! 1029: copy(droutn); ! 1030: } ! 1031: if (sflag==0) { ! 1032: if (xflag==0) { ! 1033: fclose(sout); ! 1034: copy(soutn); ! 1035: } ! 1036: symwrite(symtab, nextsym-symtab, tout); ! 1037: } ! 1038: fclose(tout); ! 1039: if (!ofilfnd) { ! 1040: unlink("a.out"); ! 1041: link("l.out", "a.out"); ! 1042: ofilename = "a.out"; ! 1043: } ! 1044: delarg = errlev; ! 1045: delexit(); ! 1046: } ! 1047: ! 1048: copy(np) ! 1049: char *np; ! 1050: { ! 1051: register c; ! 1052: register FILE *fp; ! 1053: ! 1054: if ((fp = fopen(np, "r")) == NULL) ! 1055: error(1, "cannot recopy output"); ! 1056: while ((c = getc(fp)) != EOF) ! 1057: putc(c, tout); ! 1058: fclose(fp); ! 1059: } ! 1060: ! 1061: mkfsym(s) ! 1062: char *s; ! 1063: { ! 1064: ! 1065: if (sflag || xflag) ! 1066: return; ! 1067: cp8c(s, cursym.sname); ! 1068: cursym.stype = TEXT; ! 1069: cursym.svalue = torigin; ! 1070: symwrite(&cursym, 1, sout); ! 1071: } ! 1072: ! 1073: mget(loc, n, sp) ! 1074: register STREAM *sp; ! 1075: register char *loc; ! 1076: { ! 1077: register char *p; ! 1078: ! 1079: if ((sp->nibuf -= n) >= 0) { ! 1080: if ((sp->size -= n) > 0) { ! 1081: p = sp->ptr; ! 1082: sp->pos += n; ! 1083: do ! 1084: *loc++ = *p++; ! 1085: while (--n); ! 1086: sp->ptr = p; ! 1087: return; ! 1088: } else ! 1089: sp->size += n; ! 1090: } ! 1091: sp->nibuf += n; ! 1092: do { ! 1093: *loc++ = get(sp); ! 1094: } while (--n); ! 1095: } ! 1096: ! 1097: short ! 1098: gets(sp) STREAM *sp; { ! 1099: short t; mget(&t,2,sp); return(t); ! 1100: } ! 1101: ! 1102: char ! 1103: getb(sp) STREAM *sp; { ! 1104: char t; mget(&t,1,sp); return(t); ! 1105: } ! 1106: ! 1107: long ! 1108: get3(sp) STREAM *sp; { ! 1109: long t; t=0; mget(&t,3,sp); return(t); ! 1110: } ! 1111: ! 1112: long ! 1113: getl(sp) STREAM *sp; { ! 1114: long t; mget(&t,4,sp); ! 1115: #ifndef vax ! 1116: fixl(&t); ! 1117: #endif ! 1118: return(t); ! 1119: } ! 1120: ! 1121: symget(sp,f) SYMBOL *sp; STREAM *f; { ! 1122: mget(sp,sizeof(*sp),f); ! 1123: #ifndef vax ! 1124: fixl(&sp->svalue); ! 1125: #endif ! 1126: } ! 1127: ! 1128: dseek(sp, loc, s) ! 1129: register STREAM *sp; ! 1130: long loc, s; ! 1131: { ! 1132: register PAGE *p; ! 1133: register b, o; ! 1134: int n; ! 1135: ! 1136: b = loc>>9; ! 1137: o = loc&0777; ! 1138: if (o&01) ! 1139: error(1, "loader error; odd offset"); ! 1140: --sp->pno->nuser; ! 1141: if ((p = &page[0])->bno!=b && (p = &page[1])->bno!=b) ! 1142: if (p->nuser==0 || (p = &page[0])->nuser==0) { ! 1143: if (page[0].nuser==0 && page[1].nuser==0) ! 1144: if (page[0].bno < page[1].bno) ! 1145: p = &page[0]; ! 1146: p->bno = b; ! 1147: lseek(infil, loc & ~0777L, 0); ! 1148: if ((n = read(infil, p->buff, sizeof(p->buff))) < 0) ! 1149: n = 0; ! 1150: p->nibuf = n; ! 1151: } else ! 1152: error(1, "No pages"); ! 1153: ++p->nuser; ! 1154: sp->bno = b; ! 1155: sp->pno = p; ! 1156: if (s != -1) {sp->size = s; sp->pos = 0;} ! 1157: sp->ptr = (char *)(p->buff + o); ! 1158: if ((sp->nibuf = p->nibuf-o) <= 0) ! 1159: sp->size = 0; ! 1160: } ! 1161: ! 1162: char ! 1163: get(asp) ! 1164: STREAM *asp; ! 1165: { ! 1166: register STREAM *sp; ! 1167: ! 1168: sp = asp; ! 1169: if ((sp->nibuf -= sizeof(char)) < 0) { ! 1170: dseek(sp, ((long)(sp->bno+1)<<9), (long)-1); ! 1171: sp->nibuf -= sizeof(char); ! 1172: } ! 1173: if ((sp->size -= sizeof(char)) <= 0) { ! 1174: if (sp->size < 0) ! 1175: error(1, premeof); ! 1176: ++fpage.nuser; ! 1177: --sp->pno->nuser; ! 1178: sp->pno = (PAGE *) &fpage; ! 1179: } ! 1180: sp->pos += sizeof(char); ! 1181: return(*sp->ptr++); ! 1182: } ! 1183: ! 1184: getfile(acp) ! 1185: STRING acp; ! 1186: { ! 1187: register STRING cp; ! 1188: register int c; ! 1189: int arcmag; ! 1190: ! 1191: cp = acp; ! 1192: infil = -1; ! 1193: archdr.ar_name[0] = '\0'; ! 1194: filname = cp; ! 1195: if (cp[0]=='-' && cp[1]=='l') { ! 1196: if(cp[2] == '\0') ! 1197: cp = "-la"; ! 1198: filname = "/usr/lib/libxxxxxxxxxxxxxxx"; ! 1199: for(c=0; cp[c+2]; c++) ! 1200: filname[c+12] = cp[c+2]; ! 1201: filname[c+12] = '.'; ! 1202: filname[c+13] = 'a'; ! 1203: filname[c+14] = '\0'; ! 1204: if ((infil = open(filname+4, 0)) >= 0) { ! 1205: filname += 4; ! 1206: } ! 1207: } ! 1208: if (infil == -1 && (infil = open(filname, 0)) < 0) ! 1209: error(1, "cannot open"); ! 1210: page[0].bno = page[1].bno = -1; ! 1211: page[0].nuser = page[1].nuser = 0; ! 1212: text.pno = reloc.pno = (PAGE *) &fpage; ! 1213: fpage.nuser = 2; ! 1214: dseek(&text, 0L, (long)sizeof(int)); ! 1215: if (text.size <= 0) ! 1216: error(1, premeof); ! 1217: mget(&arcmag, sizeof(arcmag), &text); ! 1218: return(arcmag==ARMAG); ! 1219: } ! 1220: ! 1221: SYMBOL **lookup() ! 1222: { ! 1223: int i; ! 1224: BOOL clash; ! 1225: register SYMBOL **hp; ! 1226: register char *cp, *cp1; ! 1227: ! 1228: i = 0; ! 1229: for (cp = cursym.sname; cp < &cursym.sname[8];) ! 1230: i = (i<<1) + *cp++; ! 1231: for (hp = &hshtab[(i&077777)%NSYM+2]; *hp!=0;) { ! 1232: cp1 = (*hp)->sname; ! 1233: clash=FALSE; ! 1234: for (cp = cursym.sname; cp < &cursym.sname[8];) ! 1235: if (*cp++ != *cp1++) { ! 1236: clash=TRUE; ! 1237: break; ! 1238: } ! 1239: if (clash) { ! 1240: if (++hp >= &hshtab[NSYM+2]) ! 1241: hp = hshtab; ! 1242: } else ! 1243: break; ! 1244: } ! 1245: return(hp); ! 1246: } ! 1247: ! 1248: SYMBOL **slookup(s) ! 1249: char *s; ! 1250: { ! 1251: cp8c(s, cursym.sname); ! 1252: cursym.stype = EXTERN+UNDEF; ! 1253: cursym.svalue = 0; ! 1254: return(lookup()); ! 1255: } ! 1256: ! 1257: enter(hp) ! 1258: register SYMBOL **hp; ! 1259: { ! 1260: register SYMBOL *sp; ! 1261: ! 1262: if (*hp==0) { ! 1263: if ((nextsym-symtab)>=NSYM) ! 1264: error(1, "Symbol table overflow"); ! 1265: if ((nextsym-symtab)>=nsym) { ! 1266: if (-1==sbrk(NSYM/5 * sizeof(*symtab))) error(1,"Memory overflow"); ! 1267: nsym += NSYM/5; ! 1268: } ! 1269: *hp = lastsym = sp = nextsym++; ! 1270: cp8c(cursym.sname, sp->sname); ! 1271: sp->stype = cursym.stype; ! 1272: sp->symhash = hp-hshtab; ! 1273: sp->svalue = cursym.svalue; ! 1274: return(1); ! 1275: } else { ! 1276: lastsym = *hp; ! 1277: return(0); ! 1278: } ! 1279: } ! 1280: ! 1281: symreloc() ! 1282: { ! 1283: if(RFflag) return; ! 1284: switch (cursym.stype & 017) { ! 1285: ! 1286: case TEXT: ! 1287: case EXTERN+TEXT: ! 1288: cursym.svalue += ctrel; ! 1289: return; ! 1290: ! 1291: case DATA: ! 1292: case EXTERN+DATA: ! 1293: cursym.svalue += cdrel; ! 1294: return; ! 1295: ! 1296: case BSS: ! 1297: case EXTERN+BSS: ! 1298: cursym.svalue += cbrel; ! 1299: return; ! 1300: ! 1301: case EXTERN+UNDEF: ! 1302: return; ! 1303: } ! 1304: if (cursym.stype&EXTERN) ! 1305: cursym.stype = EXTERN+ABS; ! 1306: } ! 1307: ! 1308: error(n, s) ! 1309: char *s; ! 1310: { ! 1311: if (errlev==0) ! 1312: printf("ld:"); ! 1313: if (filname) { ! 1314: printf("%s", filname); ! 1315: if (archdr.ar_name[0]) ! 1316: printf("(%.14s)", archdr.ar_name); ! 1317: printf(": "); ! 1318: } ! 1319: printf("%s\n", s); ! 1320: if (n) ! 1321: delexit(); ! 1322: errlev = 2; ! 1323: } ! 1324: ! 1325: SYMBOL * ! 1326: lookloc(lp, r) ! 1327: register LOCAL *lp; ! 1328: { ! 1329: register LOCAL *clp; ! 1330: register sn; ! 1331: ! 1332: sn = r; ! 1333: for (clp = local; clp<lp; clp++) ! 1334: if (clp->locindex == sn) ! 1335: return(clp->locsymbol); ! 1336: error(1, "Local symbol botch"); ! 1337: } ! 1338: ! 1339: readhdr(loc) ! 1340: long loc; ! 1341: { ! 1342: long *p; int i; ! 1343: dseek(&text, loc, (long)sizeof(filhdr)); ! 1344: mget((short *)&filhdr, sizeof(filhdr), &text); ! 1345: #ifndef vax ! 1346: for (p= &filhdr,i=8;--i>=0;) fixl(p++); ! 1347: #endif ! 1348: if (filhdr.a_magic!=A_MAGIC1 && filhdr.a_magic!=A_MAGIC2 && ! 1349: filhdr.a_magic!=A_MAGIC3 && filhdr.a_magic!=A_MAGIC4) ! 1350: error(1,"Bad magic number"); ! 1351: if (filhdr.a_text&01 || filhdr.a_data&01) { ! 1352: printf("tsize=%X dsize=%X\n",filhdr.a_text,filhdr.a_data); ! 1353: error(1, "Text/data size odd"); ! 1354: } ! 1355: filhdr.a_bss = round(filhdr.a_bss, FW); ! 1356: if (filhdr.a_magic == NMAGIC) { ! 1357: cdrel = -round(filhdr.a_text, PAGRND); ! 1358: cbrel = cdrel - filhdr.a_data; ! 1359: } else if (filhdr.a_magic == OMAGIC) { ! 1360: cdrel = -filhdr.a_text; ! 1361: cbrel = cdrel - filhdr.a_data; ! 1362: } else ! 1363: error(1, "Bad format"); ! 1364: } ! 1365: ! 1366: cp8c(from, to) ! 1367: char *from, *to; ! 1368: { ! 1369: register char *f, *t, *te; ! 1370: ! 1371: f = from; ! 1372: t = to; ! 1373: te = t+8; ! 1374: while ((*t++ = *f++) && t<te); ! 1375: while (t<te) ! 1376: *t++ = 0; ! 1377: } ! 1378: ! 1379: eq(s1, s2) ! 1380: STRING s1; ! 1381: STRING s2; ! 1382: { ! 1383: while (*s1==*s2++) ! 1384: if ((*s1++)==0) ! 1385: return(TRUE); ! 1386: return(FALSE); ! 1387: } ! 1388: ! 1389: long ! 1390: round(v, r) ! 1391: long v; ! 1392: unsigned r; ! 1393: { ! 1394: v += r; ! 1395: v &= ~(long)r; ! 1396: return(v); ! 1397: } ! 1398: ! 1399: puts(w, f) ! 1400: FILE *f; short w; { ! 1401: fwrite(&w,sizeof(short),1,f); ! 1402: } ! 1403: ! 1404: putb(w, f) ! 1405: FILE *f; char w; { ! 1406: fwrite(&w,sizeof(char),1,f); ! 1407: } ! 1408: ! 1409: put3(w, f) ! 1410: FILE *f; long w; { ! 1411: fwrite(&w,3,1,f); ! 1412: } ! 1413: ! 1414: putl(w, f) ! 1415: FILE *f; long w; { ! 1416: #ifndef vax ! 1417: fixl(&w); ! 1418: #endif ! 1419: fwrite(&w,sizeof(long),1,f); ! 1420: } ! 1421: static fundament(name) ! 1422: STRING name; ! 1423: { ! 1424: RFflag = TRUE; ! 1425: load1arg(name); ! 1426: trsize = drsize = tsize = dsize = bsize = ctrel = cdrel = cbrel = 0; ! 1427: RFflag = FALSE; ! 1428: addsym = nextsym; ! 1429: } ! 1430: fund2(name) ! 1431: STRING name; ! 1432: { ! 1433: RFflag = TRUE; ! 1434: load2arg(name); ! 1435: RFflag = FALSE; ! 1436: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.