coffdump.c revision 91041
1/* Coff file dumper.
2   Copyright 1994, 1995, 1998, 1999, 2000, 2001, 2002
3   Free Software Foundation, Inc.
4
5   This file is part of GNU Binutils.
6
7   This program is free software; you can redistribute it and/or modify
8   it under the terms of the GNU General Public License as published by
9   the Free Software Foundation; either version 2 of the License, or (at
10   your option) any later version.
11
12   This program is distributed in the hope that it will be useful,
13   but WITHOUT ANY WARRANTY; without even the implied warranty of
14   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15   GNU General Public License for more details.
16
17   You should have received a copy of the GNU General Public License
18   along with this program; if not, write to the Free Software
19   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
20
21/* Written by Steve Chamberlain <sac@cygnus.com>
22
23   This module reads a type tree generated by coffgrok and prints
24   it out so we can test the grokker.  */
25
26#include <bfd.h>
27#include <libiberty.h>
28
29#include "coffgrok.h"
30#include "bucomm.h"
31#include "getopt.h"
32
33static int atnl;
34
35static void tab PARAMS ((int));
36static void nl PARAMS ((void));
37static void dump_coff_lines PARAMS ((struct coff_line *));
38static void dump_coff_type PARAMS ((struct coff_type *));
39static void dump_coff_where PARAMS ((struct coff_where *));
40static void dump_coff_visible PARAMS ((struct coff_visible *));
41extern void dump_coff_symbol PARAMS ((struct coff_symbol *));
42static void dump_coff_scope PARAMS ((struct coff_scope *));
43static void dump_coff_sfile PARAMS ((struct coff_sfile *));
44static void dump_coff_section PARAMS ((struct coff_section *));
45extern void coff_dump PARAMS ((struct coff_ofile *));
46static void show_usage PARAMS ((FILE *, int));
47extern int main PARAMS ((int, char **));
48
49static void
50tab (x)
51     int x;
52{
53  static int indent;
54  int i;
55
56  if (atnl)
57    {
58      if (x < 0)
59	{
60	  printf (")");
61	  indent += x;
62
63	  return;
64	}
65      else
66	{
67	  printf ("\n");
68	  atnl = 0;
69	}
70    }
71
72  if (x == -1)
73    {
74      for (i = 0; i < indent; i++)
75	printf ("   ");
76
77      indent += x;
78      printf (")");
79      return;
80    }
81
82  indent += x;
83
84  for (i = 0; i < indent; i++)
85    printf ("   ");
86
87  if (x)
88    {
89      printf ("(");
90    }
91}
92
93static void
94nl ()
95{
96  atnl = 1;
97}
98
99static void
100dump_coff_lines (p)
101     struct coff_line *p;
102{
103  int i;
104  int online = 0;
105
106  tab (1);
107  printf (_("#lines %d "),p->nlines);
108
109  for (i = 0; i < p->nlines; i++)
110    {
111      printf ("(%d 0x%x)", p->lines[i], p->addresses[i]);
112
113      online++;
114
115      if (online > 6)
116	{
117	  nl ();
118	  tab (0);
119	  online = 0;
120	}
121    }
122  nl ();
123  tab (-1);
124}
125
126static void
127dump_coff_type (p)
128     struct coff_type *p;
129{
130  tab (1);
131  printf ("size %d ", p->size);
132
133  switch (p->type)
134    {
135    case coff_secdef_type:
136      printf ("section definition at %x size %x\n",
137	      p->u.asecdef.address,
138	      p->u.asecdef.size);
139      nl ();
140      break;
141    case coff_pointer_type:
142      printf ("pointer to");
143      nl ();
144      dump_coff_type (p->u.pointer.points_to);
145      break;
146    case coff_array_type:
147      printf ("array [%d] of", p->u.array.dim);
148      nl ();
149      dump_coff_type (p->u.array.array_of);
150      break;
151    case coff_function_type:
152      printf ("function returning");
153      nl ();
154      dump_coff_type (p->u.function.function_returns);
155      dump_coff_lines (p->u.function.lines);
156      printf ("arguments");
157      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