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

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

unix.superglobalmegacorp.com

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