Annotation of coherent/b/bin/nm.c, revision 1.1.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.