home *** CD-ROM | disk | FTP | other *** search
/ Fresh Fish 9 / FreshFishVol9-CD2.bin / bbs / gnu / binutils-1.8.x-src.lha / binutils-1.8.x / objdump.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-09-22  |  7.5 KB  |  344 lines

  1. /* objdump -- dump information about an object file.
  2.    Copyright (C) 1988, Free Software Foundation, Inc.
  3.  
  4.    This program is free software; you can redistribute it and/or modify
  5.    it under the terms of the GNU General Public License as published by
  6.    the Free Software Foundation; either version 1, or (at your option)
  7.    any later version.
  8.  
  9.    This program is distributed in the hope that it will be useful,
  10.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  11.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12.    GNU General Public License for more details.
  13.  
  14.    You should have received a copy of the GNU General Public License
  15.    along with this program; if not, write to the Free Software
  16.    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
  17.  
  18. /*
  19.  * objdump
  20.  * 
  21.  * dump information about an object file.  Until there is other documentation,
  22.  * refer to the manual page dump(1) in the system 5 program's reference manual
  23.  */
  24. #include <stdio.h>
  25. #include "getopt.h"
  26.  
  27. #ifdef MCH_AMIGA
  28. #define getpagesize() 256
  29. #endif
  30.  
  31. #ifndef COFF_ENCAPSULATE
  32. #include <sun/a.out.h>
  33. /* Tell a.out.gnu.h not to try to redefine some things.  */
  34. #define __STRUCT_EXEC_OVERRIDE__
  35. #define N_NLIST_DECLARED
  36. #define N_RELOCATION_INFO_DECLARED
  37. #define N_MAGIC(exec) ((exec).a_magic)
  38. #include "a.out.gnu.h"
  39. #else
  40. #include "a.out.encap.h"
  41. #endif
  42.  
  43. char *malloc();
  44. char *xmalloc();
  45. int nsyms;
  46. struct nlist *symtbl;
  47. char *strtbl;
  48. int strsize;
  49. char *program_name;
  50.  
  51. read_symbols (execp, f)
  52. struct exec *execp;
  53. FILE *f;
  54. {
  55.     int i;
  56.     struct nlist *sp;
  57.     if (symtbl)
  58.         return;
  59.     nsyms = execp->a_syms / sizeof (struct nlist);
  60.     if (nsyms == 0)
  61.         return;
  62.  
  63.     symtbl = (struct nlist *)xmalloc (nsyms * sizeof (struct nlist));
  64.  
  65.     fseek (f, N_STROFF(*execp), 0);
  66.     if (fread ((char *)&strsize, sizeof strsize, 1, f) != 1) {
  67.         fprintf (stderr, "%s: can not read string table size\n",
  68.              program_name);
  69.         exit (1);
  70.     }
  71.     strtbl = xmalloc (strsize);
  72.     fseek (f, N_STROFF (*execp), 0);
  73.     if (fread (strtbl, 1, strsize, f) != strsize) {
  74.         fprintf (stderr, "%s: error reading string table\n",
  75.              program_name);
  76.         exit (1);
  77.     }
  78.  
  79.     fseek (f, N_SYMOFF (*execp), 0);
  80.     if (fread ((char *)symtbl, sizeof (struct nlist), nsyms, f) != nsyms) {
  81.         fprintf (stderr, "%s: error reading symbol table\n",
  82.              program_name);
  83.         exit (1);
  84.     }
  85.  
  86.     for (i = 0, sp = symtbl; i < nsyms; i++, sp++) {
  87.         if (sp->n_un.n_strx == 0)
  88.             sp->n_un.n_name = "";
  89.         else if (sp->n_un.n_strx < 0 || sp->n_un.n_strx > strsize)
  90.             sp->n_un.n_name = "<bad string table index>";
  91.         else
  92.             sp->n_un.n_name = strtbl + sp->n_un.n_strx;
  93.     }
  94. }
  95.  
  96. free_symbols ()
  97. {
  98.     if (symtbl)
  99.         free (symtbl);
  100.     symtbl = NULL;
  101.     if (strtbl)
  102.         free (strtbl);
  103.     strtbl = NULL;
  104. }
  105.  
  106.  
  107. usage ()
  108. {
  109.     fprintf (stderr, "\
  110. Usage: %s [-hnrt] [+header] [+nstuff] [+reloc] [+symbols] file...\n",
  111.          program_name);
  112.     exit (1);
  113. }
  114.  
  115. int hflag;
  116. int nflag;
  117. int rflag;
  118. int tflag;
  119.  
  120. /* Size of a page.  Required by N_DATADDR in a.out.gnu.h [VAX].  */
  121. int page_size;
  122.  
  123. main (argc, argv)
  124. char **argv;
  125. {
  126.     int c;
  127.     extern char *optarg;
  128.     extern int optind;
  129.     int seenflag = 0;
  130.     int ind = 0;
  131.     static struct option long_options[] = 
  132.       {
  133.         {"symbols",   0, &tflag, 1},
  134.         {"reloc",  0, &rflag, 1},
  135.         {"nstuff", 0, &nflag, 1},
  136.         {"header", 0, &hflag, 1},
  137.         {NULL, 0, NULL, 0}
  138.       };
  139.  
  140.     page_size = getpagesize ();
  141.  
  142.     program_name = argv[0];
  143.                   
  144.     while ((c = getopt_long (argc, argv, "hnrt", long_options, &ind))
  145.                != EOF) {
  146.         seenflag = 1;
  147.         switch (c) {
  148.         case  0 : break; /* we've been given a long option */
  149.         case 't': tflag = 1; break;
  150.         case 'r': rflag = 1; break;
  151.         case 'n': nflag = 1; break;
  152.         case 'h': hflag = 1; break;
  153.         default:
  154.             usage ();
  155.         }
  156.     }
  157.  
  158.     if (seenflag == 0 || optind == argc)
  159.         usage ();
  160.  
  161.     while (optind < argc)
  162.         doit (argv[optind++]);
  163. }
  164.  
  165. doit (name)
  166. char *name;
  167. {
  168.     FILE *f;
  169.     struct exec exec;
  170.     printf ("%s:\n", name);
  171.     f = fopen (name, "r");
  172.     if (f == NULL) {
  173.         fprintf (stderr, "%s: can not open ", program_name);
  174.         perror (name);
  175.         return;
  176.     }
  177. #ifdef HEADER_SEEK
  178.     HEADER_SEEK (f);
  179. #endif
  180.     if (fread ((char *)&exec, sizeof exec, 1, f) != 1) {
  181.         fprintf (stderr, "%s: can not read header for %s\n",
  182.              program_name, name);
  183.         return;
  184.     }
  185.  
  186.     if (N_BADMAG (exec)) {
  187.         fprintf (stderr, "%s: %s is not an object file\n",
  188.              program_name, name);
  189.         return;
  190.     }
  191.  
  192.     if (hflag)
  193.         dump_header (&exec);
  194.  
  195.     if (nflag)
  196.         dump_nstuff (&exec);
  197.  
  198.     if (tflag)
  199.         dump_sym (&exec, f);
  200.  
  201.     if (rflag)
  202.         dump_reloc (&exec, f);
  203.  
  204.     free_symbols ();
  205.  
  206. }
  207.  
  208. dump_header (execp)
  209. struct exec *execp;
  210. {
  211.     int x;
  212.  
  213. #if defined (__GNU_EXEC_MACROS__) && !defined (__STRUCT_EXEC_OVERRIDE__)
  214.     printf ("magic: 0x%x (%o)", N_MAGIC(*execp), N_MAGIC(*execp));
  215.     printf ("machine type: %d", N_MACHTYPE(*execp));
  216.     printf ("flags: 0x%x", N_FLAGS(*execp));
  217. #else /* non-gnu struct exec.  */
  218.     printf ("magic: 0x%x (%o) ", execp->a_magic, execp->a_magic);
  219. #endif /* non-gnu struct exec.  */
  220.     printf ("text 0x%x ", execp->a_text);
  221.     printf ("data 0x%x ", execp->a_data);
  222.     printf ("bss 0x%x\n", execp->a_bss);
  223.     printf ("nsyms %d", execp->a_syms / sizeof (struct nlist));
  224.     x = execp->a_syms % sizeof (struct nlist);
  225.     if (x) 
  226.         printf (" (+ %d bytes)", x);
  227.     printf (" entry 0x%x ", execp->a_entry);
  228.     printf ("trsize 0x%x ", execp->a_trsize);
  229.     printf ("drsize 0x%x\n", execp->a_drsize);
  230. }
  231.  
  232. dump_nstuff (execp)
  233. struct exec *execp;
  234. {
  235.     printf ("N_BADMAG %d\n", N_BADMAG (*execp));
  236.     printf ("N_TXTOFF 0x%x\n", N_TXTOFF (*execp));
  237.     printf ("N_SYMOFF 0x%x\n", N_SYMOFF (*execp));
  238.     printf ("N_STROFF 0x%x\n", N_STROFF (*execp));
  239.     printf ("N_TXTADDR 0x%x\n", N_TXTADDR (*execp));
  240.     printf ("N_DATADDR 0x%x\n", N_DATADDR (*execp));
  241. }
  242.  
  243. dump_sym (execp, f)
  244. struct exec *execp;
  245. FILE *f;
  246. {
  247.     int i;
  248.     struct nlist *sp;
  249.  
  250.     read_symbols (execp, f);
  251.     if (nsyms == 0) {
  252.         printf ("no symbols\n");
  253.         return;
  254.     }
  255.  
  256.     printf ("%3s: %4s %5s %4s %8s\n",
  257.         "#", "type", "other", "desc", "val");
  258.     for (i = 0, sp = symtbl; i < nsyms; i++, sp++) {
  259.         printf ("%3d: %4x %5x %4x %8x %s\n",
  260.             i,
  261.             sp->n_type & 0xff,
  262.             sp->n_other & 0xff,
  263.             sp->n_desc & 0xffff,
  264.             sp->n_value,
  265.             sp->n_un.n_name);
  266.     }
  267. }
  268.  
  269. dump_reloc (execp, f)
  270. struct exec *execp;
  271. FILE *f;
  272. {
  273.     read_symbols (execp, f);
  274.     if (execp->a_trsize) {
  275.         printf ("text reloc\n");
  276.         dump_reloc1 (execp, f, N_TRELOFF (*execp), execp->a_trsize);
  277.     }
  278.     if (execp->a_drsize) {
  279.         printf ("data reloc\n");
  280.         dump_reloc1 (execp, f, N_DRELOFF (*execp), execp->a_drsize);
  281.     }
  282. }
  283.  
  284. dump_reloc1 (execp, f, off, size)
  285. struct exec *execp;
  286. FILE *f;
  287. {
  288.     int nreloc;
  289.     struct relocation_info reloc;
  290.     int i;
  291.  
  292.     nreloc = size / sizeof (struct relocation_info);
  293.  
  294.     printf ("%3s: %3s %8s %4s\n", "#", "len", "adr", "sym");
  295.     fseek (f, off, 0);
  296.     for (i = 0; i < nreloc; i++) {
  297.         if (fread ((char *)&reloc, sizeof reloc, 1, f) != 1) {
  298.             fprintf (stderr, "%s: error reading reloc\n",
  299.                  program_name);
  300.             return;
  301.         }
  302.         printf ("%3d: %3d %8x ", i, 1 << reloc.r_length,
  303.             reloc.r_address);
  304.         
  305.         if (reloc.r_extern) {
  306.             printf ("%4d ", reloc.r_symbolnum);
  307.             if (reloc.r_symbolnum < nsyms)
  308.                 printf ("%s ",
  309.                     symtbl[reloc.r_symbolnum].n_un.n_name);
  310.         } else {
  311.             printf ("     ");
  312.             switch (reloc.r_symbolnum & ~N_EXT) {
  313.             case N_TEXT: printf (".text "); break;
  314.             case N_DATA: printf (".data "); break;
  315.             case N_BSS: printf (".bss "); break;
  316.             case N_ABS: printf (".abs "); break;
  317.             default: printf ("base %x ", reloc.r_symbolnum); break;
  318.             }
  319.         }
  320.         if (reloc.r_pcrel) printf ("PCREL ");
  321. #if 0
  322.         if (reloc.r_pad) printf ("PAD %x ", reloc.r_pad);
  323. #endif
  324.         printf ("\n");
  325.     }
  326. }
  327.  
  328. /* Allocate `n' bytes of memory dynamically, with error checking.  */
  329.  
  330. char *
  331. xmalloc (n)
  332.      unsigned n;
  333. {
  334.   char *p;
  335.  
  336.   p = malloc (n);
  337.   if (p == 0)
  338.     {
  339.       fprintf (stderr, "%s: virtual memory exhausted\n", program_name);
  340.       exit (1);
  341.     }
  342.   return p;
  343. }
  344.