* coffdump.c (PROGRAM_VERSION): Delete.
[external/binutils.git] / binutils / coffdump.c
1 /* Coff file dumper.
2    Copyright 1994, 1995, 1998, 1999, 2000, 2001 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 2 of the License, or
9 (at 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
19
20 /* Written by Steve Chamberlain <sac@cygnus.com>
21
22    This module reads a type tree generated by coffgrok and prints
23    it out so we can test the grokker.
24 */
25
26 #include <bfd.h>
27 #include <getopt.h>
28 #include <libiberty.h>
29
30 #include "coffgrok.h"
31 #include "bucomm.h"
32
33 static int atnl;
34
35 static void tab PARAMS ((int));
36 static void nl PARAMS ((void));
37 static void dump_coff_lines PARAMS ((struct coff_line *));
38 static void dump_coff_type PARAMS ((struct coff_type *));
39 static void dump_coff_where PARAMS ((struct coff_where *));
40 static void dump_coff_visible PARAMS ((struct coff_visible *));
41 extern void dump_coff_symbol PARAMS ((struct coff_symbol *));
42 static void dump_coff_scope PARAMS ((struct coff_scope *));
43 static void dump_coff_sfile PARAMS ((struct coff_sfile *));
44 static void dump_coff_section PARAMS ((struct coff_section *));
45 extern void coff_dump PARAMS ((struct coff_ofile *));
46 static void show_usage PARAMS ((FILE *, int));
47 static void show_help PARAMS ((void));
48 extern int main PARAMS ((int, char **));
49
50 static void
51 tab (x)
52 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 nl ()
95 {
96   atnl = 1;
97 }
98
99 static void
100 dump_coff_lines (p)
101      struct coff_line *p;
102 {
103   int i;
104   int online = 0;
105   tab(1);
106   printf(_("#lines %d "),p->nlines);
107   for (i = 0; i < p->nlines; i++) 
108     {
109       printf("(%d 0x%x)", p->lines[i], p->addresses[i]);
110       online++;
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 (p)
124      struct coff_type *p;
125 {
126   tab (1);
127   printf ("size %d ", p->size);
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 (p)
243      struct coff_where *p;
244 {
245   tab (1);
246   switch (p->where)
247     {
248     case coff_where_stack:
249       printf ("Stack offset %x", p->offset);
250       break;
251     case coff_where_memory:
252       printf ("Memory section %s+%x", p->section->name, p->offset);
253       break;
254     case coff_where_register:
255       printf ("Register %d", p->offset);
256       break;
257     case coff_where_member_of_struct:
258       printf ("Struct Member offset %x", p->offset);
259       break;
260     case coff_where_member_of_enum:
261       printf ("Enum Member offset %x", p->offset);
262       break;
263     case coff_where_unknown:
264       printf ("Undefined symbol");
265       break;
266     case coff_where_strtag:
267       printf ("STRTAG");
268     case coff_where_entag:
269       printf ("ENTAG");
270       break;
271     case coff_where_typedef:
272       printf ("TYPEDEF");
273       break;
274     default:
275       abort ();
276     }
277   nl ();
278   tab (-1);
279 }
280
281 static void
282 dump_coff_visible (p)
283      struct coff_visible *p;
284 {
285   tab (1);
286   switch (p->type)
287     {
288     case coff_vis_ext_def:
289       printf ("coff_vis_ext_def");
290       break;
291     case coff_vis_ext_ref:
292       printf ("coff_vis_ext_ref");
293       break;
294     case coff_vis_int_def:
295       printf ("coff_vis_int_def");
296       break;
297     case coff_vis_common:
298       printf ("coff_vis_common");
299       break;
300     case coff_vis_auto:
301       printf ("coff_vis_auto");
302       break;
303     case coff_vis_autoparam:
304       printf ("coff_vis_autoparam");
305       break;
306     case coff_vis_regparam:
307       printf ("coff_vis_regparam");
308       break;
309     case coff_vis_register:
310       printf ("coff_vis_register");
311       break;
312     case coff_vis_tag:
313       printf ("coff_vis_tag");
314       break;
315     case coff_vis_member_of_struct:
316       printf ("coff_vis_member_of_struct");
317       break;
318     case coff_vis_member_of_enum:
319       printf ("coff_vis_member_of_enum");
320       break;
321     default:
322       abort ();
323     }
324   nl ();
325   tab (-1);
326 }
327
328
329 void
330 dump_coff_symbol (p)
331      struct coff_symbol *p;
332 {
333   tab (1);
334   printf ("List of symbols");
335   nl ();
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 (p)
364      struct coff_scope *p;
365 {
366 if (p) {
367   tab (1);
368   printf ("List of blocks %lx ",(unsigned long) p);
369
370   if (p->sec) {
371     printf( "  %s %x..%x",  p->sec->name,p->offset, p->offset + p->size -1);
372   }
373   nl ();
374   tab (0);
375   printf ("*****************");
376   nl ();
377   while (p)
378     {
379       tab (0);
380       printf ("vars %d", p->nvars);
381       nl ();
382       dump_coff_symbol (p->vars_head);
383       printf ("blocks");
384       nl ();
385       dump_coff_scope (p->list_head);
386       nl ();
387       p = p->next;
388     }
389
390   tab (0);
391   printf ("*****************");
392   nl ();
393   tab (-1);
394 }
395 }
396
397 static void
398 dump_coff_sfile (p)
399      struct coff_sfile *p;
400 {
401   tab (1);
402   printf ("List of source files");
403   nl ();
404   while (p)
405     {
406       tab (0);
407       printf ("Source file %s", p->name);
408       nl ();
409       dump_coff_scope (p->scope);
410       p = p->next;
411     }
412   tab (-1);
413 }
414
415 static void
416 dump_coff_section(ptr)
417 struct coff_section *ptr;
418 {
419   int i;
420   tab(1);
421   printf("section %s %d %d address %x size %x number %d nrelocs %d", 
422          ptr->name, ptr->code, ptr->data, ptr->address,ptr->size, ptr->number, ptr->nrelocs);
423   nl();
424
425   for (i = 0; i < ptr->nrelocs; i++) 
426     {
427       tab(0);    
428       printf("(%x %s %x)",
429              ptr->relocs[i].offset,
430              ptr->relocs[i].symbol->name,
431              ptr->relocs[i].addend);
432       nl();
433     }
434   tab(-1);
435
436 }
437
438 void
439 coff_dump (ptr)
440      struct coff_ofile *ptr;
441 {
442   int i;
443   printf ("Coff dump");
444   nl ();
445   printf ("#souces %d", ptr->nsources);
446   nl ();
447   dump_coff_sfile (ptr->source_head);
448   for (i = 0; i < ptr->nsections; i++)
449     dump_coff_section(ptr->sections + i);
450 }
451
452
453
454 char * program_name;
455
456 static void
457 show_usage (file, status)
458      FILE *file;
459      int status;
460 {
461   fprintf (file, "Usage: %s [-hV] in-file\n",   program_name);
462   exit (status);
463 }
464
465 static void
466 show_help ()
467 {
468   printf (_("%s: Print a human readable interpretation of a SYSROFF object file\n"),
469           program_name);
470   show_usage (stdout, 0);
471 }
472
473
474 int
475 main (ac, av)
476      int ac;
477      char *av[];
478 {
479   bfd *abfd;
480   struct coff_ofile *tree;
481   char **matching;
482   char *input_file = NULL;
483   int opt;
484   static struct option long_options[] =
485     {
486       { "help", no_argument, 0, 'h' },
487       { "version", no_argument, 0, 'V' },
488       { NULL, no_argument, 0, 0 }
489     };
490
491 #if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
492   setlocale (LC_MESSAGES, "");
493 #endif
494 #if defined (HAVE_SETLOCALE)
495   setlocale (LC_CTYPE, "");
496 #endif
497   bindtextdomain (PACKAGE, LOCALEDIR);
498   textdomain (PACKAGE);
499
500   program_name = av[0];
501   xmalloc_set_program_name (program_name);
502
503   while ((opt = getopt_long (ac, av, "hV", long_options,
504                              (int *) NULL))
505          != EOF)
506     {
507       switch (opt)
508         {
509         case 'h':
510           show_help ();
511           /*NOTREACHED*/
512         case 'V':
513           print_version ("coffdump");
514           exit (0);
515           /*NOTREACHED*/
516         case 0:
517           break;
518         default:
519           show_usage (stderr, 1);
520           /*NOTREACHED*/
521         }
522     }
523
524   if (optind < ac)
525     {
526       input_file = av[optind];
527     }
528
529   if (!input_file)
530     {
531       fatal (_("no input file specified"));
532     }
533   abfd = bfd_openr (input_file, 0);
534
535   if (!abfd)
536     bfd_fatal (input_file);
537
538   if (! bfd_check_format_matches (abfd, bfd_object, &matching))
539     {
540       bfd_nonfatal (input_file);
541       if (bfd_get_error () == bfd_error_file_ambiguously_recognized)
542         {
543           list_matching_formats (matching);
544           free (matching);
545         }
546       exit (1);
547     }
548
549   tree = coff_grok (abfd);
550
551   coff_dump(tree);
552   printf("\n");
553   return 0;
554 }