aboutsummaryrefslogtreecommitdiff
path: root/binutils-1.9/objdump.c
diff options
context:
space:
mode:
Diffstat (limited to 'binutils-1.9/objdump.c')
-rw-r--r--binutils-1.9/objdump.c418
1 files changed, 418 insertions, 0 deletions
diff --git a/binutils-1.9/objdump.c b/binutils-1.9/objdump.c
new file mode 100644
index 0000000..94c5303
--- /dev/null
+++ b/binutils-1.9/objdump.c
@@ -0,0 +1,418 @@
+/* objdump -- print information about an object file.
+ Copyright (C) 1988, 1990 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 1, or (at your option)
+ any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include <stdio.h>
+#include <errno.h>
+extern int errno;
+#include "getopt.h"
+
+#ifndef COFF_ENCAPSULATE
+#include <a.out.h>
+/* Tell a.out.gnu.h not to try to redefine some things. */
+#define __STRUCT_EXEC_OVERRIDE__
+#define N_NLIST_DECLARED
+#define N_RELOCATION_INFO_DECLARED
+#define N_MAGIC(exec) ((exec).a_magic)
+#include "a.out.gnu.h"
+#else
+#include "a.out.encap.h"
+#endif
+
+char *malloc ();
+
+char *xmalloc ();
+void dump_file ();
+void dump_header ();
+void dump_nstuff ();
+void dump_reloc ();
+void dump_reloc1 ();
+void dump_sym ();
+void error ();
+void usage ();
+
+/* Symbol table. */
+struct nlist *symtbl;
+
+/* Number of elements in `symtbl'. */
+int nsyms;
+
+/* String table. */
+char *strtbl;
+
+/* Number of elements in `strtbl'. */
+int strsize;
+
+/* Name this program was run with. */
+char *program_name;
+
+/* Name of object file currently being processed. */
+char *filename;
+
+void
+read_symbols (execp, f)
+ struct exec *execp;
+ FILE *f;
+{
+ int i;
+ struct nlist *sp;
+
+ if (symtbl)
+ return;
+ nsyms = execp->a_syms / sizeof (struct nlist);
+ if (nsyms == 0)
+ return;
+
+ symtbl = (struct nlist *) xmalloc (nsyms * sizeof (struct nlist));
+
+ fseek (f, N_STROFF (*execp), 0);
+ if (fread ((char *) &strsize, sizeof strsize, 1, f) != 1)
+ error (1, errno, "%s: cannot read string table size", filename);
+ strtbl = xmalloc (strsize);
+ fseek (f, N_STROFF (*execp), 0);
+ if (fread (strtbl, 1, strsize, f) != strsize)
+ error (1, errno, "%s: cannot read string table", filename);
+
+ fseek (f, N_SYMOFF (*execp), 0);
+ if (fread ((char *) symtbl, sizeof (struct nlist), nsyms, f) != nsyms)
+ error (1, errno, "%s: cannot read symbol table", filename);
+
+ for (i = 0, sp = symtbl; i < nsyms; i++, sp++)
+ {
+ if (sp->n_un.n_strx == 0)
+ sp->n_un.n_name = "";
+ else if (sp->n_un.n_strx < 0 || sp->n_un.n_strx > strsize)
+ sp->n_un.n_name = "<bad string table index>";
+ else
+ sp->n_un.n_name = strtbl + sp->n_un.n_strx;
+ }
+}
+
+void
+free_symbols ()
+{
+ if (symtbl)
+ free (symtbl);
+ symtbl = NULL;
+ if (strtbl)
+ free (strtbl);
+ strtbl = NULL;
+}
+
+/* If nonzero, print header information. */
+int print_header = 0;
+
+/* If nonzero, print N_* information. */
+int print_nstuff = 0;
+
+/* If nonzero, print relocation information. */
+int print_relocation = 0;
+
+/* If nonzero, print symbol information. */
+int print_symbols = 0;
+
+/* Size of a page. Required by N_DATADDR in a.out.gnu.h [VAX]. */
+int page_size;
+
+void
+main (argc, argv)
+ int argc;
+ char **argv;
+{
+ int c;
+ int ind;
+ int option_given = 0;
+ static struct option long_options[] =
+ {
+ {"symbols", 0, &print_symbols, 1},
+ {"relocation", 0, &print_relocation, 1},
+ {"nstuff", 0, &print_nstuff, 1},
+ {"header", 0, &print_header, 1},
+ {NULL, 0, NULL, 0}
+ };
+
+ page_size = getpagesize ();
+
+ program_name = argv[0];
+
+ while ((c = getopt_long (argc, argv, "hnrt", long_options, &ind))
+ != EOF)
+ {
+ option_given = 1;
+ switch (c)
+ {
+ case 0:
+ break; /* we've been given a long option */
+ case 't':
+ print_symbols = 1;
+ break;
+ case 'r':
+ print_relocation = 1;
+ break;
+ case 'n':
+ print_nstuff = 1;
+ break;
+ case 'h':
+ print_header = 1;
+ break;
+ default:
+ usage ();
+ }
+ }
+
+ if (option_given == 0 || optind == argc)
+ usage ();
+
+ while (optind < argc)
+ dump_file (argv[optind++]);
+
+ exit (0);
+}
+
+void
+dump_file (name)
+ char *name;
+{
+ FILE *f;
+ struct exec exec;
+
+ printf ("%s:\n", name);
+ f = fopen (name, "r");
+ if (f == NULL)
+ {
+ error (0, errno, "%s", name);
+ return;
+ }
+ filename = name;
+
+#ifdef HEADER_SEEK
+ HEADER_SEEK (f);
+#endif
+ if (fread ((char *) &exec, sizeof exec, 1, f) != 1)
+ {
+ error (0, errno, "%s: cannot read header", filename);
+ return;
+ }
+
+ if (N_BADMAG (exec))
+ {
+ error (0, 0, "%s: Not an object file", filename);
+ return;
+ }
+
+ if (print_header)
+ dump_header (&exec);
+
+ if (print_nstuff)
+ dump_nstuff (&exec);
+
+ if (print_symbols)
+ dump_sym (&exec, f);
+
+ if (print_relocation)
+ dump_reloc (&exec, f);
+
+ free_symbols ();
+}
+
+void
+dump_header (execp)
+ struct exec *execp;
+{
+ int x;
+
+#if defined (__GNU_EXEC_MACROS__) && !defined (__STRUCT_EXEC_OVERRIDE__)
+ printf ("magic: 0x%x (%o)", N_MAGIC (*execp), N_MAGIC (*execp));
+ printf ("machine type: %d", N_MACHTYPE (*execp));
+ printf ("flags: 0x%x", N_FLAGS (*execp));
+#else /* non-gnu struct exec. */
+ printf ("magic: 0x%x (%o) ", execp->a_magic, execp->a_magic);
+#endif /* non-gnu struct exec. */
+ printf ("text 0x%x ", execp->a_text);
+ printf ("data 0x%x ", execp->a_data);
+ printf ("bss 0x%x\n", execp->a_bss);
+ printf ("nsyms %d", execp->a_syms / sizeof (struct nlist));
+ x = execp->a_syms % sizeof (struct nlist);
+ if (x)
+ printf (" (+ %d bytes)", x);
+ printf (" entry 0x%x ", execp->a_entry);
+ printf ("trsize 0x%x ", execp->a_trsize);
+ printf ("drsize 0x%x\n", execp->a_drsize);
+}
+
+void
+dump_nstuff (execp)
+ struct exec *execp;
+{
+ printf ("N_BADMAG %d\n", N_BADMAG (*execp));
+ printf ("N_TXTOFF 0x%x\n", N_TXTOFF (*execp));
+ printf ("N_SYMOFF 0x%x\n", N_SYMOFF (*execp));
+ printf ("N_STROFF 0x%x\n", N_STROFF (*execp));
+ printf ("N_TXTADDR 0x%x\n", N_TXTADDR (*execp));
+ printf ("N_DATADDR 0x%x\n", N_DATADDR (*execp));
+}
+
+void
+dump_sym (execp, f)
+ struct exec *execp;
+ FILE *f;
+{
+ int i;
+ struct nlist *sp;
+
+ read_symbols (execp, f);
+ if (nsyms == 0)
+ {
+ printf ("no symbols\n");
+ return;
+ }
+
+ printf ("%3s: %4s %5s %4s %8s\n",
+ "#", "type", "other", "desc", "val");
+ for (i = 0, sp = symtbl; i < nsyms; i++, sp++)
+ {
+ printf ("%3d: %4x %5x %4x %8x %s\n",
+ i,
+ sp->n_type & 0xff,
+ sp->n_other & 0xff,
+ sp->n_desc & 0xffff,
+ sp->n_value,
+ sp->n_un.n_name);
+ }
+}
+
+void
+dump_reloc (execp, f)
+ struct exec *execp;
+ FILE *f;
+{
+ read_symbols (execp, f);
+ if (execp->a_trsize)
+ {
+ printf ("text reloc\n");
+ dump_reloc1 (execp, f, N_TRELOFF (*execp), execp->a_trsize);
+ }
+ if (execp->a_drsize)
+ {
+ printf ("data reloc\n");
+ dump_reloc1 (execp, f, N_DRELOFF (*execp), execp->a_drsize);
+ }
+}
+
+void
+dump_reloc1 (execp, f, off, size)
+ struct exec *execp;
+ FILE *f;
+ int off;
+ int size;
+{
+#if !defined(sun) || !defined(sparc)
+ int nreloc;
+ struct relocation_info reloc;
+ int i;
+
+ nreloc = size / sizeof (struct relocation_info);
+
+ printf ("%3s: %3s %8s %4s\n", "#", "len", "adr", "sym");
+ fseek (f, off, 0);
+ for (i = 0; i < nreloc; i++)
+ {
+ if (fread ((char *) &reloc, sizeof reloc, 1, f) != 1)
+ {
+ error (0, errno, "%s: cannot read relocation information",
+ filename);
+ return;
+ }
+ printf ("%3d: %3d %8x ", i, 1 << reloc.r_length,
+ reloc.r_address);
+
+ if (reloc.r_extern)
+ {
+ printf ("%4d ", reloc.r_symbolnum);
+ if (reloc.r_symbolnum < nsyms)
+ printf ("%s ", symtbl[reloc.r_symbolnum].n_un.n_name);
+ }
+ else
+ {
+ printf (" ");
+ switch (reloc.r_symbolnum & ~N_EXT)
+ {
+ case N_TEXT:
+ printf (".text ");
+ break;
+ case N_DATA:
+ printf (".data ");
+ break;
+ case N_BSS:
+ printf (".bss ");
+ break;
+ case N_ABS:
+ printf (".abs ");
+ break;
+ default:
+ printf ("base %x ", reloc.r_symbolnum);
+ break;
+ }
+ }
+ if (reloc.r_pcrel)
+ printf ("PCREL ");
+#if 0
+ if (reloc.r_pad)
+ printf ("PAD %x ", reloc.r_pad);
+#endif
+ printf ("\n");
+ }
+#endif
+}
+
+/* Allocate N bytes of memory dynamically, with error checking. */
+
+char *
+xmalloc (n)
+ unsigned n;
+{
+ char *p;
+
+ p = malloc (n);
+ if (p == 0)
+ error (1, 0, "virtual memory exhausted");
+ return p;
+}
+
+#ifdef USG
+int
+getpagesize ()
+{
+ return 4096;
+}
+#endif
+
+#if defined(sun) && defined(sparc)
+int
+getpagesize ()
+{
+ return 8192;
+}
+#endif
+
+void
+usage ()
+{
+ fprintf (stderr, "\
+Usage: %s [-hnrt] [+header] [+nstuff] [+relocation] [+symbols] objfile...\n",
+ program_name);
+ exit (1);
+}