|
|
1.1 ! root 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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.