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