Back to index

cell-binutils  2.17cvs20070401
sysdump.c
Go to the documentation of this file.
00001 /* Sysroff object format 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
00010    (at 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
00020    02110-1301, USA.  */
00021 
00022 
00023 /* Written by Steve Chamberlain <sac@cygnus.com>.
00024 
00025  This program reads a SYSROFF object file and prints it in an
00026  almost human readable form to stdout.  */
00027 
00028 #include "bfd.h"
00029 #include "bucomm.h"
00030 #include "safe-ctype.h"
00031 
00032 #include <stdio.h>
00033 #include "libiberty.h"
00034 #include "getopt.h"
00035 #include "sysroff.h"
00036 
00037 static int dump = 1;
00038 static int segmented_p;
00039 static int code;
00040 static int addrsize = 4;
00041 static FILE *file;
00042 
00043 static void dh (unsigned char *, int);
00044 static void itheader (char *, int);
00045 static void p (void);
00046 static void tabout (void);
00047 static void pbarray (barray *);
00048 static int getone (int);
00049 static int opt (int);
00050 static void must (int);
00051 static void tab (int, char *);
00052 static void dump_symbol_info (void);
00053 static void derived_type (void);
00054 static void module (void);
00055 static void show_usage (FILE *, int);
00056 
00057 extern int main (int, char **);
00058 
00059 static char *
00060 getCHARS (unsigned char *ptr, int *idx, int size, int max)
00061 {
00062   int oc = *idx / 8;
00063   char *r;
00064   int b = size;
00065 
00066   if (b >= max)
00067     return "*undefined*";
00068 
00069   if (b == 0)
00070     {
00071       /* Got to work out the length of the string from self.  */
00072       b = ptr[oc++];
00073       (*idx) += 8;
00074     }
00075 
00076   *idx += b * 8;
00077   r = xcalloc (b + 1, 1);
00078   memcpy (r, ptr + oc, b);
00079   r[b] = 0;
00080 
00081   return r;
00082 }
00083 
00084 static void
00085 dh (unsigned char *ptr, int size)
00086 {
00087   int i;
00088   int j;
00089   int span = 16;
00090 
00091   printf ("\n************************************************************\n");
00092 
00093   for (i = 0; i < size; i += span)
00094     {
00095       for (j = 0; j < span; j++)
00096        {
00097          if (j + i < size)
00098            printf ("%02x ", ptr[i + j]);
00099          else
00100            printf ("   ");
00101        }
00102 
00103       for (j = 0; j < span && j + i < size; j++)
00104        {
00105          int c = ptr[i + j];
00106 
00107          if (c < 32 || c > 127)
00108            c = '.';
00109          printf ("%c", c);
00110        }
00111 
00112       printf ("\n");
00113     }
00114 }
00115 
00116 static int
00117 fillup (unsigned char *ptr)
00118 {
00119   int size;
00120   int sum;
00121   int i;
00122 
00123   size = getc (file) - 2;
00124   fread (ptr, 1, size, file);
00125   sum = code + size + 2;
00126 
00127   for (i = 0; i < size; i++)
00128     sum += ptr[i];
00129 
00130   if ((sum & 0xff) != 0xff)
00131     printf ("SUM IS %x\n", sum);
00132 
00133   if (dump)
00134     dh (ptr, size);
00135 
00136   return size - 1;
00137 }
00138 
00139 static barray
00140 getBARRAY (unsigned char *ptr, int *idx, int dsize ATTRIBUTE_UNUSED,
00141           int max ATTRIBUTE_UNUSED)
00142 {
00143   barray res;
00144   int i;
00145   int byte = *idx / 8;
00146   int size = ptr[byte++];
00147 
00148   res.len = size;
00149   res.data = (unsigned char *) xmalloc (size);
00150 
00151   for (i = 0; i < size; i++)
00152     res.data[i] = ptr[byte++];
00153 
00154   return res;
00155 }
00156 
00157 static int
00158 getINT (unsigned char *ptr, int *idx, int size, int max)
00159 {
00160   int n = 0;
00161   int byte = *idx / 8;
00162 
00163   if (byte >= max)
00164     return 0;
00165 
00166   if (size == -2)
00167     size = addrsize;
00168 
00169   if (size == -1)
00170     size = 0;
00171 
00172   switch (size)
00173     {
00174     case 0:
00175       return 0;
00176     case 1:
00177       n = (ptr[byte]);
00178       break;
00179     case 2:
00180       n = (ptr[byte + 0] << 8) + ptr[byte + 1];
00181       break;
00182     case 4:
00183       n = (ptr[byte + 0] << 24) + (ptr[byte + 1] << 16) + (ptr[byte + 2] << 8) + (ptr[byte + 3]);
00184       break;
00185     default:
00186       abort ();
00187     }
00188 
00189   *idx += size * 8;
00190   return n;
00191 }
00192 
00193 static int
00194 getBITS (unsigned char *ptr, int *idx, int size, int max)
00195 {
00196   int byte = *idx / 8;
00197   int bit = *idx % 8;
00198 
00199   if (byte >= max)
00200     return 0;
00201 
00202   *idx += size;
00203 
00204   return (ptr[byte] >> (8 - bit - size)) & ((1 << size) - 1);
00205 }
00206 
00207 static void
00208 itheader (char *name, int code)
00209 {
00210   printf ("\n%s 0x%02x\n", name, code);
00211 }
00212 
00213 static int indent;
00214 
00215 static void
00216 p (void)
00217 {
00218   int i;
00219 
00220   for (i = 0; i < indent; i++)
00221     printf ("| ");
00222 
00223   printf ("> ");
00224 }
00225 
00226 static void
00227 tabout (void)
00228 {
00229   p ();
00230 }
00231 
00232 static void
00233 pbarray (barray *y)
00234 {
00235   int x;
00236 
00237   printf ("%d (", y->len);
00238 
00239   for (x = 0; x < y->len; x++)
00240     printf ("(%02x %c)", y->data[x],
00241            ISPRINT (y->data[x]) ? y->data[x] : '.');
00242 
00243   printf (")\n");
00244 }
00245 
00246 #define SYSROFF_PRINT
00247 #define SYSROFF_SWAP_IN
00248 
00249 #include "sysroff.c"
00250 
00251 /* FIXME: sysinfo, which generates sysroff.[ch] from sysroff.info, can't
00252    hack the special case of the tr block, which has no contents.  So we
00253    implement our own functions for reading in and printing out the tr
00254    block.  */
00255 
00256 #define IT_tr_CODE   0x7f
00257 
00258 static void
00259 sysroff_swap_tr_in (void)
00260 {
00261   unsigned char raw[255];
00262 
00263   memset (raw, 0, 255);
00264   fillup (raw);
00265 }
00266 
00267 static void
00268 sysroff_print_tr_out (void)
00269 {
00270   itheader ("tr", IT_tr_CODE);
00271 }
00272 
00273 static int
00274 getone (int type)
00275 {
00276   int c = getc (file);
00277 
00278   code = c;
00279 
00280   if ((c & 0x7f) != type)
00281     {
00282       ungetc (c, file);
00283       return 0;
00284     }
00285 
00286   switch (c & 0x7f)
00287     {
00288     case IT_cs_CODE:
00289       {
00290        struct IT_cs dummy;
00291        sysroff_swap_cs_in (&dummy);
00292        sysroff_print_cs_out (&dummy);
00293       }
00294       break;
00295 
00296     case IT_dln_CODE:
00297       {
00298        struct IT_dln dummy;
00299        sysroff_swap_dln_in (&dummy);
00300        sysroff_print_dln_out (&dummy);
00301       }
00302       break;
00303 
00304     case IT_hd_CODE:
00305       {
00306        struct IT_hd dummy;
00307        sysroff_swap_hd_in (&dummy);
00308        addrsize = dummy.afl;
00309        sysroff_print_hd_out (&dummy);
00310       }
00311       break;
00312 
00313     case IT_dar_CODE:
00314       {
00315        struct IT_dar dummy;
00316        sysroff_swap_dar_in (&dummy);
00317        sysroff_print_dar_out (&dummy);
00318       }
00319       break;
00320 
00321     case IT_dsy_CODE:
00322       {
00323        struct IT_dsy dummy;
00324        sysroff_swap_dsy_in (&dummy);
00325        sysroff_print_dsy_out (&dummy);
00326       }
00327       break;
00328 
00329     case IT_dfp_CODE:
00330       {
00331        struct IT_dfp dummy;
00332        sysroff_swap_dfp_in (&dummy);
00333        sysroff_print_dfp_out (&dummy);
00334       }
00335       break;
00336 
00337     case IT_dso_CODE:
00338       {
00339        struct IT_dso dummy;
00340        sysroff_swap_dso_in (&dummy);
00341        sysroff_print_dso_out (&dummy);
00342       }
00343       break;
00344 
00345     case IT_dpt_CODE:
00346       {
00347        struct IT_dpt dummy;
00348        sysroff_swap_dpt_in (&dummy);
00349        sysroff_print_dpt_out (&dummy);
00350       }
00351       break;
00352 
00353     case IT_den_CODE:
00354       {
00355        struct IT_den dummy;
00356        sysroff_swap_den_in (&dummy);
00357        sysroff_print_den_out (&dummy);
00358       }
00359       break;
00360 
00361     case IT_dbt_CODE:
00362       {
00363        struct IT_dbt dummy;
00364        sysroff_swap_dbt_in (&dummy);
00365        sysroff_print_dbt_out (&dummy);
00366       }
00367       break;
00368 
00369     case IT_dty_CODE:
00370       {
00371        struct IT_dty dummy;
00372        sysroff_swap_dty_in (&dummy);
00373        sysroff_print_dty_out (&dummy);
00374       }
00375       break;
00376 
00377     case IT_un_CODE:
00378       {
00379        struct IT_un dummy;
00380        sysroff_swap_un_in (&dummy);
00381        sysroff_print_un_out (&dummy);
00382       }
00383       break;
00384 
00385     case IT_sc_CODE:
00386       {
00387        struct IT_sc dummy;
00388        sysroff_swap_sc_in (&dummy);
00389        sysroff_print_sc_out (&dummy);
00390       }
00391       break;
00392 
00393     case IT_er_CODE:
00394       {
00395        struct IT_er dummy;
00396        sysroff_swap_er_in (&dummy);
00397        sysroff_print_er_out (&dummy);
00398       }
00399       break;
00400 
00401     case IT_ed_CODE:
00402       {
00403        struct IT_ed dummy;
00404        sysroff_swap_ed_in (&dummy);
00405        sysroff_print_ed_out (&dummy);
00406       }
00407       break;
00408 
00409     case IT_sh_CODE:
00410       {
00411        struct IT_sh dummy;
00412        sysroff_swap_sh_in (&dummy);
00413        sysroff_print_sh_out (&dummy);
00414       }
00415       break;
00416 
00417     case IT_ob_CODE:
00418       {
00419        struct IT_ob dummy;
00420        sysroff_swap_ob_in (&dummy);
00421        sysroff_print_ob_out (&dummy);
00422       }
00423       break;
00424 
00425     case IT_rl_CODE:
00426       {
00427        struct IT_rl dummy;
00428        sysroff_swap_rl_in (&dummy);
00429        sysroff_print_rl_out (&dummy);
00430       }
00431       break;
00432 
00433     case IT_du_CODE:
00434       {
00435        struct IT_du dummy;
00436        sysroff_swap_du_in (&dummy);
00437 
00438        sysroff_print_du_out (&dummy);
00439       }
00440       break;
00441 
00442     case IT_dus_CODE:
00443       {
00444        struct IT_dus dummy;
00445        sysroff_swap_dus_in (&dummy);
00446        sysroff_print_dus_out (&dummy);
00447       }
00448       break;
00449 
00450     case IT_dul_CODE:
00451       {
00452        struct IT_dul dummy;
00453        sysroff_swap_dul_in (&dummy);
00454        sysroff_print_dul_out (&dummy);
00455       }
00456       break;
00457 
00458     case IT_dss_CODE:
00459       {
00460        struct IT_dss dummy;
00461        sysroff_swap_dss_in (&dummy);
00462        sysroff_print_dss_out (&dummy);
00463       }
00464       break;
00465 
00466     case IT_hs_CODE:
00467       {
00468        struct IT_hs dummy;
00469        sysroff_swap_hs_in (&dummy);
00470        sysroff_print_hs_out (&dummy);
00471       }
00472       break;
00473 
00474     case IT_dps_CODE:
00475       {
00476        struct IT_dps dummy;
00477        sysroff_swap_dps_in (&dummy);
00478        sysroff_print_dps_out (&dummy);
00479       }
00480       break;
00481 
00482     case IT_tr_CODE:
00483       sysroff_swap_tr_in ();
00484       sysroff_print_tr_out ();
00485       break;
00486 
00487     case IT_dds_CODE:
00488       {
00489        struct IT_dds dummy;
00490 
00491        sysroff_swap_dds_in (&dummy);
00492        sysroff_print_dds_out (&dummy);
00493       }
00494       break;
00495 
00496     default:
00497       printf ("GOT A %x\n", c);
00498       return 0;
00499       break;
00500     }
00501 
00502   return 1;
00503 }
00504 
00505 static int
00506 opt (int x)
00507 {
00508   return getone (x);
00509 }
00510 
00511 static void
00512 must (int x)
00513 {
00514   if (!getone (x))
00515     printf ("WANTED %x!!\n", x);
00516 }
00517 
00518 static void
00519 tab (int i, char *s)
00520 {
00521   indent += i;
00522 
00523   if (s)
00524     {
00525       p ();
00526       printf (s);
00527       printf ("\n");
00528     }
00529 }
00530 
00531 static void
00532 dump_symbol_info (void)
00533 {
00534   tab (1, "SYMBOL INFO");
00535 
00536   while (opt (IT_dsy_CODE))
00537     {
00538       if (opt (IT_dty_CODE))
00539        {
00540          must (IT_dbt_CODE);
00541          derived_type ();
00542          must (IT_dty_CODE);
00543        }
00544     }
00545 
00546   tab (-1, "");
00547 }
00548 
00549 static void
00550 derived_type (void)
00551 {
00552   tab (1, "DERIVED TYPE");
00553 
00554   while (1)
00555     {
00556       if (opt (IT_dpp_CODE))
00557        {
00558          dump_symbol_info ();
00559          must (IT_dpp_CODE);
00560        }
00561       else if (opt (IT_dfp_CODE))
00562        {
00563          dump_symbol_info ();
00564          must (IT_dfp_CODE);
00565        }
00566       else if (opt (IT_den_CODE))
00567        {
00568          dump_symbol_info ();
00569          must (IT_den_CODE);
00570        }
00571       else if (opt (IT_den_CODE))
00572        {
00573          dump_symbol_info ();
00574          must (IT_den_CODE);
00575        }
00576       else if (opt (IT_dds_CODE))
00577        {
00578          dump_symbol_info ();
00579          must (IT_dds_CODE);
00580        }
00581       else if (opt (IT_dar_CODE))
00582        {
00583        }
00584       else if (opt (IT_dpt_CODE))
00585        {
00586        }
00587       else if (opt (IT_dul_CODE))
00588        {
00589        }
00590       else if (opt (IT_dse_CODE))
00591        {
00592        }
00593       else if (opt (IT_dot_CODE))
00594        {
00595        }
00596       else
00597        break;
00598     }
00599 
00600   tab (-1, "");
00601 }
00602 
00603 static void
00604 module (void)
00605 {
00606   int c = 0;
00607   int l = 0;
00608 
00609   tab (1, "MODULE***\n");
00610 
00611   do
00612     {
00613       c = getc (file);
00614       ungetc (c, file);
00615 
00616       c &= 0x7f;
00617     }
00618   while (getone (c) && c != IT_tr_CODE);
00619 
00620   tab (-1, "");
00621 
00622   c = getc (file);
00623   while (c != EOF)
00624     {
00625       printf ("%02x ", c);
00626       l++;
00627       if (l == 32)
00628        {
00629          printf ("\n");
00630          l = 0;
00631        }
00632       c = getc (file);
00633     }
00634 }
00635 
00636 char *program_name;
00637 
00638 static void
00639 show_usage (FILE *file, int status)
00640 {
00641   fprintf (file, _("Usage: %s [option(s)] in-file\n"), program_name);
00642   fprintf (file, _("Print a human readable interpretation of a SYSROFF object file\n"));
00643   fprintf (file, _(" The options are:\n\
00644   -h --help        Display this information\n\
00645   -v --version     Print the program's version number\n"));
00646 
00647   if (REPORT_BUGS_TO[0] && status == 0)
00648     fprintf (file, _("Report bugs to %s\n"), REPORT_BUGS_TO);
00649   exit (status);
00650 }
00651 
00652 int
00653 main (int ac, char **av)
00654 {
00655   char *input_file = NULL;
00656   int opt;
00657   static struct option long_options[] =
00658   {
00659     {"help", no_argument, 0, 'h'},
00660     {"version", no_argument, 0, 'V'},
00661     {NULL, no_argument, 0, 0}
00662   };
00663 
00664 #if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
00665   setlocale (LC_MESSAGES, "");
00666 #endif
00667 #if defined (HAVE_SETLOCALE)
00668   setlocale (LC_CTYPE, "");
00669 #endif
00670   bindtextdomain (PACKAGE, LOCALEDIR);
00671   textdomain (PACKAGE);
00672 
00673   program_name = av[0];
00674   xmalloc_set_program_name (program_name);
00675 
00676   expandargv (&ac, &av);
00677 
00678   while ((opt = getopt_long (ac, av, "HhVv", long_options, (int *) NULL)) != EOF)
00679     {
00680       switch (opt)
00681        {
00682        case 'H':
00683        case 'h':
00684          show_usage (stdout, 0);
00685          /*NOTREACHED*/
00686        case 'v':
00687        case 'V':
00688          print_version ("sysdump");
00689          exit (0);
00690          /*NOTREACHED*/
00691        case 0:
00692          break;
00693        default:
00694          show_usage (stderr, 1);
00695          /*NOTREACHED*/
00696        }
00697     }
00698 
00699   /* The input and output files may be named on the command line.  */
00700 
00701   if (optind < ac)
00702     input_file = av[optind];
00703 
00704   if (!input_file)
00705     fatal (_("no input file specified"));
00706 
00707   file = fopen (input_file, FOPEN_RB);
00708 
00709   if (!file)
00710     fatal (_("cannot open input file %s"), input_file);
00711 
00712   module ();
00713   return 0;
00714 }