1: #ifndef lint
   2: static  char sccsid[] = "@(#)nm.c 4.7 5/19/86";
   3: #endif
   4: /*
   5:  * nm - print name list; VAX string table version
   6:  */
   7: #include <sys/types.h>
   8: #include <ar.h>
   9: #include <stdio.h>
  10: #include <ctype.h>
  11: #include <a.out.h>
  12: #include <stab.h>
  13: #include <sys/stat.h>
  14: 
  15: #define SELECT  archive ? archdr.ar_name : *xargv
  16: 
  17: int aflg, gflg, nflg, oflg, pflg, uflg;
  18: int rflg = 1;
  19: char    **xargv;
  20: int archive;
  21: struct  ar_hdr  archdr;
  22: union {
  23:     char    mag_armag[SARMAG+1];
  24:     struct  exec mag_exp;
  25: } mag_un;
  26: #define OARMAG  0177545
  27: FILE    *fi;
  28: off_t   off;
  29: off_t   ftell();
  30: char    *malloc();
  31: char    *realloc();
  32: char    *strp;
  33: char    *stab();
  34: off_t   strsiz;
  35: int compare();
  36: int narg;
  37: int errs;
  38: 
  39: main(argc, argv)
  40: char **argv;
  41: {
  42: 
  43:     if (--argc>0 && argv[1][0]=='-' && argv[1][1]!=0) {
  44:         argv++;
  45:         while (*++*argv) switch (**argv) {
  46: 
  47:         case 'n':
  48:             nflg++;
  49:             continue;
  50:         case 'g':
  51:             gflg++;
  52:             continue;
  53:         case 'u':
  54:             uflg++;
  55:             continue;
  56:         case 'r':
  57:             rflg = -1;
  58:             continue;
  59:         case 'p':
  60:             pflg++;
  61:             continue;
  62:         case 'o':
  63:             oflg++;
  64:             continue;
  65:         case 'a':
  66:             aflg++;
  67:             continue;
  68:         default:
  69:             fprintf(stderr, "nm: invalid argument -%c\n",
  70:                 *argv[0]);
  71:             exit(2);
  72:         }
  73:         argc--;
  74:     }
  75:     if (argc == 0) {
  76:         argc = 1;
  77:         argv[1] = "a.out";
  78:     }
  79:     narg = argc;
  80:     xargv = argv;
  81:     while (argc--) {
  82:         ++xargv;
  83:         namelist();
  84:     }
  85:     exit(errs);
  86: }
  87: 
  88: namelist()
  89: {
  90:     register int j;
  91: 
  92:     archive = 0;
  93:     fi = fopen(*xargv, "r");
  94:     if (fi == NULL) {
  95:         error(0, "cannot open");
  96:         return;
  97:     }
  98:     off = SARMAG;
  99:     fread((char *)&mag_un, 1, sizeof(mag_un), fi);
 100:     if (mag_un.mag_exp.a_magic == OARMAG) {
 101:         error(0, "old archive");
 102:         goto out;
 103:     }
 104:     if (strncmp(mag_un.mag_armag, ARMAG, SARMAG)==0)
 105:         archive++;
 106:     else if (N_BADMAG(mag_un.mag_exp)) {
 107:         error(0, "bad format");
 108:         goto out;
 109:     }
 110:     fseek(fi, 0L, 0);
 111:     if (archive) {
 112:         nextel(fi);
 113:         if (narg > 1)
 114:             printf("\n%s:\n", *xargv);
 115:     }
 116:     do {
 117:         off_t o;
 118:         register i, n, c;
 119:         struct nlist *symp = NULL;
 120:         struct nlist sym;
 121:         struct stat stb;
 122: 
 123:         fread((char *)&mag_un.mag_exp, 1, sizeof(struct exec), fi);
 124:         if (N_BADMAG(mag_un.mag_exp))
 125:             continue;
 126:         if (archive == 0)
 127:             fstat(fileno(fi), &stb);
 128:         o = N_SYMOFF(mag_un.mag_exp) - sizeof (struct exec);
 129:         fseek(fi, o, 1);
 130:         n = mag_un.mag_exp.a_syms / sizeof(struct nlist);
 131:         if (n == 0) {
 132:             error(0, "no name list");
 133:             continue;
 134:         }
 135:         if (N_STROFF(mag_un.mag_exp) + sizeof (off_t) >
 136:             (archive ? off : stb.st_size)) {
 137:             error(0, "old format .o (no string table) or truncated file");
 138:             continue;
 139:         }
 140:         i = 0;
 141:         if (strp)
 142:             free(strp), strp = 0;
 143:         while (--n >= 0) {
 144:             fread((char *)&sym, 1, sizeof(sym), fi);
 145:             if (gflg && (sym.n_type&N_EXT)==0)
 146:                 continue;
 147:             if ((sym.n_type&N_STAB) && (!aflg||gflg||uflg))
 148:                 continue;
 149:             if (symp==NULL)
 150:                 symp = (struct nlist *)
 151:                     malloc(sizeof(struct nlist));
 152:             else
 153:                 symp = (struct nlist *)
 154:                     realloc(symp,
 155:                     (i+1)*sizeof(struct nlist));
 156:             if (symp == NULL)
 157:                 error(1, "out of memory");
 158:             symp[i++] = sym;
 159:         }
 160:         if (archive && ftell(fi)+sizeof(off_t) >= off) {
 161:             error(0, "no string table (old format .o?)");
 162:             continue;
 163:         }
 164:         if (fread((char *)&strsiz,sizeof(strsiz),1,fi) != 1) {
 165:             error(0, "no string table (old format .o?)");
 166:             goto out;
 167:         }
 168:         strp = (char *)malloc(strsiz);
 169:         if (strp == NULL)
 170:             error(1, "ran out of memory");
 171:         if (fread(strp+sizeof(strsiz),strsiz-sizeof(strsiz),1,fi) != 1)
 172:             error(1, "error reading string table");
 173:         for (j = 0; j < i; j++)
 174:             if (symp[j].n_un.n_strx)
 175:                 symp[j].n_un.n_name =
 176:                     symp[j].n_un.n_strx + strp;
 177:             else
 178:                 symp[j].n_un.n_name = "";
 179:         if (pflg==0)
 180:             qsort(symp, i, sizeof(struct nlist), compare);
 181:         if ((archive || narg>1) && oflg==0)
 182:             printf("\n%s:\n", SELECT);
 183:         psyms(symp, i);
 184:         if (symp)
 185:             free((char *)symp), symp = 0;
 186:         if (strp)
 187:             free((char *)strp), strp = 0;
 188:     } while(archive && nextel(fi));
 189: out:
 190:     fclose(fi);
 191: }
 192: 
 193: psyms(symp, nsyms)
 194:     register struct nlist *symp;
 195:     int nsyms;
 196: {
 197:     register int n, c;
 198: 
 199:     for (n=0; n<nsyms; n++) {
 200:         c = symp[n].n_type;
 201:         if (c & N_STAB) {
 202:             if (oflg) {
 203:                 if (archive)
 204:                     printf("%s:", *xargv);
 205:                 printf("%s:", SELECT);
 206:             }
 207:             printf("%08x - %02x %04x %5.5s %s\n",
 208:                 symp[n].n_value,
 209:                 symp[n].n_other & 0xff, symp[n].n_desc & 0xffff,
 210:                 stab(symp[n].n_type & 0xff),
 211:                 symp[n].n_un.n_name);
 212:             continue;
 213:         }
 214:         if (c == N_FN)
 215:             c = 'f';
 216:         else switch (c&N_TYPE) {
 217: 
 218:         case N_UNDF:
 219:             c = 'u';
 220:             if (symp[n].n_value)
 221:                 c = 'c';
 222:             break;
 223:         case N_ABS:
 224:             c = 'a';
 225:             break;
 226:         case N_TEXT:
 227:             c = 't';
 228:             break;
 229:         case N_DATA:
 230:             c = 'd';
 231:             break;
 232:         case N_BSS:
 233:             c = 'b';
 234:             break;
 235:         default:
 236:             c = '?';
 237:             break;
 238:         }
 239:         if (uflg && c!='u')
 240:             continue;
 241:         if (oflg) {
 242:             if (archive)
 243:                 printf("%s:", *xargv);
 244:             printf("%s:", SELECT);
 245:         }
 246:         if (symp[n].n_type&N_EXT)
 247:             c = toupper(c);
 248:         if (!uflg) {
 249:             if (c=='u' || c=='U')
 250:                 printf("        ");
 251:             else
 252:                 printf(N_FORMAT, symp[n].n_value);
 253:             printf(" %c ", c);
 254:         }
 255:         printf("%s\n", symp[n].n_un.n_name);
 256: l1:     ;
 257:     }
 258: }
 259: 
 260: compare(p1, p2)
 261: struct nlist *p1, *p2;
 262: {
 263:     register i;
 264: 
 265:     if (nflg) {
 266:         if (p1->n_value > p2->n_value)
 267:             return(rflg);
 268:         if (p1->n_value < p2->n_value)
 269:             return(-rflg);
 270:     }
 271:     return (rflg * strcmp(p1->n_un.n_name, p2->n_un.n_name));
 272: }
 273: 
 274: nextel(af)
 275: FILE *af;
 276: {
 277:     register char *cp;
 278:     register r;
 279:     long arsize;
 280: 
 281:     fseek(af, off, 0);
 282:     r = fread((char *)&archdr, 1, sizeof(struct ar_hdr), af);
 283:     if (r != sizeof(struct ar_hdr))
 284:         return(0);
 285:     for (cp = archdr.ar_name; cp < &archdr.ar_name[sizeof(archdr.ar_name)]; cp++)
 286:         if (*cp == ' ')
 287:             *cp = '\0';
 288:     arsize = atol(archdr.ar_size);
 289:     if (arsize & 1)
 290:         ++arsize;
 291:     off = ftell(af) + arsize;   /* beginning of next element */
 292:     return(1);
 293: }
 294: 
 295: error(n, s)
 296: char *s;
 297: {
 298:     fprintf(stderr, "nm: %s:", *xargv);
 299:     if (archive) {
 300:         fprintf(stderr, "(%s)", archdr.ar_name);
 301:         fprintf(stderr, ": ");
 302:     } else
 303:         fprintf(stderr, " ");
 304:     fprintf(stderr, "%s\n", s);
 305:     if (n)
 306:         exit(2);
 307:     errs = 1;
 308: }
 309: 
 310: struct  stabnames {
 311:     int st_value;
 312:     char    *st_name;
 313: } stabnames[] ={
 314:     N_GSYM, "GSYM",
 315:     N_FNAME, "FNAME",
 316:     N_FUN, "FUN",
 317:     N_STSYM, "STSYM",
 318:     N_LCSYM, "LCSYM",
 319:     N_RSYM, "RSYM",
 320:     N_SLINE, "SLINE",
 321:     N_SSYM, "SSYM",
 322:     N_SO, "SO",
 323:     N_LSYM, "LSYM",
 324:     N_SOL, "SOL",
 325:     N_PSYM, "PSYM",
 326:     N_ENTRY, "ENTRY",
 327:     N_LBRAC, "LBRAC",
 328:     N_RBRAC, "RBRAC",
 329:     N_BCOMM, "BCOMM",
 330:     N_ECOMM, "ECOMM",
 331:     N_ECOML, "ECOML",
 332:     N_LENG, "LENG",
 333:     N_PC, "PC",
 334:     0, 0
 335: };
 336: 
 337: char *
 338: stab(val)
 339: {
 340:     register struct stabnames *sp;
 341:     static char prbuf[32];
 342: 
 343:     for (sp = stabnames; sp->st_name; sp++)
 344:         if (sp->st_value == val)
 345:             return (sp->st_name);
 346:     sprintf(prbuf, "%02x", val);
 347:     return (prbuf);
 348: }

Defined functions

compare defined in line 260; used 2 times
error defined in line 295; used 10 times
main defined in line 39; never used
namelist defined in line 88; used 1 times
  • in line 83
nextel defined in line 274; used 2 times
psyms defined in line 193; used 1 times
stab defined in line 337; used 2 times

Defined variables

aflg defined in line 17; used 2 times
archdr defined in line 21; used 7 times
archive defined in line 20; used 12 times
errs defined in line 37; used 2 times
gflg defined in line 17; used 3 times
narg defined in line 36; used 3 times
nflg defined in line 17; used 2 times
oflg defined in line 17; used 4 times
pflg defined in line 17; used 2 times
rflg defined in line 18; used 4 times
sccsid defined in line 2; never used
stabnames defined in line 313; used 1 times
strp defined in line 32; used 10 times
uflg defined in line 17; used 4 times
xargv defined in line 19; used 8 times

Defined struct's

stabnames defined in line 310; used 2 times
  • in line 340(2)

Defined macros

OARMAG defined in line 26; used 1 times
SELECT defined in line 15; used 3 times
Last modified: 1986-05-20
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1599
Valid CSS Valid XHTML 1.0 Strict