Annotation of 3BSD/cmd/ld.c, revision 1.1

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

unix.superglobalmegacorp.com

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