|
|
1.1 root 1: /*
2: ** print symbol tables for
3: ** object or archive files
4: **
5: ** nm [-goprun] [name ...]
6: */
7:
8:
9:
10: #include <ar.h>
11: #include <stdio.h>
12: #include <ctype.h>
13: #include <a.out.h>
14: #include <pagsiz.h>
15:
16: #define MAGIC exp.a_magic
17: #define BADMAG MAGIC!=A_MAGIC1 && MAGIC!=A_MAGIC2 \
18: && MAGIC!=A_MAGIC3 && MAGIC!=A_MAGIC4 && MAGIC != 0412 && MAGIC != 0413
19: #define SELECT arch_flg ? arp.ar_name : *argv
20: int numsort_flg;
21: int undef_flg;
22: int revsort_flg = 1;
23: int globl_flg;
24: int nosort_flg;
25: int arch_flg;
26: int prep_flg;
27: struct ar_hdr arp;
28: struct exec exp;
29: FILE *fi;
30: long off;
31: long ftell();
32: char *malloc();
33: char *realloc();
34:
35: main(argc, argv)
36: char **argv;
37: {
38: int narg;
39: int compare();
40:
41: if (--argc>0 && argv[1][0]=='-' && argv[1][1]!=0) {
42: argv++;
43: while (*++*argv) switch (**argv) {
44: case 'n': /* sort numerically */
45: numsort_flg++;
46: continue;
47:
48: case 'g': /* globl symbols only */
49: globl_flg++;
50: continue;
51:
52: case 'u': /* undefined symbols only */
53: undef_flg++;
54: continue;
55:
56: case 'r': /* sort in reverse order */
57: revsort_flg = -1;
58: continue;
59:
60: case 'p': /* don't sort -- symbol table order */
61: nosort_flg++;
62: continue;
63:
64: case 'o': /* prepend a name to each line */
65: prep_flg++;
66: continue;
67:
68: default: /* oops */
69: fprintf(stderr, "nm: invalid argument -%c\n", *argv[0]);
70: exit(1);
71: }
72: argc--;
73: }
74: if (argc == 0) {
75: argc = 1;
76: argv[1] = "a.out";
77: }
78: narg = argc;
79: while(argc--) {
80: fi = fopen(*++argv,"r");
81: if (fi == NULL) {
82: fprintf(stderr, "nm: cannot open %s\n", *argv);
83: continue;
84: }
85: off = sizeof(exp.a_magic);
86: fread((char *)&exp, 1, sizeof(MAGIC), fi); /* get magic no. */
87: if (MAGIC == ARMAG)
88: arch_flg++;
89: else if (BADMAG) {
90: fprintf(stderr, "nm: %s-- bad format\n", *argv);
91: continue;
92: }
93: fseek(fi, 0L, 0);
94: if (arch_flg) {
95: nextel(fi);
96: if (narg > 1)
97: printf("\n%s:\n", *argv);
98: }
99: do {
100: long o;
101: register i, n, c;
102: struct nlist *symp = NULL;
103: struct nlist sym;
104:
105: fread((char *)&exp, 1, sizeof(struct exec), fi);
106: if (BADMAG) /* archive element not in */
107: continue; /* proper format - skip it */
108: o = (long)exp.a_text + exp.a_data + exp.a_trsize + exp.a_drsize;
109: if (MAGIC==0412 || MAGIC==0413)
110: o += PAGSIZ - sizeof(struct exec);
111: fseek(fi, o, 1);
112: n = exp.a_syms / sizeof(struct nlist);
113: if (n == 0) {
114: fprintf(stderr, "nm: %s-- no name list\n", SELECT);
115: continue;
116: }
117: i = 0;
118: while (--n >= 0) {
119: fread((char *)&sym, 1, sizeof(sym), fi);
120: if (globl_flg && (sym.n_type&N_EXT)==0)
121: continue;
122: if (symp==NULL)
123: symp = (struct nlist *)malloc(sizeof(struct nlist));
124: else {
125: symp = (struct nlist *)realloc(symp, (i+1)*sizeof(struct nlist));
126: }
127: if (symp == NULL) {
128: fprintf(stderr, "nm: out of memory on %s\n", *argv);
129: exit(2);
130: }
131: symp[i++] = sym;
132: }
133: if (nosort_flg==0)
134: qsort(symp, i, sizeof(struct nlist), compare);
135: if ((arch_flg || narg>1) && prep_flg==0)
136: printf("\n%s:\n", SELECT);
137: for (n=0; n<i; n++) {
138: if (prep_flg) {
139: if (arch_flg)
140: printf("%s:", *argv);
141: printf("%s:", SELECT);
142: }
143: c = symp[n].n_type;
144:
145: if (c & STABTYPE) {
146: printf("%08x - %-8.8s %02x %02x %04x\n",
147: symp[n].n_value,
148: symp[n].n_name,
149: symp[n].n_type & 0xff,
150: symp[n].n_other & 0xff,
151: symp[n].n_desc & 0xffff);
152: continue;
153: }
154: switch (c&(N_TYPE-N_EXT)) {
155:
156: case N_UNDF:
157: c = 'u';
158: if (symp[n].n_value)
159: c = 'c';
160: break;
161:
162: case N_ABS:
163: c = 'a';
164: break;
165:
166: case N_TEXT:
167: c = 't';
168: break;
169:
170: case N_DATA:
171: c = 'd';
172: break;
173:
174: case N_BSS:
175: c = 'b';
176: break;
177:
178: case N_FN:
179: c = 'f';
180: break;
181:
182: /*
183: case N_REG:
184: c = 'r';
185: break;
186: */
187: }
188: if (undef_flg && c!='u')
189: continue;
190: if (symp[n].n_type&N_EXT)
191: c = toupper(c);
192: if (!undef_flg) {
193: if (c=='u' || c=='U')
194: printf(" ");
195: else
196: printf(FORMAT, symp[n].n_value);
197: printf(" %c ", c);
198: }
199: printf("%.8s\n", symp[n].n_name);
200: l1:; }
201: if (symp)
202: free((char *)symp);
203: } while(arch_flg && nextel(fi));
204: fclose(fi);
205: }
206: exit(0);
207: }
208:
209: compare(p1, p2)
210: struct nlist *p1, *p2;
211: {
212: register i;
213:
214: if (numsort_flg) {
215: if (p1->n_value > p2->n_value)
216: return(revsort_flg);
217: if (p1->n_value < p2->n_value)
218: return(-revsort_flg);
219: }
220: for(i=0; i<sizeof(p1->n_name); i++)
221: if (p1->n_name[i] != p2->n_name[i]) {
222: if (p1->n_name[i] > p2->n_name[i])
223: return(revsort_flg);
224: else
225: return(-revsort_flg);
226: }
227: return(0);
228: }
229:
230: nextel(af)
231: FILE *af;
232: {
233: register r;
234:
235: fseek(af, off, 0);
236: r = fread((char *)&arp, 1, sizeof(struct ar_hdr), af); /* read archive header */
237: if (r <= 0)
238: return(0);
239: if (arp.ar_size & 1)
240: ++arp.ar_size;
241: off = ftell(af) + arp.ar_size; /* offset to next element */
242: return(1);
243: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.