coffdump.c revision 91041
1230557Sjimharris/* Coff file dumper.
2230557Sjimharris   Copyright 1994, 1995, 1998, 1999, 2000, 2001, 2002
3230557Sjimharris   Free Software Foundation, Inc.
4230557Sjimharris
5230557Sjimharris   This file is part of GNU Binutils.
6230557Sjimharris
7230557Sjimharris   This program is free software; you can redistribute it and/or modify
8230557Sjimharris   it under the terms of the GNU General Public License as published by
9230557Sjimharris   the Free Software Foundation; either version 2 of the License, or (at
10230557Sjimharris   your option) any later version.
11230557Sjimharris
12230557Sjimharris   This program is distributed in the hope that it will be useful,
13230557Sjimharris   but WITHOUT ANY WARRANTY; without even the implied warranty of
14230557Sjimharris   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15230557Sjimharris   GNU General Public License for more details.
16230557Sjimharris
17230557Sjimharris   You should have received a copy of the GNU General Public License
18230557Sjimharris   along with this program; if not, write to the Free Software
19230557Sjimharris   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
20230557Sjimharris
21230557Sjimharris/* Written by Steve Chamberlain <sac@cygnus.com>
22230557Sjimharris
23230557Sjimharris   This module reads a type tree generated by coffgrok and prints
24230557Sjimharris   it out so we can test the grokker.  */
25230557Sjimharris
26230557Sjimharris#include <bfd.h>
27230557Sjimharris#include <libiberty.h>
28230557Sjimharris
29230557Sjimharris#include "coffgrok.h"
30230557Sjimharris#include "bucomm.h"
31230557Sjimharris#include "getopt.h"
32230557Sjimharris
33230557Sjimharrisstatic int atnl;
34230557Sjimharris
35230557Sjimharrisstatic void tab PARAMS ((int));
36230557Sjimharrisstatic void nl PARAMS ((void));
37230557Sjimharrisstatic void dump_coff_lines PARAMS ((struct coff_line *));
38230557Sjimharrisstatic void dump_coff_type PARAMS ((struct coff_type *));
39230557Sjimharrisstatic void dump_coff_where PARAMS ((struct coff_where *));
40230557Sjimharrisstatic void dump_coff_visible PARAMS ((struct coff_visible *));
41230557Sjimharrisextern void dump_coff_symbol PARAMS ((struct coff_symbol *));
42230557Sjimharrisstatic void dump_coff_scope PARAMS ((struct coff_scope *));
43230557Sjimharrisstatic void dump_coff_sfile PARAMS ((struct coff_sfile *));
44230557Sjimharrisstatic void dump_coff_section PARAMS ((struct coff_section *));
45230557Sjimharrisextern void coff_dump PARAMS ((struct coff_ofile *));
46230557Sjimharrisstatic void show_usage PARAMS ((FILE *, int));
47230557Sjimharrisextern int main PARAMS ((int, char **));
48230557Sjimharris
49230557Sjimharrisstatic void
50230557Sjimharristab (x)
51230557Sjimharris     int x;
52230557Sjimharris{
53230557Sjimharris  static int indent;
54230557Sjimharris  int i;
55230557Sjimharris
56230557Sjimharris  if (atnl)
57230557Sjimharris    {
58230557Sjimharris      if (x < 0)
59230557Sjimharris	{
60230557Sjimharris	  printf (")");
61230557Sjimharris	  indent += x;
62230557Sjimharris
63230557Sjimharris	  return;
64230557Sjimharris	}
65230557Sjimharris      else
66230557Sjimharris	{
67230557Sjimharris	  printf ("\n");
68230557Sjimharris	  atnl = 0;
69230557Sjimharris	}
70230557Sjimharris    }
71230557Sjimharris
72230557Sjimharris  if (x == -1)
73230557Sjimharris    {
74230557Sjimharris      for (i = 0; i < indent; i++)
75230557Sjimharris	printf ("   ");
76230557Sjimharris
77230557Sjimharris      indent += x;
78230557Sjimharris      printf (")");
79230557Sjimharris      return;
80230557Sjimharris    }
81230557Sjimharris
82230557Sjimharris  indent += x;
83230557Sjimharris
84230557Sjimharris  for (i = 0; i < indent; i++)
85230557Sjimharris    printf ("   ");
86230557Sjimharris
87230557Sjimharris  if (x)
88230557Sjimharris    {
89230557Sjimharris      printf ("(");
90230557Sjimharris    }
91230557Sjimharris}
92230557Sjimharris
93230557Sjimharrisstatic void
94230557Sjimharrisnl ()
95230557Sjimharris{
96230557Sjimharris  atnl = 1;
97230557Sjimharris}
98230557Sjimharris
99230557Sjimharrisstatic void
100230557Sjimharrisdump_coff_lines (p)
101230557Sjimharris     struct coff_line *p;
102230557Sjimharris{
103230557Sjimharris  int i;
104230557Sjimharris  int online = 0;
105230557Sjimharris
106230557Sjimharris  tab (1);
107230557Sjimharris  printf (_("#lines %d "),p->nlines);
108230557Sjimharris
109230557Sjimharris  for (i = 0; i < p->nlines; i++)
110230557Sjimharris    {
111230557Sjimharris      printf ("(%d 0x%x)", p->lines[i], p->addresses[i]);
112230557Sjimharris
113230557Sjimharris      online++;
114230557Sjimharris
115230557Sjimharris      if (online > 6)
116230557Sjimharris	{
117230557Sjimharris	  nl ();
118230557Sjimharris	  tab (0);
119230557Sjimharris	  online = 0;
120230557Sjimharris	}
121230557Sjimharris    }
122230557Sjimharris  nl ();
123230557Sjimharris  tab (-1);
124230557Sjimharris}
125230557Sjimharris
126230557Sjimharrisstatic void
127230557Sjimharrisdump_coff_type (p)
128230557Sjimharris     struct coff_type *p;
129230557Sjimharris{
130230557Sjimharris  tab (1);
131230557Sjimharris  printf ("size %d ", p->size);
132230557Sjimharris
133230557Sjimharris  switch (p->type)
134230557Sjimharris    {
135230557Sjimharris    case coff_secdef_type:
136230557Sjimharris      printf ("section definition at %x size %x\n",
137230557Sjimharris	      p->u.asecdef.address,
138230557Sjimharris	      p->u.asecdef.size);
139230557Sjimharris      nl ();
140230557Sjimharris      break;
141230557Sjimharris    case coff_pointer_type:
142230557Sjimharris      printf ("pointer to");
143230557Sjimharris      nl ();
144230557Sjimharris      dump_coff_type (p->u.pointer.points_to);
145230557Sjimharris      break;
146230557Sjimharris    case coff_array_type:
147230557Sjimharris      printf ("array [%d] of", p->u.array.dim);
148230557Sjimharris      nl ();
149230557Sjimharris      dump_coff_type (p->u.array.array_of);
150230557Sjimharris      break;
151230557Sjimharris    case coff_function_type:
152230557Sjimharris      printf ("function returning");
153230557Sjimharris      nl ();
154230557Sjimharris      dump_coff_type (p->u.function.function_returns);
155230557Sjimharris      dump_coff_lines (p->u.function.lines);
156230557Sjimharris      printf ("arguments");
157230557Sjimharris      nl ();
158      dump_coff_scope (p->u.function.parameters);
159      tab (0);
160      printf ("code");
161      nl ();
162      dump_coff_scope (p->u.function.code);
163      tab(0);
164      break;
165    case coff_structdef_type:
166      printf ("structure definition");
167      nl ();
168      dump_coff_scope (p->u.astructdef.elements);
169      break;
170    case coff_structref_type:
171      if (!p->u.aenumref.ref)
172	printf ("structure ref to UNKNOWN struct");
173      else
174	printf ("structure ref to %s", p->u.aenumref.ref->name);
175      break;
176    case coff_enumref_type:
177      printf ("enum ref to %s", p->u.astructref.ref->name);
178      break;
179    case coff_enumdef_type:
180      printf ("enum definition");
181      nl ();
182      dump_coff_scope (p->u.aenumdef.elements);
183      break;
184    case coff_basic_type:
185      switch (p->u.basic)
186	{
187	case T_NULL:
188	  printf ("NULL");
189	  break;
190	case T_VOID:
191	  printf ("VOID");
192	  break;
193	case T_CHAR:
194	  printf ("CHAR");
195	  break;
196	case T_SHORT:
197	  printf ("SHORT");
198	  break;
199	case T_INT:
200	  printf ("INT ");
201	  break;
202	case T_LONG:
203	  printf ("LONG");
204	  break;
205	case T_FLOAT:
206	  printf ("FLOAT");
207	  break;
208	case T_DOUBLE:
209	  printf ("DOUBLE");
210	  break;
211	case T_STRUCT:
212	  printf ("STRUCT");
213	  break;
214	case T_UNION:
215	  printf ("UNION");
216	  break;
217	case T_ENUM:
218	  printf ("ENUM");
219	  break;
220	case T_MOE:
221	  printf ("MOE ");
222	  break;
223	case T_UCHAR:
224	  printf ("UCHAR");
225	  break;
226	case T_USHORT:
227	  printf ("USHORT");
228	  break;
229	case T_UINT:
230	  printf ("UINT");
231	  break;
232	case T_ULONG:
233	  printf ("ULONG");
234	  break;
235	case T_LNGDBL:
236	  printf ("LNGDBL");
237	  break;
238	default:
239	  abort ();
240	}
241    }
242  nl ();
243  tab (-1);
244}
245
246static void
247dump_coff_where (p)
248     struct coff_where *p;
249{
250  tab (1);
251  switch (p->where)
252    {
253    case coff_where_stack:
254      printf ("Stack offset %x", p->offset);
255      break;
256    case coff_where_memory:
257      printf ("Memory section %s+%x", p->section->name, p->offset);
258      break;
259    case coff_where_register:
260      printf ("Register %d", p->offset);
261      break;
262    case coff_where_member_of_struct:
263      printf ("Struct Member offset %x", p->offset);
264      break;
265    case coff_where_member_of_enum:
266      printf ("Enum Member offset %x", p->offset);
267      break;
268    case coff_where_unknown:
269      printf ("Undefined symbol");
270      break;
271    case coff_where_strtag:
272      printf ("STRTAG");
273    case coff_where_entag:
274      printf ("ENTAG");
275      break;
276    case coff_where_typedef:
277      printf ("TYPEDEF");
278      break;
279    default:
280      abort ();
281    }
282  nl ();
283  tab (-1);
284}
285
286static void
287dump_coff_visible (p)
288     struct coff_visible *p;
289{
290  tab (1);
291  switch (p->type)
292    {
293    case coff_vis_ext_def:
294      printf ("coff_vis_ext_def");
295      break;
296    case coff_vis_ext_ref:
297      printf ("coff_vis_ext_ref");
298      break;
299    case coff_vis_int_def:
300      printf ("coff_vis_int_def");
301      break;
302    case coff_vis_common:
303      printf ("coff_vis_common");
304      break;
305    case coff_vis_auto:
306      printf ("coff_vis_auto");
307      break;
308    case coff_vis_autoparam:
309      printf ("coff_vis_autoparam");
310      break;
311    case coff_vis_regparam:
312      printf ("coff_vis_regparam");
313      break;
314    case coff_vis_register:
315      printf ("coff_vis_register");
316      break;
317    case coff_vis_tag:
318      printf ("coff_vis_tag");
319      break;
320    case coff_vis_member_of_struct:
321      printf ("coff_vis_member_of_struct");
322      break;
323    case coff_vis_member_of_enum:
324      printf ("coff_vis_member_of_enum");
325      break;
326    default:
327      abort ();
328    }
329  nl ();
330  tab (-1);
331}
332
333void
334dump_coff_symbol (p)
335     struct coff_symbol *p;
336{
337  tab (1);
338  printf ("List of symbols");
339  nl ();
340
341  while (p)
342    {
343      tab (1);
344      tab (1);
345      printf ("Symbol  %s, tag %d, number %d", p->name, p->tag, p->number);
346      nl ();
347      tab (-1);
348      tab (1);
349      printf ("Type");
350      nl ();
351      dump_coff_type (p->type);
352      tab (-1);
353      tab (1);
354      printf ("Where");
355      dump_coff_where (p->where);
356      tab (-1);
357      tab (1);
358      printf ("Visible");
359      dump_coff_visible (p->visible);
360      tab (-1);
361      p = p->next;
362      tab (-1);
363    }
364  tab (-1);
365}
366
367static void
368dump_coff_scope (p)
369     struct coff_scope *p;
370{
371  if (p)
372    {
373      tab (1);
374      printf ("List of blocks %lx ",(unsigned long) p);
375
376      if (p->sec)
377	printf( "  %s %x..%x",  p->sec->name,p->offset, p->offset + p->size -1);
378
379      nl ();
380      tab (0);
381      printf ("*****************");
382      nl ();
383
384      while (p)
385	{
386	  tab (0);
387	  printf ("vars %d", p->nvars);
388	  nl ();
389	  dump_coff_symbol (p->vars_head);
390	  printf ("blocks");
391	  nl ();
392	  dump_coff_scope (p->list_head);
393	  nl ();
394	  p = p->next;
395	}
396
397      tab (0);
398      printf ("*****************");
399      nl ();
400      tab (-1);
401    }
402}
403
404static void
405dump_coff_sfile (p)
406     struct coff_sfile *p;
407{
408  tab (1);
409  printf ("List of source files");
410  nl ();
411
412  while (p)
413    {
414      tab (0);
415      printf ("Source file %s", p->name);
416      nl ();
417      dump_coff_scope (p->scope);
418      p = p->next;
419    }
420  tab (-1);
421}
422
423static void
424dump_coff_section(ptr)
425     struct coff_section *ptr;
426{
427  int i;
428
429  tab (1);
430  printf ("section %s %d %d address %x size %x number %d nrelocs %d",
431	  ptr->name, ptr->code, ptr->data, ptr->address,ptr->size,
432	  ptr->number, ptr->nrelocs);
433  nl ();
434
435  for (i = 0; i < ptr->nrelocs; i++)
436    {
437      tab (0);
438      printf ("(%x %s %x)",
439	      ptr->relocs[i].offset,
440	      ptr->relocs[i].symbol->name,
441	      ptr->relocs[i].addend);
442      nl ();
443    }
444
445  tab (-1);
446}
447
448void
449coff_dump (ptr)
450     struct coff_ofile *ptr;
451{
452  int i;
453
454  printf ("Coff dump");
455  nl ();
456  printf ("#souces %d", ptr->nsources);
457  nl ();
458  dump_coff_sfile (ptr->source_head);
459
460  for (i = 0; i < ptr->nsections; i++)
461    dump_coff_section (ptr->sections + i);
462}
463
464char * program_name;
465
466static void
467show_usage (file, status)
468     FILE *file;
469     int status;
470{
471  fprintf (file, _("Usage: %s [option(s)] in-file\n"), program_name);
472  fprintf (file, _(" Print a human readable interpretation of a SYSROFF object file\n"));
473  fprintf (file, _(" The options are:\n\
474  -h --help              Display this information\n\
475  -v --version           Display the program's version\n\
476\n"));
477
478  if (status == 0)
479    fprintf (file, _("Report bugs to %s\n"), REPORT_BUGS_TO);
480
481  exit (status);
482}
483
484int
485main (ac, av)
486     int ac;
487     char *av[];
488{
489  bfd *abfd;
490  struct coff_ofile *tree;
491  char **matching;
492  char *input_file = NULL;
493  int opt;
494  static struct option long_options[] =
495    {
496      { "help", no_argument, 0, 'h' },
497      { "version", no_argument, 0, 'V' },
498      { NULL, no_argument, 0, 0 }
499    };
500
501#if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
502  setlocale (LC_MESSAGES, "");
503#endif
504#if defined (HAVE_SETLOCALE)
505  setlocale (LC_CTYPE, "");
506#endif
507  bindtextdomain (PACKAGE, LOCALEDIR);
508  textdomain (PACKAGE);
509
510  program_name = av[0];
511  xmalloc_set_program_name (program_name);
512
513  while ((opt = getopt_long (ac, av, "HhVv", long_options,
514			     (int *) NULL))
515	 != EOF)
516    {
517      switch (opt)
518	{
519	case 'H':
520	case 'h':
521	  show_usage (stdout, 0);
522	  break;
523	case 'v':
524	case 'V':
525	  print_version ("coffdump");
526	  exit (0);
527	case 0:
528	  break;
529	default:
530	  show_usage (stderr, 1);
531	  break;
532	}
533    }
534
535  if (optind < ac)
536    {
537      input_file = av[optind];
538    }
539
540  if (!input_file)
541    fatal (_("no input file specified"));
542
543  abfd = bfd_openr (input_file, 0);
544
545  if (!abfd)
546    bfd_fatal (input_file);
547
548  if (! bfd_check_format_matches (abfd, bfd_object, &matching))
549    {
550      bfd_nonfatal (input_file);
551
552      if (bfd_get_error () == bfd_error_file_ambiguously_recognized)
553	{
554	  list_matching_formats (matching);
555	  free (matching);
556	}
557      exit (1);
558    }
559
560  tree = coff_grok (abfd);
561
562  coff_dump (tree);
563  printf ("\n");
564
565  return 0;
566}
567