Annotation of 43BSDTahoe/bin/nm.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * Copyright (c) 1987 Regents of the University of California.
                      3:  * All rights reserved.  The Berkeley software License Agreement
                      4:  * specifies the terms and conditions for redistribution.
                      5:  */
                      6: 
                      7: #ifndef lint
                      8: static char sccsid[] = "@(#)nm.c 4.8 4/7/87";
                      9: #endif
                     10: 
                     11: /*
                     12:  * nm - print name list; VAX string table version
                     13:  */
                     14: 
                     15: #include <sys/types.h>
                     16: #include <sys/file.h>
                     17: #include <ar.h>
                     18: #include <stdio.h>
                     19: #include <ctype.h>
                     20: #include <a.out.h>
                     21: #include <stab.h>
                     22: #include <ranlib.h>
                     23: 
                     24: #define        OARMAG          0177545         /* OLD archive magic number */
                     25: #define        SELECT          (archive ? archdr.ar_name : *xargv)
                     26: 
                     27: #define        YES             1
                     28: #define        NO              0
                     29: 
                     30: #define        u_strx          n_un.n_strx
                     31: #define        u_name          n_un.n_name
                     32: 
                     33: typedef struct nlist   NLIST;
                     34: 
                     35: union {                                /* exec header, or magic string from library */
                     36:        char    mag_armag[SARMAG + 1];
                     37:        struct  exec mag_exp;
                     38: } mag_un;
                     39: 
                     40: struct ar_hdr  archdr;         /* archive file header structure */
                     41: FILE   *fi;                    /* input file stream */
                     42: off_t  off;                    /* offset into file */
                     43: int    aflg,                   /* print debugger symbols */
                     44:        gflg,                   /* print only global (external symbols */
                     45:        nflg,                   /* sort numerically, not alphabetically */
                     46:        oflg,                   /* prepend element name to each output line */
                     47:        pflg,                   /* don't sort */
                     48:        rflg = 1,               /* how to sort */
                     49:        uflg,                   /* print only undefined symbols */
                     50:        narg,                   /* global number of arguments */
                     51:        errs,                   /* global error flag */
                     52:        archive;                /* if file is an archive */
                     53: char   **xargv;                /* global pointer to file name */
                     54: 
                     55: main(argc, argv)
                     56:        int     argc;
                     57:        char    **argv;
                     58: {
                     59:        extern int      optind;
                     60:        int     ch;                     /* getopts char */
                     61: 
                     62:        while ((ch = getopt(argc, argv, "agnopru")) != EOF)
                     63:                switch((char)ch) {
                     64:                case 'a':
                     65:                        aflg = YES;
                     66:                        break;
                     67:                case 'g':
                     68:                        gflg = YES;
                     69:                        break;
                     70:                case 'n':
                     71:                        nflg = YES;
                     72:                        break;
                     73:                case 'o':
                     74:                        oflg = YES;
                     75:                        break;
                     76:                case 'p':
                     77:                        pflg = YES;
                     78:                        break;
                     79:                case 'r':
                     80:                        rflg = -1;
                     81:                        break;
                     82:                case 'u':
                     83:                        uflg = YES;
                     84:                        break;
                     85:                case '?':
                     86:                default:
                     87:                        fputs("usage: nm [-agnopru] [file ...]\n", stderr);
                     88:                        exit(2);
                     89:                }
                     90:        argc -= optind;
                     91:        argv += optind;
                     92:        if (!argc) {
                     93:                argc = 1;
                     94:                argv[0] = "a.out";
                     95:        }
                     96:        narg = argc;
                     97:        for (xargv = argv; argc--; ++xargv)
                     98:                if (fi = fopen(*xargv, "r")) {
                     99:                        namelist();
                    100:                        (void)fclose(fi);
                    101:                }
                    102:                else
                    103:                        error(NO, "cannot open");
                    104:        exit(errs);
                    105: }
                    106: 
                    107: namelist()
                    108: {
                    109:        register NLIST  *N, **L;
                    110:        register int    symcount, nsyms;
                    111:        static  NLIST   *symp, **list;
                    112:        static int      lastnsyms = -1,
                    113:                        laststrsiz = -1;
                    114:        static char     *strp;
                    115:        off_t   strsiz;
                    116:        long    lseek();
                    117:        int     compare();
                    118:        char    *malloc(), *realloc();
                    119: 
                    120:        /*
                    121:         * read first few bytes, determine if an archive,
                    122:         * or executable; if executable, check magic number
                    123:         */
                    124:        /*NOSTRICT*/
                    125:        if (!fread((char *)&mag_un, sizeof(mag_un), 1, fi)) {
                    126:                error(NO, "unable to read file");
                    127:                return;
                    128:        }
                    129:        if (mag_un.mag_exp.a_magic == OARMAG) {
                    130:                error(NO, "old archive");
                    131:                return;
                    132:        }
                    133:        if (bcmp(mag_un.mag_armag, ARMAG, SARMAG)) {
                    134:                if (N_BADMAG(mag_un.mag_exp)) {
                    135:                        error(NO, "bad format");
                    136:                        return;
                    137:                }
                    138:                archive = NO;
                    139:                rewind(fi);
                    140:        }
                    141:        else {
                    142:                /*
                    143:                 * if archive, skip first entry
                    144:                 * if ranlib'd, skip second entry
                    145:                 */
                    146:                off = SARMAG;           /* see nextel() */
                    147:                (void)nextel();
                    148:                if (!strcmp(RANLIBMAG, archdr.ar_name))
                    149:                        (void)nextel();
                    150:                if (narg > 1)
                    151:                        printf("\n%s:\n", *xargv);
                    152:                archive = YES;
                    153:        }
                    154: 
                    155:        do {
                    156:                /* check for bad magic number */
                    157:                /*NOSTRICT*/
                    158:                if (!fread((char *)&mag_un.mag_exp, sizeof(struct exec), 1, fi)) {
                    159:                        error(NO, "unable to read magic number");
                    160:                        return;
                    161:                }
                    162:                if (N_BADMAG(mag_un.mag_exp))
                    163:                        continue;
                    164: 
                    165:                /* calculate number of symbols in object */
                    166:                if (!(nsyms = mag_un.mag_exp.a_syms / sizeof(NLIST))) {
                    167:                        error(NO, "no name list");
                    168:                        continue;
                    169:                }
                    170: 
                    171:                /* seek to and read symbols */
                    172:                (void)fseek(fi, (long)(N_SYMOFF(mag_un.mag_exp) - sizeof(struct exec)), L_INCR);
                    173:                if (!symp || nsyms > lastnsyms) {
                    174:                        if (!symp) {
                    175:                                /*NOSTRICT*/
                    176:                                symp = (NLIST *)malloc((u_int)(nsyms * sizeof(NLIST)));
                    177:                                /*NOSTRICT*/
                    178:                                list = (NLIST **)malloc((u_int)(nsyms * sizeof(NLIST *)));
                    179:                        }
                    180:                        else {
                    181:                                /*NOSTRICT*/
                    182:                                symp = (NLIST *)realloc((char *)symp, (u_int)(nsyms * sizeof(NLIST)));
                    183:                                /*NOSTRICT*/
                    184:                                list = (NLIST **)realloc((char *)list, (u_int)(nsyms * sizeof(NLIST *)));
                    185:                        }
                    186:                        if (!symp || !list)
                    187:                                error(YES, "out of memory");
                    188:                        lastnsyms = nsyms;
                    189:                }
                    190:                /*NOSTRICT*/
                    191:                if (fread((char *)symp, sizeof(NLIST), nsyms, fi) != nsyms) {
                    192:                        error(NO, "bad symbol table");
                    193:                        continue;
                    194:                }
                    195: 
                    196:                /* read number of strings, string table */
                    197:                /*NOSTRICT*/
                    198:                if (!fread((char *)&strsiz, sizeof(strsiz), 1, fi)) {
                    199:                        error(NO, "no string table (old format .o?)");
                    200:                        continue;
                    201:                }
                    202:                if (!strp || strsiz > laststrsiz) {
                    203:                        strp = strp ? realloc(strp, (u_int)strsiz) : malloc((u_int)strsiz);
                    204:                        if (!strp)
                    205:                                error(YES, "out of memory");
                    206:                        laststrsiz = strsiz;
                    207:                }
                    208:                if (!fread(strp + sizeof(strsiz), 1, (int)(strsiz - sizeof(strsiz)), fi)) {
                    209:                        error(NO, "no string table (old format .o?)");
                    210:                        continue;
                    211:                }
                    212: 
                    213:                for (symcount = nsyms, L = list, N = symp;--nsyms >= 0;++N)
                    214:                        if (!(N->n_type & N_EXT) && gflg || N->n_type & N_STAB && (!aflg || gflg || uflg))
                    215:                                --symcount;
                    216:                        else {
                    217:                                N->u_name = N->u_strx ? strp + N->u_strx : "";
                    218:                                *L++ = N;
                    219:                        }
                    220: 
                    221:                if (!pflg)
                    222:                        qsort(list, symcount, sizeof(NLIST *), compare);
                    223: 
                    224:                if ((archive || narg > 1) && !oflg)
                    225:                        printf("\n%s:\n", SELECT);
                    226: 
                    227:                psyms(list, symcount);
                    228:        } while(archive && nextel());
                    229: }
                    230: 
                    231: psyms(list, nsyms)
                    232:        NLIST   **list;
                    233:        register int    nsyms;
                    234: {
                    235:        register NLIST  *L;
                    236:        register u_char type;
                    237:        char    *stab();
                    238: 
                    239:        while (nsyms--) {
                    240:                L = *list++;
                    241:                type = L->n_type;
                    242:                if (type & N_STAB) {
                    243:                        if (oflg) {
                    244:                                if (archive)
                    245:                                        printf("%s:", *xargv);
                    246:                                printf("%s:", SELECT);
                    247:                        }
                    248:                        printf("%08x - %02x %04x %5.5s %s\n", (int)L->n_value, L->n_other & 0xff, L->n_desc & 0xffff, stab(L->n_type), L->u_name);
                    249:                        continue;
                    250:                }
                    251:                switch (type & N_TYPE) {
                    252:                case N_UNDF:
                    253:                        type = L->n_value ? 'c' : 'u';
                    254:                        break;
                    255:                case N_ABS:
                    256:                        type = 'a';
                    257:                        break;
                    258:                case N_TEXT:
                    259:                        type = 't';
                    260:                        break;
                    261:                case N_DATA:
                    262:                        type = 'd';
                    263:                        break;
                    264:                case N_BSS:
                    265:                        type = 'b';
                    266:                        break;
                    267:                case N_FN:
                    268:                        type = 'f';
                    269:                        break;
                    270:                default:
                    271:                        type = '?';
                    272:                        break;
                    273:                }
                    274:                if (uflg && type != 'u')
                    275:                        continue;
                    276:                if (oflg) {
                    277:                        if (archive)
                    278:                                printf("%s:", *xargv);
                    279:                        printf("%s:", SELECT);
                    280:                }
                    281:                if (L->n_type & N_EXT)
                    282:                        type = toupper(type);
                    283:                if (!uflg) {
                    284:                        if (type == 'u' || type == 'U')
                    285:                                fputs("        ", stdout);
                    286:                        else
                    287:                                printf(N_FORMAT, (int)L->n_value);
                    288:                        printf(" %c ", (char)type);
                    289:                }
                    290:                puts(L->u_name);
                    291:        }
                    292: }
                    293: 
                    294: compare(p1, p2)
                    295:        NLIST   **p1, **p2;
                    296: {
                    297:        if (nflg) {
                    298:                if ((*p1)->n_value > (*p2)->n_value)
                    299:                        return(rflg);
                    300:                if ((*p1)->n_value < (*p2)->n_value)
                    301:                        return(-rflg);
                    302:        }
                    303:        return(rflg * strcmp((*p1)->u_name, (*p2)->u_name));
                    304: }
                    305: 
                    306: nextel()
                    307: {
                    308:        register char   *cp;
                    309:        long    arsize,
                    310:                lseek();
                    311: 
                    312:        (void)fseek(fi, off, L_SET);
                    313:        /*NOSTRICT*/
                    314:        if (!fread((char *)&archdr, sizeof(struct ar_hdr), 1, fi))
                    315:                return(0);
                    316:        for (cp = archdr.ar_name; cp < &archdr.ar_name[sizeof(archdr.ar_name)]; ++cp)
                    317:                if (*cp == ' ') {
                    318:                        *cp = '\0';
                    319:                        break;
                    320:                }
                    321:        arsize = atol(archdr.ar_size);
                    322:        if (arsize & 1)
                    323:                ++arsize;
                    324:        off = ftell(fi) + arsize;       /* beginning of next element */
                    325:        return(1);
                    326: }
                    327: 
                    328: struct stabnames {
                    329:        int     st_value;
                    330:        char    *st_name;
                    331: } stabnames[] ={
                    332:        N_GSYM,         "GSYM",
                    333:        N_FNAME,        "FNAME",
                    334:        N_FUN,          "FUN",
                    335:        N_STSYM,        "STSYM",
                    336:        N_LCSYM,        "LCSYM",
                    337:        N_RSYM,         "RSYM",
                    338:        N_SLINE,        "SLINE",
                    339:        N_SSYM,         "SSYM",
                    340:        N_SO,           "SO",
                    341:        N_LSYM,         "LSYM",
                    342:        N_SOL,          "SOL",
                    343:        N_PSYM,         "PSYM",
                    344:        N_ENTRY,        "ENTRY",
                    345:        N_LBRAC,        "LBRAC",
                    346:        N_RBRAC,        "RBRAC",
                    347:        N_BCOMM,        "BCOMM",
                    348:        N_ECOMM,        "ECOMM",
                    349:        N_ECOML,        "ECOML",
                    350:        N_LENG,         "LENG",
                    351:        N_PC,           "PC",
                    352:        0,              0
                    353: };
                    354: 
                    355: char *
                    356: stab(val)
                    357:        register u_char val;
                    358: {
                    359:        register struct stabnames       *sp;
                    360:        static char     prbuf[5];
                    361: 
                    362:        for (sp = stabnames; sp->st_value; ++sp)
                    363:                if (sp->st_value == val)
                    364:                        return(sp->st_name);
                    365:        (void)sprintf(prbuf, "%02x", (int)val);
                    366:        return(prbuf);
                    367: }
                    368: 
                    369: error(doexit, msg)
                    370:        int     doexit;
                    371:        char    *msg;
                    372: {
                    373:        fprintf(stderr, "nm: %s:", *xargv);
                    374:        if (archive)
                    375:                fprintf(stderr, "(%s): %s\n", archdr.ar_name, msg);
                    376:        else
                    377:                fprintf(stderr, " %s\n", msg);
                    378:        if (doexit)
                    379:                exit(2);
                    380:        errs = 1;
                    381: }

unix.superglobalmegacorp.com

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