Annotation of coherent/b/bin/nm.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * List a coff symbol table.
        !             3:  */
        !             4: #include <misc.h>
        !             5: #include <canon.h>
        !             6: #include <l.out.h>
        !             7: #include <ar.h>
        !             8: #include <errno.h>
        !             9: 
        !            10: FILE *fd;      /* Current input file */
        !            11: 
        !            12: int asw;       /* list all symbols */
        !            13: int dsw;       /* list only defined symbols */
        !            14: int gsw;       /* print only global symbols */
        !            15: int nsw;       /* list numerically not alphabetically */
        !            16: int osw;       /* append file name to each line */
        !            17: int psw;       /* print symbols in symbol table order */
        !            18: int rsw;       /* print in reverse alpha order */
        !            19: int usw;       /* print only undefined symbols */
        !            20: int vsw;       /* print coff type symbols */
        !            21: 
        !            22: int namesw;    /* one if header is required */
        !            23: char *str_tab;
        !            24: char *fname;
        !            25: 
        !            26: /*
        !            27:  * read or have an error.
        !            28:  */
        !            29: static void
        !            30: xread(to, size, msg)
        !            31: char *to;
        !            32: unsigned size;
        !            33: char *msg;
        !            34: {
        !            35:        if (1 != fread(to, size, 1, fd))
        !            36:                fatal("Error reading %s - %s", fname, msg);
        !            37: }
        !            38: 
        !            39: /*
        !            40:  * Old form sort logic.
        !            41:  */
        !            42: ncomp_old(s1, s2)
        !            43: struct nlist *s1, *s2;
        !            44: {
        !            45:        long i;
        !            46: 
        !            47:        if (!(i = (s1->n_value - s2->n_value)))
        !            48:                return (0);
        !            49:        if (i < 0)
        !            50:                return (-1);
        !            51:        return (1);
        !            52: }
        !            53: 
        !            54: acomp_old(s1, s2)
        !            55: struct nlist *s1, *s2;
        !            56: {
        !            57:        return(strncmp(s1->n_name, s2->n_name, NCPLN));
        !            58: }
        !            59: 
        !            60: rcomp_old(s1, s2)
        !            61: struct nlist *s1, *s2;
        !            62: {
        !            63:        return(strncmp(s2->n_name, s1->n_name, NCPLN));
        !            64: }
        !            65: 
        !            66: /*
        !            67:  * Process old ar files.
        !            68:  */
        !            69: old_ar(filen, at)
        !            70: char *filen;
        !            71: long at;
        !            72: {
        !            73:        long arhend;
        !            74:        struct old_ar_hdr arh;
        !            75: 
        !            76:        namesw = 0;
        !            77:        for (arhend = at + sizeof(short); ; ) {
        !            78:                fseek(fd, arhend, 0);
        !            79:                if (1 != fread(&arh, sizeof(arh), 1, fd))
        !            80:                        break;
        !            81:                arhend += sizeof(arh);
        !            82:                arh.ar_date = 0;        /* terminate name */
        !            83:                cansize(arh.ar_size);
        !            84:                if (strcmp(arh.ar_name, HDRNAME)) {
        !            85:                        printf("%s(%s)\n", filen, arh.ar_name);
        !            86:                        readHeaders(arhend, arh.ar_size);
        !            87:                }
        !            88:                arhend += arh.ar_size;
        !            89:        }
        !            90:        namesw = 1;
        !            91: }
        !            92: 
        !            93: /*
        !            94:  * Process old form stuff.
        !            95:  */
        !            96: old_nout(at)
        !            97: long at;
        !            98: {
        !            99:        struct ldheader ldh;
        !           100:        struct ldsym *sym, *s;
        !           101:        register unsigned i, syms, ct;
        !           102:        long toSym;
        !           103:        short type;
        !           104:        extern char *realloc();
        !           105: 
        !           106:        fseek(fd, at, 0);
        !           107:        xread(&ldh, sizeof(ldh), "n.out header");
        !           108:        if (!ldh.l_ssize[L_SYM]) {
        !           109:                printf("No symbols in %s\n", fname);
        !           110:                return;
        !           111:        }
        !           112: 
        !           113:        if (namesw)
        !           114:                printf("%s:\n", fname);
        !           115: 
        !           116:        canshort(ldh.l_machine);
        !           117:        toSym = ldh.l_entry + sizeof(ldh);
        !           118: 
        !           119:        for (i = 0; i < L_SYM; i++) {
        !           120:                cansize(ldh.l_ssize[i]);
        !           121:                if (i != L_BSSI && i != L_BSSD)
        !           122:                        toSym += ldh.l_ssize[i];
        !           123:        }
        !           124: 
        !           125:        fseek(fd, at + toSym, 0);
        !           126:        cansize(ldh.l_ssize[L_SYM]);
        !           127:        i = ldh.l_ssize[L_SYM];
        !           128:        if (i != ldh.l_ssize[L_SYM])
        !           129:                fatal("Out of space");
        !           130:        sym = alloc(i);
        !           131:        xread(sym, i, "symbol table");
        !           132:        ct = i / sizeof(*sym);
        !           133: 
        !           134:        /* squeeze out unneeded stuff before sort */
        !           135:        for (i = syms = 0; i < ct; i++) {
        !           136:                canshort(sym[i].ls_type);
        !           137:                canshort(sym[i].ls_addr);
        !           138:                type = sym[i].ls_type;
        !           139:                if (gsw && !(type & L_GLOBAL))
        !           140:                        continue;
        !           141:                if ((type & ~L_GLOBAL) == L_REF) {      /* a reference */
        !           142:                        if (dsw)        /* list only defined */
        !           143:                                continue;
        !           144:                        if (usw && sym[i].ls_addr)
        !           145:                                continue;
        !           146:                }
        !           147:                else if (usw)
        !           148:                        continue;
        !           149:                if (!asw && !csymbol(sym + i))
        !           150:                        continue;
        !           151:                if (i != syms)
        !           152:                        sym[syms] = sym[i];
        !           153:                syms++;
        !           154:        }
        !           155:        sym = realloc(sym, syms * sizeof(*sym));
        !           156: 
        !           157:        if (nsw)
        !           158:                qsort(sym, syms, sizeof(*sym), ncomp_old);
        !           159:        else if (rsw)
        !           160:                qsort(sym, syms, sizeof(*sym), rcomp_old);
        !           161:        else if (!psw)
        !           162:                qsort(sym, syms, sizeof(*sym), acomp_old);
        !           163: 
        !           164:        for (s = sym; s < (sym + syms); s++) {
        !           165:                static char *gn[] = {
        !           166:                        "SI", "PI", "BI",
        !           167:                        "SD", "PD", "BD",
        !           168:                        " D", "  ", "  ",
        !           169:                        " A", " C", "??"
        !           170:                };
        !           171:                static char *ln[] = {
        !           172:                        "si", "pi", "bi",
        !           173:                        "sd", "pd", "bd",
        !           174:                        " d", "  ", "  ",
        !           175:                        " a", " c", "??"
        !           176:                };
        !           177:                if (osw)
        !           178:                        printf("%s ", fname);
        !           179:                i = s->ls_type & L_GLOBAL;
        !           180:                type = s->ls_type & ~ L_GLOBAL;
        !           181:                if (type < L_SHRI || type > L_REF)
        !           182:                        type = L_REF + 1;
        !           183:                if (type == L_REF && !s->ls_addr)
        !           184:                        printf("      %c", i ? 'U' : 'u');
        !           185:                else
        !           186:                        printf("%04x %s",
        !           187:                                s->ls_addr,
        !           188:                                i ? gn[type] : ln[type]);
        !           189:                printf(" %.*s\n", NCPLN, s->ls_id);
        !           190:        }
        !           191: 
        !           192:        free(sym);
        !           193: }
        !           194: 
        !           195: /*
        !           196:  * This routine gets called if we
        !           197:  * are not in '-a' mode. It determines if
        !           198:  * the symbol pointed to by 'sp' is a C
        !           199:  * style symbol (trailing '_' or longer than
        !           200:  * (NCPLN-1) characters). If it is it eats the '_'
        !           201:  * and returns true.
        !           202:  */
        !           203: csymbol(sp)
        !           204: register struct ldsym *sp;
        !           205: {
        !           206:        register char *cp1, *cp2;
        !           207: 
        !           208:        cp1 = &sp->ls_id[0];
        !           209:        cp2 = &sp->ls_id[NCPLN];
        !           210:        while (cp2!=cp1 && *--cp2==0)
        !           211:                ;
        !           212:        if (*cp2 != 0) {
        !           213:                if (*cp2 == '_') {
        !           214:                        *cp2 = 0;
        !           215:                        return (1);
        !           216:                }
        !           217:                if (cp2-cp1 >= (NCPLN-1))
        !           218:                        return (1);
        !           219:        }
        !           220:        return (0);
        !           221: }
        !           222: 
        !           223: /*
        !           224:  * Note some #defines in these include files interferes with
        !           225:  * items in preceeding include files. Hence the strange
        !           226:  * program order.
        !           227:  */
        !           228: #include <coff.h>
        !           229: #include <arcoff.h>
        !           230: 
        !           231: #define cx(x) case C_ ## x: printf("%6.6s ", #x); break
        !           232: #define ct(x) case T_ ## x: printf("%6.6s ", #x); break
        !           233: 
        !           234: static char helpmsg[] =
        !           235:        "-d list only defined symbols\n"
        !           236:        "-g print only global symbols\n"
        !           237:        "-n list numerically not alphabetically\n"
        !           238:        "-o append file name to each line\n"
        !           239:        "-p print symbols in symbol table order\n"
        !           240:        "-r print in reverse alpha order\n"
        !           241:        "-u print only undefined symbols\n"
        !           242:        "-v print coff type symbols\n";
        !           243: 
        !           244: FILEHDR fh;
        !           245: SCNHDR *scns;
        !           246: 
        !           247: /*
        !           248:  * Symbol name.
        !           249:  */
        !           250: static char *
        !           251: symName(sym, work)
        !           252: SYMENT *sym;
        !           253: char *work;
        !           254: {
        !           255:        if (!sym->n_zeroes)
        !           256:                return (str_tab + sym->n_offset - 4);
        !           257: 
        !           258:        /* make sure it's zero terminated */
        !           259:        memcpy(work, sym->n_name, SYMNMLEN);
        !           260:        work[SYMNMLEN] = '\0';
        !           261:        return (work);
        !           262: }
        !           263: 
        !           264: main(argc, argv)
        !           265: char *argv[];
        !           266: {
        !           267:        char c;
        !           268:        extern int optind;
        !           269:        extern char *optarg;
        !           270: 
        !           271:        while (EOF != (c = getopt(argc, argv, "adgnopruv?"))) {
        !           272:                switch (c) {
        !           273:                case '?':
        !           274:                        printf(helpmsg);
        !           275:                        break;
        !           276:                case 'a':
        !           277:                        asw = 1;
        !           278:                        break;
        !           279:                case 'd':
        !           280:                        dsw = 1;
        !           281:                        break;
        !           282:                case 'g':
        !           283:                        gsw = 1;
        !           284:                        break;
        !           285:                case 'n':
        !           286:                        nsw = 1;
        !           287:                        break;
        !           288:                case 'o':
        !           289:                        osw = 1;
        !           290:                        break;
        !           291:                case 'p':
        !           292:                        psw = 1;
        !           293:                        break;
        !           294:                case 'r':
        !           295:                        rsw = 1;
        !           296:                        break;
        !           297:                case 'u':
        !           298:                        usw = 1;
        !           299:                        break;
        !           300:                case 'v':
        !           301:                        vsw = 1;
        !           302:                        break;
        !           303:                default:
        !           304:                        printf("usage: nm [-dgnopruv?] file ...\n");
        !           305:                        exit(1);
        !           306:                }
        !           307:        }
        !           308: 
        !           309:        if ((psw + rsw + nsw) > 1)
        !           310:                fatal("More than one sort order");
        !           311: 
        !           312:        namesw = (argc - optind) > 1;
        !           313:        for (; optind < argc; optind++) {
        !           314:                fd = xopen(fname = argv[optind], "rb");
        !           315: 
        !           316:                printf("%s\n", fname);
        !           317:                readHeaders(0L, 0L);
        !           318:                fclose(fd);
        !           319:        }
        !           320: 
        !           321:        exit (0);
        !           322: }
        !           323: 
        !           324: static
        !           325: readHeaders(at, size)
        !           326: long at, size;
        !           327: {
        !           328:        unsigned i;
        !           329: 
        !           330:        if (1 != fread(&fh, sizeof(fh), 1, fd)) {
        !           331:                if (ferror(fd))
        !           332:                        fatal("Error reading %s", fname);
        !           333:                printf("Inappropriate filetype %s\n", fname);
        !           334:                return (0);
        !           335:        }
        !           336:        if (C_386_MAGIC != fh.f_magic) {
        !           337:                if (!memcmp(ARMAG, &fh, SARMAG))
        !           338:                        return(archive(at));
        !           339: 
        !           340:                canshort(fh.f_magic);
        !           341:                if (fh.f_magic == OLD_ARMAG)
        !           342:                        return (old_ar(fname, at));
        !           343:                if (fh.f_magic == L_MAGIC)
        !           344:                        return (old_nout(at));
        !           345:                printf("Inappropriate filetype %s\n", fname);
        !           346:                return (0);
        !           347:        }
        !           348:        if (fh.f_opthdr)        /* pass opt hdr */
        !           349:                fseek(fd, at + sizeof(fh) + fh.f_opthdr, 0);
        !           350:        scns = alloc(i = (fh.f_nscns * sizeof(SCNHDR)));
        !           351:        xread(scns, i, "section headers");
        !           352: 
        !           353:        if (fh.f_nsyms)
        !           354:                readSymbols(at, size);
        !           355:        else
        !           356:                printf("No symbols in %s\n", fname);
        !           357: 
        !           358: }
        !           359: 
        !           360: /*
        !           361:  * Sort by alpha.
        !           362:  */
        !           363: acomp(s1, s2)
        !           364: SYMENT *s1, *s2;
        !           365: {
        !           366:        char w1[SYMNMLEN + 1], w2[SYMNMLEN + 1];
        !           367: 
        !           368:        return (strcmp(symName(s1, w1), symName(s2, w2)));
        !           369: }
        !           370: 
        !           371: /*
        !           372:  * Sort by reverse alpha.
        !           373:  */
        !           374: rcomp(s1, s2)
        !           375: SYMENT *s1, *s2;
        !           376: {
        !           377:        char w1[SYMNMLEN + 1], w2[SYMNMLEN + 1];
        !           378: 
        !           379:        return (- strcmp(symName(s1, w1), symName(s2, w2)));
        !           380: }
        !           381: 
        !           382: /*
        !           383:  * Sort by value;
        !           384:  */
        !           385: ncomp(s1, s2)
        !           386: SYMENT *s1, *s2;
        !           387: {
        !           388:        long i;
        !           389: 
        !           390:        if (!(i = (s1->n_value - s2->n_value)))
        !           391:                return (0);
        !           392:        if (i < 0)
        !           393:                return (-1);
        !           394:        return (1);
        !           395: }
        !           396: 
        !           397: static
        !           398: readSymbols(at, size)
        !           399: long at;
        !           400: {
        !           401:        register SYMENT *s;
        !           402:        SYMENT *sym;
        !           403:        long str_len;
        !           404:        unsigned len;
        !           405:        int i, aux, syms;
        !           406:        extern char *realloc();
        !           407: 
        !           408:        /* read whole symbol table */
        !           409:        fseek(fd, at + fh.f_symptr, 0);
        !           410:        len = str_len = SYMESZ * fh.f_nsyms;
        !           411:        if (str_len != len)
        !           412:                fatal("Cannot process small model");
        !           413:        sym = alloc(len);
        !           414:        xread(sym, len, "symbol table");
        !           415: 
        !           416:        /* squeeze out unneeded stuff before sort */
        !           417:        for (i = aux = syms = 0; i < fh.f_nsyms; i++) {
        !           418:                if (aux) {
        !           419:                        aux--;
        !           420:                        continue;
        !           421:                }
        !           422:                s = sym + i;
        !           423:                aux = s->n_numaux;
        !           424:                switch (s->n_sclass) {
        !           425:                case C_EXT:
        !           426:                        if (s->n_scnum || s->n_value) { /* defined */
        !           427:                                if (usw)        /* print only undefined */
        !           428:                                        continue;
        !           429:                        } else {                        /* undefined */
        !           430:                                if (dsw)        /* print only defined */
        !           431:                                        continue;
        !           432:                        }
        !           433:                        break;
        !           434:                case C_EXTDEF:
        !           435:                        if (dsw)
        !           436:                                continue;
        !           437:                        break;
        !           438:                case C_STAT:
        !           439:                        if (gsw || usw)
        !           440:                                continue;
        !           441:                        switch (s->n_scnum) {
        !           442:                        case 1:
        !           443:                                if (!strcmp(s->n_name, ".text"))
        !           444:                                        continue;
        !           445:                                break;
        !           446:                        case 2:
        !           447:                                if (!strcmp(s->n_name, ".data"))
        !           448:                                        continue;
        !           449:                                break;
        !           450:                        case 3:
        !           451:                                if (!strcmp(s->n_name, ".bss"))
        !           452:                                        continue;
        !           453:                                break;
        !           454:                        }
        !           455:                        break;
        !           456:                default:
        !           457:                        if (!vsw)
        !           458:                                continue;
        !           459:                }
        !           460:                if (i != syms)
        !           461:                        sym[syms] = *s;
        !           462:                syms++;
        !           463:        }
        !           464:        sym = realloc(sym, syms * SYMESZ);
        !           465: 
        !           466:        str_len = 0;
        !           467:        if (!size || ((fh.f_symptr + len + sizeof(long)) < size))
        !           468:                if (1 != fread(&str_len, sizeof(str_len), 1, fd))
        !           469:                        str_len = 0;
        !           470:        if (str_len) {
        !           471:                len = str_len -= 4;
        !           472:                if (len != str_len)
        !           473:                        fatal("Cannot process small model");
        !           474:                str_tab = alloc(len);
        !           475:                xread(str_tab, len, "string table");
        !           476:        }
        !           477: 
        !           478:        if (nsw)
        !           479:                qsort(sym, syms, SYMESZ, ncomp);
        !           480:        else if (rsw)
        !           481:                qsort(sym, syms, SYMESZ, rcomp);
        !           482:        else if (!psw)
        !           483:                qsort(sym, syms, SYMESZ, acomp);
        !           484: 
        !           485:        for (s = sym; s < (sym + syms); s++) {
        !           486:                char w1[SYMNMLEN + 1], *n;
        !           487: 
        !           488:                i = strlen(n = symName(s, w1));
        !           489: 
        !           490:                if (osw)
        !           491:                        printf("%s ", fname);
        !           492: 
        !           493:                /* display section name */
        !           494:                switch (s->n_scnum) {
        !           495:                case N_DEBUG:
        !           496:                        printf("DEBUG    ");
        !           497:                        break;
        !           498:                case N_ABS:
        !           499:                        printf("ABSOLUTE ");
        !           500:                        break;
        !           501:                case N_TV:
        !           502:                        printf("TV       ");
        !           503:                        break;          
        !           504:                case N_UNDEF:
        !           505:                        if (s->n_value)
        !           506:                                printf(".comm    ");
        !           507:                        else
        !           508:                                printf("UNDEF    ");
        !           509:                        break;
        !           510:                default:
        !           511:                        printf("%-8.8s ", scns[s->n_scnum - 1].s_name);
        !           512:                }
        !           513: 
        !           514:                if (vsw) {      /* print coff type data */
        !           515:                        /* display storage class */
        !           516:                        switch (s->n_sclass) {
        !           517:                        cx(EFCN);
        !           518:                        cx(NULL);
        !           519:                        cx(AUTO);
        !           520:                        cx(EXT);
        !           521:                        cx(STAT);
        !           522:                        cx(REG);
        !           523:                        cx(EXTDEF);
        !           524:                        cx(LABEL);
        !           525:                        cx(ULABEL);
        !           526:                        cx(MOS);
        !           527:                        cx(ARG);
        !           528:                        cx(STRTAG);
        !           529:                        cx(MOU);
        !           530:                        cx(UNTAG);
        !           531:                        cx(TPDEF);
        !           532:                        cx(USTATIC);
        !           533:                        cx(ENTAG);
        !           534:                        cx(MOE);
        !           535:                        cx(REGPARM);
        !           536:                        cx(FIELD);
        !           537:                        cx(BLOCK);
        !           538:                        cx(FCN);
        !           539:                        cx(EOS);
        !           540:                        cx(FILE);
        !           541:                        default:
        !           542:                                printf("unknown ");
        !           543:                        }
        !           544: 
        !           545:                        if (s->n_type & N_TMASK) {
        !           546:                                if (ISPTR(s->n_type))
        !           547:                                        printf("pointer ");
        !           548:                                else if (ISFCN(s->n_type))
        !           549:                                        printf("function ");
        !           550:                                else if (ISARY(s->n_type))
        !           551:                                        printf("array ");
        !           552:                                else if (ISTAG(s->n_type))
        !           553:                                        printf("struct ");
        !           554:                                else if (INCREF(s->n_type))
        !           555:                                        printf("union  ");
        !           556:                                else if (DECREF(s->n_type))
        !           557:                                        printf("enum ");
        !           558:                        }
        !           559:                        else
        !           560:                                printf("- ");
        !           561:        
        !           562:                        /* display type */
        !           563:                        switch (BTYPE(s->n_type)) {
        !           564:                        ct(NULL);
        !           565:                        ct(ARG);
        !           566:                        ct(CHAR);
        !           567:                        ct(SHORT);
        !           568:                        ct(INT);
        !           569:                        ct(LONG);
        !           570:                        ct(FLOAT);
        !           571:                        ct(DOUBLE);
        !           572:                        ct(STRUCT);
        !           573:                        ct(UNION);
        !           574:                        ct(ENUM);
        !           575:                        ct(MOE);
        !           576:                        ct(UCHAR);
        !           577:                        ct(USHORT);
        !           578:                        ct(UINT);
        !           579:                        ct(ULONG);
        !           580:                        default:
        !           581:                                printf("unknown ");
        !           582:                        }
        !           583:                }
        !           584: 
        !           585:                printf("%08lX %s\n", s->n_value, n);
        !           586:        }
        !           587:        free(sym);
        !           588: }
        !           589: 
        !           590: /*
        !           591:  * Print members of archive.
        !           592:  */
        !           593: archive(at)
        !           594: long at;
        !           595: {
        !           596:        long arhend;
        !           597:        struct ar_hdr coff_arh;
        !           598:        struct old_ar_hdr arh;
        !           599:        char *p;
        !           600:        extern char *strchr();
        !           601: 
        !           602:        namesw = 0;
        !           603:        for (arhend = at + SARMAG; ; ) {
        !           604:                fseek(fd, arhend, 0);
        !           605:                if (1 != fread(&coff_arh, sizeof(coff_arh), 1, fd))
        !           606:                        break;
        !           607:                memset(&arh, '\0', sizeof(arh));
        !           608:                memcpy(arh.ar_name, coff_arh.ar_name, DIRSIZ);
        !           609:                if (NULL != (p = strchr(arh.ar_name, '/')))
        !           610:                        *p = '\0';
        !           611: 
        !           612:                sscanf(coff_arh.ar_date, "%ld %d %d %o %ld",
        !           613:                        &arh.ar_date, &arh.ar_uid,
        !           614:                        &arh.ar_gid, &arh.ar_mode, &arh.ar_size);
        !           615: 
        !           616:                arhend += sizeof(coff_arh);
        !           617:                if (arh.ar_name[0]) {
        !           618:                        printf("%s(%s)\n", fname, arh.ar_name);
        !           619:                        readHeaders(arhend, arh.ar_size);
        !           620:                }
        !           621:                arhend += arh.ar_size;
        !           622:                if (arhend & 1)
        !           623:                        arhend++;               
        !           624:        }
        !           625:        namesw = 1;
        !           626: }

unix.superglobalmegacorp.com

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