diff options
author | Richard Henderson <rth@redhat.com> | 1999-05-03 07:29:11 +0000 |
---|---|---|
committer | Richard Henderson <rth@redhat.com> | 1999-05-03 07:29:11 +0000 |
commit | 252b5132c753830d5fd56823373aed85f2a0db63 (patch) | |
tree | 1af963bfd8d3e55167b81def4207f175eaff3a56 /binutils/coffdump.c | |
download | gdb-252b5132c753830d5fd56823373aed85f2a0db63.zip gdb-252b5132c753830d5fd56823373aed85f2a0db63.tar.gz gdb-252b5132c753830d5fd56823373aed85f2a0db63.tar.bz2 |
19990502 sourceware importbinu_ss_19990502
Diffstat (limited to 'binutils/coffdump.c')
-rw-r--r-- | binutils/coffdump.c | 541 |
1 files changed, 541 insertions, 0 deletions
diff --git a/binutils/coffdump.c b/binutils/coffdump.c new file mode 100644 index 0000000..dc84d50 --- /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; +} |