Annotation of 3BSD/cmd/lisp/nld.c, revision 1.1

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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.