home *** CD-ROM | disk | FTP | other *** search
- /*
- ** print symbol tables for
- ** object or archive files
- **
- ** nm [-goprun] [name ...]
- */
-
-
-
- #include <ar.h>
- #include <a.out.h>
- #include <stdio.h>
- #include <ctype.h>
- #define MAGIC exp.a_magic
- #define BADMAG MAGIC!=A_MAGIC1 && MAGIC!=A_MAGIC2 \
- && MAGIC!=A_MAGIC3 && MAGIC!=A_MAGIC4
- #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;
- FILE *fi;
- long off;
- long ftell();
- char *malloc();
- char *realloc();
-
- 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++;
- continue;
-
- case 'u': /* undefined symbols only */
- undef_flg++;
- continue;
-
- case 'r': /* sort in reverse order */
- revsort_flg = -1;
- continue;
-
- case 'p': /* don't sort -- symbol table order */
- nosort_flg++;
- continue;
-
- case 'o': /* prepend a name to each line */
- prep_flg++;
- continue;
-
- default: /* oops */
- fprintf(stderr, "nm: invalid argument -%c\n", *argv[0]);
- exit(1);
- }
- argc--;
- }
- if (argc == 0) {
- argc = 1;
- argv[1] = "a.out";
- }
- narg = argc;
- while(argc--) {
- fi = fopen(*++argv,"r");
- if (fi == NULL) {
- fprintf(stderr, "nm: cannot open %s\n", *argv);
- 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);
- continue;
- }
- fseek(fi, 0L, 0);
- if (arch_flg) {
- nextel(fi);
- if (narg > 1)
- printf("\n%s:\n", *argv);
- }
- 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;
- if ((exp.a_flag & 01) == 0)
- o *= 2;
- 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;
- switch (sym.n_type&N_TYPE) {
-
- case N_UNDF:
- c = 'u';
- if (sym.n_value)
- c = 'c';
- break;
-
- default:
- case N_ABS:
- c = 'a';
- break;
-
- case N_TEXT:
- c = 't';
- break;
-
- case N_DATA:
- c = 'd';
- break;
-
- case N_BSS:
- c = 'b';
- break;
-
- case N_FN:
- c = 'f';
- break;
-
- case N_REG:
- c = 'r';
- break;
- }
- if (undef_flg && c!='u')
- continue;
- if (sym.n_type&N_EXT)
- c = toupper(c);
- sym.n_type = c;
- 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;
- }
- if (nosort_flg==0)
- qsort(symp, i, sizeof(struct nlist), compare);
- if ((arch_flg || narg>1) && prep_flg==0)
- printf("\n%s:\n", SELECT);
- for (n=0; n<i; n++) {
- if (prep_flg) {
- if (arch_flg)
- printf("%s:", *argv);
- printf("%s:", SELECT);
- }
- c = symp[n].n_type;
- if (!undef_flg) {
- if (c=='u' || c=='U')
- printf(" ");
- else
- printf(FORMAT, symp[n].n_value);
- printf(" %c ", c);
- }
- printf("%.8s\n", symp[n].n_name);
- }
- if (symp)
- free((char *)symp);
- } while(arch_flg && nextel(fi));
- fclose(fi);
- }
- exit(0);
- }
-
- compare(p1, p2)
- struct nlist *p1, *p2;
- {
- register i;
-
- if (numsort_flg) {
- if (p1->n_value > p2->n_value)
- return(revsort_flg);
- if (p1->n_value < p2->n_value)
- return(-revsort_flg);
- }
- for(i=0; i<sizeof(p1->n_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);
- }
-
- nextel(af)
- FILE *af;
- {
- register r;
-
- fseek(af, off, 0);
- r = fread((char *)&arp, 1, sizeof(struct ar_hdr), af); /* read archive header */
- if (r <= 0)
- return(0);
- if (arp.ar_size & 1)
- ++arp.ar_size;
- off = ftell(af) + arp.ar_size; /* offset to next element */
- return(1);
- }
-