diff options
Diffstat (limited to 'src/cmd/nm/nm.c')
-rw-r--r-- | src/cmd/nm/nm.c | 401 |
1 files changed, 0 insertions, 401 deletions
diff --git a/src/cmd/nm/nm.c b/src/cmd/nm/nm.c deleted file mode 100644 index 820942426..000000000 --- a/src/cmd/nm/nm.c +++ /dev/null @@ -1,401 +0,0 @@ -// Inferno utils/nm/nm.c -// http://code.google.com/p/inferno-os/source/browse/utils/nm/nm.c -// -// Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved. -// Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net) -// Portions Copyright © 1997-1999 Vita Nuova Limited -// Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com) -// Portions Copyright © 2004,2006 Bruce Ellis -// Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net) -// Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others -// Portions Copyright © 2009 The Go Authors. All rights reserved. -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. - -/* - * nm.c -- drive nm - */ -#include <u.h> -#include <libc.h> -#include <ar.h> -#include <bio.h> -#include <mach.h> - -enum{ - CHUNK = 256 /* must be power of 2 */ -}; - -char *errs; /* exit status */ -char *filename; /* current file */ -char symname[]="__.GOSYMDEF"; /* table of contents file name */ -int multifile; /* processing multiple files */ -int aflag; -int gflag; -int hflag; -int nflag; -int sflag; -int Sflag; -int uflag; -int Tflag; -int tflag; - -Sym **fnames; /* file path translation table */ -Sym **symptr; -int nsym; -Biobuf bout; - -int cmp(void*, void*); -void error(char*, ...); -void execsyms(int); -void psym(Sym*, void*); -void printsyms(Sym**, long); -void doar(Biobuf*); -void dofile(Biobuf*); -void zenter(Sym*); - -void -usage(void) -{ - fprint(2, "usage: nm [-aghnsSTu] file ...\n"); - exits("usage"); -} - -void -main(int argc, char *argv[]) -{ - int i; - Biobuf *bin; - - Binit(&bout, 1, OWRITE); - argv0 = argv[0]; - ARGBEGIN { - default: usage(); - case 'a': aflag = 1; break; - case 'g': gflag = 1; break; - case 'h': hflag = 1; break; - case 'n': nflag = 1; break; - case 's': sflag = 1; break; - case 'S': nflag = Sflag = 1; break; - case 'u': uflag = 1; break; - case 't': tflag = 1; break; - case 'T': Tflag = 1; break; - } ARGEND - if (argc == 0) - usage(); - if (argc > 1) - multifile++; - for(i=0; i<argc; i++){ - filename = argv[i]; - bin = Bopen(filename, OREAD); - if(bin == 0){ - error("cannot open %s", filename); - continue; - } - if (isar(bin)) - doar(bin); - else{ - Bseek(bin, 0, 0); - dofile(bin); - } - Bterm(bin); - } - exits(errs); -} - -/* - * read an archive file, - * processing the symbols for each intermediate file in it. - */ -void -doar(Biobuf *bp) -{ - int offset, size, obj; - char name[SARNAME]; - - multifile = 1; - for (offset = Boffset(bp);;offset += size) { - size = nextar(bp, offset, name); - if (size < 0) { - error("phase error on ar header %d", offset); - return; - } - if (size == 0) - return; - if (strcmp(name, symname) == 0) - continue; - obj = objtype(bp, 0); - if (obj < 0) { - // perhaps foreign object - if(strlen(name) > 2 && strcmp(name+strlen(name)-2, ".o") == 0) - return; - error("inconsistent file %s in %s", - name, filename); - return; - } - if (!readar(bp, obj, offset+size, 1)) { - error("invalid symbol reference in file %s", - name); - return; - } - filename = name; - nsym=0; - objtraverse(psym, 0); - printsyms(symptr, nsym); - } -} - -/* - * process symbols in a file - */ -void -dofile(Biobuf *bp) -{ - int obj; - - obj = objtype(bp, 0); - if (obj < 0) - execsyms(Bfildes(bp)); - else - if (readobj(bp, obj)) { - nsym = 0; - objtraverse(psym, 0); - printsyms(symptr, nsym); - } -} - -/* - * comparison routine for sorting the symbol table - * this screws up on 'z' records when aflag == 1 - */ -int -cmp(void *vs, void *vt) -{ - Sym **s, **t; - - s = vs; - t = vt; - if(nflag) // sort on address (numeric) order - if((*s)->value < (*t)->value) - return -1; - else - return (*s)->value > (*t)->value; - if(sflag) // sort on file order (sequence) - return (*s)->sequence - (*t)->sequence; - return strcmp((*s)->name, (*t)->name); -} -/* - * enter a symbol in the table of filename elements - */ -void -zenter(Sym *s) -{ - static int maxf = 0; - - if (s->value > maxf) { - maxf = (s->value+CHUNK-1) &~ (CHUNK-1); - fnames = realloc(fnames, (maxf+1)*sizeof(*fnames)); - if(fnames == 0) { - error("out of memory", argv0); - exits("memory"); - } - } - fnames[s->value] = s; -} - -/* - * get the symbol table from an executable file, if it has one - */ -void -execsyms(int fd) -{ - Fhdr f; - Sym *s; - int32 n; - - seek(fd, 0, 0); - if (crackhdr(fd, &f) == 0) { - error("Can't read header for %s", filename); - return; - } - if (syminit(fd, &f) < 0) - return; - s = symbase(&n); - nsym = 0; - while(n--) - psym(s++, 0); - - printsyms(symptr, nsym); -} - -void -psym(Sym *s, void* p) -{ - USED(p); - switch(s->type) { - case 'T': - case 'L': - case 'D': - case 'B': - if (uflag) - return; - if (!aflag && ((s->name[0] == '.' || s->name[0] == '$'))) - return; - break; - case 'b': - case 'd': - case 'l': - case 't': - if (uflag || gflag) - return; - if (!aflag && ((s->name[0] == '.' || s->name[0] == '$'))) - return; - break; - case 'U': - if (gflag) - return; - break; - case 'Z': - if (!aflag) - return; - break; - case 'm': - if(!aflag || uflag || gflag) - return; - break; - case 'f': /* we only see a 'z' when the following is true*/ - if(!aflag || uflag || gflag) - return; - zenter(s); - break; - case 'a': - case 'p': - case 'z': - default: - if(!aflag || uflag || gflag) - return; - break; - } - symptr = realloc(symptr, (nsym+1)*sizeof(Sym*)); - if (symptr == 0) { - error("out of memory"); - exits("memory"); - } - symptr[nsym++] = s; -} - -const char *skipnames[] = { - "bss", - "data", - "ebss", - "edata", - "egcbss", - "egcdata", - "enoptrbss", - "enoptrdata", - "epclntab", - "erodata", - "esymtab", - "etext", - "etypelink", - "noptrbss", - "noptrdata", - "rodata", - "text", -}; - -int -skipsize(char *name) -{ - int i; - - for(i=0; i<nelem(skipnames); i++) - if(strcmp(skipnames[i], name) == 0) - return 1; - return 0; -} - -void -printsyms(Sym **symptr, long nsym) -{ - int i, j, wid; - Sym *s; - char *cp; - char path[512]; - - qsort(symptr, nsym, sizeof(*symptr), (void*)cmp); - - wid = 0; - for (i=0; i<nsym; i++) { - s = symptr[i]; - if (s->value && wid == 0) - wid = 8; - else if (s->value >= 0x100000000LL && wid == 8) - wid = 16; - } - for (i=0; i<nsym; i++) { - s = symptr[i]; - if (multifile && !hflag) - Bprint(&bout, "%s:", filename); - if (s->type == 'z') { - fileelem(fnames, (uchar *) s->name, path, 512); - cp = path; - } else - cp = s->name; - if (Tflag) - Bprint(&bout, "%8ux ", s->sig); - if (s->value || s->type == 'a' || s->type == 'p') - Bprint(&bout, "%*llux ", wid, s->value); - else - Bprint(&bout, "%*s ", wid, ""); - if(Sflag && !skipsize(cp)) { - vlong siz; - - siz = 0; - for(j=i+1; j<nsym; j++) { - if(!skipsize(symptr[j]->name) && symptr[j]->type != 'a' && symptr[j]->type != 'p') { - siz = symptr[j]->value - s->value; - break; - } - } - if(siz > 0) - Bprint(&bout, "%*llud ", wid, siz); - } - Bprint(&bout, "%c %s", s->type, cp); - if(tflag && s->gotype) - Bprint(&bout, " %*llux", wid, s->gotype); - Bprint(&bout, "\n"); - } -} - -void -error(char *fmt, ...) -{ - Fmt f; - char buf[128]; - va_list arg; - - fmtfdinit(&f, 2, buf, sizeof buf); - fmtprint(&f, "%s: ", argv0); - va_start(arg, fmt); - fmtvprint(&f, fmt, arg); - va_end(arg); - fmtprint(&f, "\n"); - fmtfdflush(&f); - errs = "errors"; -} |