Annotation of researchv10no/cmd/PDP11/11ld.c, revision 1.1

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

unix.superglobalmegacorp.com

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