|
|
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.