|
|
1.1 ! root 1: #ifndef lint ! 2: static char sccsid[] = "@(#)nm.c 4.4 7/1/83"; ! 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: return; ! 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: return; ! 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(1, "old format .o (no string table) or truncated file"); ! 138: i = 0; ! 139: if (strp) ! 140: free(strp), strp = 0; ! 141: while (--n >= 0) { ! 142: fread((char *)&sym, 1, sizeof(sym), fi); ! 143: if (gflg && (sym.n_type&N_EXT)==0) ! 144: continue; ! 145: if ((sym.n_type&N_STAB) && (!aflg||gflg||uflg)) ! 146: continue; ! 147: if (symp==NULL) ! 148: symp = (struct nlist *) ! 149: malloc(sizeof(struct nlist)); ! 150: else ! 151: symp = (struct nlist *) ! 152: realloc(symp, ! 153: (i+1)*sizeof(struct nlist)); ! 154: if (symp == NULL) ! 155: error(1, "out of memory"); ! 156: symp[i++] = sym; ! 157: } ! 158: if (archive && ftell(fi)+sizeof(off_t) >= off) { ! 159: error(0, "no string table (old format .o?)"); ! 160: continue; ! 161: } ! 162: if (fread((char *)&strsiz,sizeof(strsiz),1,fi) != 1) { ! 163: error(0, "no string table (old format .o?)"); ! 164: goto out; ! 165: } ! 166: strp = (char *)malloc(strsiz); ! 167: if (strp == NULL) ! 168: error(1, "ran out of memory"); ! 169: if (fread(strp+sizeof(strsiz),strsiz-sizeof(strsiz),1,fi) != 1) ! 170: error(1, "error reading string table"); ! 171: for (j = 0; j < i; j++) ! 172: if (symp[j].n_un.n_strx) ! 173: symp[j].n_un.n_name = ! 174: symp[j].n_un.n_strx + strp; ! 175: else ! 176: symp[j].n_un.n_name = ""; ! 177: if (pflg==0) ! 178: qsort(symp, i, sizeof(struct nlist), compare); ! 179: if ((archive || narg>1) && oflg==0) ! 180: printf("\n%s:\n", SELECT); ! 181: psyms(symp, i); ! 182: if (symp) ! 183: free((char *)symp), symp = 0; ! 184: if (strp) ! 185: free((char *)strp), strp = 0; ! 186: } while(archive && nextel(fi)); ! 187: out: ! 188: fclose(fi); ! 189: } ! 190: ! 191: psyms(symp, nsyms) ! 192: register struct nlist *symp; ! 193: int nsyms; ! 194: { ! 195: register int n, c; ! 196: ! 197: for (n=0; n<nsyms; n++) { ! 198: c = symp[n].n_type; ! 199: if (c & N_STAB) { ! 200: if (oflg) { ! 201: if (archive) ! 202: printf("%s:", *xargv); ! 203: printf("%s:", SELECT); ! 204: } ! 205: printf("%08x - %02x %04x %5.5s %s\n", ! 206: symp[n].n_value, ! 207: symp[n].n_other & 0xff, symp[n].n_desc & 0xffff, ! 208: stab(symp[n].n_type & 0xff), ! 209: symp[n].n_un.n_name); ! 210: continue; ! 211: } ! 212: switch (c&N_TYPE) { ! 213: ! 214: case N_UNDF: ! 215: c = 'u'; ! 216: if (symp[n].n_value) ! 217: c = 'c'; ! 218: break; ! 219: case N_ABS: ! 220: c = 'a'; ! 221: break; ! 222: case N_TEXT: ! 223: c = 't'; ! 224: break; ! 225: case N_DATA: ! 226: c = 'd'; ! 227: break; ! 228: case N_BSS: ! 229: c = 'b'; ! 230: break; ! 231: case N_FN: ! 232: c = 'f'; ! 233: break; ! 234: } ! 235: if (uflg && c!='u') ! 236: continue; ! 237: if (oflg) { ! 238: if (archive) ! 239: printf("%s:", *xargv); ! 240: printf("%s:", SELECT); ! 241: } ! 242: if (symp[n].n_type&N_EXT) ! 243: c = toupper(c); ! 244: if (!uflg) { ! 245: if (c=='u' || c=='U') ! 246: printf(" "); ! 247: else ! 248: printf(N_FORMAT, symp[n].n_value); ! 249: printf(" %c ", c); ! 250: } ! 251: printf("%s\n", symp[n].n_un.n_name); ! 252: l1: ; ! 253: } ! 254: } ! 255: ! 256: compare(p1, p2) ! 257: struct nlist *p1, *p2; ! 258: { ! 259: register i; ! 260: ! 261: if (nflg) { ! 262: if (p1->n_value > p2->n_value) ! 263: return(rflg); ! 264: if (p1->n_value < p2->n_value) ! 265: return(-rflg); ! 266: } ! 267: return (rflg * strcmp(p1->n_un.n_name, p2->n_un.n_name)); ! 268: } ! 269: ! 270: nextel(af) ! 271: FILE *af; ! 272: { ! 273: register char *cp; ! 274: register r; ! 275: long arsize; ! 276: ! 277: fseek(af, off, 0); ! 278: r = fread((char *)&archdr, 1, sizeof(struct ar_hdr), af); ! 279: if (r != sizeof(struct ar_hdr)) ! 280: return(0); ! 281: for (cp = archdr.ar_name; cp < &archdr.ar_name[sizeof(archdr.ar_name)]; cp++) ! 282: if (*cp == ' ') ! 283: *cp = '\0'; ! 284: arsize = atol(archdr.ar_size); ! 285: if (arsize & 1) ! 286: ++arsize; ! 287: off = ftell(af) + arsize; /* beginning of next element */ ! 288: return(1); ! 289: } ! 290: ! 291: error(n, s) ! 292: char *s; ! 293: { ! 294: fprintf(stderr, "nm: %s:", *xargv); ! 295: if (archive) { ! 296: fprintf(stderr, "(%s)", archdr.ar_name); ! 297: fprintf(stderr, ": "); ! 298: } else ! 299: fprintf(stderr, " "); ! 300: fprintf(stderr, "%s\n", s); ! 301: if (n) ! 302: exit(2); ! 303: errs = 1; ! 304: } ! 305: ! 306: struct stabnames { ! 307: int st_value; ! 308: char *st_name; ! 309: } stabnames[] ={ ! 310: N_GSYM, "GSYM", ! 311: N_FNAME, "FNAME", ! 312: N_FUN, "FUN", ! 313: N_STSYM, "STSYM", ! 314: N_LCSYM, "LCSYM", ! 315: N_RSYM, "RSYM", ! 316: N_SLINE, "SLINE", ! 317: N_SSYM, "SSYM", ! 318: N_SO, "SO", ! 319: N_LSYM, "LSYM", ! 320: N_SOL, "SOL", ! 321: N_PSYM, "PSYM", ! 322: N_ENTRY, "ENTRY", ! 323: N_LBRAC, "LBRAC", ! 324: N_RBRAC, "RBRAC", ! 325: N_BCOMM, "BCOMM", ! 326: N_ECOMM, "ECOMM", ! 327: N_ECOML, "ECOML", ! 328: N_LENG, "LENG", ! 329: N_PC, "PC", ! 330: 0, 0 ! 331: }; ! 332: ! 333: char * ! 334: stab(val) ! 335: { ! 336: register struct stabnames *sp; ! 337: static char prbuf[32]; ! 338: ! 339: for (sp = stabnames; sp->st_name; sp++) ! 340: if (sp->st_value == val) ! 341: return (sp->st_name); ! 342: sprintf(prbuf, "%02x", val); ! 343: return (prbuf); ! 344: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.