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