Back to index

cell-binutils  2.17cvs20070401
coffdump.c
Go to the documentation of this file.
00001 /* Coff file dumper.
00002    Copyright 1994, 1995, 1998, 1999, 2000, 2001, 2002, 2003, 2005, 2007
00003    Free Software Foundation, Inc.
00004 
00005    This file is part of GNU Binutils.
00006 
00007    This program is free software; you can redistribute it and/or modify
00008    it under the terms of the GNU General Public License as published by
00009    the Free Software Foundation; either version 2 of the License, or (at
00010    your option) any later version.
00011 
00012    This program is distributed in the hope that it will be useful,
00013    but WITHOUT ANY WARRANTY; without even the implied warranty of
00014    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015    GNU General Public License for more details.
00016 
00017    You should have received a copy of the GNU General Public License
00018    along with this program; if not, write to the Free Software
00019    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.  */
00020 
00021 /* Written by Steve Chamberlain <sac@cygnus.com>
00022 
00023    This module reads a type tree generated by coffgrok and prints
00024    it out so we can test the grokker.  */
00025 
00026 #include "bfd.h"
00027 #include "libiberty.h"
00028 
00029 #include "coffgrok.h"
00030 #include "bucomm.h"
00031 #include "getopt.h"
00032 
00033 static int atnl;
00034 
00035 static void tab (int);
00036 static void nl (void);
00037 static void dump_coff_lines (struct coff_line *);
00038 static void dump_coff_type (struct coff_type *);
00039 static void dump_coff_where (struct coff_where *);
00040 static void dump_coff_visible (struct coff_visible *);
00041 static void dump_coff_scope (struct coff_scope *);
00042 static void dump_coff_sfile (struct coff_sfile *);
00043 static void dump_coff_section (struct coff_section *);
00044 static void show_usage (FILE *, int);
00045 extern int main (int, char **);
00046 
00047 static void
00048 tab (int x)
00049 {
00050   static int indent;
00051   int i;
00052 
00053   if (atnl)
00054     {
00055       if (x < 0)
00056        {
00057          printf (")");
00058          indent += x;
00059 
00060          return;
00061        }
00062       else
00063        {
00064          printf ("\n");
00065          atnl = 0;
00066        }
00067     }
00068 
00069   if (x == -1)
00070     {
00071       for (i = 0; i < indent; i++)
00072        printf ("   ");
00073 
00074       indent += x;
00075       printf (")");
00076       return;
00077     }
00078 
00079   indent += x;
00080 
00081   for (i = 0; i < indent; i++)
00082     printf ("   ");
00083 
00084   if (x)
00085     {
00086       printf ("(");
00087     }
00088 }
00089 
00090 static void
00091 nl (void)
00092 {
00093   atnl = 1;
00094 }
00095 
00096 static void
00097 dump_coff_lines (struct coff_line *p)
00098 {
00099   int i;
00100   int online = 0;
00101 
00102   tab (1);
00103   printf (_("#lines %d "),p->nlines);
00104 
00105   for (i = 0; i < p->nlines; i++)
00106     {
00107       printf ("(%d 0x%x)", p->lines[i], p->addresses[i]);
00108 
00109       online++;
00110 
00111       if (online > 6)
00112        {
00113          nl ();
00114          tab (0);
00115          online = 0;
00116        }
00117     }
00118   nl ();
00119   tab (-1);
00120 }
00121 
00122 static void
00123 dump_coff_type (struct coff_type *p)
00124 {
00125   tab (1);
00126   printf ("size %d ", p->size);
00127 
00128   switch (p->type)
00129     {
00130     case coff_secdef_type:
00131       printf ("section definition at %x size %x\n",
00132              p->u.asecdef.address,
00133              p->u.asecdef.size);
00134       nl ();
00135       break;
00136     case coff_pointer_type:
00137       printf ("pointer to");
00138       nl ();
00139       dump_coff_type (p->u.pointer.points_to);
00140       break;
00141     case coff_array_type:
00142       printf ("array [%d] of", p->u.array.dim);
00143       nl ();
00144       dump_coff_type (p->u.array.array_of);
00145       break;
00146     case coff_function_type:
00147       printf ("function returning");
00148       nl ();
00149       dump_coff_type (p->u.function.function_returns);
00150       dump_coff_lines (p->u.function.lines);
00151       printf ("arguments");
00152       nl ();
00153       dump_coff_scope (p->u.function.parameters);
00154       tab (0);
00155       printf ("code");
00156       nl ();
00157       dump_coff_scope (p->u.function.code);
00158       tab(0);
00159       break;
00160     case coff_structdef_type:
00161       printf ("structure definition");
00162       nl ();
00163       dump_coff_scope (p->u.astructdef.elements);
00164       break;
00165     case coff_structref_type:
00166       if (!p->u.aenumref.ref)
00167        printf ("structure ref to UNKNOWN struct");
00168       else
00169        printf ("structure ref to %s", p->u.aenumref.ref->name);
00170       break;
00171     case coff_enumref_type:
00172       printf ("enum ref to %s", p->u.astructref.ref->name);
00173       break;
00174     case coff_enumdef_type:
00175       printf ("enum definition");
00176       nl ();
00177       dump_coff_scope (p->u.aenumdef.elements);
00178       break;
00179     case coff_basic_type:
00180       switch (p->u.basic)
00181        {
00182        case T_NULL:
00183          printf ("NULL");
00184          break;
00185        case T_VOID:
00186          printf ("VOID");
00187          break;
00188        case T_CHAR:
00189          printf ("CHAR");
00190          break;
00191        case T_SHORT:
00192          printf ("SHORT");
00193          break;
00194        case T_INT:
00195          printf ("INT ");
00196          break;
00197        case T_LONG:
00198          printf ("LONG");
00199          break;
00200        case T_FLOAT:
00201          printf ("FLOAT");
00202          break;
00203        case T_DOUBLE:
00204          printf ("DOUBLE");
00205          break;
00206        case T_STRUCT:
00207          printf ("STRUCT");
00208          break;
00209        case T_UNION:
00210          printf ("UNION");
00211          break;
00212        case T_ENUM:
00213          printf ("ENUM");
00214          break;
00215        case T_MOE:
00216          printf ("MOE ");
00217          break;
00218        case T_UCHAR:
00219          printf ("UCHAR");
00220          break;
00221        case T_USHORT:
00222          printf ("USHORT");
00223          break;
00224        case T_UINT:
00225          printf ("UINT");
00226          break;
00227        case T_ULONG:
00228          printf ("ULONG");
00229          break;
00230        case T_LNGDBL:
00231          printf ("LNGDBL");
00232          break;
00233        default:
00234          abort ();
00235        }
00236     }
00237   nl ();
00238   tab (-1);
00239 }
00240 
00241 static void
00242 dump_coff_where (struct coff_where *p)
00243 {
00244   tab (1);
00245   switch (p->where)
00246     {
00247     case coff_where_stack:
00248       printf ("Stack offset %x", p->offset);
00249       break;
00250     case coff_where_memory:
00251       printf ("Memory section %s+%x", p->section->name, p->offset);
00252       break;
00253     case coff_where_register:
00254       printf ("Register %d", p->offset);
00255       break;
00256     case coff_where_member_of_struct:
00257       printf ("Struct Member offset %x", p->offset);
00258       break;
00259     case coff_where_member_of_enum:
00260       printf ("Enum Member offset %x", p->offset);
00261       break;
00262     case coff_where_unknown:
00263       printf ("Undefined symbol");
00264       break;
00265     case coff_where_strtag:
00266       printf ("STRTAG");
00267     case coff_where_entag:
00268       printf ("ENTAG");
00269       break;
00270     case coff_where_typedef:
00271       printf ("TYPEDEF");
00272       break;
00273     default:
00274       abort ();
00275     }
00276   nl ();
00277   tab (-1);
00278 }
00279 
00280 static void
00281 dump_coff_visible (struct coff_visible *p)
00282 {
00283   tab (1);
00284   switch (p->type)
00285     {
00286     case coff_vis_ext_def:
00287       printf ("coff_vis_ext_def");
00288       break;
00289     case coff_vis_ext_ref:
00290       printf ("coff_vis_ext_ref");
00291       break;
00292     case coff_vis_int_def:
00293       printf ("coff_vis_int_def");
00294       break;
00295     case coff_vis_common:
00296       printf ("coff_vis_common");
00297       break;
00298     case coff_vis_auto:
00299       printf ("coff_vis_auto");
00300       break;
00301     case coff_vis_autoparam:
00302       printf ("coff_vis_autoparam");
00303       break;
00304     case coff_vis_regparam:
00305       printf ("coff_vis_regparam");
00306       break;
00307     case coff_vis_register:
00308       printf ("coff_vis_register");
00309       break;
00310     case coff_vis_tag:
00311       printf ("coff_vis_tag");
00312       break;
00313     case coff_vis_member_of_struct:
00314       printf ("coff_vis_member_of_struct");
00315       break;
00316     case coff_vis_member_of_enum:
00317       printf ("coff_vis_member_of_enum");
00318       break;
00319     default:
00320       abort ();
00321     }
00322   nl ();
00323   tab (-1);
00324 }
00325 
00326 static void
00327 dump_coff_symbol (struct coff_symbol *p)
00328 {
00329   tab (1);
00330   printf ("List of symbols");
00331   nl ();
00332 
00333   while (p)
00334     {
00335       tab (1);
00336       tab (1);
00337       printf ("Symbol  %s, tag %d, number %d", p->name, p->tag, p->number);
00338       nl ();
00339       tab (-1);
00340       tab (1);
00341       printf ("Type");
00342       nl ();
00343       dump_coff_type (p->type);
00344       tab (-1);
00345       tab (1);
00346       printf ("Where");
00347       dump_coff_where (p->where);
00348       tab (-1);
00349       tab (1);
00350       printf ("Visible");
00351       dump_coff_visible (p->visible);
00352       tab (-1);
00353       p = p->next;
00354       tab (-1);
00355     }
00356   tab (-1);
00357 }
00358 
00359 static void
00360 dump_coff_scope (struct coff_scope *p)
00361 {
00362   if (p)
00363     {
00364       tab (1);
00365       printf ("List of blocks %lx ",(unsigned long) p);
00366 
00367       if (p->sec)
00368        printf( "  %s %x..%x",  p->sec->name,p->offset, p->offset + p->size -1);
00369 
00370       nl ();
00371       tab (0);
00372       printf ("*****************");
00373       nl ();
00374 
00375       while (p)
00376        {
00377          tab (0);
00378          printf ("vars %d", p->nvars);
00379          nl ();
00380          dump_coff_symbol (p->vars_head);
00381          printf ("blocks");
00382          nl ();
00383          dump_coff_scope (p->list_head);
00384          nl ();
00385          p = p->next;
00386        }
00387 
00388       tab (0);
00389       printf ("*****************");
00390       nl ();
00391       tab (-1);
00392     }
00393 }
00394 
00395 static void
00396 dump_coff_sfile (struct coff_sfile *p)
00397 {
00398   tab (1);
00399   printf ("List of source files");
00400   nl ();
00401 
00402   while (p)
00403     {
00404       tab (0);
00405       printf ("Source file %s", p->name);
00406       nl ();
00407       dump_coff_scope (p->scope);
00408       p = p->next;
00409     }
00410   tab (-1);
00411 }
00412 
00413 static void
00414 dump_coff_section (struct coff_section *ptr)
00415 {
00416   int i;
00417 
00418   tab (1);
00419   printf ("section %s %d %d address %x size %x number %d nrelocs %d",
00420          ptr->name, ptr->code, ptr->data, ptr->address,ptr->size,
00421          ptr->number, ptr->nrelocs);
00422   nl ();
00423 
00424   for (i = 0; i < ptr->nrelocs; i++)
00425     {
00426       tab (0);
00427       printf ("(%x %s %x)",
00428              ptr->relocs[i].offset,
00429              ptr->relocs[i].symbol->name,
00430              ptr->relocs[i].addend);
00431       nl ();
00432     }
00433 
00434   tab (-1);
00435 }
00436 
00437 static void
00438 coff_dump (struct coff_ofile *ptr)
00439 {
00440   int i;
00441 
00442   printf ("Coff dump");
00443   nl ();
00444   printf ("#souces %d", ptr->nsources);
00445   nl ();
00446   dump_coff_sfile (ptr->source_head);
00447 
00448   for (i = 0; i < ptr->nsections; i++)
00449     dump_coff_section (ptr->sections + i);
00450 }
00451 
00452 char * program_name;
00453 
00454 static void
00455 show_usage (FILE *file, int status)
00456 {
00457   fprintf (file, _("Usage: %s [option(s)] in-file\n"), program_name);
00458   fprintf (file, _(" Print a human readable interpretation of a SYSROFF object file\n"));
00459   fprintf (file, _(" The options are:\n\
00460   @<file>                Read options from <file>\n\
00461   -h --help              Display this information\n\
00462   -v --version           Display the program's version\n\
00463 \n"));
00464 
00465   if (REPORT_BUGS_TO[0] && status == 0)
00466     fprintf (file, _("Report bugs to %s\n"), REPORT_BUGS_TO);
00467 
00468   exit (status);
00469 }
00470 
00471 int
00472 main (int ac, char **av)
00473 {
00474   bfd *abfd;
00475   struct coff_ofile *tree;
00476   char **matching;
00477   char *input_file = NULL;
00478   int opt;
00479   static struct option long_options[] =
00480     {
00481       { "help", no_argument, 0, 'h' },
00482       { "version", no_argument, 0, 'V' },
00483       { NULL, no_argument, 0, 0 }
00484     };
00485 
00486 #if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
00487   setlocale (LC_MESSAGES, "");
00488 #endif
00489 #if defined (HAVE_SETLOCALE)
00490   setlocale (LC_CTYPE, "");
00491 #endif
00492   bindtextdomain (PACKAGE, LOCALEDIR);
00493   textdomain (PACKAGE);
00494 
00495   program_name = av[0];
00496   xmalloc_set_program_name (program_name);
00497 
00498   expandargv (&ac, &av);
00499 
00500   while ((opt = getopt_long (ac, av, "HhVv", long_options,
00501                           (int *) NULL))
00502         != EOF)
00503     {
00504       switch (opt)
00505        {
00506        case 'H':
00507        case 'h':
00508          show_usage (stdout, 0);
00509          break;
00510        case 'v':
00511        case 'V':
00512          print_version ("coffdump");
00513          exit (0);
00514        case 0:
00515          break;
00516        default:
00517          show_usage (stderr, 1);
00518          break;
00519        }
00520     }
00521 
00522   if (optind < ac)
00523     {
00524       input_file = av[optind];
00525     }
00526 
00527   if (!input_file)
00528     fatal (_("no input file specified"));
00529 
00530   abfd = bfd_openr (input_file, 0);
00531 
00532   if (!abfd)
00533     bfd_fatal (input_file);
00534 
00535   if (! bfd_check_format_matches (abfd, bfd_object, &matching))
00536     {
00537       bfd_nonfatal (input_file);
00538 
00539       if (bfd_get_error () == bfd_error_file_ambiguously_recognized)
00540        {
00541          list_matching_formats (matching);
00542          free (matching);
00543        }
00544       exit (1);
00545     }
00546 
00547   tree = coff_grok (abfd);
00548 
00549   coff_dump (tree);
00550   printf ("\n");
00551 
00552   return 0;
00553 }