Annotation of 3BSD/cmd/ld.c, revision 1.1.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.