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