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