diff options
Diffstat (limited to 'binutils-2.25/binutils/coffdump.c')
-rw-r--r-- | binutils-2.25/binutils/coffdump.c | 558 |
1 files changed, 558 insertions, 0 deletions
diff --git a/binutils-2.25/binutils/coffdump.c b/binutils-2.25/binutils/coffdump.c new file mode 100644 index 00000000..d871e1eb --- /dev/null +++ b/binutils-2.25/binutils/coffdump.c @@ -0,0 +1,558 @@ +/* Coff file dumper. + Copyright 1994, 1995, 1998, 1999, 2000, 2001, 2002, 2003, 2005, 2007, + 2011 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 3 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., 51 Franklin Street - Fifth Floor, Boston, + MA 02110-1301, 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 "sysdep.h" +#include "bfd.h" +#include "bfd_stdint.h" +#include "libiberty.h" +#include "bucomm.h" + +#include "coffgrok.h" +#include "getopt.h" + +static int atnl; + +static void tab (int); +static void nl (void); +static void dump_coff_lines (struct coff_line *); +static void dump_coff_type (struct coff_type *); +static void dump_coff_where (struct coff_where *); +static void dump_coff_visible (struct coff_visible *); +static void dump_coff_scope (struct coff_scope *); +static void dump_coff_sfile (struct coff_sfile *); +static void dump_coff_section (struct coff_section *); +static void show_usage (FILE *, int); +extern int main (int, char **); + +static void +tab (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 (void) +{ + atnl = 1; +} + +static void +dump_coff_lines (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 (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 (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 (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); +} + +static void +dump_coff_symbol (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 (struct coff_scope *p) +{ + if (p) + { + tab (1); + printf ("%s %" BFD_VMA_FMT "x ", + _("List of blocks "), (bfd_vma) (uintptr_t) 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 (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 (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); +} + +static void +coff_dump (struct coff_ofile *ptr) +{ + int i; + + printf ("Coff dump"); + nl (); + printf (_("#sources %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 *file, int status) +{ + fprintf (file, _("Usage: %s [option(s)] in-file\n"), program_name); + fprintf (file, _(" Print a human readable interpretation of a COFF object file\n")); + fprintf (file, _(" The options are:\n\ + @<file> Read options from <file>\n\ + -h --help Display this information\n\ + -v --version Display the program's version\n\ +\n")); + + if (REPORT_BUGS_TO[0] && status == 0) + fprintf (file, _("Report bugs to %s\n"), REPORT_BUGS_TO); + + exit (status); +} + +int +main (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 +#if defined (HAVE_SETLOCALE) + setlocale (LC_CTYPE, ""); +#endif + bindtextdomain (PACKAGE, LOCALEDIR); + textdomain (PACKAGE); + + program_name = av[0]; + xmalloc_set_program_name (program_name); + + expandargv (&ac, &av); + + while ((opt = getopt_long (ac, av, "HhVv", long_options, + (int *) NULL)) + != EOF) + { + switch (opt) + { + case 'H': + case 'h': + show_usage (stdout, 0); + break; + case 'v': + case 'V': + print_version ("coffdump"); + exit (0); + case 0: + break; + default: + show_usage (stderr, 1); + break; + } + } + + if (optind < ac) + { + input_file = av[optind]; + } + + if (!input_file) + fatal (_("no input file specified")); + + 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; +} |