home *** CD-ROM | disk | FTP | other *** search
/ GEMini Atari / GEMini_Atari_CD-ROM_Walnut_Creek_December_1993.iso / zip / gnu / utlsrc33.lzh / UTLSRC33 / CNM.C < prev    next >
C/C++ Source or Header  |  1993-07-30  |  7KB  |  381 lines

  1. /* Copyright (c) 1988 by Sozobon, Limited.  Author: Johann Ruegg
  2.  *
  3.  * Permission is granted to anyone to use this software for any purpose
  4.  * on any computer system, and to redistribute it freely, with the
  5.  * following restrictions:
  6.  * 1) No charge may be made other than reasonable charges for reproduction.
  7.  * 2) Modified versions must be clearly marked as such.
  8.  * 3) The authors are not responsible for any harmful consequences
  9.  *    of using this software, even if they result from defects in it.
  10.  *
  11.  *    Alternative ST symbol table lister.
  12.  */
  13.  
  14. /* highly munged from above, VERY quick and dirty nm, just enough
  15.    here to find _stksize for fixstk.c and printstk.c, may be
  16.    useful for other stuff.
  17.  
  18.    WARNING: -g option will not work with gcc-ld produced a.out
  19.  
  20.  
  21.      ++jrb
  22.  */
  23.  /*
  24.  * Modified to handle expanded, GST linker derived, format for symbols.
  25.  * This format is produced with -G flag to a proper version of gcc-ld.
  26.  * -g flag also will work if ld coached properly.
  27.  *
  28.  *   --mj
  29.  */
  30.  
  31. /*
  32.  * ++jrb rework and cleanup while adding A_TFILE A_TFARC
  33.  */
  34.  
  35. #include <compiler.h>
  36. #include <stdio.h>
  37. #include <st-out.h>
  38.  
  39. #if __STDC__
  40. #include <stdlib.h>
  41. #else
  42. extern char *malloc(), *realloc();
  43. #endif
  44.  
  45. #ifdef atarist
  46. # define READB    "rb"
  47. #else
  48. # define READB "r"
  49. #endif
  50.  
  51. #if !__STDC__ && !defined(hpux)
  52. typedef unsigned long size_t;
  53. #endif
  54.  
  55. #ifndef WORD_ALIGNED
  56. # define SIZEOF_SYM ((size_t)sizeof(struct asym))
  57. #else
  58. # define SIZEOF_SYM ((size_t)14)
  59. #endif
  60.  
  61. struct xsym {
  62.     char name[8];
  63.     union {
  64.     unsigned char  _flags[2];
  65.     unsigned short _sflgs;
  66.     } u;
  67.     unsigned long value;
  68.     char tail[SIZEOF_SYM];
  69. };
  70.  
  71. #define flags    u._flags[0]
  72. #define xflags  u._flags[1]
  73. #define sflgs   u._sflgs
  74.  
  75. #ifdef __STDC__
  76. # define P(s) s
  77. #else
  78. # define P(s) ()
  79. #endif
  80.  
  81. int main P((int argc , char **argv ));
  82. int cmp P((struct xsym *s1 , struct xsym *s2 ));
  83. int doname P((char *s , int many ));
  84. long dohdr P((FILE *fd ));
  85. void dosym P((struct xsym *s ));
  86. int not_glob P((unsigned int x ));
  87. void sflags P((struct xsym *s ));
  88. void ckfread P((void *buf , int siz , int n , FILE *fp ));
  89. long readhead P((struct aexec *h , int n , FILE *fd ));
  90. int readsyms P((struct xsym *syms , int n , FILE *fd ));
  91. void usage P((void ));
  92.  
  93. #undef P
  94.  
  95.  
  96. int gflag;
  97.  
  98. int main(argc, argv)
  99. int argc;
  100. char **argv;
  101. {
  102.     int c, status = 0;
  103.     extern char *optarg;
  104.     extern int optind;
  105.     while ((c = getopt(argc, argv, "g")) != -1)
  106.     switch (c)
  107.     {
  108.       case 'g':
  109.         gflag = 1;
  110.         break;
  111.       case '?':
  112.         usage();
  113.     }
  114.     c = argc - optind;
  115.     if(c <= 0)
  116.     usage();
  117.     
  118.     for (; optind < argc; optind++) 
  119.     status |= doname(argv[optind], (c > 1));
  120.     return status;
  121. }
  122.  
  123. int  cmp(s1, s2)
  124. struct xsym *s1, *s2;
  125. {
  126.     return(s1->value - s2->value);
  127. }
  128.  
  129. int doname(s, many)
  130. char *s;
  131. int many;
  132. {
  133.     FILE *fd, *fopen();
  134.     long i, count;
  135.  
  136.     if(!(fd = fopen(s, READB)))
  137.     {
  138.     perror(s);
  139.     return 2;
  140.     }
  141.     if (many)
  142.     printf("\n%s:\n", s);
  143.  
  144.     if (i = dohdr(fd))
  145.     {
  146.     struct xsym *syms, *savesyms;
  147.     struct xsym *currsym;
  148.     printf("%ld slots mem %ld\n", i, (long)(i*sizeof(struct xsym)));
  149.     
  150.     if((savesyms = syms = (struct xsym *)malloc(i*sizeof(struct xsym))) == NULL)
  151.     {
  152.         perror("Outa mem");
  153.         exit(4);
  154.     }
  155.     count = i;
  156.     currsym = syms;
  157.     while (count)
  158.     {
  159.         if(readsyms(currsym, 1, fd) != 1)
  160.         {
  161.         perror("reading syms");
  162.         exit(8);
  163.         }
  164.         if (--count)
  165.         {
  166.         if (A_LNAM == (currsym->xflags & A_LNAM))
  167.         {
  168.             if(fread(currsym->tail, SIZEOF_SYM, 1, fd) != 1)
  169.             {
  170.             perror("reading syms");
  171.             exit(16);
  172.             }
  173.             --i;
  174.             --count;
  175.         }
  176.         }
  177.         else /* object was partially stripped */
  178.         currsym->xflags &= ~A_LNAM;        
  179.         if (gflag && not_glob((unsigned int)(currsym->flags)))
  180.         --i;
  181.         else
  182.         currsym++;
  183.     }
  184.     fclose(fd);
  185.     printf("%ld %s symbol(s)\n", i, (gflag ? "global ": ""));
  186.     qsort(syms, i, sizeof(struct xsym), cmp);
  187.     while (i--)
  188.     {
  189.         dosym(syms);
  190.         syms += 1;
  191.     }
  192.     free(savesyms);
  193.     }
  194.     return 0;
  195. }
  196.  
  197. long dohdr(fd)
  198. FILE *fd;
  199. {
  200.     struct aexec h;
  201.     long i;
  202.         
  203.     i = readhead(&h, 1, fd);
  204.     if (i != 1 || h.a_magic != CMAGIC)
  205.     {
  206.     fprintf(stderr, "Bad header\n");
  207.     return 0L;
  208.     }
  209.     fseek(fd, (h.a_text + h.a_data), 1);
  210.     return h.a_syms / SIZEOF_SYM;
  211. }
  212.  
  213. void
  214. dosym(s)
  215. struct xsym *s;
  216. {
  217.     printf("%-8.8s", s->name);
  218.     printf("%-14.14s", (A_LNAM == (s->xflags & A_LNAM) ? s->tail : ""));
  219.     printf("\t%8lx ", s->value);
  220.     s->xflags &= ~A_LNAM;
  221.     sflags(s);
  222.     putchar('\n');
  223. }
  224.  
  225. char *fname[] = {
  226.     "?0?", " bss", " text", "?3?", " data",
  227.     "?5?", "?6?", "?7?"
  228. };
  229. char *Fname[] = {
  230.     "?0?", "Bss", "Text", "?3?", "Data",
  231.     "?5?", "?6?", "?7?"
  232. };
  233.  
  234. int not_glob(x)
  235. unsigned int x;
  236. {
  237.     x &= 0xff;
  238.     if (x & 0x20)
  239.         return 0;
  240.     x &= ~0x20;
  241.     if (x == 0x88)
  242.         return 0;
  243.     return 1;
  244. }
  245.  
  246. void
  247. sflags(s)
  248. struct xsym *s;
  249. {
  250.     unsigned int x = s->flags;
  251.     char **category;
  252.     int lflag;
  253.     
  254.     if(s->sflgs == A_TFILE)
  255.     printf("text file");
  256.     else if (s->sflgs == A_TFARC)
  257.     printf("text file archive");
  258.     else
  259.     {
  260.     if (0 != (lflag = not_glob(x)))
  261.         category = fname;
  262.     else
  263.         category = Fname;
  264.  
  265.     x &= 0xff;
  266.     if (x & 0x20)
  267.         printf("global ");
  268.     x &= ~0x20;
  269.     if (x & 0xd8)
  270.     {
  271.         if (x & 0x08)
  272.         printf (" external");
  273.         if (x & 0x50)
  274.         {
  275.         printf (" equ");
  276.         if (x & 0x10)
  277.             printf (" reg");
  278.         }
  279.         if (x & 0x80)
  280.         printf (" abs");
  281.         if (!lflag)
  282.         printf(" G");
  283.     }
  284.     else
  285.     {
  286.         x &= 7;
  287.         printf(category[x]);
  288.     }
  289.     }
  290.     printf(" (0x%04x)",(unsigned int)(s->sflgs));
  291. }
  292.  
  293. void ckfread(buf, siz, n, fp)
  294. void *buf;
  295. int siz, n;
  296. FILE *fp;
  297. {
  298.     if(fread(buf, siz, n, fp) != n)
  299.     {
  300.         perror("reading");
  301.         exit(32);
  302.     }
  303. }
  304.  
  305. long readhead(h, n, fd)
  306. struct aexec *h;
  307. int n;
  308. FILE *fd;
  309. {
  310.     short i;
  311.     long j;
  312.     int k;
  313.  
  314.     for(k = 0; k < n; k++)
  315.     {
  316.     ckfread(&i, 2, 1, fd);
  317.     h->a_magic = i;
  318.     ckfread(&j, 4, 1, fd);
  319.     h->a_text = j;
  320.     ckfread(&j, 4, 1, fd);
  321.     h->a_data = j;
  322.     ckfread(&j, 4, 1, fd);
  323.     h->a_bss = j;
  324.     ckfread(&j, 4, 1, fd);
  325.     h->a_syms = j;
  326.     ckfread(&j, 4, 1, fd);
  327.     h->a_AZero1 = j;
  328.     ckfread(&j, 4, 1, fd);
  329.     h->a_ldflgs = j;
  330.     ckfread(&i, 2, 1, fd);
  331.     h->a_isreloc = i;
  332.     }
  333.     return k;
  334. }
  335.  
  336. int readsyms(syms, n, fd)
  337. struct xsym *syms;
  338. int n;
  339. FILE *fd;
  340. {
  341.     int k;
  342.  
  343.     for(k = 0; k < n; k++, syms++)
  344.     {
  345.     ckfread(syms->name, 8, 1, fd);
  346.     ckfread(&(syms->sflgs), 2, 1, fd);
  347.     ckfread(&(syms->value), 4, 1, fd);
  348.    }
  349.    return k;
  350. }
  351.  
  352. void usage()
  353. {
  354.     fprintf(stderr, "cnm [-g] files...\n");
  355.     exit(1);
  356. }
  357.  
  358. #if !defined(__GNUC__) &&  defined(hpux)
  359.  
  360. char *xmalloc(n)
  361. int n;    /* sigh! */
  362. {
  363.    char *ret = (char *)malloc(n);
  364.  
  365.    if(ret) return ret;
  366.    perror("malloc");
  367.    exit(1);
  368. }
  369.  
  370. char *xrealloc(b, n)
  371. char * b;
  372. int n;    /* sigh! */
  373. {
  374.    char *ret = (char *)realloc(b, n);
  375.  
  376.    if(ret) return ret;
  377.    perror("realloc");
  378.    exit(2);
  379. }
  380. #endif
  381.