home *** CD-ROM | disk | FTP | other *** search
/ minnie.tuhs.org / unixen.tar / unixen / PDP-11 / Trees / V7 / usr / src / cmd / nm.c < prev    next >
Encoding:
C/C++ Source or Header  |  1979-01-10  |  4.3 KB  |  232 lines

  1. /*
  2. **    print symbol tables for
  3. **    object or archive files
  4. **
  5. **    nm [-goprun] [name ...]
  6. */
  7.  
  8.  
  9.  
  10. #include    <ar.h>
  11. #include    <a.out.h>
  12. #include    <stdio.h>
  13. #include    <ctype.h>
  14. #define    MAGIC    exp.a_magic
  15. #define    BADMAG    MAGIC!=A_MAGIC1 && MAGIC!=A_MAGIC2  \
  16.         && MAGIC!=A_MAGIC3 && MAGIC!=A_MAGIC4
  17. #define    SELECT    arch_flg ? arp.ar_name : *argv
  18. int    numsort_flg;
  19. int    undef_flg;
  20. int    revsort_flg = 1;
  21. int    globl_flg;
  22. int    nosort_flg;
  23. int    arch_flg;
  24. int    prep_flg;
  25. struct    ar_hdr    arp;
  26. struct    exec    exp;
  27. FILE    *fi;
  28. long    off;
  29. long    ftell();
  30. char    *malloc();
  31. char    *realloc();
  32.  
  33. main(argc, argv)
  34. char **argv;
  35. {
  36.     int narg;
  37.     int  compare();
  38.  
  39.     if (--argc>0 && argv[1][0]=='-' && argv[1][1]!=0) {
  40.         argv++;
  41.         while (*++*argv) switch (**argv) {
  42.         case 'n':        /* sort numerically */
  43.             numsort_flg++;
  44.             continue;
  45.  
  46.         case 'g':        /* globl symbols only */
  47.             globl_flg++;
  48.             continue;
  49.  
  50.         case 'u':        /* undefined symbols only */
  51.             undef_flg++;
  52.             continue;
  53.  
  54.         case 'r':        /* sort in reverse order */
  55.             revsort_flg = -1;
  56.             continue;
  57.  
  58.         case 'p':        /* don't sort -- symbol table order */
  59.             nosort_flg++;
  60.             continue;
  61.  
  62.         case 'o':        /* prepend a name to each line */
  63.             prep_flg++;
  64.             continue;
  65.  
  66.         default:        /* oops */
  67.             fprintf(stderr, "nm: invalid argument -%c\n", *argv[0]);
  68.             exit(1);
  69.         }
  70.         argc--;
  71.     }
  72.     if (argc == 0) {
  73.         argc = 1;
  74.         argv[1] = "a.out";
  75.     }
  76.     narg = argc;
  77.     while(argc--) {
  78.         fi = fopen(*++argv,"r");
  79.         if (fi == NULL) {
  80.             fprintf(stderr, "nm: cannot open %s\n", *argv);
  81.             continue;
  82.         }
  83.         off = sizeof(exp.a_magic);
  84.         fread((char *)&exp, 1, sizeof(MAGIC), fi);    /* get magic no. */
  85.         if (MAGIC == ARMAG)
  86.             arch_flg++;
  87.         else if (BADMAG) {
  88.             fprintf(stderr, "nm: %s-- bad format\n", *argv);
  89.             continue;
  90.         }
  91.         fseek(fi, 0L, 0);
  92.         if (arch_flg) {
  93.             nextel(fi);
  94.             if (narg > 1)
  95.                 printf("\n%s:\n", *argv);
  96.         }
  97.         do {
  98.             long o;
  99.             register i, n, c;
  100.             struct nlist *symp = NULL;
  101.             struct nlist sym;
  102.  
  103.             fread((char *)&exp, 1, sizeof(struct exec), fi);
  104.             if (BADMAG)        /* archive element not in  */
  105.                 continue;    /* proper format - skip it */
  106.             o = (long)exp.a_text + exp.a_data;
  107.             if ((exp.a_flag & 01) == 0)
  108.                 o *= 2;
  109.             fseek(fi, o, 1);
  110.             n = exp.a_syms / sizeof(struct nlist);
  111.             if (n == 0) {
  112.                 fprintf(stderr, "nm: %s-- no name list\n", SELECT);
  113.                 continue;
  114.             }
  115.             i = 0;
  116.             while (--n >= 0) {
  117.                 fread((char *)&sym, 1, sizeof(sym), fi);
  118.                 if (globl_flg && (sym.n_type&N_EXT)==0)
  119.                     continue;
  120.                 switch (sym.n_type&N_TYPE) {
  121.  
  122.                 case N_UNDF:
  123.                     c = 'u';
  124.                     if (sym.n_value)
  125.                         c = 'c';
  126.                     break;
  127.  
  128.                 default:
  129.                 case N_ABS:
  130.                     c = 'a';
  131.                     break;
  132.  
  133.                 case N_TEXT:
  134.                     c = 't';
  135.                     break;
  136.  
  137.                 case N_DATA:
  138.                     c = 'd';
  139.                     break;
  140.  
  141.                 case N_BSS:
  142.                     c = 'b';
  143.                     break;
  144.  
  145.                 case N_FN:
  146.                     c = 'f';
  147.                     break;
  148.  
  149.                 case N_REG:
  150.                     c = 'r';
  151.                     break;
  152.                 }
  153.                 if (undef_flg && c!='u')
  154.                     continue;
  155.                 if (sym.n_type&N_EXT)
  156.                     c = toupper(c);
  157.                 sym.n_type = c;
  158.                 if (symp==NULL)
  159.                     symp = (struct nlist *)malloc(sizeof(struct nlist));
  160.                 else {
  161.                     symp = (struct nlist *)realloc(symp, (i+1)*sizeof(struct nlist));
  162.                 }
  163.                 if (symp == NULL) {
  164.                     fprintf(stderr, "nm: out of memory on %s\n", *argv);
  165.                     exit(2);
  166.                 }
  167.                 symp[i++] = sym;
  168.             }
  169.             if (nosort_flg==0)
  170.                 qsort(symp, i, sizeof(struct nlist), compare);
  171.             if ((arch_flg || narg>1) && prep_flg==0)
  172.                 printf("\n%s:\n", SELECT);
  173.             for (n=0; n<i; n++) {
  174.                 if (prep_flg) {
  175.                     if (arch_flg)
  176.                         printf("%s:", *argv);
  177.                     printf("%s:", SELECT);
  178.                 }
  179.                 c = symp[n].n_type;
  180.                 if (!undef_flg) {
  181.                     if (c=='u' || c=='U')
  182.                         printf("      ");
  183.                     else
  184.                         printf(FORMAT, symp[n].n_value);
  185.                     printf(" %c ", c);
  186.                 }
  187.                 printf("%.8s\n", symp[n].n_name);
  188.             }
  189.             if (symp)
  190.                 free((char *)symp);
  191.         } while(arch_flg && nextel(fi));
  192.         fclose(fi);
  193.     }
  194.     exit(0);
  195. }
  196.  
  197. compare(p1, p2)
  198. struct nlist *p1, *p2;
  199. {
  200.     register i;
  201.  
  202.     if (numsort_flg) {
  203.         if (p1->n_value > p2->n_value)
  204.             return(revsort_flg);
  205.         if (p1->n_value < p2->n_value)
  206.             return(-revsort_flg);
  207.     }
  208.     for(i=0; i<sizeof(p1->n_name); i++)
  209.         if (p1->n_name[i] != p2->n_name[i]) {
  210.             if (p1->n_name[i] > p2->n_name[i])
  211.                 return(revsort_flg);
  212.             else
  213.                 return(-revsort_flg);
  214.         }
  215.     return(0);
  216. }
  217.  
  218. nextel(af)
  219. FILE *af;
  220. {
  221.     register r;
  222.  
  223.     fseek(af, off, 0);
  224.     r = fread((char *)&arp, 1, sizeof(struct ar_hdr), af);  /* read archive header */
  225.     if (r <= 0)
  226.         return(0);
  227.     if (arp.ar_size & 1)
  228.         ++arp.ar_size;
  229.     off = ftell(af) + arp.ar_size;    /* offset to next element */
  230.     return(1);
  231. }
  232.