summaryrefslogtreecommitdiff
path: root/binutils/coffdump.c
diff options
context:
space:
mode:
Diffstat (limited to 'binutils/coffdump.c')
-rw-r--r--binutils/coffdump.c541
1 files changed, 541 insertions, 0 deletions
diff --git a/binutils/coffdump.c b/binutils/coffdump.c
new file mode 100644
index 00000000000..dc84d509176
--- /dev/null
+++ b/binutils/coffdump.c
@@ -0,0 +1,541 @@
+/* Coff file dumper.
+ Copyright (C) 1994, 1998, 1999 Free Software Foundation, Inc.
+
+This file is part of GNU Binutils.
+
+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 2 of the License, 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+/* Written by Steve Chamberlain <sac@cygnus.com>
+
+ This module reads a type tree generated by coffgrok and prints
+ it out so we can test the grokker.
+*/
+
+#include <bfd.h>
+#include <getopt.h>
+#include <libiberty.h>
+
+#include "coffgrok.h"
+#include "bucomm.h"
+
+#define PROGRAM_VERSION "1.0"
+
+static int atnl;
+static void dump_coff_scope ();
+
+static void
+tab (x)
+int x;
+{
+ static int indent;
+ int i;
+
+ if (atnl)
+ {
+ if (x < 0)
+ {
+ printf (")");
+ indent += x;
+
+ return;
+ }
+ else
+ {
+ printf ("\n");
+ atnl = 0;
+ }
+ }
+
+ if (x == -1)
+ {
+ for (i = 0; i < indent; i++)
+ printf (" ");
+
+ indent += x;
+ printf (")");
+ return;
+ }
+
+ indent += x;
+
+ for (i = 0; i < indent; i++)
+ printf (" ");
+
+ if (x)
+ {
+ printf ("(");
+ }
+}
+
+static void nl ()
+{
+ atnl = 1;
+}
+
+static void
+dump_coff_lines (p)
+ struct coff_line *p;
+{
+ int i;
+ int online = 0;
+ tab(1);
+ printf(_("#lines %d "),p->nlines);
+ for (i = 0; i < p->nlines; i++)
+ {
+ printf("(%d 0x%x)", p->lines[i], p->addresses[i]);
+ online++;
+ if (online > 6)
+ {
+ nl();
+ tab(0);
+ online = 0;
+ }
+ }
+ nl();
+ tab(-1);
+}
+
+static void
+dump_coff_type (p)
+ struct coff_type *p;
+{
+ tab (1);
+ printf ("size %d ", p->size);
+ switch (p->type)
+ {
+ case coff_secdef_type:
+ printf ("section definition at %x size %x\n",
+ p->u.asecdef.address,
+ p->u.asecdef.size);
+ nl();
+ break;
+ case coff_pointer_type:
+ printf ("pointer to");
+ nl ();
+ dump_coff_type (p->u.pointer.points_to);
+ break;
+ case coff_array_type:
+ printf ("array [%d] of", p->u.array.dim);
+ nl ();
+ dump_coff_type (p->u.array.array_of);
+ break;
+ case coff_function_type:
+ printf ("function returning");
+ nl ();
+ dump_coff_type (p->u.function.function_returns);
+ dump_coff_lines (p->u.function.lines);
+ printf ("arguments");
+ nl ();
+ dump_coff_scope (p->u.function.parameters);
+ tab (0);
+ printf ("code");
+ nl ();
+ dump_coff_scope (p->u.function.code);
+ tab(0);
+ break;
+ case coff_structdef_type:
+ printf ("structure definition");
+ nl ();
+ dump_coff_scope (p->u.astructdef.elements);
+ break;
+ case coff_structref_type:
+ if (!p->u.aenumref.ref)
+ printf ("structure ref to UNKNOWN struct");
+ else
+ printf ("structure ref to %s", p->u.aenumref.ref->name);
+ break;
+ case coff_enumref_type:
+ printf ("enum ref to %s", p->u.astructref.ref->name);
+ break;
+ case coff_enumdef_type:
+ printf ("enum definition");
+ nl ();
+ dump_coff_scope (p->u.aenumdef.elements);
+ break;
+ case coff_basic_type:
+ switch (p->u.basic)
+ {
+ case T_NULL:
+ printf ("NULL");
+ break;
+ case T_VOID:
+ printf ("VOID");
+ break;
+ case T_CHAR:
+ printf ("CHAR");
+ break;
+ case T_SHORT:
+ printf ("SHORT");
+ break;
+ case T_INT:
+ printf ("INT ");
+ break;
+ case T_LONG:
+ printf ("LONG");
+ break;
+ case T_FLOAT:
+ printf ("FLOAT");
+ break;
+ case T_DOUBLE:
+ printf ("DOUBLE");
+ break;
+ case T_STRUCT:
+ printf ("STRUCT");
+ break;
+ case T_UNION:
+ printf ("UNION");
+ break;
+ case T_ENUM:
+ printf ("ENUM");
+ break;
+ case T_MOE:
+ printf ("MOE ");
+ break;
+ case T_UCHAR:
+ printf ("UCHAR");
+ break;
+ case T_USHORT:
+ printf ("USHORT");
+ break;
+ case T_UINT:
+ printf ("UINT");
+ break;
+ case T_ULONG:
+ printf ("ULONG");
+ break;
+ case T_LNGDBL:
+ printf ("LNGDBL");
+ break;
+ default:
+ abort ();
+ }
+ }
+ nl ();
+ tab (-1);
+}
+
+static void
+dump_coff_where (p)
+ struct coff_where *p;
+{
+ tab (1);
+ switch (p->where)
+ {
+ case coff_where_stack:
+ printf ("Stack offset %x", p->offset);
+ break;
+ case coff_where_memory:
+ printf ("Memory section %s+%x", p->section->name, p->offset);
+ break;
+ case coff_where_register:
+ printf ("Register %d", p->offset);
+ break;
+ case coff_where_member_of_struct:
+ printf ("Struct Member offset %x", p->offset);
+ break;
+ case coff_where_member_of_enum:
+ printf ("Enum Member offset %x", p->offset);
+ break;
+ case coff_where_unknown:
+ printf ("Undefined symbol");
+ break;
+ case coff_where_strtag:
+ printf ("STRTAG");
+ case coff_where_entag:
+ printf ("ENTAG");
+ break;
+ case coff_where_typedef:
+ printf ("TYPEDEF");
+ break;
+ default:
+ abort ();
+ }
+ nl ();
+ tab (-1);
+}
+
+static void
+dump_coff_visible (p)
+ struct coff_visible *p;
+{
+ tab (1);
+ switch (p->type)
+ {
+ case coff_vis_ext_def:
+ printf ("coff_vis_ext_def");
+ break;
+ case coff_vis_ext_ref:
+ printf ("coff_vis_ext_ref");
+ break;
+ case coff_vis_int_def:
+ printf ("coff_vis_int_def");
+ break;
+ case coff_vis_common:
+ printf ("coff_vis_common");
+ break;
+ case coff_vis_auto:
+ printf ("coff_vis_auto");
+ break;
+ case coff_vis_autoparam:
+ printf ("coff_vis_autoparam");
+ break;
+ case coff_vis_regparam:
+ printf ("coff_vis_regparam");
+ break;
+ case coff_vis_register:
+ printf ("coff_vis_register");
+ break;
+ case coff_vis_tag:
+ printf ("coff_vis_tag");
+ break;
+ case coff_vis_member_of_struct:
+ printf ("coff_vis_member_of_struct");
+ break;
+ case coff_vis_member_of_enum:
+ printf ("coff_vis_member_of_enum");
+ break;
+ default:
+ abort ();
+ }
+ nl ();
+ tab (-1);
+}
+
+
+void
+dump_coff_symbol (p)
+ struct coff_symbol *p;
+{
+ tab (1);
+ printf ("List of symbols");
+ nl ();
+ while (p)
+ {
+ tab (1);
+ tab (1);
+ printf ("Symbol %s, tag %d, number %d", p->name, p->tag, p->number);
+ nl ();
+ tab (-1);
+ tab (1);
+ printf ("Type");
+ nl ();
+ dump_coff_type (p->type);
+ tab (-1);
+ tab (1);
+ printf ("Where");
+ dump_coff_where (p->where);
+ tab (-1);
+ tab (1);
+ printf ("Visible");
+ dump_coff_visible (p->visible);
+ tab (-1);
+ p = p->next;
+ tab (-1);
+ }
+ tab (-1);
+}
+
+static void
+dump_coff_scope (p)
+ struct coff_scope *p;
+{
+if (p) {
+ tab (1);
+ printf ("List of blocks %lx ",(unsigned long) p);
+
+ if (p->sec) {
+ printf( " %s %x..%x", p->sec->name,p->offset, p->offset + p->size -1);
+ }
+ nl ();
+ tab (0);
+ printf ("*****************");
+ nl ();
+ while (p)
+ {
+ tab (0);
+ printf ("vars %d", p->nvars);
+ nl ();
+ dump_coff_symbol (p->vars_head);
+ printf ("blocks");
+ nl ();
+ dump_coff_scope (p->list_head);
+ nl ();
+ p = p->next;
+ }
+
+ tab (0);
+ printf ("*****************");
+ nl ();
+ tab (-1);
+}
+}
+
+static void
+dump_coff_sfile (p)
+ struct coff_sfile *p;
+{
+ tab (1);
+ printf ("List of source files");
+ nl ();
+ while (p)
+ {
+ tab (0);
+ printf ("Source file %s", p->name);
+ nl ();
+ dump_coff_scope (p->scope);
+ p = p->next;
+ }
+ tab (-1);
+}
+
+static void
+dump_coff_section(ptr)
+struct coff_section *ptr;
+{
+ int i;
+ tab(1);
+ printf("section %s %d %d address %x size %x number %d nrelocs %d",
+ ptr->name, ptr->code, ptr->data, ptr->address,ptr->size, ptr->number, ptr->nrelocs);
+ nl();
+
+ for (i = 0; i < ptr->nrelocs; i++)
+ {
+ tab(0);
+ printf("(%x %s %x)",
+ ptr->relocs[i].offset,
+ ptr->relocs[i].symbol->name,
+ ptr->relocs[i].addend);
+ nl();
+ }
+ tab(-1);
+
+}
+
+void
+coff_dump (ptr)
+ struct coff_ofile *ptr;
+{
+ int i;
+ printf ("Coff dump");
+ nl ();
+ printf ("#souces %d", ptr->nsources);
+ nl ();
+ dump_coff_sfile (ptr->source_head);
+ for (i = 0; i < ptr->nsections; i++)
+ dump_coff_section(ptr->sections + i);
+}
+
+
+
+char * program_name;
+
+static void
+show_usage (file, status)
+ FILE *file;
+ int status;
+{
+ fprintf (file, "Usage: %s [-hV] in-file\n", program_name);
+ exit (status);
+}
+
+static void
+show_help ()
+{
+ printf (_("%s: Print a human readable interpretation of a SYSROFF object file\n"),
+ program_name);
+ show_usage (stdout, 0);
+}
+
+
+int
+main (ac, av)
+ int ac;
+ char *av[];
+{
+ bfd *abfd;
+ struct coff_ofile *tree;
+ char **matching;
+ char *input_file = NULL;
+ int opt;
+ static struct option long_options[] =
+ {
+ { "help", no_argument, 0, 'h' },
+ { "version", no_argument, 0, 'V' },
+ { NULL, no_argument, 0, 0 }
+ };
+
+#if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
+ setlocale (LC_MESSAGES, "");
+#endif
+ bindtextdomain (PACKAGE, LOCALEDIR);
+ textdomain (PACKAGE);
+
+ program_name = av[0];
+ xmalloc_set_program_name (program_name);
+
+ while ((opt = getopt_long (ac, av, "hV", long_options,
+ (int *) NULL))
+ != EOF)
+ {
+ switch (opt)
+ {
+ case 'h':
+ show_help ();
+ /*NOTREACHED*/
+ case 'V':
+ printf (_("GNU %s version %s\n"), program_name, PROGRAM_VERSION);
+ exit (0);
+ /*NOTREACHED*/
+ case 0:
+ break;
+ default:
+ show_usage (stderr, 1);
+ /*NOTREACHED*/
+ }
+ }
+
+ if (optind < ac)
+ {
+ input_file = av[optind];
+ }
+
+ if (!input_file)
+ {
+ fprintf (stderr,_("%s: no input file specified\n"),
+ program_name);
+ exit(1);
+ }
+ abfd = bfd_openr (input_file, 0);
+
+ if (!abfd)
+ bfd_fatal (input_file);
+
+ if (! bfd_check_format_matches (abfd, bfd_object, &matching))
+ {
+ bfd_nonfatal (input_file);
+ if (bfd_get_error () == bfd_error_file_ambiguously_recognized)
+ {
+ list_matching_formats (matching);
+ free (matching);
+ }
+ exit (1);
+ }
+
+ tree = coff_grok (abfd);
+
+ coff_dump(tree);
+ printf("\n");
+ return 0;
+}