Research V7 development
authorDennis Ritchie <dmr@research.uucp>
Wed, 10 Jan 1979 20:02:03 +0000 (15:02 -0500)
committerDennis Ritchie <dmr@research.uucp>
Wed, 10 Jan 1979 20:02:03 +0000 (15:02 -0500)
Work on file usr/src/cmd/nm.c

Co-Authored-By: Ken Thompson <ken@research.uucp>
Synthesized-from: v7

usr/src/cmd/nm.c [new file with mode: 0644]

diff --git a/usr/src/cmd/nm.c b/usr/src/cmd/nm.c
new file mode 100644 (file)
index 0000000..2d3ee27
--- /dev/null
@@ -0,0 +1,231 @@
+/*
+**     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);
+}