Upload Tizen:Base source
[external/binutils.git] / binutils / coffdump.c
1 /* Coff file dumper.
2    Copyright 1994, 1995, 1998, 1999, 2000, 2001, 2002, 2003, 2005, 2007,
3    2011 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 3 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,
20    MA 02110-1301, USA.  */
21
22
23 /* Written by Steve Chamberlain <sac@cygnus.com>
24
25    This module reads a type tree generated by coffgrok and prints
26    it out so we can test the grokker.  */
27
28 #include "sysdep.h"
29 #include "bfd.h"
30 #include "bfd_stdint.h"
31 #include "libiberty.h"
32 #include "bucomm.h"
33
34 #include "coffgrok.h"
35 #include "getopt.h"
36
37 static int atnl;
38
39 static void tab (int);
40 static void nl (void);
41 static void dump_coff_lines (struct coff_line *);
42 static void dump_coff_type (struct coff_type *);
43 static void dump_coff_where (struct coff_where *);
44 static void dump_coff_visible (struct coff_visible *);
45 static void dump_coff_scope (struct coff_scope *);
46 static void dump_coff_sfile (struct coff_sfile *);
47 static void dump_coff_section (struct coff_section *);
48 static void show_usage (FILE *, int);
49 extern int main (int, char **);
50
51 static void
52 tab (int x)
53 {
54   static int indent;
55   int i;
56
57   if (atnl)
58     {
59       if (x < 0)
60         {
61           printf (")");
62           indent += x;
63
64           return;
65         }
66       else
67         {
68           printf ("\n");
69           atnl = 0;
70         }
71     }
72
73   if (x == -1)
74     {
75       for (i = 0; i < indent; i++)
76         printf ("   ");
77
78       indent += x;
79       printf (")");
80       return;
81     }
82
83   indent += x;
84
85   for (i = 0; i < indent; i++)
86     printf ("   ");
87
88   if (x)
89     {
90       printf ("(");
91     }
92 }
93
94 static void
95 nl (void)
96 {
97   atnl = 1;
98 }
99
100 static void
101 dump_coff_lines (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
126 static void
127 dump_coff_type (struct coff_type *p)
128 {
129   tab (1);
130   printf ("size %d ", p->size);
131
132   switch (p->type)
133     {
134     case coff_secdef_type:
135       printf ("section definition at %x size %x\n",
136               p->u.asecdef.address,
137               p->u.asecdef.size);
138       nl ();
139       break;
140     case coff_pointer_type:
141       printf ("pointer to");
142       nl ();
143       dump_coff_type (p->u.pointer.points_to);
144       break;
145     case coff_array_type:
146       printf ("array [%d] of", p->u.array.dim);
147       nl ();
148       dump_coff_type (p->u.array.array_of);
149       break;
150     case coff_function_type:
151       printf ("function returning");
152       nl ();
153       dump_coff_type (p->u.function.function_returns);
154       dump_coff_lines (p->u.function.lines);
155       printf ("arguments");
156       nl ();
157       dump_coff_scope (p->u.function.parameters);
158       tab (0);
159       printf ("code");
160       nl ();
161       dump_coff_scope (p->u.function.code);
162       tab(0);
163       break;
164     case coff_structdef_type:
165       printf ("structure definition");
166       nl ();
167       dump_coff_scope (p->u.astructdef.elements);
168       break;
169     case coff_structref_type:
170       if (!p->u.aenumref.ref)
171         printf ("structure ref to UNKNOWN struct");
172       else
173         printf ("structure ref to %s", p->u.aenumref.ref->name);
174       break;
175     case coff_enumref_type:
176       printf ("enum ref to %s", p->u.astructref.ref->name);
177       break;
178     case coff_enumdef_type:
179       printf ("enum definition");
180       nl ();
181       dump_coff_scope (p->u.aenumdef.elements);
182       break;
183     case coff_basic_type:
184       switch (p->u.basic)
185         {
186         case T_NULL:
187           printf ("NULL");
188           break;
189         case T_VOID:
190           printf ("VOID");
191           break;
192         case T_CHAR:
193           printf ("CHAR");
194           break;
195         case T_SHORT:
196           printf ("SHORT");
197           break;
198         case T_INT:
199           printf ("INT ");
200           break;
201         case T_LONG:
202           printf ("LONG");
203           break;
204         case T_FLOAT:
205           printf ("FLOAT");
206           break;
207         case T_DOUBLE:
208           printf ("DOUBLE");
209           break;
210         case T_STRUCT:
211           printf ("STRUCT");
212           break;
213         case T_UNION:
214           printf ("UNION");
215           break;
216         case T_ENUM:
217           printf ("ENUM");
218           break;
219         case T_MOE:
220           printf ("MOE ");
221           break;
222         case T_UCHAR:
223           printf ("UCHAR");
224           break;
225         case T_USHORT:
226           printf ("USHORT");
227           break;
228         case T_UINT:
229           printf ("UINT");
230           break;
231         case T_ULONG:
232           printf ("ULONG");
233           break;
234         case T_LNGDBL:
235           printf ("LNGDBL");
236           break;
237         default:
238           abort ();
239         }
240     }
241   nl ();
242   tab (-1);
243 }
244
245 static void
246 dump_coff_where (struct coff_where *p)
247 {
248   tab (1);
249   switch (p->where)
250     {
251     case coff_where_stack:
252       printf ("Stack offset %x", p->offset);
253       break;
254     case coff_where_memory:
255       printf ("Memory section %s+%x", p->section->name, p->offset);
256       break;
257     case coff_where_register:
258       printf ("Register %d", p->offset);
259       break;
260     case coff_where_member_of_struct:
261       printf ("Struct Member offset %x", p->offset);
262       break;
263     case coff_where_member_of_enum:
264       printf ("Enum Member offset %x", p->offset);
265       break;
266     case coff_where_unknown:
267       printf ("Undefined symbol");
268       break;
269     case coff_where_strtag:
270       printf ("STRTAG");
271     case coff_where_entag:
272       printf ("ENTAG");
273       break;
274     case coff_where_typedef:
275       printf ("TYPEDEF");
276       break;
277     default:
278       abort ();
279     }
280   nl ();
281   tab (-1);
282 }
283
284 static void
285 dump_coff_visible (struct coff_visible *p)
286 {
287   tab (1);
288   switch (p->type)
289     {
290     case coff_vis_ext_def:
291       printf ("coff_vis_ext_def");
292       break;
293     case coff_vis_ext_ref:
294       printf ("coff_vis_ext_ref");
295       break;
296     case coff_vis_int_def:
297       printf ("coff_vis_int_def");
298       break;
299     case coff_vis_common:
300       printf ("coff_vis_common");
301       break;
302     case coff_vis_auto:
303       printf ("coff_vis_auto");
304       break;
305     case coff_vis_autoparam:
306       printf ("coff_vis_autoparam");
307       break;
308     case coff_vis_regparam:
309       printf ("coff_vis_regparam");
310       break;
311     case coff_vis_register:
312       printf ("coff_vis_register");
313       break;
314     case coff_vis_tag:
315       printf ("coff_vis_tag");
316       break;
317     case coff_vis_member_of_struct:
318       printf ("coff_vis_member_of_struct");
319       break;
320     case coff_vis_member_of_enum:
321       printf ("coff_vis_member_of_enum");
322       break;
323     default:
324       abort ();
325     }
326   nl ();
327   tab (-1);
328 }
329
330 static void
331 dump_coff_symbol (struct coff_symbol *p)
332 {
333   tab (1);
334   printf ("List of symbols");
335   nl ();
336
337   while (p)
338     {
339       tab (1);
340       tab (1);
341       printf ("Symbol  %s, tag %d, number %d", p->name, p->tag, p->number);
342       nl ();
343       tab (-1);
344       tab (1);
345       printf ("Type");
346       nl ();
347       dump_coff_type (p->type);
348       tab (-1);
349       tab (1);
350       printf ("Where");
351       dump_coff_where (p->where);
352       tab (-1);
353       tab (1);
354       printf ("Visible");
355       dump_coff_visible (p->visible);
356       tab (-1);
357       p = p->next;
358       tab (-1);
359     }
360   tab (-1);
361 }
362
363 static void
364 dump_coff_scope (struct coff_scope *p)
365 {
366   if (p)
367     {
368       tab (1);
369       printf ("List of blocks %" BFD_VMA_FMT "x ",(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 }