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