12159047fSniklas /* Coff file dumper.
2007c2a45Smiod Copyright 1994, 1995, 1998, 1999, 2000, 2001, 2002, 2003
3c074d1c9Sdrahn Free Software Foundation, Inc.
42159047fSniklas
52159047fSniklas This file is part of GNU Binutils.
62159047fSniklas
72159047fSniklas This program is free software; you can redistribute it and/or modify
82159047fSniklas it under the terms of the GNU General Public License as published by
9c074d1c9Sdrahn the Free Software Foundation; either version 2 of the License, or (at
10c074d1c9Sdrahn your option) any later version.
112159047fSniklas
122159047fSniklas This program is distributed in the hope that it will be useful,
132159047fSniklas but WITHOUT ANY WARRANTY; without even the implied warranty of
142159047fSniklas MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
152159047fSniklas GNU General Public License for more details.
162159047fSniklas
172159047fSniklas You should have received a copy of the GNU General Public License
182159047fSniklas along with this program; if not, write to the Free Software
192159047fSniklas Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
202159047fSniklas
212159047fSniklas /* Written by Steve Chamberlain <sac@cygnus.com>
222159047fSniklas
232159047fSniklas This module reads a type tree generated by coffgrok and prints
24c074d1c9Sdrahn it out so we can test the grokker. */
252159047fSniklas
26c074d1c9Sdrahn #include "bfd.h"
27c074d1c9Sdrahn #include "libiberty.h"
282159047fSniklas
292159047fSniklas #include "coffgrok.h"
302159047fSniklas #include "bucomm.h"
31c074d1c9Sdrahn #include "getopt.h"
322159047fSniklas
332159047fSniklas static int atnl;
34c074d1c9Sdrahn
35007c2a45Smiod static void tab (int);
36007c2a45Smiod static void nl (void);
37007c2a45Smiod static void dump_coff_lines (struct coff_line *);
38007c2a45Smiod static void dump_coff_type (struct coff_type *);
39007c2a45Smiod static void dump_coff_where (struct coff_where *);
40007c2a45Smiod static void dump_coff_visible (struct coff_visible *);
41007c2a45Smiod extern void dump_coff_symbol (struct coff_symbol *);
42007c2a45Smiod static void dump_coff_scope (struct coff_scope *);
43007c2a45Smiod static void dump_coff_sfile (struct coff_sfile *);
44007c2a45Smiod static void dump_coff_section (struct coff_section *);
45007c2a45Smiod extern void coff_dump (struct coff_ofile *);
46007c2a45Smiod static void show_usage (FILE *, int);
47007c2a45Smiod extern int main (int, char **);
482159047fSniklas
492159047fSniklas static void
tab(int x)50007c2a45Smiod tab (int x)
512159047fSniklas {
522159047fSniklas static int indent;
532159047fSniklas int i;
542159047fSniklas
552159047fSniklas if (atnl)
562159047fSniklas {
572159047fSniklas if (x < 0)
582159047fSniklas {
592159047fSniklas printf (")");
602159047fSniklas indent += x;
612159047fSniklas
622159047fSniklas return;
632159047fSniklas }
642159047fSniklas else
652159047fSniklas {
662159047fSniklas printf ("\n");
672159047fSniklas atnl = 0;
682159047fSniklas }
692159047fSniklas }
702159047fSniklas
712159047fSniklas if (x == -1)
722159047fSniklas {
732159047fSniklas for (i = 0; i < indent; i++)
742159047fSniklas printf (" ");
752159047fSniklas
762159047fSniklas indent += x;
772159047fSniklas printf (")");
782159047fSniklas return;
792159047fSniklas }
802159047fSniklas
812159047fSniklas indent += x;
822159047fSniklas
832159047fSniklas for (i = 0; i < indent; i++)
842159047fSniklas printf (" ");
852159047fSniklas
862159047fSniklas if (x)
872159047fSniklas {
882159047fSniklas printf ("(");
892159047fSniklas }
902159047fSniklas }
912159047fSniklas
92c074d1c9Sdrahn static void
nl(void)93007c2a45Smiod nl (void)
942159047fSniklas {
952159047fSniklas atnl = 1;
962159047fSniklas }
972159047fSniklas
982159047fSniklas static void
dump_coff_lines(struct coff_line * p)99007c2a45Smiod dump_coff_lines (struct coff_line *p)
1002159047fSniklas {
1012159047fSniklas int i;
1022159047fSniklas int online = 0;
103c074d1c9Sdrahn
1042159047fSniklas tab (1);
105f7cc78ecSespie printf (_("#lines %d "),p->nlines);
106c074d1c9Sdrahn
1072159047fSniklas for (i = 0; i < p->nlines; i++)
1082159047fSniklas {
1092159047fSniklas printf ("(%d 0x%x)", p->lines[i], p->addresses[i]);
110c074d1c9Sdrahn
1112159047fSniklas online++;
112c074d1c9Sdrahn
1132159047fSniklas if (online > 6)
1142159047fSniklas {
1152159047fSniklas nl ();
1162159047fSniklas tab (0);
1172159047fSniklas online = 0;
1182159047fSniklas }
1192159047fSniklas }
1202159047fSniklas nl ();
1212159047fSniklas tab (-1);
1222159047fSniklas }
1232159047fSniklas
1242159047fSniklas static void
dump_coff_type(struct coff_type * p)125007c2a45Smiod dump_coff_type (struct coff_type *p)
1262159047fSniklas {
1272159047fSniklas tab (1);
1282159047fSniklas printf ("size %d ", p->size);
129c074d1c9Sdrahn
1302159047fSniklas switch (p->type)
1312159047fSniklas {
1322159047fSniklas case coff_secdef_type:
1332159047fSniklas printf ("section definition at %x size %x\n",
1342159047fSniklas p->u.asecdef.address,
1352159047fSniklas p->u.asecdef.size);
1362159047fSniklas nl ();
1372159047fSniklas break;
1382159047fSniklas case coff_pointer_type:
1392159047fSniklas printf ("pointer to");
1402159047fSniklas nl ();
1412159047fSniklas dump_coff_type (p->u.pointer.points_to);
1422159047fSniklas break;
1432159047fSniklas case coff_array_type:
1442159047fSniklas printf ("array [%d] of", p->u.array.dim);
1452159047fSniklas nl ();
1462159047fSniklas dump_coff_type (p->u.array.array_of);
1472159047fSniklas break;
1482159047fSniklas case coff_function_type:
1492159047fSniklas printf ("function returning");
1502159047fSniklas nl ();
1512159047fSniklas dump_coff_type (p->u.function.function_returns);
1522159047fSniklas dump_coff_lines (p->u.function.lines);
1532159047fSniklas printf ("arguments");
1542159047fSniklas nl ();
1552159047fSniklas dump_coff_scope (p->u.function.parameters);
1562159047fSniklas tab (0);
1572159047fSniklas printf ("code");
1582159047fSniklas nl ();
1592159047fSniklas dump_coff_scope (p->u.function.code);
1602159047fSniklas tab(0);
1612159047fSniklas break;
1622159047fSniklas case coff_structdef_type:
1632159047fSniklas printf ("structure definition");
1642159047fSniklas nl ();
1652159047fSniklas dump_coff_scope (p->u.astructdef.elements);
1662159047fSniklas break;
1672159047fSniklas case coff_structref_type:
1682159047fSniklas if (!p->u.aenumref.ref)
1692159047fSniklas printf ("structure ref to UNKNOWN struct");
1702159047fSniklas else
1712159047fSniklas printf ("structure ref to %s", p->u.aenumref.ref->name);
1722159047fSniklas break;
1732159047fSniklas case coff_enumref_type:
1742159047fSniklas printf ("enum ref to %s", p->u.astructref.ref->name);
1752159047fSniklas break;
1762159047fSniklas case coff_enumdef_type:
1772159047fSniklas printf ("enum definition");
1782159047fSniklas nl ();
1792159047fSniklas dump_coff_scope (p->u.aenumdef.elements);
1802159047fSniklas break;
1812159047fSniklas case coff_basic_type:
1822159047fSniklas switch (p->u.basic)
1832159047fSniklas {
1842159047fSniklas case T_NULL:
1852159047fSniklas printf ("NULL");
1862159047fSniklas break;
1872159047fSniklas case T_VOID:
1882159047fSniklas printf ("VOID");
1892159047fSniklas break;
1902159047fSniklas case T_CHAR:
1912159047fSniklas printf ("CHAR");
1922159047fSniklas break;
1932159047fSniklas case T_SHORT:
1942159047fSniklas printf ("SHORT");
1952159047fSniklas break;
1962159047fSniklas case T_INT:
1972159047fSniklas printf ("INT ");
1982159047fSniklas break;
1992159047fSniklas case T_LONG:
2002159047fSniklas printf ("LONG");
2012159047fSniklas break;
2022159047fSniklas case T_FLOAT:
2032159047fSniklas printf ("FLOAT");
2042159047fSniklas break;
2052159047fSniklas case T_DOUBLE:
2062159047fSniklas printf ("DOUBLE");
2072159047fSniklas break;
2082159047fSniklas case T_STRUCT:
2092159047fSniklas printf ("STRUCT");
2102159047fSniklas break;
2112159047fSniklas case T_UNION:
2122159047fSniklas printf ("UNION");
2132159047fSniklas break;
2142159047fSniklas case T_ENUM:
2152159047fSniklas printf ("ENUM");
2162159047fSniklas break;
2172159047fSniklas case T_MOE:
2182159047fSniklas printf ("MOE ");
2192159047fSniklas break;
2202159047fSniklas case T_UCHAR:
2212159047fSniklas printf ("UCHAR");
2222159047fSniklas break;
2232159047fSniklas case T_USHORT:
2242159047fSniklas printf ("USHORT");
2252159047fSniklas break;
2262159047fSniklas case T_UINT:
2272159047fSniklas printf ("UINT");
2282159047fSniklas break;
2292159047fSniklas case T_ULONG:
2302159047fSniklas printf ("ULONG");
2312159047fSniklas break;
2322159047fSniklas case T_LNGDBL:
2332159047fSniklas printf ("LNGDBL");
2342159047fSniklas break;
2352159047fSniklas default:
2362159047fSniklas abort ();
2372159047fSniklas }
2382159047fSniklas }
2392159047fSniklas nl ();
2402159047fSniklas tab (-1);
2412159047fSniklas }
2422159047fSniklas
2432159047fSniklas static void
dump_coff_where(struct coff_where * p)244007c2a45Smiod dump_coff_where (struct coff_where *p)
2452159047fSniklas {
2462159047fSniklas tab (1);
2472159047fSniklas switch (p->where)
2482159047fSniklas {
2492159047fSniklas case coff_where_stack:
2502159047fSniklas printf ("Stack offset %x", p->offset);
2512159047fSniklas break;
2522159047fSniklas case coff_where_memory:
2532159047fSniklas printf ("Memory section %s+%x", p->section->name, p->offset);
2542159047fSniklas break;
2552159047fSniklas case coff_where_register:
2562159047fSniklas printf ("Register %d", p->offset);
2572159047fSniklas break;
2582159047fSniklas case coff_where_member_of_struct:
2592159047fSniklas printf ("Struct Member offset %x", p->offset);
2602159047fSniklas break;
2612159047fSniklas case coff_where_member_of_enum:
2622159047fSniklas printf ("Enum Member offset %x", p->offset);
2632159047fSniklas break;
2642159047fSniklas case coff_where_unknown:
2652159047fSniklas printf ("Undefined symbol");
2662159047fSniklas break;
2672159047fSniklas case coff_where_strtag:
2682159047fSniklas printf ("STRTAG");
2692159047fSniklas case coff_where_entag:
2702159047fSniklas printf ("ENTAG");
2712159047fSniklas break;
2722159047fSniklas case coff_where_typedef:
2732159047fSniklas printf ("TYPEDEF");
2742159047fSniklas break;
2752159047fSniklas default:
2762159047fSniklas abort ();
2772159047fSniklas }
2782159047fSniklas nl ();
2792159047fSniklas tab (-1);
2802159047fSniklas }
2812159047fSniklas
2822159047fSniklas static void
dump_coff_visible(struct coff_visible * p)283007c2a45Smiod dump_coff_visible (struct coff_visible *p)
2842159047fSniklas {
2852159047fSniklas tab (1);
2862159047fSniklas switch (p->type)
2872159047fSniklas {
2882159047fSniklas case coff_vis_ext_def:
2892159047fSniklas printf ("coff_vis_ext_def");
2902159047fSniklas break;
2912159047fSniklas case coff_vis_ext_ref:
2922159047fSniklas printf ("coff_vis_ext_ref");
2932159047fSniklas break;
2942159047fSniklas case coff_vis_int_def:
2952159047fSniklas printf ("coff_vis_int_def");
2962159047fSniklas break;
2972159047fSniklas case coff_vis_common:
2982159047fSniklas printf ("coff_vis_common");
2992159047fSniklas break;
3002159047fSniklas case coff_vis_auto:
3012159047fSniklas printf ("coff_vis_auto");
3022159047fSniklas break;
3032159047fSniklas case coff_vis_autoparam:
3042159047fSniklas printf ("coff_vis_autoparam");
3052159047fSniklas break;
3062159047fSniklas case coff_vis_regparam:
3072159047fSniklas printf ("coff_vis_regparam");
3082159047fSniklas break;
3092159047fSniklas case coff_vis_register:
3102159047fSniklas printf ("coff_vis_register");
3112159047fSniklas break;
3122159047fSniklas case coff_vis_tag:
3132159047fSniklas printf ("coff_vis_tag");
3142159047fSniklas break;
3152159047fSniklas case coff_vis_member_of_struct:
3162159047fSniklas printf ("coff_vis_member_of_struct");
3172159047fSniklas break;
3182159047fSniklas case coff_vis_member_of_enum:
3192159047fSniklas printf ("coff_vis_member_of_enum");
3202159047fSniklas break;
3212159047fSniklas default:
3222159047fSniklas abort ();
3232159047fSniklas }
3242159047fSniklas nl ();
3252159047fSniklas tab (-1);
3262159047fSniklas }
3272159047fSniklas
3282159047fSniklas void
dump_coff_symbol(struct coff_symbol * p)329007c2a45Smiod dump_coff_symbol (struct coff_symbol *p)
3302159047fSniklas {
3312159047fSniklas tab (1);
3322159047fSniklas printf ("List of symbols");
3332159047fSniklas nl ();
334c074d1c9Sdrahn
3352159047fSniklas while (p)
3362159047fSniklas {
3372159047fSniklas tab (1);
3382159047fSniklas tab (1);
3392159047fSniklas printf ("Symbol %s, tag %d, number %d", p->name, p->tag, p->number);
3402159047fSniklas nl ();
3412159047fSniklas tab (-1);
3422159047fSniklas tab (1);
3432159047fSniklas printf ("Type");
3442159047fSniklas nl ();
3452159047fSniklas dump_coff_type (p->type);
3462159047fSniklas tab (-1);
3472159047fSniklas tab (1);
3482159047fSniklas printf ("Where");
3492159047fSniklas dump_coff_where (p->where);
3502159047fSniklas tab (-1);
3512159047fSniklas tab (1);
3522159047fSniklas printf ("Visible");
3532159047fSniklas dump_coff_visible (p->visible);
3542159047fSniklas tab (-1);
3552159047fSniklas p = p->next;
3562159047fSniklas tab (-1);
3572159047fSniklas }
3582159047fSniklas tab (-1);
3592159047fSniklas }
3602159047fSniklas
3612159047fSniklas static void
dump_coff_scope(struct coff_scope * p)362007c2a45Smiod dump_coff_scope (struct coff_scope *p)
3632159047fSniklas {
364c074d1c9Sdrahn if (p)
365c074d1c9Sdrahn {
3662159047fSniklas tab (1);
3672159047fSniklas printf ("List of blocks %lx ",(unsigned long) p);
3682159047fSniklas
369c074d1c9Sdrahn if (p->sec)
3702159047fSniklas printf( " %s %x..%x", p->sec->name,p->offset, p->offset + p->size -1);
371c074d1c9Sdrahn
3722159047fSniklas nl ();
3732159047fSniklas tab (0);
3742159047fSniklas printf ("*****************");
3752159047fSniklas nl ();
376c074d1c9Sdrahn
3772159047fSniklas while (p)
3782159047fSniklas {
3792159047fSniklas tab (0);
3802159047fSniklas printf ("vars %d", p->nvars);
3812159047fSniklas nl ();
3822159047fSniklas dump_coff_symbol (p->vars_head);
3832159047fSniklas printf ("blocks");
3842159047fSniklas nl ();
3852159047fSniklas dump_coff_scope (p->list_head);
3862159047fSniklas nl ();
3872159047fSniklas p = p->next;
3882159047fSniklas }
3892159047fSniklas
3902159047fSniklas tab (0);
3912159047fSniklas printf ("*****************");
3922159047fSniklas nl ();
3932159047fSniklas tab (-1);
3942159047fSniklas }
3952159047fSniklas }
3962159047fSniklas
3972159047fSniklas static void
dump_coff_sfile(struct coff_sfile * p)398007c2a45Smiod dump_coff_sfile (struct coff_sfile *p)
3992159047fSniklas {
4002159047fSniklas tab (1);
4012159047fSniklas printf ("List of source files");
4022159047fSniklas nl ();
403c074d1c9Sdrahn
4042159047fSniklas while (p)
4052159047fSniklas {
4062159047fSniklas tab (0);
4072159047fSniklas printf ("Source file %s", p->name);
4082159047fSniklas nl ();
4092159047fSniklas dump_coff_scope (p->scope);
4102159047fSniklas p = p->next;
4112159047fSniklas }
4122159047fSniklas tab (-1);
4132159047fSniklas }
4142159047fSniklas
4152159047fSniklas static void
dump_coff_section(struct coff_section * ptr)416007c2a45Smiod dump_coff_section (struct coff_section *ptr)
4172159047fSniklas {
4182159047fSniklas int i;
419c074d1c9Sdrahn
4202159047fSniklas tab (1);
4212159047fSniklas printf ("section %s %d %d address %x size %x number %d nrelocs %d",
422c074d1c9Sdrahn ptr->name, ptr->code, ptr->data, ptr->address,ptr->size,
423c074d1c9Sdrahn ptr->number, ptr->nrelocs);
4242159047fSniklas nl ();
4252159047fSniklas
4262159047fSniklas for (i = 0; i < ptr->nrelocs; i++)
4272159047fSniklas {
4282159047fSniklas tab (0);
4292159047fSniklas printf ("(%x %s %x)",
4302159047fSniklas ptr->relocs[i].offset,
4312159047fSniklas ptr->relocs[i].symbol->name,
4322159047fSniklas ptr->relocs[i].addend);
4332159047fSniklas nl ();
4342159047fSniklas }
4352159047fSniklas
436c074d1c9Sdrahn tab (-1);
4372159047fSniklas }
4382159047fSniklas
4392159047fSniklas void
coff_dump(struct coff_ofile * ptr)440007c2a45Smiod coff_dump (struct coff_ofile *ptr)
4412159047fSniklas {
4422159047fSniklas int i;
443c074d1c9Sdrahn
4442159047fSniklas printf ("Coff dump");
4452159047fSniklas nl ();
4462159047fSniklas printf ("#souces %d", ptr->nsources);
4472159047fSniklas nl ();
4482159047fSniklas dump_coff_sfile (ptr->source_head);
449c074d1c9Sdrahn
4502159047fSniklas for (i = 0; i < ptr->nsections; i++)
4512159047fSniklas dump_coff_section (ptr->sections + i);
4522159047fSniklas }
4532159047fSniklas
4542159047fSniklas char * program_name;
4552159047fSniklas
4562159047fSniklas static void
show_usage(FILE * file,int status)457007c2a45Smiod show_usage (FILE *file, int status)
4582159047fSniklas {
459c074d1c9Sdrahn fprintf (file, _("Usage: %s [option(s)] in-file\n"), program_name);
460c074d1c9Sdrahn fprintf (file, _(" Print a human readable interpretation of a SYSROFF object file\n"));
461c074d1c9Sdrahn fprintf (file, _(" The options are:\n\
462c074d1c9Sdrahn -h --help Display this information\n\
463c074d1c9Sdrahn -v --version Display the program's version\n\
464c074d1c9Sdrahn \n"));
465c074d1c9Sdrahn
466c074d1c9Sdrahn if (status == 0)
467c074d1c9Sdrahn fprintf (file, _("Report bugs to %s\n"), REPORT_BUGS_TO);
468c074d1c9Sdrahn
4692159047fSniklas exit (status);
4702159047fSniklas }
4712159047fSniklas
4722159047fSniklas int
main(int ac,char ** av)473007c2a45Smiod main (int ac, char **av)
4742159047fSniklas {
4752159047fSniklas bfd *abfd;
4762159047fSniklas struct coff_ofile *tree;
4772159047fSniklas char **matching;
4782159047fSniklas char *input_file = NULL;
4792159047fSniklas int opt;
4802159047fSniklas static struct option long_options[] =
4812159047fSniklas {
4822159047fSniklas { "help", no_argument, 0, 'h' },
4832159047fSniklas { "version", no_argument, 0, 'V' },
4842159047fSniklas { NULL, no_argument, 0, 0 }
4852159047fSniklas };
4862159047fSniklas
487f7cc78ecSespie #if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
488f7cc78ecSespie setlocale (LC_MESSAGES, "");
489f7cc78ecSespie #endif
490c074d1c9Sdrahn #if defined (HAVE_SETLOCALE)
491c074d1c9Sdrahn setlocale (LC_CTYPE, "");
492c074d1c9Sdrahn #endif
493f7cc78ecSespie bindtextdomain (PACKAGE, LOCALEDIR);
494f7cc78ecSespie textdomain (PACKAGE);
495f7cc78ecSespie
4962159047fSniklas program_name = av[0];
4972159047fSniklas xmalloc_set_program_name (program_name);
4982159047fSniklas
499*a95e6fecStobiasu expandargv (&ac, &av);
500*a95e6fecStobiasu
501c074d1c9Sdrahn while ((opt = getopt_long (ac, av, "HhVv", long_options,
5022159047fSniklas (int *) NULL))
5032159047fSniklas != EOF)
5042159047fSniklas {
5052159047fSniklas switch (opt)
5062159047fSniklas {
507c074d1c9Sdrahn case 'H':
5082159047fSniklas case 'h':
509c074d1c9Sdrahn show_usage (stdout, 0);
510c074d1c9Sdrahn break;
511c074d1c9Sdrahn case 'v':
5122159047fSniklas case 'V':
513c074d1c9Sdrahn print_version ("coffdump");
5142159047fSniklas exit (0);
5152159047fSniklas case 0:
5162159047fSniklas break;
5172159047fSniklas default:
5182159047fSniklas show_usage (stderr, 1);
519c074d1c9Sdrahn break;
5202159047fSniklas }
5212159047fSniklas }
5222159047fSniklas
5232159047fSniklas if (optind < ac)
5242159047fSniklas {
5252159047fSniklas input_file = av[optind];
5262159047fSniklas }
5272159047fSniklas
5282159047fSniklas if (!input_file)
529f7cc78ecSespie fatal (_("no input file specified"));
530c074d1c9Sdrahn
5312159047fSniklas abfd = bfd_openr (input_file, 0);
5322159047fSniklas
5332159047fSniklas if (!abfd)
5342159047fSniklas bfd_fatal (input_file);
5352159047fSniklas
5362159047fSniklas if (! bfd_check_format_matches (abfd, bfd_object, &matching))
5372159047fSniklas {
5382159047fSniklas bfd_nonfatal (input_file);
539c074d1c9Sdrahn
5402159047fSniklas if (bfd_get_error () == bfd_error_file_ambiguously_recognized)
5412159047fSniklas {
5422159047fSniklas list_matching_formats (matching);
5432159047fSniklas free (matching);
5442159047fSniklas }
5452159047fSniklas exit (1);
5462159047fSniklas }
5472159047fSniklas
5482159047fSniklas tree = coff_grok (abfd);
5492159047fSniklas
5502159047fSniklas coff_dump (tree);
5512159047fSniklas printf ("\n");
552c074d1c9Sdrahn
5532159047fSniklas return 0;
5542159047fSniklas }
555