Annotation of coherent/d/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:  * 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.