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

unix.superglobalmegacorp.com

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