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