Annotation of 43BSDTahoe/bin/nm.c, revision 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.