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