11 CHUNK = 256 /* must be power of 2 */
14 char *errs; /* exit status */
15 char *filename; /* current file */
16 char symname[]="__.SYMDEF"; /* table of contents file name */
17 int multifile; /* processing multiple files */
25 Symbol **fnames; /* file path translation table */
30 int cmp(void*, void*);
31 void error(char*, ...);
33 void psym(Symbol*, void*);
34 void printsyms(Symbol**, long);
40 main(int argc, char *argv[])
45 Binit(&bout, 1, OWRITE);
48 case 'a': aflag = 1; break;
49 case 'g': gflag = 1; break;
50 case 'h': hflag = 1; break;
51 case 'n': nflag = 1; break;
52 case 's': sflag = 1; break;
53 case 'u': uflag = 1; break;
57 for(i=0; i<argc; i++){
59 bin = Bopen(filename, OREAD);
61 error("cannot open %s", filename);
76 * read an archive file,
77 * processing the symbols for each intermediate file in it.
82 int offset, size, obj;
83 char membername[SARNAME];
86 for (offset = Boffset(bp);;offset += size) {
87 size = nextar(bp, offset, membername);
89 error("phase error on ar header %ld", offset);
94 if (strcmp(membername, symname) == 0)
98 error("inconsistent file %s in %s",
99 membername, filename);
102 if (!readar(bp, obj, offset+size, 1)) {
103 error("invalid symbol reference in file %s",
107 filename = membername;
109 objtraverse(psym, 0);
110 printsyms(symptr, nsym);
115 * process symbols in a file
122 obj = objtype(bp, 0);
124 execsyms(Bfildes(bp));
126 if (readobj(bp, obj)) {
128 objtraverse(psym, 0);
129 printsyms(symptr, nsym);
134 * comparison routine for sorting the symbol table
135 * this screws up on 'z' records when aflag == 1
138 cmp(void *vs, void *vt)
145 if((*s)->value < (*t)->value)
148 return (*s)->value > (*t)->value;
149 return strcmp((*s)->name, (*t)->name);
152 * enter a symbol in the table of filename elements
159 if (s->value > maxf) {
160 maxf = (s->value+CHUNK-1) &~ (CHUNK-1);
161 fnames = realloc(fnames, (maxf+1)*sizeof(*fnames));
163 error("out of memory", argv0);
167 fnames[s->value] = s;
171 * get the symbol table from an executable file, if it has one
181 if (crackhdr(fd, &f) == 0) {
182 error("Can't read header for %s", filename);
185 if (syminit(fd, &f) < 0)
192 printsyms(symptr, nsym);
196 psym(Symbol *s, void* p)
206 if (!aflag && ((s->name[0] == '.' || s->name[0] == '$')))
215 if (!aflag && ((s->name[0] == '.' || s->name[0] == '$')))
227 case 'f': /* we only see a 'z' when the following is true*/
228 if(!aflag || uflag || gflag)
230 if (strcmp(s->name, ".frame"))
237 if(!aflag || uflag || gflag)
241 symptr = realloc(symptr, (nsym+1)*sizeof(Sym*));
243 error("out of memory");
250 printsyms(Symbol **symptr, long nsym)
257 qsort(symptr, nsym, sizeof(*symptr), cmp);
260 if (multifile && !hflag)
261 Bprint(&bout, "%s:", filename);
262 if (s->type == 'z') {
263 fileelem(fnames, (uchar *) s->name, path, 512);
267 if (s->value || s->type == 'a' || s->type == 'p')
268 Bprint(&bout, "%8lux %c %s\n", s->value, s->type, cp);
270 Bprint(&bout, " %c %s\n", s->type, cp);
275 error(char *fmt, ...)
281 fmtfdinit(&f, 2, buf, sizeof buf);
282 fmtprint(&f, "%s: ", argv0);
284 fmtvprint(&f, fmt, arg);