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