1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28: #include "sysdep.h"
29: #include "bfd.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 ("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:
378: while (p)
379: {
380: tab (0);
381: printf ("vars %d", p->nvars);
382: nl ();
383: dump_coff_symbol (p->vars_head);
384: printf ("blocks");
385: nl ();
386: dump_coff_scope (p->list_head);
387: nl ();
388: p = p->next;
389: }
390:
391: tab (0);
392: printf ("*****************");
393: nl ();
394: tab (-1);
395: }
396: }
397:
398: static void
399: dump_coff_sfile (struct coff_sfile *p)
400: {
401: tab (1);
402: printf ("List of source files");
403: nl ();
404:
405: while (p)
406: {
407: tab (0);
408: printf ("Source file %s", p->name);
409: nl ();
410: dump_coff_scope (p->scope);
411: p = p->next;
412: }
413: tab (-1);
414: }
415:
416: static void
417: dump_coff_section (struct coff_section *ptr)
418: {
419: int i;
420:
421: tab (1);
422: printf ("section %s %d %d address %x size %x number %d nrelocs %d",
423: ptr->name, ptr->code, ptr->data, ptr->address,ptr->size,
424: ptr->number, ptr->nrelocs);
425: nl ();
426:
427: for (i = 0; i < ptr->nrelocs; i++)
428: {
429: tab (0);
430: printf ("(%x %s %x)",
431: ptr->relocs[i].offset,
432: ptr->relocs[i].symbol->name,
433: ptr->relocs[i].addend);
434: nl ();
435: }
436:
437: tab (-1);
438: }
439:
440: static void
441: coff_dump (struct coff_ofile *ptr)
442: {
443: int i;
444:
445: printf ("Coff dump");
446: nl ();
447: printf ("#souces %d", ptr->nsources);
448: nl ();
449: dump_coff_sfile (ptr->source_head);
450:
451: for (i = 0; i < ptr->nsections; i++)
452: dump_coff_section (ptr->sections + i);
453: }
454:
455: char * program_name;
456:
457: static void
458: show_usage (FILE *file, int status)
459: {
460: fprintf (file, _("Usage: %s [option(s)] in-file\n"), program_name);
461: fprintf (file, _(" Print a human readable interpretation of a SYSROFF object file\n"));
462: fprintf (file, _(" The options are:\n\
463: @<file> Read options from <file>\n\
464: -h --help Display this information\n\
465: -v --version Display the program's version\n\
466: \n"));
467:
468: if (REPORT_BUGS_TO[0] && status == 0)
469: fprintf (file, _("Report bugs to %s\n"), REPORT_BUGS_TO);
470:
471: exit (status);
472: }
473:
474: int
475: main (int ac, char **av)
476: {
477: bfd *abfd;
478: struct coff_ofile *tree;
479: char **matching;
480: char *input_file = NULL;
481: int opt;
482: static struct option long_options[] =
483: {
484: { "help", no_argument, 0, 'h' },
485: { "version", no_argument, 0, 'V' },
486: { NULL, no_argument, 0, 0 }
487: };
488:
489: #if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
490: setlocale (LC_MESSAGES, "");
491: #endif
492: #if defined (HAVE_SETLOCALE)
493: setlocale (LC_CTYPE, "");
494: #endif
495: bindtextdomain (PACKAGE, LOCALEDIR);
496: textdomain (PACKAGE);
497:
498: program_name = av[0];
499: xmalloc_set_program_name (program_name);
500:
501: expandargv (&ac, &av);
502:
503: while ((opt = getopt_long (ac, av, "HhVv", long_options,
504: (int *) NULL))
505: != EOF)
506: {
507: switch (opt)
508: {
509: case 'H':
510: case 'h':
511: show_usage (stdout, 0);
512: break;
513: case 'v':
514: case 'V':
515: print_version ("coffdump");
516: exit (0);
517: case 0:
518: break;
519: default:
520: show_usage (stderr, 1);
521: break;
522: }
523: }
524:
525: if (optind < ac)
526: {
527: input_file = av[optind];
528: }
529:
530: if (!input_file)
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:
542: if (bfd_get_error () == bfd_error_file_ambiguously_recognized)
543: {
544: list_matching_formats (matching);
545: free (matching);
546: }
547: exit (1);
548: }
549:
550: tree = coff_grok (abfd);
551:
552: coff_dump (tree);
553: printf ("\n");
554:
555: return 0;
556: }