133965Sjdp/* Coff file dumper. 2218822Sdim Copyright 1994, 1995, 1998, 1999, 2000, 2001, 2002, 2003, 2005, 2007 389857Sobrien Free Software Foundation, Inc. 433965Sjdp 589857Sobrien This file is part of GNU Binutils. 633965Sjdp 789857Sobrien This program is free software; you can redistribute it and/or modify 889857Sobrien it under the terms of the GNU General Public License as published by 989857Sobrien the Free Software Foundation; either version 2 of the License, or (at 1089857Sobrien your option) any later version. 1133965Sjdp 1289857Sobrien This program is distributed in the hope that it will be useful, 1389857Sobrien but WITHOUT ANY WARRANTY; without even the implied warranty of 1489857Sobrien MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1589857Sobrien GNU General Public License for more details. 1633965Sjdp 1789857Sobrien You should have received a copy of the GNU General Public License 1889857Sobrien along with this program; if not, write to the Free Software 19218822Sdim Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ 2033965Sjdp 2133965Sjdp/* Written by Steve Chamberlain <sac@cygnus.com> 2233965Sjdp 2333965Sjdp This module reads a type tree generated by coffgrok and prints 2489857Sobrien it out so we can test the grokker. */ 2533965Sjdp 26218822Sdim#include "sysdep.h" 27104834Sobrien#include "bfd.h" 28104834Sobrien#include "libiberty.h" 29218822Sdim#include "bucomm.h" 3033965Sjdp 3133965Sjdp#include "coffgrok.h" 3291041Sobrien#include "getopt.h" 3333965Sjdp 3433965Sjdpstatic int atnl; 3533965Sjdp 36130561Sobrienstatic void tab (int); 37130561Sobrienstatic void nl (void); 38130561Sobrienstatic void dump_coff_lines (struct coff_line *); 39130561Sobrienstatic void dump_coff_type (struct coff_type *); 40130561Sobrienstatic void dump_coff_where (struct coff_where *); 41130561Sobrienstatic void dump_coff_visible (struct coff_visible *); 42130561Sobrienstatic void dump_coff_scope (struct coff_scope *); 43130561Sobrienstatic void dump_coff_sfile (struct coff_sfile *); 44130561Sobrienstatic void dump_coff_section (struct coff_section *); 45130561Sobrienstatic void show_usage (FILE *, int); 46130561Sobrienextern int main (int, char **); 4789857Sobrien 4833965Sjdpstatic void 49130561Sobrientab (int x) 5033965Sjdp{ 5133965Sjdp static int indent; 5233965Sjdp int i; 5333965Sjdp 5433965Sjdp if (atnl) 5533965Sjdp { 5633965Sjdp if (x < 0) 5733965Sjdp { 5833965Sjdp printf (")"); 5933965Sjdp indent += x; 6033965Sjdp 6133965Sjdp return; 6233965Sjdp } 6333965Sjdp else 6433965Sjdp { 6533965Sjdp printf ("\n"); 6633965Sjdp atnl = 0; 6733965Sjdp } 6833965Sjdp } 6933965Sjdp 7033965Sjdp if (x == -1) 7133965Sjdp { 7233965Sjdp for (i = 0; i < indent; i++) 7333965Sjdp printf (" "); 7433965Sjdp 7533965Sjdp indent += x; 7633965Sjdp printf (")"); 7733965Sjdp return; 7833965Sjdp } 7933965Sjdp 8033965Sjdp indent += x; 8133965Sjdp 8233965Sjdp for (i = 0; i < indent; i++) 8333965Sjdp printf (" "); 8433965Sjdp 8533965Sjdp if (x) 8633965Sjdp { 8733965Sjdp printf ("("); 8833965Sjdp } 8933965Sjdp} 9033965Sjdp 9189857Sobrienstatic void 92130561Sobriennl (void) 9333965Sjdp{ 9433965Sjdp atnl = 1; 9533965Sjdp} 9633965Sjdp 9733965Sjdpstatic void 98130561Sobriendump_coff_lines (struct coff_line *p) 9933965Sjdp{ 10033965Sjdp int i; 10133965Sjdp int online = 0; 10289857Sobrien 10389857Sobrien tab (1); 10489857Sobrien printf (_("#lines %d "),p->nlines); 10589857Sobrien 106104834Sobrien for (i = 0; i < p->nlines; i++) 10733965Sjdp { 10889857Sobrien printf ("(%d 0x%x)", p->lines[i], p->addresses[i]); 10989857Sobrien 11033965Sjdp online++; 11189857Sobrien 11233965Sjdp if (online > 6) 11333965Sjdp { 11489857Sobrien nl (); 11589857Sobrien tab (0); 11633965Sjdp online = 0; 11733965Sjdp } 11833965Sjdp } 11989857Sobrien nl (); 12089857Sobrien tab (-1); 12133965Sjdp} 12233965Sjdp 12333965Sjdpstatic void 124130561Sobriendump_coff_type (struct coff_type *p) 12533965Sjdp{ 12633965Sjdp tab (1); 12733965Sjdp printf ("size %d ", p->size); 12889857Sobrien 12933965Sjdp switch (p->type) 13033965Sjdp { 13133965Sjdp case coff_secdef_type: 132104834Sobrien printf ("section definition at %x size %x\n", 13333965Sjdp p->u.asecdef.address, 13433965Sjdp p->u.asecdef.size); 13589857Sobrien nl (); 13633965Sjdp break; 13733965Sjdp case coff_pointer_type: 13833965Sjdp printf ("pointer to"); 13933965Sjdp nl (); 14033965Sjdp dump_coff_type (p->u.pointer.points_to); 14133965Sjdp break; 14233965Sjdp case coff_array_type: 14333965Sjdp printf ("array [%d] of", p->u.array.dim); 14433965Sjdp nl (); 14533965Sjdp dump_coff_type (p->u.array.array_of); 14633965Sjdp break; 14733965Sjdp case coff_function_type: 14833965Sjdp printf ("function returning"); 14933965Sjdp nl (); 15033965Sjdp dump_coff_type (p->u.function.function_returns); 15133965Sjdp dump_coff_lines (p->u.function.lines); 15233965Sjdp printf ("arguments"); 15333965Sjdp nl (); 15433965Sjdp dump_coff_scope (p->u.function.parameters); 15533965Sjdp tab (0); 15633965Sjdp printf ("code"); 15733965Sjdp nl (); 15833965Sjdp dump_coff_scope (p->u.function.code); 15933965Sjdp tab(0); 16033965Sjdp break; 16133965Sjdp case coff_structdef_type: 16233965Sjdp printf ("structure definition"); 16333965Sjdp nl (); 16433965Sjdp dump_coff_scope (p->u.astructdef.elements); 16533965Sjdp break; 16633965Sjdp case coff_structref_type: 16733965Sjdp if (!p->u.aenumref.ref) 16833965Sjdp printf ("structure ref to UNKNOWN struct"); 16933965Sjdp else 17033965Sjdp printf ("structure ref to %s", p->u.aenumref.ref->name); 17133965Sjdp break; 17233965Sjdp case coff_enumref_type: 17333965Sjdp printf ("enum ref to %s", p->u.astructref.ref->name); 17433965Sjdp break; 17533965Sjdp case coff_enumdef_type: 17633965Sjdp printf ("enum definition"); 17733965Sjdp nl (); 17833965Sjdp dump_coff_scope (p->u.aenumdef.elements); 17933965Sjdp break; 18033965Sjdp case coff_basic_type: 18133965Sjdp switch (p->u.basic) 18233965Sjdp { 18333965Sjdp case T_NULL: 18433965Sjdp printf ("NULL"); 18533965Sjdp break; 18633965Sjdp case T_VOID: 18733965Sjdp printf ("VOID"); 18833965Sjdp break; 18933965Sjdp case T_CHAR: 19033965Sjdp printf ("CHAR"); 19133965Sjdp break; 19233965Sjdp case T_SHORT: 19333965Sjdp printf ("SHORT"); 19433965Sjdp break; 19533965Sjdp case T_INT: 19633965Sjdp printf ("INT "); 19733965Sjdp break; 19833965Sjdp case T_LONG: 19933965Sjdp printf ("LONG"); 20033965Sjdp break; 20133965Sjdp case T_FLOAT: 20233965Sjdp printf ("FLOAT"); 20333965Sjdp break; 20433965Sjdp case T_DOUBLE: 20533965Sjdp printf ("DOUBLE"); 20633965Sjdp break; 20733965Sjdp case T_STRUCT: 20833965Sjdp printf ("STRUCT"); 20933965Sjdp break; 21033965Sjdp case T_UNION: 21133965Sjdp printf ("UNION"); 21233965Sjdp break; 21333965Sjdp case T_ENUM: 21433965Sjdp printf ("ENUM"); 21533965Sjdp break; 21633965Sjdp case T_MOE: 21733965Sjdp printf ("MOE "); 21833965Sjdp break; 21933965Sjdp case T_UCHAR: 22033965Sjdp printf ("UCHAR"); 22133965Sjdp break; 22233965Sjdp case T_USHORT: 22333965Sjdp printf ("USHORT"); 22433965Sjdp break; 22533965Sjdp case T_UINT: 22633965Sjdp printf ("UINT"); 22733965Sjdp break; 22833965Sjdp case T_ULONG: 22933965Sjdp printf ("ULONG"); 23033965Sjdp break; 23133965Sjdp case T_LNGDBL: 23233965Sjdp printf ("LNGDBL"); 23333965Sjdp break; 23433965Sjdp default: 23533965Sjdp abort (); 23633965Sjdp } 23733965Sjdp } 23833965Sjdp nl (); 23933965Sjdp tab (-1); 24033965Sjdp} 24133965Sjdp 24233965Sjdpstatic void 243130561Sobriendump_coff_where (struct coff_where *p) 24433965Sjdp{ 24533965Sjdp tab (1); 24633965Sjdp switch (p->where) 24733965Sjdp { 24833965Sjdp case coff_where_stack: 24933965Sjdp printf ("Stack offset %x", p->offset); 25033965Sjdp break; 25133965Sjdp case coff_where_memory: 25233965Sjdp printf ("Memory section %s+%x", p->section->name, p->offset); 25333965Sjdp break; 25433965Sjdp case coff_where_register: 25533965Sjdp printf ("Register %d", p->offset); 25633965Sjdp break; 25733965Sjdp case coff_where_member_of_struct: 25833965Sjdp printf ("Struct Member offset %x", p->offset); 25933965Sjdp break; 26033965Sjdp case coff_where_member_of_enum: 26133965Sjdp printf ("Enum Member offset %x", p->offset); 26233965Sjdp break; 26333965Sjdp case coff_where_unknown: 26433965Sjdp printf ("Undefined symbol"); 26533965Sjdp break; 26633965Sjdp case coff_where_strtag: 26733965Sjdp printf ("STRTAG"); 26833965Sjdp case coff_where_entag: 26933965Sjdp printf ("ENTAG"); 27033965Sjdp break; 27133965Sjdp case coff_where_typedef: 27233965Sjdp printf ("TYPEDEF"); 27333965Sjdp break; 27433965Sjdp default: 27533965Sjdp abort (); 27633965Sjdp } 27733965Sjdp nl (); 27833965Sjdp tab (-1); 27933965Sjdp} 28033965Sjdp 28133965Sjdpstatic void 282130561Sobriendump_coff_visible (struct coff_visible *p) 28333965Sjdp{ 28433965Sjdp tab (1); 28533965Sjdp switch (p->type) 28633965Sjdp { 28733965Sjdp case coff_vis_ext_def: 28833965Sjdp printf ("coff_vis_ext_def"); 28933965Sjdp break; 29033965Sjdp case coff_vis_ext_ref: 29133965Sjdp printf ("coff_vis_ext_ref"); 29233965Sjdp break; 29333965Sjdp case coff_vis_int_def: 29433965Sjdp printf ("coff_vis_int_def"); 29533965Sjdp break; 29633965Sjdp case coff_vis_common: 29733965Sjdp printf ("coff_vis_common"); 29833965Sjdp break; 29933965Sjdp case coff_vis_auto: 30033965Sjdp printf ("coff_vis_auto"); 30133965Sjdp break; 30233965Sjdp case coff_vis_autoparam: 30333965Sjdp printf ("coff_vis_autoparam"); 30433965Sjdp break; 30533965Sjdp case coff_vis_regparam: 30633965Sjdp printf ("coff_vis_regparam"); 30733965Sjdp break; 30833965Sjdp case coff_vis_register: 30933965Sjdp printf ("coff_vis_register"); 31033965Sjdp break; 31133965Sjdp case coff_vis_tag: 31233965Sjdp printf ("coff_vis_tag"); 31333965Sjdp break; 31433965Sjdp case coff_vis_member_of_struct: 31533965Sjdp printf ("coff_vis_member_of_struct"); 31633965Sjdp break; 31733965Sjdp case coff_vis_member_of_enum: 31833965Sjdp printf ("coff_vis_member_of_enum"); 31933965Sjdp break; 32033965Sjdp default: 32133965Sjdp abort (); 32233965Sjdp } 32333965Sjdp nl (); 32433965Sjdp tab (-1); 32533965Sjdp} 32633965Sjdp 327218822Sdimstatic void 328130561Sobriendump_coff_symbol (struct coff_symbol *p) 32933965Sjdp{ 33033965Sjdp tab (1); 33133965Sjdp printf ("List of symbols"); 33233965Sjdp nl (); 33389857Sobrien 33433965Sjdp while (p) 33533965Sjdp { 33633965Sjdp tab (1); 33733965Sjdp tab (1); 33833965Sjdp printf ("Symbol %s, tag %d, number %d", p->name, p->tag, p->number); 33933965Sjdp nl (); 34033965Sjdp tab (-1); 34133965Sjdp tab (1); 34233965Sjdp printf ("Type"); 34333965Sjdp nl (); 34433965Sjdp dump_coff_type (p->type); 34533965Sjdp tab (-1); 34633965Sjdp tab (1); 34733965Sjdp printf ("Where"); 34833965Sjdp dump_coff_where (p->where); 34933965Sjdp tab (-1); 35033965Sjdp tab (1); 35133965Sjdp printf ("Visible"); 35233965Sjdp dump_coff_visible (p->visible); 35333965Sjdp tab (-1); 35433965Sjdp p = p->next; 35533965Sjdp tab (-1); 35633965Sjdp } 35733965Sjdp tab (-1); 35833965Sjdp} 35933965Sjdp 36033965Sjdpstatic void 361130561Sobriendump_coff_scope (struct coff_scope *p) 36233965Sjdp{ 36389857Sobrien if (p) 36489857Sobrien { 36589857Sobrien tab (1); 36689857Sobrien printf ("List of blocks %lx ",(unsigned long) p); 36733965Sjdp 36889857Sobrien if (p->sec) 36989857Sobrien printf( " %s %x..%x", p->sec->name,p->offset, p->offset + p->size -1); 37089857Sobrien 37189857Sobrien nl (); 37233965Sjdp tab (0); 37389857Sobrien printf ("*****************"); 37433965Sjdp nl (); 37589857Sobrien 37689857Sobrien while (p) 37789857Sobrien { 37889857Sobrien tab (0); 37989857Sobrien printf ("vars %d", p->nvars); 38089857Sobrien nl (); 38189857Sobrien dump_coff_symbol (p->vars_head); 38289857Sobrien printf ("blocks"); 38389857Sobrien nl (); 38489857Sobrien dump_coff_scope (p->list_head); 38589857Sobrien nl (); 38689857Sobrien p = p->next; 38789857Sobrien } 38889857Sobrien 38989857Sobrien tab (0); 39089857Sobrien printf ("*****************"); 39133965Sjdp nl (); 39289857Sobrien tab (-1); 39333965Sjdp } 39433965Sjdp} 39533965Sjdp 39633965Sjdpstatic void 397130561Sobriendump_coff_sfile (struct coff_sfile *p) 39833965Sjdp{ 39933965Sjdp tab (1); 40033965Sjdp printf ("List of source files"); 40133965Sjdp nl (); 40289857Sobrien 40333965Sjdp while (p) 40433965Sjdp { 40533965Sjdp tab (0); 40633965Sjdp printf ("Source file %s", p->name); 40733965Sjdp nl (); 40833965Sjdp dump_coff_scope (p->scope); 40933965Sjdp p = p->next; 41033965Sjdp } 41133965Sjdp tab (-1); 41233965Sjdp} 41333965Sjdp 41433965Sjdpstatic void 415130561Sobriendump_coff_section (struct coff_section *ptr) 41633965Sjdp{ 41733965Sjdp int i; 41833965Sjdp 41989857Sobrien tab (1); 420104834Sobrien printf ("section %s %d %d address %x size %x number %d nrelocs %d", 42189857Sobrien ptr->name, ptr->code, ptr->data, ptr->address,ptr->size, 42289857Sobrien ptr->number, ptr->nrelocs); 42389857Sobrien nl (); 42489857Sobrien 425104834Sobrien for (i = 0; i < ptr->nrelocs; i++) 42633965Sjdp { 427104834Sobrien tab (0); 42889857Sobrien printf ("(%x %s %x)", 42989857Sobrien ptr->relocs[i].offset, 43089857Sobrien ptr->relocs[i].symbol->name, 43189857Sobrien ptr->relocs[i].addend); 43289857Sobrien nl (); 43333965Sjdp } 43433965Sjdp 43589857Sobrien tab (-1); 43633965Sjdp} 43733965Sjdp 438218822Sdimstatic void 439130561Sobriencoff_dump (struct coff_ofile *ptr) 44033965Sjdp{ 44133965Sjdp int i; 44289857Sobrien 44333965Sjdp printf ("Coff dump"); 44433965Sjdp nl (); 44533965Sjdp printf ("#souces %d", ptr->nsources); 44633965Sjdp nl (); 44733965Sjdp dump_coff_sfile (ptr->source_head); 44889857Sobrien 44933965Sjdp for (i = 0; i < ptr->nsections; i++) 45089857Sobrien dump_coff_section (ptr->sections + i); 45133965Sjdp} 45233965Sjdp 45333965Sjdpchar * program_name; 45433965Sjdp 45533965Sjdpstatic void 456130561Sobrienshow_usage (FILE *file, int status) 45733965Sjdp{ 45889857Sobrien fprintf (file, _("Usage: %s [option(s)] in-file\n"), program_name); 45989857Sobrien fprintf (file, _(" Print a human readable interpretation of a SYSROFF object file\n")); 46089857Sobrien fprintf (file, _(" The options are:\n\ 461218822Sdim @<file> Read options from <file>\n\ 46289857Sobrien -h --help Display this information\n\ 46389857Sobrien -v --version Display the program's version\n\ 46489857Sobrien\n")); 46589857Sobrien 466218822Sdim if (REPORT_BUGS_TO[0] && status == 0) 46789857Sobrien fprintf (file, _("Report bugs to %s\n"), REPORT_BUGS_TO); 46889857Sobrien 46933965Sjdp exit (status); 47033965Sjdp} 47133965Sjdp 47233965Sjdpint 473130561Sobrienmain (int ac, char **av) 47433965Sjdp{ 47533965Sjdp bfd *abfd; 47633965Sjdp struct coff_ofile *tree; 47733965Sjdp char **matching; 47833965Sjdp char *input_file = NULL; 47933965Sjdp int opt; 48033965Sjdp static struct option long_options[] = 48133965Sjdp { 48233965Sjdp { "help", no_argument, 0, 'h' }, 48333965Sjdp { "version", no_argument, 0, 'V' }, 48433965Sjdp { NULL, no_argument, 0, 0 } 48533965Sjdp }; 48633965Sjdp 48760484Sobrien#if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES) 48860484Sobrien setlocale (LC_MESSAGES, ""); 48960484Sobrien#endif 49089857Sobrien#if defined (HAVE_SETLOCALE) 49189857Sobrien setlocale (LC_CTYPE, ""); 49289857Sobrien#endif 49360484Sobrien bindtextdomain (PACKAGE, LOCALEDIR); 49460484Sobrien textdomain (PACKAGE); 49560484Sobrien 49633965Sjdp program_name = av[0]; 49733965Sjdp xmalloc_set_program_name (program_name); 49833965Sjdp 499218822Sdim expandargv (&ac, &av); 500218822Sdim 50189857Sobrien while ((opt = getopt_long (ac, av, "HhVv", long_options, 50233965Sjdp (int *) NULL)) 50333965Sjdp != EOF) 50433965Sjdp { 50533965Sjdp switch (opt) 50633965Sjdp { 50789857Sobrien case 'H': 50833965Sjdp case 'h': 50989857Sobrien show_usage (stdout, 0); 51089857Sobrien break; 51189857Sobrien case 'v': 51233965Sjdp case 'V': 51389857Sobrien print_version ("coffdump"); 51433965Sjdp exit (0); 51533965Sjdp case 0: 51633965Sjdp break; 51733965Sjdp default: 51833965Sjdp show_usage (stderr, 1); 51989857Sobrien break; 52033965Sjdp } 52133965Sjdp } 52233965Sjdp 52333965Sjdp if (optind < ac) 52433965Sjdp { 52533965Sjdp input_file = av[optind]; 52633965Sjdp } 52733965Sjdp 52833965Sjdp if (!input_file) 52989857Sobrien fatal (_("no input file specified")); 53089857Sobrien 53133965Sjdp abfd = bfd_openr (input_file, 0); 53233965Sjdp 53333965Sjdp if (!abfd) 53433965Sjdp bfd_fatal (input_file); 53533965Sjdp 53633965Sjdp if (! bfd_check_format_matches (abfd, bfd_object, &matching)) 53733965Sjdp { 53833965Sjdp bfd_nonfatal (input_file); 53989857Sobrien 54033965Sjdp if (bfd_get_error () == bfd_error_file_ambiguously_recognized) 54133965Sjdp { 54233965Sjdp list_matching_formats (matching); 54333965Sjdp free (matching); 54433965Sjdp } 54533965Sjdp exit (1); 54633965Sjdp } 54733965Sjdp 54833965Sjdp tree = coff_grok (abfd); 54933965Sjdp 55089857Sobrien coff_dump (tree); 55189857Sobrien printf ("\n"); 55289857Sobrien 55333965Sjdp return 0; 55433965Sjdp} 555