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