This commit was generated by cvs2svn to track changes on a CVS vendor
[external/binutils.git] / binutils / coffdump.c
1 /* Coff file dumper.
2    Copyright 1994, 1995, 1998, 1999, 2000, 2001, 2002, 2003
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., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, 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
33 static int atnl;
34
35 static void tab (int);
36 static void nl (void);
37 static void dump_coff_lines (struct coff_line *);
38 static void dump_coff_type (struct coff_type *);
39 static void dump_coff_where (struct coff_where *);
40 static void dump_coff_visible (struct coff_visible *);
41 static void dump_coff_scope (struct coff_scope *);
42 static void dump_coff_sfile (struct coff_sfile *);
43 static void dump_coff_section (struct coff_section *);
44 static void show_usage (FILE *, int);
45 extern int main (int, char **);
46
47 static void
48 tab (int x)
49 {
50   static int indent;
51   int i;
52
53   if (atnl)
54     {
55       if (x < 0)
56         {
57           printf (")");
58           indent += x;
59
60           return;
61         }
62       else
63         {
64           printf ("\n");
65           atnl = 0;
66         }
67     }
68
69   if (x == -1)
70     {
71       for (i = 0; i < indent; i++)
72         printf ("   ");
73
74       indent += x;
75       printf (")");
76       return;
77     }
78
79   indent += x;
80
81   for (i = 0; i < indent; i++)
82     printf ("   ");
83
84   if (x)
85     {
86       printf ("(");
87     }
88 }
89
90 static void
91 nl (void)
92 {
93   atnl = 1;
94 }
95
96 static void
97 dump_coff_lines (struct coff_line *p)
98 {
99   int i;
100   int online = 0;
101
102   tab (1);
103   printf (_("#lines %d "),p->nlines);
104
105   for (i = 0; i < p->nlines; i++)
106     {
107       printf ("(%d 0x%x)", p->lines[i], p->addresses[i]);
108
109       online++;
110
111       if (online > 6)
112         {
113           nl ();
114           tab (0);
115           online = 0;
116         }
117     }
118   nl ();
119   tab (-1);
120 }
121
122 static void
123 dump_coff_type (struct coff_type *p)
124 {
125   tab (1);
126   printf ("size %d ", p->size);
127
128   switch (p->type)
129     {
130     case coff_secdef_type:
131       printf ("section definition at %x size %x\n",
132               p->u.asecdef.address,
133               p->u.asecdef.size);
134       nl ();
135       break;
136     case coff_pointer_type:
137       printf ("pointer to");
138       nl ();
139       dump_coff_type (p->u.pointer.points_to);
140       break;
141     case coff_array_type:
142       printf ("array [%d] of", p->u.array.dim);
143       nl ();
144       dump_coff_type (p->u.array.array_of);
145       break;
146     case coff_function_type:
147       printf ("function returning");
148       nl ();
149       dump_coff_type (p->u.function.function_returns);
150       dump_coff_lines (p->u.function.lines);
151       printf ("arguments");
152       nl ();
153       dump_coff_scope (p->u.function.parameters);
154       tab (0);
155       printf ("code");
156       nl ();
157       dump_coff_scope (p->u.function.code);
158       tab(0);
159       break;
160     case coff_structdef_type:
161       printf ("structure definition");
162       nl ();
163       dump_coff_scope (p->u.astructdef.elements);
164       break;
165     case coff_structref_type:
166       if (!p->u.aenumref.ref)
167         printf ("structure ref to UNKNOWN struct");
168       else
169         printf ("structure ref to %s", p->u.aenumref.ref->name);
170       break;
171     case coff_enumref_type:
172       printf ("enum ref to %s", p->u.astructref.ref->name);
173       break;
174     case coff_enumdef_type:
175       printf ("enum definition");
176       nl ();
177       dump_coff_scope (p->u.aenumdef.elements);
178       break;
179     case coff_basic_type:
180       switch (p->u.basic)
181         {
182         case T_NULL:
183           printf ("NULL");
184           break;
185         case T_VOID:
186           printf ("VOID");
187           break;
188         case T_CHAR:
189           printf ("CHAR");
190           break;
191         case T_SHORT:
192           printf ("SHORT");
193           break;
194         case T_INT:
195           printf ("INT ");
196           break;
197         case T_LONG:
198           printf ("LONG");
199           break;
200         case T_FLOAT:
201           printf ("FLOAT");
202           break;
203         case T_DOUBLE:
204           printf ("DOUBLE");
205           break;
206         case T_STRUCT:
207           printf ("STRUCT");
208           break;
209         case T_UNION:
210           printf ("UNION");
211           break;
212         case T_ENUM:
213           printf ("ENUM");
214           break;
215         case T_MOE:
216           printf ("MOE ");
217           break;
218         case T_UCHAR:
219           printf ("UCHAR");
220           break;
221         case T_USHORT:
222           printf ("USHORT");
223           break;
224         case T_UINT:
225           printf ("UINT");
226           break;
227         case T_ULONG:
228           printf ("ULONG");
229           break;
230         case T_LNGDBL:
231           printf ("LNGDBL");
232           break;
233         default:
234           abort ();
235         }
236     }
237   nl ();
238   tab (-1);
239 }
240
241 static void
242 dump_coff_where (struct coff_where *p)
243 {
244   tab (1);
245   switch (p->where)
246     {
247     case coff_where_stack:
248       printf ("Stack offset %x", p->offset);
249       break;
250     case coff_where_memory:
251       printf ("Memory section %s+%x", p->section->name, p->offset);
252       break;
253     case coff_where_register:
254       printf ("Register %d", p->offset);
255       break;
256     case coff_where_member_of_struct:
257       printf ("Struct Member offset %x", p->offset);
258       break;
259     case coff_where_member_of_enum:
260       printf ("Enum Member offset %x", p->offset);
261       break;
262     case coff_where_unknown:
263       printf ("Undefined symbol");
264       break;
265     case coff_where_strtag:
266       printf ("STRTAG");
267     case coff_where_entag:
268       printf ("ENTAG");
269       break;
270     case coff_where_typedef:
271       printf ("TYPEDEF");
272       break;
273     default:
274       abort ();
275     }
276   nl ();
277   tab (-1);
278 }
279
280 static void
281 dump_coff_visible (struct coff_visible *p)
282 {
283   tab (1);
284   switch (p->type)
285     {
286     case coff_vis_ext_def:
287       printf ("coff_vis_ext_def");
288       break;
289     case coff_vis_ext_ref:
290       printf ("coff_vis_ext_ref");
291       break;
292     case coff_vis_int_def:
293       printf ("coff_vis_int_def");
294       break;
295     case coff_vis_common:
296       printf ("coff_vis_common");
297       break;
298     case coff_vis_auto:
299       printf ("coff_vis_auto");
300       break;
301     case coff_vis_autoparam:
302       printf ("coff_vis_autoparam");
303       break;
304     case coff_vis_regparam:
305       printf ("coff_vis_regparam");
306       break;
307     case coff_vis_register:
308       printf ("coff_vis_register");
309       break;
310     case coff_vis_tag:
311       printf ("coff_vis_tag");
312       break;
313     case coff_vis_member_of_struct:
314       printf ("coff_vis_member_of_struct");
315       break;
316     case coff_vis_member_of_enum:
317       printf ("coff_vis_member_of_enum");
318       break;
319     default:
320       abort ();
321     }
322   nl ();
323   tab (-1);
324 }
325
326 static void
327 dump_coff_symbol (struct coff_symbol *p)
328 {
329   tab (1);
330   printf ("List of symbols");
331   nl ();
332
333   while (p)
334     {
335       tab (1);
336       tab (1);
337       printf ("Symbol  %s, tag %d, number %d", p->name, p->tag, p->number);
338       nl ();
339       tab (-1);
340       tab (1);
341       printf ("Type");
342       nl ();
343       dump_coff_type (p->type);
344       tab (-1);
345       tab (1);
346       printf ("Where");
347       dump_coff_where (p->where);
348       tab (-1);
349       tab (1);
350       printf ("Visible");
351       dump_coff_visible (p->visible);
352       tab (-1);
353       p = p->next;
354       tab (-1);
355     }
356   tab (-1);
357 }
358
359 static void
360 dump_coff_scope (struct coff_scope *p)
361 {
362   if (p)
363     {
364       tab (1);
365       printf ("List of blocks %lx ",(unsigned long) p);
366
367       if (p->sec)
368         printf( "  %s %x..%x",  p->sec->name,p->offset, p->offset + p->size -1);
369
370       nl ();
371       tab (0);
372       printf ("*****************");
373       nl ();
374
375       while (p)
376         {
377           tab (0);
378           printf ("vars %d", p->nvars);
379           nl ();
380           dump_coff_symbol (p->vars_head);
381           printf ("blocks");
382           nl ();
383           dump_coff_scope (p->list_head);
384           nl ();
385           p = p->next;
386         }
387
388       tab (0);
389       printf ("*****************");
390       nl ();
391       tab (-1);
392     }
393 }
394
395 static void
396 dump_coff_sfile (struct coff_sfile *p)
397 {
398   tab (1);
399   printf ("List of source files");
400   nl ();
401
402   while (p)
403     {
404       tab (0);
405       printf ("Source file %s", p->name);
406       nl ();
407       dump_coff_scope (p->scope);
408       p = p->next;
409     }
410   tab (-1);
411 }
412
413 static void
414 dump_coff_section (struct coff_section *ptr)
415 {
416   int i;
417
418   tab (1);
419   printf ("section %s %d %d address %x size %x number %d nrelocs %d",
420           ptr->name, ptr->code, ptr->data, ptr->address,ptr->size,
421           ptr->number, ptr->nrelocs);
422   nl ();
423
424   for (i = 0; i < ptr->nrelocs; i++)
425     {
426       tab (0);
427       printf ("(%x %s %x)",
428               ptr->relocs[i].offset,
429               ptr->relocs[i].symbol->name,
430               ptr->relocs[i].addend);
431       nl ();
432     }
433
434   tab (-1);
435 }
436
437 static void
438 coff_dump (struct coff_ofile *ptr)
439 {
440   int i;
441
442   printf ("Coff dump");
443   nl ();
444   printf ("#souces %d", ptr->nsources);
445   nl ();
446   dump_coff_sfile (ptr->source_head);
447
448   for (i = 0; i < ptr->nsections; i++)
449     dump_coff_section (ptr->sections + i);
450 }
451
452 char * program_name;
453
454 static void
455 show_usage (FILE *file, int status)
456 {
457   fprintf (file, _("Usage: %s [option(s)] in-file\n"), program_name);
458   fprintf (file, _(" Print a human readable interpretation of a SYSROFF object file\n"));
459   fprintf (file, _(" The options are:\n\
460   @<file>                Read options from <file>\n\
461   -h --help              Display this information\n\
462   -v --version           Display the program's version\n\
463 \n"));
464
465   if (status == 0)
466     fprintf (file, _("Report bugs to %s\n"), REPORT_BUGS_TO);
467
468   exit (status);
469 }
470
471 int
472 main (int ac, char **av)
473 {
474   bfd *abfd;
475   struct coff_ofile *tree;
476   char **matching;
477   char *input_file = NULL;
478   int opt;
479   static struct option long_options[] =
480     {
481       { "help", no_argument, 0, 'h' },
482       { "version", no_argument, 0, 'V' },
483       { NULL, no_argument, 0, 0 }
484     };
485
486 #if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
487   setlocale (LC_MESSAGES, "");
488 #endif
489 #if defined (HAVE_SETLOCALE)
490   setlocale (LC_CTYPE, "");
491 #endif
492   bindtextdomain (PACKAGE, LOCALEDIR);
493   textdomain (PACKAGE);
494
495   program_name = av[0];
496   xmalloc_set_program_name (program_name);
497
498   expandargv (&ac, &av);
499
500   while ((opt = getopt_long (ac, av, "HhVv", long_options,
501                              (int *) NULL))
502          != EOF)
503     {
504       switch (opt)
505         {
506         case 'H':
507         case 'h':
508           show_usage (stdout, 0);
509           break;
510         case 'v':
511         case 'V':
512           print_version ("coffdump");
513           exit (0);
514         case 0:
515           break;
516         default:
517           show_usage (stderr, 1);
518           break;
519         }
520     }
521
522   if (optind < ac)
523     {
524       input_file = av[optind];
525     }
526
527   if (!input_file)
528     fatal (_("no input file specified"));
529
530   abfd = bfd_openr (input_file, 0);
531
532   if (!abfd)
533     bfd_fatal (input_file);
534
535   if (! bfd_check_format_matches (abfd, bfd_object, &matching))
536     {
537       bfd_nonfatal (input_file);
538
539       if (bfd_get_error () == bfd_error_file_ambiguously_recognized)
540         {
541           list_matching_formats (matching);
542           free (matching);
543         }
544       exit (1);
545     }
546
547   tree = coff_grok (abfd);
548
549   coff_dump (tree);
550   printf ("\n");
551
552   return 0;
553 }