]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blob - binutils/coffdump.c
top level:
[thirdparty/binutils-gdb.git] / binutils / coffdump.c
1 /* Coff file dumper.
2 Copyright 1994, 1995, 1998, 1999, 2000, 2001, 2002, 2003, 2005, 2007
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 (REPORT_BUGS_TO[0] && 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 }