X-Git-Url: https://git.subgeniuskitty.com/unix-history/.git/blobdiff_plain/2b84abb596f52ab2068d52108adc96838ad4340a..31cef89cb428866f787983e68246030321893df4:/usr/src/cmd/nm.c diff --git a/usr/src/cmd/nm.c b/usr/src/cmd/nm.c index 1c620f3804..38b890641a 100644 --- a/usr/src/cmd/nm.c +++ b/usr/src/cmd/nm.c @@ -1,73 +1,73 @@ +static char sccsid[] = "@(#)nm.c 4.1 10/1/80"; /* -** print symbol tables for -** object or archive files -** -** nm [-goprun] [name ...] -*/ - - - -#include -#include -#include -#include -#include - -#define MAGIC exp.a_magic -#define BADMAG MAGIC!=A_MAGIC1 && MAGIC!=A_MAGIC2 \ - && MAGIC!=A_MAGIC3 && MAGIC!=A_MAGIC4 && MAGIC != 0412 && MAGIC != 0413 -#define SELECT arch_flg ? arp.ar_name : *argv -int numsort_flg; -int undef_flg; -int revsort_flg = 1; -int globl_flg; -int nosort_flg; -int arch_flg; -int prep_flg; -struct ar_hdr arp; -struct exec exp; + * nm - print name list; VAX string table version + */ +#include +#include +#include +#include +#include +#include +#include +#include + +#define SELECT archive ? archdr.ar_name : *xargv + +int aflg, gflg, nflg, oflg, pflg, uflg; +int rflg = 1; +char **xargv; +int archive; +struct ar_hdr archdr; +union { + char mag_armag[SARMAG+1]; + struct exec mag_exp; +} mag_un; +#define OARMAG 0177545 FILE *fi; -long off; -long ftell(); +off_t off; +off_t ftell(); char *malloc(); char *realloc(); +char *strp; +char *stab(); +off_t strsiz; +int compare(); +int narg; +int errs; main(argc, argv) char **argv; { - int narg; - int compare(); if (--argc>0 && argv[1][0]=='-' && argv[1][1]!=0) { argv++; while (*++*argv) switch (**argv) { - case 'n': /* sort numerically */ - numsort_flg++; - continue; - case 'g': /* globl symbols only */ - globl_flg++; + case 'n': + nflg++; continue; - - case 'u': /* undefined symbols only */ - undef_flg++; + case 'g': + gflg++; continue; - - case 'r': /* sort in reverse order */ - revsort_flg = -1; + case 'u': + uflg++; continue; - - case 'p': /* don't sort -- symbol table order */ - nosort_flg++; + case 'r': + rflg = -1; continue; - - case 'o': /* prepend a name to each line */ - prep_flg++; + case 'p': + pflg++; continue; - - default: /* oops */ - fprintf(stderr, "nm: invalid argument -%c\n", *argv[0]); - exit(1); + case 'o': + oflg++; + continue; + case 'a': + aflg++; + continue; + default: + fprintf(stderr, "nm: invalid argument -%c\n", + *argv[0]); + exit(2); } argc--; } @@ -76,134 +76,180 @@ char **argv; argv[1] = "a.out"; } narg = argc; - while(argc--) { - fi = fopen(*++argv,"r"); - if (fi == NULL) { - fprintf(stderr, "nm: cannot open %s\n", *argv); + xargv = argv; + while (argc--) { + ++xargv; + namelist(); + } + exit(errs); +} + +namelist() +{ + register int j; + + archive = 0; + fi = fopen(*xargv, "r"); + if (fi == NULL) { + error(0, "cannot open"); + return; + } + off = SARMAG; + fread((char *)&mag_un, 1, sizeof(mag_un), fi); + if (mag_un.mag_exp.a_magic == OARMAG) { + error(0, "old archive"); + return; + } + if (strncmp(mag_un.mag_armag, ARMAG, SARMAG)==0) + archive++; + else if (N_BADMAG(mag_un.mag_exp)) { + error(0, "bad format"); + return; + } + fseek(fi, 0L, 0); + if (archive) { + nextel(fi); + if (narg > 1) + printf("\n%s:\n", *xargv); + } + do { + off_t o; + register i, n, c; + struct nlist *symp = NULL; + struct nlist sym; + struct stat stb; + + fread((char *)&mag_un.mag_exp, 1, sizeof(struct exec), fi); + if (N_BADMAG(mag_un.mag_exp)) + continue; + if (archive == 0) + fstat(fileno(fi), &stb); + o = N_SYMOFF(mag_un.mag_exp) - sizeof (struct exec); + fseek(fi, o, 1); + n = mag_un.mag_exp.a_syms / sizeof(struct nlist); + if (n == 0) { + error(0, "no name list"); continue; } - off = sizeof(exp.a_magic); - fread((char *)&exp, 1, sizeof(MAGIC), fi); /* get magic no. */ - if (MAGIC == ARMAG) - arch_flg++; - else if (BADMAG) { - fprintf(stderr, "nm: %s-- bad format\n", *argv); + if (N_STROFF(mag_un.mag_exp) + sizeof (off_t) > + (archive ? off : stb.st_size)) + error(1, "old format .o (no string table) or truncated file"); + i = 0; + if (strp) + free(strp), strp = 0; + while (--n >= 0) { + fread((char *)&sym, 1, sizeof(sym), fi); + if (gflg && (sym.n_type&N_EXT)==0) + continue; + if ((sym.n_type&N_STAB) && (!aflg||gflg||uflg)) + continue; + if (symp==NULL) + symp = (struct nlist *) + malloc(sizeof(struct nlist)); + else + symp = (struct nlist *) + realloc(symp, + (i+1)*sizeof(struct nlist)); + if (symp == NULL) + error(1, "out of memory"); + symp[i++] = sym; + } + if (archive && ftell(fi)+sizeof(off_t) >= off) { + error(0, "no string table (old format .o?)"); continue; } - fseek(fi, 0L, 0); - if (arch_flg) { - nextel(fi); - if (narg > 1) - printf("\n%s:\n", *argv); + if (fread((char *)&strsiz,sizeof(strsiz),1,fi) != 1) { + error(0, "no string table (old format .o?)"); + goto out; } - do { - long o; - register i, n, c; - struct nlist *symp = NULL; - struct nlist sym; - - fread((char *)&exp, 1, sizeof(struct exec), fi); - if (BADMAG) /* archive element not in */ - continue; /* proper format - skip it */ - o = (long)exp.a_text + exp.a_data + exp.a_trsize + exp.a_drsize; - if (MAGIC==0412 || MAGIC==0413) - o += PAGSIZ - sizeof(struct exec); - fseek(fi, o, 1); - n = exp.a_syms / sizeof(struct nlist); - if (n == 0) { - fprintf(stderr, "nm: %s-- no name list\n", SELECT); - continue; - } - i = 0; - while (--n >= 0) { - fread((char *)&sym, 1, sizeof(sym), fi); - if (globl_flg && (sym.n_type&N_EXT)==0) - continue; - if (symp==NULL) - symp = (struct nlist *)malloc(sizeof(struct nlist)); - else { - symp = (struct nlist *)realloc(symp, (i+1)*sizeof(struct nlist)); - } - if (symp == NULL) { - fprintf(stderr, "nm: out of memory on %s\n", *argv); - exit(2); - } - symp[i++] = sym; + strp = (char *)malloc(strsiz); + if (strp == NULL) + error(1, "ran out of memory"); + if (fread(strp+sizeof(strsiz),strsiz-sizeof(strsiz),1,fi) != 1) + error(1, "error reading string table"); + for (j = 0; j < i; j++) + if (symp[j].n_un.n_strx) + symp[j].n_un.n_name = + symp[j].n_un.n_strx + strp; + else + symp[j].n_un.n_name = ""; + if (pflg==0) + qsort(symp, i, sizeof(struct nlist), compare); + if ((archive || narg>1) && oflg==0) + printf("\n%s:\n", SELECT); + psyms(symp, i); + if (symp) + free((char *)symp), symp = 0; + if (strp) + free((char *)strp), strp = 0; + } while(archive && nextel(fi)); +out: + fclose(fi); +} + +psyms(symp, nsyms) + register struct nlist *symp; + int nsyms; +{ + register int n, c; + + for (n=0; n1) && prep_flg==0) - printf("\n%s:\n", SELECT); - for (n=0; nn_value > p2->n_value) - return(revsort_flg); + return(rflg); if (p1->n_value < p2->n_value) - return(-revsort_flg); + return(-rflg); } - for(i=0; in_name); i++) - if (p1->n_name[i] != p2->n_name[i]) { - if (p1->n_name[i] > p2->n_name[i]) - return(revsort_flg); - else - return(-revsort_flg); - } - return(0); + return (rflg * strcmp(p1->n_un.n_name, p2->n_un.n_name)); } nextel(af) FILE *af; { + register char *cp; register r; + long arsize; fseek(af, off, 0); - r = fread((char *)&arp, 1, sizeof(struct ar_hdr), af); /* read archive header */ - if (r <= 0) + r = fread((char *)&archdr, 1, sizeof(struct ar_hdr), af); + if (r != sizeof(struct ar_hdr)) return(0); - if (arp.ar_size & 1) - ++arp.ar_size; - off = ftell(af) + arp.ar_size; /* offset to next element */ + for (cp = archdr.ar_name; cp < &archdr.ar_name[sizeof(archdr.ar_name)]; cp++) + if (*cp == ' ') + *cp = '\0'; + arsize = atol(archdr.ar_size); + if (arsize & 1) + ++arsize; + off = ftell(af) + arsize; /* beginning of next element */ return(1); } + +error(n, s) +char *s; +{ + fprintf(stderr, "nm: %s:", *xargv); + if (archive) { + fprintf(stderr, "(%s)", archdr.ar_name); + fprintf(stderr, ": "); + } else + fprintf(stderr, " "); + fprintf(stderr, "%s\n", s); + if (n) + exit(2); + errs = 1; +} + +struct stabnames { + int st_value; + char *st_name; +} stabnames[] ={ + N_GSYM, "GSYM", + N_FNAME, "FNAME", + N_FUN, "FUN", + N_STSYM, "STSYM", + N_LCSYM, "LCSYM", + N_RSYM, "RSYM", + N_SLINE, "SLINE", + N_SSYM, "SSYM", + N_SO, "SO", + N_LSYM, "LSYM", + N_SOL, "SOL", + N_PSYM, "PSYM", + N_ENTRY, "ENTRY", + N_LBRAC, "LBRAC", + N_RBRAC, "RBRAC", + N_BCOMM, "BCOMM", + N_ECOMM, "ECOMM", + N_ECOML, "ECOML", + N_LENG, "LENG", + N_PC, "PC", + 0, 0 +}; + +char * +stab(val) +{ + register struct stabnames *sp; + static char prbuf[32]; + + for (sp = stabnames; sp->st_name; sp++) + if (sp->st_value == val) + return (sp->st_name); + sprintf(prbuf, "%02x", val); + return (prbuf); +}