|
|
1.1 ! root 1: #include <sys/types.h> ! 2: #include <stdio.h> ! 3: #include <ctype.h> ! 4: #include <sys/stat.h> ! 5: #include "filehdr.h" ! 6: #include "aouthdr.h" ! 7: #include "scnhdr.h" ! 8: #include "storclass.h" ! 9: #include "syms.h" ! 10: ! 11: /* global */ ! 12: int nflg, gflg, uflg, rflg, pflg, oflg, aflg; ! 13: #define SYMINC(sp,n) (struct syment *)(((u_int)sp)+(n)*SYMESZ) ! 14: #define AUXINC(ap,n) (struct auxent *)(((u_int)ap)+(n)*SYMESZ) ! 15: char section[256]; /* section types ('T', 'D', 'B', or '?') */ ! 16: struct symbol { ! 17: char *name; ! 18: u_long value; ! 19: char sclass; ! 20: }; ! 21: ! 22: /* predeclared */ ! 23: struct symbol *dosymtab(); ! 24: char *dofile(); ! 25: char *namelist(); ! 26: ! 27: main(argc, argv) ! 28: char **argv; ! 29: { ! 30: int errs; ! 31: char *rv; ! 32: int printname; ! 33: ! 34: rflg = 1; ! 35: if (--argc>0 && argv[1][0]=='-' && argv[1][1]!=0) { ! 36: argv++; ! 37: while (*++*argv) switch (**argv) { ! 38: ! 39: case 'n': ! 40: nflg = 1; ! 41: continue; ! 42: case 'g': ! 43: gflg = 1; ! 44: continue; ! 45: case 'u': ! 46: uflg = 1; ! 47: continue; ! 48: case 'r': ! 49: rflg = -1; ! 50: continue; ! 51: case 'p': ! 52: pflg = 1; ! 53: continue; ! 54: case 'o': ! 55: oflg = 1; ! 56: continue; ! 57: case 'a': ! 58: aflg = 1; ! 59: continue; ! 60: default: ! 61: fprintf(stderr, "nm: invalid argument -%c\n", ! 62: *argv[0]); ! 63: exit(2); ! 64: } ! 65: argc--; ! 66: } ! 67: if (argc == 0) { ! 68: argc = 1; ! 69: argv[1] = "a.out"; ! 70: } ! 71: printname = argc > 1 && !oflg; ! 72: while (argc--) { ! 73: if (printname) ! 74: printf("%s:\n", argv[1]); ! 75: if ((rv = dofile(argv[1])) != NULL) { ! 76: errs++; ! 77: fprintf(stderr, "nm: %s (%s)\n", rv, argv[1]); ! 78: } ! 79: argv++; ! 80: } ! 81: exit(errs); ! 82: } ! 83: ! 84: char * ! 85: dofile(file) ! 86: char *file; ! 87: { ! 88: int fd; ! 89: char *rv; ! 90: ! 91: if ((fd = open(file, 0)) < 0) ! 92: return "can't open"; ! 93: rv = namelist(file, fd); ! 94: close(fd); ! 95: return rv; ! 96: } ! 97: ! 98: char * ! 99: namelist(file, fd) ! 100: char *file; ! 101: int fd; ! 102: { ! 103: struct filehdr fh; ! 104: struct aouthdr ah; ! 105: struct syment *syms; ! 106: struct symbol *symtab; ! 107: struct scnhdr sh; ! 108: char *strings; ! 109: struct stat sbuf; ! 110: unsigned int nel, i, size; ! 111: ! 112: /* get file length */ ! 113: if (fstat(fd, &sbuf) < 0) ! 114: return "problem stating"; ! 115: ! 116: /* get file header and a.out header */ ! 117: if (read(fd, &fh, sizeof(fh)) != sizeof(fh)) ! 118: return "problem reading"; ! 119: if (read(fd, &ah, sizeof(ah)) != sizeof(ah)) ! 120: return "error reading a.out header"; ! 121: if (fh.f_magic != FBOMAGIC) ! 122: return "bad magic"; ! 123: ! 124: /* read and classify section headers */ ! 125: for (i = 1; i <= fh.f_nscns; i++) { ! 126: if (read(fd, &sh, sizeof(sh)) != sizeof(sh)) ! 127: return "error reading section header"; ! 128: if (strncmp(sh.s_name, _TEXT, sizeof(sh.s_name)) == 0) ! 129: section[i] = 'T'; ! 130: else if (strncmp(sh.s_name, _DATA, sizeof(sh.s_name)) == 0) ! 131: section[i] = 'D'; ! 132: else if (strncmp(sh.s_name, _BSS, sizeof(sh.s_name)) == 0) ! 133: section[i] = 'B'; ! 134: else ! 135: section[i] = 'O'; ! 136: } ! 137: ! 138: /* read in the symbols */ ! 139: size = fh.f_nsyms*SYMESZ; ! 140: if (lseek(fd, fh.f_symptr, 0) < 0) ! 141: return "problem seeking "; ! 142: syms = (struct syment *)malloc(size); ! 143: if (syms == NULL) ! 144: return "not enough memory"; ! 145: if (read(fd, syms, size) != size) { ! 146: free(syms); ! 147: return "problem reading"; ! 148: } ! 149: ! 150: /* read in string table */ ! 151: size = sbuf.st_size - size - fh.f_symptr; ! 152: strings = (char *)malloc(size); ! 153: if (strings == NULL) { ! 154: free(syms); ! 155: return "not enough memory"; ! 156: } ! 157: if (read(fd, strings, size) != size) { ! 158: free(syms); free(strings); ! 159: return "problem reading"; ! 160: } ! 161: ! 162: /* create symbol table */ ! 163: symtab = dosymtab(syms, strings, fh.f_nsyms, &nel); ! 164: if (symtab == NULL) { ! 165: free(syms); free(strings); ! 166: return "not enough memory"; ! 167: } ! 168: ! 169: /* sort it */ ! 170: if (!pflg) { ! 171: int ncompare(), scompare(); ! 172: if (nflg) ! 173: qsort(symtab, nel, sizeof(struct symbol), ncompare); ! 174: else ! 175: qsort(symtab, nel, sizeof(struct symbol), scompare); ! 176: } ! 177: ! 178: /* print out symbols */ ! 179: doprint(file, symtab, nel); ! 180: free(syms); ! 181: free(strings); ! 182: free(symtab); ! 183: return NULL; ! 184: } ! 185: ! 186: struct symbol * ! 187: dosymtab(syms, strings, nsyms, np) ! 188: struct syment *syms; ! 189: char *strings; ! 190: unsigned int nsyms; ! 191: unsigned int *np; ! 192: { ! 193: struct symbol *symtab, *stp; ! 194: struct syment *sp; ! 195: int nel=0; ! 196: ! 197: /* build table */ ! 198: stp = symtab = (struct symbol *)malloc(nsyms*sizeof(struct symbol)); ! 199: if (symtab == NULL) ! 200: return NULL; ! 201: for (sp = syms; sp < SYMINC(syms,nsyms); sp=SYMINC(sp, sp->n_numaux+1)) { ! 202: switch(sp->n_sclass) { ! 203: case C_REG: case C_REGPARM: ! 204: if (!aflg || uflg || gflg) continue; ! 205: stp->sclass = 'r'; ! 206: break; ! 207: case C_AUTO: case C_MOS: case C_ARG: ! 208: case C_MOU: case C_MOE: case C_FIELD: ! 209: if (!aflg || uflg || gflg) continue; ! 210: stp->sclass = 'a'; ! 211: break; ! 212: case C_EXT: ! 213: stp->sclass = class(sp); ! 214: if (uflg && stp->sclass != 'U') continue; ! 215: break; ! 216: case C_STAT: case C_HIDDEN: ! 217: if (uflg || gflg) continue; ! 218: stp->sclass = tolower(class(sp)); ! 219: break; ! 220: case C_USTATIC: ! 221: if (!aflg || gflg) continue; ! 222: stp->sclass = 'u'; ! 223: break; ! 224: case C_LABEL: case C_BLOCK: case C_FCN: ! 225: if (!aflg || uflg || gflg) continue; ! 226: stp->sclass = tolower(class(*symtab)); ! 227: break; ! 228: case C_ULABEL: ! 229: if ((!aflg && !uflg) || gflg) continue; ! 230: stp->sclass = 'u'; ! 231: break; ! 232: case C_EXTDEF: ! 233: if (uflg) continue; ! 234: stp->sclass = class(*symtab); ! 235: break; ! 236: case C_NULL: case C_STRTAG: ! 237: case C_UNTAG: case C_TPDEF: case C_ENTAG: case C_EOS: ! 238: if (!aflg || uflg || gflg) continue; ! 239: stp->sclass = 'a'; ! 240: break; ! 241: case C_FILE: ! 242: if (uflg) continue; ! 243: stp->sclass = 'f'; ! 244: if (sp->n_numaux > 0) { ! 245: struct auxent *ap; ! 246: ap = AUXINC(sp, 1); ! 247: stp->name = ap->x_file.x_fname; ! 248: ap->x_file.x_fname[sizeof(ap->x_file.x_fname)] = 0; ! 249: } ! 250: break; ! 251: default: ! 252: continue; ! 253: } ! 254: stp->value = sp->n_value; ! 255: if (stp->sclass != 'f') { ! 256: if (sp->n_zeroes == 0) { ! 257: /* long name */ ! 258: stp->name = strings + sp->n_offset; ! 259: } else { ! 260: /* short name */ ! 261: stp->name = sp->n_name; ! 262: sp->n_name[sizeof(sp->n_name)] = '\0'; ! 263: } ! 264: if (*(stp->name) == '.') continue; ! 265: } ! 266: stp++; ! 267: } ! 268: *np = stp - symtab; ! 269: return symtab; ! 270: } ! 271: ! 272: ncompare(s1, s2) ! 273: struct symbol *s1, *s2; ! 274: { ! 275: return rflg*(s1->value - s2->value); ! 276: } ! 277: ! 278: scompare(s1, s2) ! 279: struct symbol *s1, *s2; ! 280: { ! 281: return rflg*strcmp(s1->name, s2->name); ! 282: } ! 283: ! 284: class(sp) ! 285: struct syment *sp; ! 286: { ! 287: if (sp->n_scnum == 0) { ! 288: if (sp->n_value == 0) ! 289: return 'U'; ! 290: else ! 291: return 'C'; ! 292: }else if (sp->n_scnum == -1) ! 293: return 'A'; ! 294: return section[sp->n_scnum]; ! 295: } ! 296: ! 297: doprint(file, sp, nel) ! 298: char *file; ! 299: struct symbol *sp; ! 300: int nel; ! 301: { ! 302: while (nel-- > 0) { ! 303: if (oflg) ! 304: printf("%s:%08x %c %s\n", file, sp->value, sp->sclass, ! 305: sp->name); ! 306: else ! 307: printf("%08x %c %s\n", sp->value, sp->sclass, sp->name); ! 308: sp++; ! 309: } ! 310: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.