Annotation of coherent/b/bin/ld386/pass1.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * ld/pass1.c
        !             3:  *
        !             4:  * One Pass Coff Loader.
        !             5:  * By Charles Fiterman 3/31/92 for Mark Williams.
        !             6:  */ 
        !             7: #include "ld.h"
        !             8: 
        !             9: mod_t *sysHead;
        !            10: static int  ifd;
        !            11: static char *fname;
        !            12: 
        !            13: /*
        !            14:  * Reverse bytes on the 80386 for archive pointers.
        !            15:  */
        !            16: #ifdef GEMDOS
        !            17: #include <osbind.h>
        !            18: #define flipbytes(x)
        !            19: #else
        !            20: flipbytes(c)
        !            21: register char *c;
        !            22: {
        !            23:        register char t;
        !            24: 
        !            25:        t = c[0]; c[0] = c[3]; c[3] = t;
        !            26:        t = c[1]; c[1] = c[2]; c[2] = t;
        !            27: }
        !            28: #endif
        !            29: 
        !            30: /*
        !            31:  * Symbol name.
        !            32:  */
        !            33: char *
        !            34: symName(sym, work)
        !            35: register SYMENT *sym;
        !            36: register char *work;
        !            37: {
        !            38:        if (1 == sym->n_zeroes) {       /* pointer to table record */
        !            39:                sym_t *s;
        !            40: 
        !            41:                s = (sym_t *)sym->n_offset;
        !            42:                sym = &(s->sym);
        !            43:        }
        !            44: 
        !            45:        if (!sym->n_zeroes)             /* pointer to long symbol */
        !            46:                return ((char *)sym->n_offset);
        !            47: 
        !            48:        /*
        !            49:         * Name in record may need terminator.
        !            50:         * Profiling shows this gets used a lot so do it quick
        !            51:         * even at the cost of some readability.
        !            52:         */
        !            53:        ((long *)work)[0] = sym->n_zeroes;
        !            54:        ((long *)work)[1] = sym->n_offset;
        !            55: /*     memcpy(work, sym->n_name, SYMNMLEN); */
        !            56:        work[SYMNMLEN] = '\0';
        !            57:        return (work);
        !            58: }
        !            59: 
        !            60: /*
        !            61:  * complain about redefined symbol
        !            62:  */
        !            63: void
        !            64: symredef(sp, mp)
        !            65: sym_t  *sp;
        !            66: mod_t  *mp;
        !            67: {
        !            68:        /*
        !            69:         * Simple module.
        !            70:         */
        !            71:        if (mp->mname[0] == '\0')
        !            72:                spmsg(sp, "redefined in file '%s'", mp->fname);
        !            73:        /* A symbol is defined in incompatible ways in different files. */
        !            74: 
        !            75:        else
        !            76:                spmsg(sp, "redefined in file '%s': module '%.*s'",
        !            77:                        mp->fname, DIRSIZ, mp->mname );
        !            78:        /* A symbol is defined in incompatible ways in different files. */
        !            79: }
        !            80: 
        !            81: /*
        !            82:  * Return undefined reference to given symbol if any.
        !            83:  */
        !            84: sym_t *
        !            85: symref(name)
        !            86: char *name;
        !            87: {
        !            88:        char work[SYMNMLEN + 1];
        !            89:        register sym_t  *sp;
        !            90:        register SYMENT *sym;
        !            91: 
        !            92:        /* Scan internal symbol table for undefined reference. */
        !            93:        for (sp=symtable[crc16(name) % NHASH]; sp != NULL; sp=sp->next) {
        !            94:                sym = &(sp->sym);
        !            95:                if (undefined(sym) && !strcmp(symName(sym, work), name))
        !            96:                        break;
        !            97:        }
        !            98:        return(sp); /* Return reference, or NULL. */
        !            99: }
        !           100: 
        !           101: /*
        !           102:  * Read input files.
        !           103:  */
        !           104: readFile(fn, loadsw, p)
        !           105: char *fn;      /* file name */
        !           106: int  loadsw;   /* 1 = load this file, 0 = use its symbol table */
        !           107: register char *p;
        !           108: {
        !           109:        struct stat st;
        !           110: 
        !           111:        fname = fn;
        !           112: 
        !           113:        if (NULL == p) {        /* not forced */
        !           114:                /*
        !           115:                 * Look for rename entrys.
        !           116:                 * con=atcon
        !           117:                 * is not a filename with an =
        !           118:                 * it means rename con to atcon.
        !           119:                 * This is a drvld requirment.
        !           120:                 */
        !           121:                if (NULL != (p = strchr(fname, '='))) {
        !           122:                        ren_t   *new;
        !           123:        
        !           124:                        new = alloc(sizeof(*new));
        !           125:                        new->next = rhead;
        !           126:                        rhead = new;
        !           127:                        new->from = fname;
        !           128:                        *p = '\0';
        !           129:                        new->to = p + 1;
        !           130:                        return;
        !           131:                }
        !           132: 
        !           133:                /* all names must be *.[ao] */
        !           134:                if (NULL == (p = strrchr(fname, '.')) || p[2])
        !           135:                        p = ".?";
        !           136:                if (!loadsw)    /* drvld's read of the system */
        !           137:                        p = "_s.o" + 2;
        !           138: #if    0
        !           139: /* This is bogus, e.g. it suppresses the ld of a_s.o in "cc a_s.o". */
        !           140:                /* shared libs have names like libc_s.a */
        !           141:                if ((p[-2] == '_') && (p[-1] == 's'))
        !           142:                        loadsw = 0;
        !           143: #endif
        !           144:        }
        !           145: #ifdef GEMDOS
        !           146:        stat(fname, &st);
        !           147:        ifd = qopen(fname, 0);
        !           148: #else
        !           149:        ifd = qopen(fname, 0);
        !           150:        fstat(ifd, &st);
        !           151: #endif
        !           152:        switch(p[1]) {
        !           153:        case 'a':
        !           154:                archive(loadsw);
        !           155:                break;
        !           156:        case 'o':
        !           157:                object("", st.st_size, loadsw);
        !           158:                break;
        !           159:        default:
        !           160:                message("unlikely input file name '%s'", fname);
        !           161:                /* Input file names must end \fB.o\fR for object or \fB.a\fR
        !           162:                 * for archive. */
        !           163:        }
        !           164:        close(ifd);
        !           165: }
        !           166: 
        !           167: /*
        !           168:  * Add item to correct common
        !           169:  */
        !           170: static void
        !           171: addComm(v)
        !           172: long v;
        !           173: {
        !           174:        switch ((int)v & 3) {
        !           175:        case 0:
        !           176:                comnl += v;     /* Long aligned commons */
        !           177:                break;
        !           178:        case 2:
        !           179:                comns += v;     /* Short aligned commons */
        !           180:                break;
        !           181:        default:
        !           182:                comnb += v;     /* Byte aligned commons */
        !           183:        }
        !           184: }
        !           185: 
        !           186: /*
        !           187:  * add a symbol to the symbol table.
        !           188:  */
        !           189: addsym(s, mp)
        !           190: register SYMENT *s;
        !           191: mod_t *mp;
        !           192: {
        !           193:        register sym_t *sp;
        !           194:        ren_t *ren;
        !           195:        enum state {
        !           196:                local, gdef, gref, comm
        !           197:        } new, old;
        !           198:        int h, sec;
        !           199:        char has_fsize, has_fcn, nodata;
        !           200:        char *name;
        !           201:        char w1[SYMNMLEN + 1], w2[SYMNMLEN + 1];
        !           202: 
        !           203:        sec = s->n_scnum;
        !           204:        switch (s->n_sclass) {
        !           205:        case C_EXTDEF:
        !           206:                s->n_sclass = C_EXT;
        !           207:                sec = s->n_value = s->n_scnum = 0;
        !           208:        case C_EXT:
        !           209:                if (sec)
        !           210:                        new = gdef;
        !           211:                else if (s->n_value)
        !           212:                        new = comm;
        !           213:                else
        !           214:                        new = gref;
        !           215:                break;
        !           216:        case C_STAT:
        !           217:                new = local;
        !           218:                break;
        !           219:        default:
        !           220:                if (!debflg)
        !           221:                        return;
        !           222:                new = local;
        !           223:        }
        !           224: 
        !           225:        name = symName(s, w1);
        !           226: 
        !           227:        /* check rename entrys */
        !           228:        for (ren = rhead; NULL != ren; ren = ren->next) {
        !           229:                if (!strcmp(ren->from, name)) {
        !           230:                        s->n_zeroes = 0;
        !           231:                        name = ren->to;
        !           232:                        s->n_offset = (long)name;
        !           233:                        break;
        !           234:                }
        !           235:        }
        !           236:        h = crc16(name) % NHASH;
        !           237: 
        !           238:        /* Make symbols segment relative, if mp == NULL than sec == 0 */
        !           239:        if (sec > 0)
        !           240:                s->n_value += secth[sec - 1].s_size - mp->s[sec - 1].s_vaddr;
        !           241:                                
        !           242:        if (local == new && 
        !           243:            (nolcl ||
        !           244:             (noilcl && (name[0] == '.') && (name[1] == 'L'))))
        !           245:                return;
        !           246: 
        !           247:        for (sp = ((local == new) ? NULL : symtable[h]);
        !           248:             sp != NULL;
        !           249:             sp = sp->next) {
        !           250:                if ((sp->sym.n_sclass != C_EXT) ||
        !           251:                    (strcmp(symName(&(sp->sym), w2), name)))
        !           252:                        continue;
        !           253:        
        !           254:                if (sp->sym.n_scnum)
        !           255:                        old = gdef;
        !           256:                else if (sp->sym.n_value)
        !           257:                        old = comm;
        !           258:                else
        !           259:                        old = gref;
        !           260: 
        !           261:                switch (new) {
        !           262:                /* case local: can't get here */
        !           263: 
        !           264:                case gref:
        !           265:                        s->n_offset = (long)sp;
        !           266:                        s->n_zeroes = 1;
        !           267:                        return;
        !           268: 
        !           269:                case gdef:
        !           270:                        switch (old) {
        !           271:                        case comm:
        !           272:                                spwarn(sp,
        !           273:                        "symbol defined as a common then a global");
        !           274:                        /* A symbol was defined as a common and a globl, eg
        !           275:                         * .DM
        !           276:                         *      int x;          // a common in one module
        !           277:                         *      int x = 5;      // a globl in another module
        !           278:                         * .DE
        !           279:                         * Read your code and think about variable usage.
        !           280:                         * We redefined the common as an external to match
        !           281:                         * the UNIX linker, which fails to flag this.
        !           282:                         */
        !           283:                                addComm(- sp->sym.n_value); /* zonk common */
        !           284:                                memcpy(&(sp->sym), s, sizeof(*s));
        !           285:                                sp->mod = mp;
        !           286:                                s->n_offset = (long)sp;
        !           287:                                s->n_zeroes = 1;
        !           288:                                return;
        !           289: 
        !           290:                        case gref:
        !           291:                                nundef--;
        !           292:                                memcpy(&(sp->sym), s, sizeof(*s));
        !           293:                                sp->mod = mp;
        !           294:                                s->n_offset = (long)sp;
        !           295:                                s->n_zeroes = 1;
        !           296:                                return;
        !           297: 
        !           298:                        default:
        !           299:                                symredef(sp, mp);
        !           300:                                return;
        !           301:                        }
        !           302: 
        !           303:                case comm:
        !           304:                        switch (old) {
        !           305:                        case comm:
        !           306:                                s->n_offset = (long)sp;
        !           307:                                s->n_zeroes = 1;
        !           308: 
        !           309:                                if (sp->sym.n_value == s->n_value)
        !           310:                                        return;
        !           311: 
        !           312:                                spwarn(sp,  "defined with lengths %ld and %ld",
        !           313:                                        sp->sym.n_value,
        !           314:                                        s->n_value);
        !           315:                                /* A common was defined with different lengths,
        !           316:                                 * while this is legal it is very unusual in
        !           317:                                 * C programs. This warning may be turned off
        !           318:                                 * with the -q flag */
        !           319: 
        !           320:                                addComm(- sp->sym.n_value);
        !           321:                                if (sp->sym.n_value < s->n_value) {
        !           322:                                        sp->sym.n_value = s->n_value;
        !           323:                                        sp->mod = mp;
        !           324:                                }
        !           325:                                sp->sym.n_value += 3;
        !           326:                                sp->sym.n_value &= ~3L;
        !           327:                                addComm(sp->sym.n_value);
        !           328:                                return;
        !           329: 
        !           330:                        case gref:
        !           331:                                addComm(s->n_value);
        !           332:                                nundef--;
        !           333:                                memcpy(&(sp->sym), s, sizeof(*s));
        !           334:                                sp->mod = mp;
        !           335:                                s->n_offset = (long)sp;
        !           336:                                s->n_zeroes = 1;
        !           337:                                return;
        !           338: 
        !           339:                        case gdef:
        !           340:                                spwarn(sp, "Defined as a global then a common");
        !           341:                                        /* NODOC */
        !           342:                                s->n_offset = (long)sp;
        !           343:                                s->n_zeroes = 1;
        !           344:                                return;
        !           345:                        }
        !           346:                }
        !           347:        }
        !           348: 
        !           349:        /* symbol local or not found */
        !           350:        sp = alloc(sizeof(*sp));
        !           351:        memcpy(&(sp->sym), s, sizeof(*s));
        !           352:        sp->next = symtable[h];
        !           353:        symtable[h] = sp;
        !           354: 
        !           355:        switch (new) {
        !           356:        case comm:
        !           357:                addComm(s->n_value);
        !           358:        case local:
        !           359:                break;
        !           360:        case gref:
        !           361:                nundef++;
        !           362:        }
        !           363:        
        !           364:        sp->mod = mp;
        !           365:        s->n_offset = (long)sp;
        !           366:        s->n_zeroes = 1;
        !           367: }
        !           368: 
        !           369: /*
        !           370:  * Read input file.
        !           371:  */
        !           372: static void
        !           373: xread(loc, size)
        !           374: char *loc;
        !           375: unsigned size;
        !           376: {
        !           377:        if (size != read(ifd, loc, size))
        !           378:                fatal("error reading '%s'", fname); /**/
        !           379: }
        !           380: 
        !           381: /*
        !           382:  * Inhale object file.
        !           383:  */
        !           384: object(mname, size, loadsw)
        !           385: char *mname;
        !           386: long size;
        !           387: {
        !           388:        register SYMENT *sym;
        !           389:        register SCNHDR *s;
        !           390:        SYMENT *endSym;
        !           391:        mod_t *mp;
        !           392:        char *endmod;
        !           393:        long i, j, k;
        !           394: 
        !           395:        if (watch) {
        !           396:                errCount--;
        !           397:                modmsg(fname, mname, "adding"); /* NODOC */
        !           398:        }
        !           399:        if (size < sizeof(FILEHDR)) {
        !           400:                modmsg(fname, mname, "not an object file - length %d", size);
        !           401:                /* This cannot be an object file */
        !           402:                exit(1);
        !           403:        }
        !           404:        mp    = alloc(sizeof(*mp));     /* allocate our header */
        !           405:        mp->f = alloc((int)size);       /* allocate space for file */
        !           406:        endmod = mp->f + size;          /* end of space for file */
        !           407:        xread(mp->f, (int)size);        /* inhale file */
        !           408: 
        !           409:        if (mp->f->f_magic != C_386_MAGIC) {
        !           410:                modmsg(fname, mname, "not an object file - header starts %x", mp->f->f_magic);
        !           411:                /* Coff headers are expected to start 0x14C,
        !           412:                 * which is called the magic number.
        !           413:                 * This started with the stated hex number. */
        !           414:                exit(1);
        !           415:        }
        !           416: 
        !           417:        mp->fname = newcpy(fname);
        !           418:        if (*mname)
        !           419:                mp->mname = newcpy(mname);
        !           420:        else
        !           421:                mp->mname = "";
        !           422: 
        !           423:        if (loadsw) {   /* put modules on load list */
        !           424:                if (head == NULL)
        !           425:                        head = mp;
        !           426:                else
        !           427:                        tail->next = mp;
        !           428:                tail = mp;
        !           429:                fileh.f_magic = C_386_MAGIC;
        !           430:        }
        !           431:        else {          /* put modules on linkto list */
        !           432:                if (xhead == NULL)
        !           433:                        xhead = mp;
        !           434:                else
        !           435:                        xtail->next = mp;
        !           436:                xtail = mp;
        !           437:        }
        !           438: 
        !           439:        /*
        !           440:         * Turn disk pointers into ram pointers.
        !           441:         */
        !           442:        j = ((long)(mp->f));
        !           443:        mp->s = (SCNHDR *)(sizeof(FILEHDR) + j + mp->f->f_opthdr);
        !           444:        mp->f->f_symptr += j;
        !           445:        mp->l = (char *)(mp->f->f_symptr + (mp->f->f_nsyms * sizeof(SYMENT)));
        !           446:        if ((mp->f->f_symptr > (long)endmod) ||
        !           447:            (mp->l > endmod) ||
        !           448:            (mp->f->f_nsyms < 0))
        !           449:                corrupt(mp);
        !           450: 
        !           451:        /* Setup all sections */
        !           452:        for (i = 0; i < mp->f->f_nscns; i++) {
        !           453:                s = mp->s + i;
        !           454: 
        !           455:                if (nosym && (STYP_INFO == s->s_flags))
        !           456:                        continue;       /* -s strips comments */
        !           457: 
        !           458:                /* Test disk pointers for sanity and make them char pointers */
        !           459: #define tst(x) if ((s->x > size) || (s->x < 0)) corrupt(mp); s->x += j;
        !           460:                tst(s_scnptr);
        !           461:                tst(s_relptr);
        !           462:                tst(s_lnnoptr);
        !           463: #undef tst
        !           464: 
        !           465:                for (k = 0; k < osegs; k++) {
        !           466:                        if (!strncmp(secth[k].s_name, s->s_name, 8)) {
        !           467:                                s->s_paddr = k; /* remember outseg number */
        !           468:                                break;
        !           469:                        }
        !           470:                }
        !           471: 
        !           472:                if ((k == osegs) && loadsw) {   /* New segment */
        !           473:                        if (++osegs == MAXSEG)
        !           474:                           fatal("Max segment limit of %s exceeded", MAXSEG);
        !           475:                        w_message("adding segment '%s'", s->s_name);
        !           476:                        memcpy(secth + k, s, sizeof(*s));
        !           477:                        s->s_paddr = k;
        !           478:                        secth[k].s_size = secth[k].s_nreloc = 0;
        !           479: 
        !           480:                        /* extra segments go to four places */
        !           481:                        switch(s->s_flags) {
        !           482:                        case STYP_TEXT:
        !           483:                                segMap[k] = S_TEXT;
        !           484:                                break;
        !           485:                        case STYP_DATA:
        !           486:                                segMap[k] = S_DATA;
        !           487:                                break;
        !           488:                        case STYP_BSS:
        !           489:                                segMap[k] = S_BSSD;
        !           490:                                break;
        !           491:                        case STYP_INFO:
        !           492:                                segMap[k] = S_COMM;
        !           493:                                break;
        !           494:                        default:
        !           495:                                segMap[k] = S_COMM;
        !           496:                                fprintf(stderr, 
        !           497:                        "warning: segment '%s' treated as comment\n",
        !           498:                                        s->s_name);
        !           499:                        }
        !           500:                }
        !           501:        }
        !           502: 
        !           503:        /* Do all symbols */
        !           504:        sym = (SYMENT *)mp->f->f_symptr;
        !           505:        endSym =  sym + mp->f->f_nsyms;
        !           506:        for (; sym < endSym; sym += sym->n_numaux + 1) {
        !           507:                if (sym->n_numaux < 0)
        !           508:                        corrupt(mp);
        !           509:                if (!sym->n_zeroes)
        !           510:                        sym->n_offset += (long)(mp->l);
        !           511:                addsym(sym, mp);
        !           512:        }
        !           513: 
        !           514:        if (loadsw) {
        !           515:                /* Add to all sections */
        !           516:                for (i = 0; i < mp->f->f_nscns; i++) {
        !           517:                        s = mp->s + i;
        !           518: 
        !           519:                        if (nosym && (STYP_INFO == s->s_flags))
        !           520:                                continue;       /* -s strips comments */
        !           521: 
        !           522:                        for (k = 0; k < osegs; k++)
        !           523:                                if (!strncmp(secth[k].s_name, s->s_name, 8))
        !           524:                                        break;
        !           525: 
        !           526:                        secth[k].s_size  += s->s_size;
        !           527:                        secth[k].s_nlnno += s->s_nlnno;
        !           528:                        if (reloc)
        !           529:                                secth[k].s_nreloc += s->s_nreloc;
        !           530:                }
        !           531:        }
        !           532: }
        !           533: 
        !           534: /*
        !           535:  * Read archive.
        !           536:  */
        !           537: archive(loadsw)
        !           538: {
        !           539:        struct old_hdr {
        !           540:                char    ar_name[DIRSIZ];        /* Member name */
        !           541:                time_t  ar_date;                /* Time inserted */
        !           542:                short   ar_gid;                 /* Group id */
        !           543:                short   ar_uid;                 /* User id */
        !           544:                short   ar_mode;                /* Mode */
        !           545:                fsize_t ar_size;                /* File size */
        !           546:        } arh;
        !           547: 
        !           548:        struct  ar_hdr in_arh;
        !           549:        fsize_t count, size, *ptrs;
        !           550:        char    magic[SARMAG], *p;
        !           551:        int     found;
        !           552:        unsigned i;
        !           553:        char    *names, *name;
        !           554: 
        !           555:        xread(magic, sizeof(magic));    /* read archive magic string */
        !           556: 
        !           557:        if (memcmp(ARMAG, magic, SARMAG))
        !           558:                fatal("'%s' is not a COFF archive", fname);
        !           559:                /* All files ending \fB.a\fR should be COFF archives. */
        !           560: 
        !           561:        xread(&in_arh, sizeof(in_arh)); /* read archive header */
        !           562: 
        !           563:        memset(&arh, '\0', sizeof(arh));
        !           564:        memcpy(arh.ar_name, in_arh.ar_name, DIRSIZ);
        !           565:        if (NULL != (p = strchr(arh.ar_name, '/')))
        !           566:                *p = '\0';
        !           567: 
        !           568:        sscanf(in_arh.ar_date, "%ld %d %d %o %ld",
        !           569:                &arh.ar_date, &arh.ar_uid,
        !           570:                &arh.ar_gid, &arh.ar_mode, &arh.ar_size);
        !           571: 
        !           572:        if (arh.ar_name[0])
        !           573:                fatal("Library must be created with ar -s option");
        !           574:                /* The \fBar \-s\fR option gives libraries a symbol table
        !           575:                 * for the use of \fBld\fR. */
        !           576: 
        !           577:        /*
        !           578:         * read random libraries symbol table.
        !           579:         */
        !           580:        xread(&count, sizeof(count));   /* read pointer count */
        !           581:        flipbytes(&count);
        !           582: 
        !           583:        /* read file pointers */
        !           584:        i = size = count * sizeof(count);
        !           585:        if (i != size)
        !           586:                fatal("archive '%s' is corrupt", fname);
        !           587:                /* This file makes no sense as a COFF archive. */
        !           588:        ptrs = alloca(i);
        !           589:        xread(ptrs, i);
        !           590: 
        !           591:        /* read symbol names corresponding to pointers */
        !           592:        i = size = arh.ar_size - size - sizeof(count);
        !           593:        if (i != size)
        !           594:                fatal("archive '%s' is corrupt", fname); /* NODOC */
        !           595:        names = alloca(i);
        !           596:        xread(names, i);
        !           597: 
        !           598:        w_message("reading archive '%s' nundef %d", fname, nundef);
        !           599: 
        !           600:        /* search symbol table unitl nothing found */
        !           601:        do {
        !           602:                for (found = i = 0, name = names;
        !           603:                     (i < count) && nundef;
        !           604:                     i++, name = strchr(name, '\0') + 1) {
        !           605:                        if(!ptrs[i] || symref(name, 0) == NULL)
        !           606:                                continue;
        !           607: 
        !           608:                        found = 1;      /* found something this pass */
        !           609:                        flipbytes(ptrs + i);
        !           610:                        lseek(ifd, ptrs[i], 0);
        !           611:                        xread(&in_arh, sizeof(in_arh));
        !           612: 
        !           613:                        sscanf(in_arh.ar_date,
        !           614:                                "%ld %d %d %o %ld",
        !           615:                                &arh.ar_date, &arh.ar_uid,
        !           616:                                &arh.ar_gid, &arh.ar_mode,
        !           617:                                &arh.ar_size);
        !           618: 
        !           619:                        in_arh.ar_date[0] = '\0';
        !           620:                        if (NULL != (p = strchr(in_arh.ar_name,'/')))
        !           621:                                *p = '\0';
        !           622: 
        !           623:                        object(in_arh.ar_name, arh.ar_size, loadsw);
        !           624: 
        !           625:                        ptrs[i] = 0;    /* don't find this again */
        !           626:                }
        !           627:        } while (found);
        !           628: }

unix.superglobalmegacorp.com

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