(root)/
binutils-2.41/
binutils/
sysdump.c
       1  /* Sysroff object format dumper.
       2     Copyright (C) 1994-2023 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 3 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., 51 Franklin Street - Fifth Floor, Boston, MA
      19     02110-1301, USA.  */
      20  
      21  
      22  /* Written by Steve Chamberlain <sac@cygnus.com>.
      23  
      24   This program reads a SYSROFF object file and prints it in an
      25   almost human readable form to stdout.  */
      26  
      27  #include "sysdep.h"
      28  #include "bfd.h"
      29  #include "safe-ctype.h"
      30  #include "libiberty.h"
      31  #include "getopt.h"
      32  #include "bucomm.h"
      33  #include "sysroff.h"
      34  
      35  static int dump = 1;
      36  static int segmented_p;
      37  static int code;
      38  static int addrsize = 4;
      39  static FILE *file;
      40  
      41  static void derived_type (void);
      42  
      43  static char *
      44  getCHARS (unsigned char *ptr, int *idx, int size, int max)
      45  {
      46    int oc = *idx / 8;
      47    char *r;
      48    int b = size;
      49  
      50    if (b >= max)
      51      return _("*undefined*");
      52  
      53    if (b == 0)
      54      {
      55        /* PR 17512: file: 13caced2.  */
      56        if (oc >= max)
      57  	return _("*corrupt*");
      58        /* Got to work out the length of the string from self.  */
      59        b = ptr[oc++];
      60        (*idx) += 8;
      61      }
      62  
      63    if (oc + b > size)
      64      {
      65        /* PR 28564  */
      66        return _("*corrupt*");
      67      }
      68  
      69    *idx += b * 8;
      70    r = xcalloc (b + 1, 1);
      71    memcpy (r, ptr + oc, b);
      72    r[b] = 0;
      73  
      74    return r;
      75  }
      76  
      77  static void
      78  dh (unsigned char *ptr, int size)
      79  {
      80    int i;
      81    int j;
      82    int span = 16;
      83  
      84    printf ("\n************************************************************\n");
      85  
      86    for (i = 0; i < size; i += span)
      87      {
      88        for (j = 0; j < span; j++)
      89  	{
      90  	  if (j + i < size)
      91  	    printf ("%02x ", ptr[i + j]);
      92  	  else
      93  	    printf ("   ");
      94  	}
      95  
      96        for (j = 0; j < span && j + i < size; j++)
      97  	{
      98  	  int c = ptr[i + j];
      99  
     100  	  if (c < 32 || c > 127)
     101  	    c = '.';
     102  	  printf ("%c", c);
     103  	}
     104  
     105        printf ("\n");
     106      }
     107  }
     108  
     109  static int
     110  fillup (unsigned char *ptr)
     111  {
     112    int size;
     113    int sum;
     114    int i;
     115  
     116    size = getc (file);
     117    if (size == EOF
     118        || size <= 2)
     119      return 0;
     120  
     121    size -= 2;
     122    if (fread (ptr, size, 1, file) != 1)
     123      return 0;
     124  
     125    sum = code + size + 2;
     126  
     127    for (i = 0; i < size; i++)
     128      sum += ptr[i];
     129  
     130    if ((sum & 0xff) != 0xff)
     131      printf (_("SUM IS %x\n"), sum);
     132  
     133    if (dump)
     134      dh (ptr, size);
     135  
     136    return size;
     137  }
     138  
     139  static barray
     140  getBARRAY (unsigned char *ptr, int *idx, int dsize ATTRIBUTE_UNUSED, int max)
     141  {
     142    barray res;
     143    int i;
     144    int byte = *idx / 8;
     145    int size = 0;
     146  
     147    if (byte < max)
     148      size = ptr[byte++];
     149  
     150    res.len = size;
     151    res.data = (unsigned char *) xmalloc (size);
     152  
     153    for (i = 0; i < size; i++)
     154      res.data[i] = byte < max ? ptr[byte++] : 0;
     155  
     156    return res;
     157  }
     158  
     159  static int
     160  getINT (unsigned char *ptr, int *idx, int size, int max)
     161  {
     162    int n = 0;
     163    int byte = *idx / 8;
     164  
     165    if (byte >= max)
     166      {
     167        /* PR 17512: file: id:000001,src:000002,op:flip1,pos:45.  */
     168        /* Prevent infinite loops re-reading beyond the end of the buffer.  */
     169        fatal (_("ICE: getINT: Out of buffer space"));
     170        return 0;
     171      }
     172  
     173    if (size == -2)
     174      size = addrsize;
     175  
     176    if (size == -1)
     177      size = 0;
     178  
     179    switch (size)
     180      {
     181      case 0:
     182        return 0;
     183      case 1:
     184        n = (ptr[byte]);
     185        break;
     186      case 2:
     187        n = (ptr[byte + 0] << 8) + ptr[byte + 1];
     188        break;
     189      case 4:
     190        n = (((unsigned) ptr[byte + 0] << 24) + (ptr[byte + 1] << 16)
     191  	   + (ptr[byte + 2] << 8) + (ptr[byte + 3]));
     192        break;
     193      default:
     194        fatal (_("Unsupported read size: %d"), size);
     195      }
     196  
     197    *idx += size * 8;
     198    return n;
     199  }
     200  
     201  static int
     202  getBITS (unsigned char *ptr, int *idx, int size, int max)
     203  {
     204    int byte = *idx / 8;
     205    int bit = *idx % 8;
     206  
     207    if (byte >= max)
     208      return 0;
     209  
     210    *idx += size;
     211  
     212    return (ptr[byte] >> (8 - bit - size)) & ((1 << size) - 1);
     213  }
     214  
     215  static void
     216  itheader (char *name, int icode)
     217  {
     218    printf ("\n%s 0x%02x\n", name, icode);
     219  }
     220  
     221  static int indent;
     222  
     223  static void
     224  p (void)
     225  {
     226    int i;
     227  
     228    for (i = 0; i < indent; i++)
     229      printf ("| ");
     230  
     231    printf ("> ");
     232  }
     233  
     234  static void
     235  tabout (void)
     236  {
     237    p ();
     238  }
     239  
     240  static void
     241  pbarray (barray *y)
     242  {
     243    int x;
     244  
     245    printf ("%d (", y->len);
     246  
     247    for (x = 0; x < y->len; x++)
     248      printf ("(%02x %c)", y->data[x],
     249  	    ISPRINT (y->data[x]) ? y->data[x] : '.');
     250  
     251    printf (")\n");
     252  }
     253  
     254  #define SYSROFF_PRINT
     255  #define SYSROFF_SWAP_IN
     256  
     257  #include "sysroff.c"
     258  
     259  /* FIXME: sysinfo, which generates sysroff.[ch] from sysroff.info, can't
     260     hack the special case of the tr block, which has no contents.  So we
     261     implement our own functions for reading in and printing out the tr
     262     block.  */
     263  
     264  #define IT_tr_CODE	0x7f
     265  
     266  static void
     267  sysroff_swap_tr_in (void)
     268  {
     269    unsigned char raw[255];
     270  
     271    memset (raw, 0, 255);
     272    fillup (raw);
     273  }
     274  
     275  static void
     276  sysroff_print_tr_out (void)
     277  {
     278    itheader ("tr", IT_tr_CODE);
     279  }
     280  
     281  static int
     282  getone (int type)
     283  {
     284    int c = getc (file);
     285  
     286    code = c;
     287  
     288    if ((c & 0x7f) != type)
     289      {
     290        ungetc (c, file);
     291        return 0;
     292      }
     293  
     294    switch (c & 0x7f)
     295      {
     296      case IT_cs_CODE:
     297        {
     298  	struct IT_cs dummy;
     299  	sysroff_swap_cs_in (&dummy);
     300  	sysroff_print_cs_out (&dummy);
     301        }
     302        break;
     303  
     304      case IT_dln_CODE:
     305        {
     306  	struct IT_dln dummy;
     307  	sysroff_swap_dln_in (&dummy);
     308  	sysroff_print_dln_out (&dummy);
     309        }
     310        break;
     311  
     312      case IT_hd_CODE:
     313        {
     314  	struct IT_hd dummy;
     315  	sysroff_swap_hd_in (&dummy);
     316  	addrsize = dummy.afl;
     317  	sysroff_print_hd_out (&dummy);
     318        }
     319        break;
     320  
     321      case IT_dar_CODE:
     322        {
     323  	struct IT_dar dummy;
     324  	sysroff_swap_dar_in (&dummy);
     325  	sysroff_print_dar_out (&dummy);
     326        }
     327        break;
     328  
     329      case IT_dsy_CODE:
     330        {
     331  	struct IT_dsy dummy;
     332  	sysroff_swap_dsy_in (&dummy);
     333  	sysroff_print_dsy_out (&dummy);
     334        }
     335        break;
     336  
     337      case IT_dfp_CODE:
     338        {
     339  	struct IT_dfp dummy;
     340  	sysroff_swap_dfp_in (&dummy);
     341  	sysroff_print_dfp_out (&dummy);
     342        }
     343        break;
     344  
     345      case IT_dso_CODE:
     346        {
     347  	struct IT_dso dummy;
     348  	sysroff_swap_dso_in (&dummy);
     349  	sysroff_print_dso_out (&dummy);
     350        }
     351        break;
     352  
     353      case IT_dpt_CODE:
     354        {
     355  	struct IT_dpt dummy;
     356  	sysroff_swap_dpt_in (&dummy);
     357  	sysroff_print_dpt_out (&dummy);
     358        }
     359        break;
     360  
     361      case IT_den_CODE:
     362        {
     363  	struct IT_den dummy;
     364  	sysroff_swap_den_in (&dummy);
     365  	sysroff_print_den_out (&dummy);
     366        }
     367        break;
     368  
     369      case IT_dbt_CODE:
     370        {
     371  	struct IT_dbt dummy;
     372  	sysroff_swap_dbt_in (&dummy);
     373  	sysroff_print_dbt_out (&dummy);
     374        }
     375        break;
     376  
     377      case IT_dty_CODE:
     378        {
     379  	struct IT_dty dummy;
     380  	sysroff_swap_dty_in (&dummy);
     381  	sysroff_print_dty_out (&dummy);
     382        }
     383        break;
     384  
     385      case IT_un_CODE:
     386        {
     387  	struct IT_un dummy;
     388  	sysroff_swap_un_in (&dummy);
     389  	sysroff_print_un_out (&dummy);
     390        }
     391        break;
     392  
     393      case IT_sc_CODE:
     394        {
     395  	struct IT_sc dummy;
     396  	sysroff_swap_sc_in (&dummy);
     397  	sysroff_print_sc_out (&dummy);
     398        }
     399        break;
     400  
     401      case IT_er_CODE:
     402        {
     403  	struct IT_er dummy;
     404  	sysroff_swap_er_in (&dummy);
     405  	sysroff_print_er_out (&dummy);
     406        }
     407        break;
     408  
     409      case IT_ed_CODE:
     410        {
     411  	struct IT_ed dummy;
     412  	sysroff_swap_ed_in (&dummy);
     413  	sysroff_print_ed_out (&dummy);
     414        }
     415        break;
     416  
     417      case IT_sh_CODE:
     418        {
     419  	struct IT_sh dummy;
     420  	sysroff_swap_sh_in (&dummy);
     421  	sysroff_print_sh_out (&dummy);
     422        }
     423        break;
     424  
     425      case IT_ob_CODE:
     426        {
     427  	struct IT_ob dummy;
     428  	sysroff_swap_ob_in (&dummy);
     429  	sysroff_print_ob_out (&dummy);
     430        }
     431        break;
     432  
     433      case IT_rl_CODE:
     434        {
     435  	struct IT_rl dummy;
     436  	sysroff_swap_rl_in (&dummy);
     437  	sysroff_print_rl_out (&dummy);
     438        }
     439        break;
     440  
     441      case IT_du_CODE:
     442        {
     443  	struct IT_du dummy;
     444  	sysroff_swap_du_in (&dummy);
     445  
     446  	sysroff_print_du_out (&dummy);
     447        }
     448        break;
     449  
     450      case IT_dus_CODE:
     451        {
     452  	struct IT_dus dummy;
     453  	sysroff_swap_dus_in (&dummy);
     454  	sysroff_print_dus_out (&dummy);
     455        }
     456        break;
     457  
     458      case IT_dul_CODE:
     459        {
     460  	struct IT_dul dummy;
     461  	sysroff_swap_dul_in (&dummy);
     462  	sysroff_print_dul_out (&dummy);
     463        }
     464        break;
     465  
     466      case IT_dss_CODE:
     467        {
     468  	struct IT_dss dummy;
     469  	sysroff_swap_dss_in (&dummy);
     470  	sysroff_print_dss_out (&dummy);
     471        }
     472        break;
     473  
     474      case IT_hs_CODE:
     475        {
     476  	struct IT_hs dummy;
     477  	sysroff_swap_hs_in (&dummy);
     478  	sysroff_print_hs_out (&dummy);
     479        }
     480        break;
     481  
     482      case IT_dps_CODE:
     483        {
     484  	struct IT_dps dummy;
     485  	sysroff_swap_dps_in (&dummy);
     486  	sysroff_print_dps_out (&dummy);
     487        }
     488        break;
     489  
     490      case IT_tr_CODE:
     491        sysroff_swap_tr_in ();
     492        sysroff_print_tr_out ();
     493        break;
     494  
     495      case IT_dds_CODE:
     496        {
     497  	struct IT_dds dummy;
     498  
     499  	sysroff_swap_dds_in (&dummy);
     500  	sysroff_print_dds_out (&dummy);
     501        }
     502        break;
     503  
     504      default:
     505        printf (_("GOT A %x\n"), c);
     506        return 0;
     507        break;
     508      }
     509  
     510    return 1;
     511  }
     512  
     513  static int
     514  opt (int x)
     515  {
     516    return getone (x);
     517  }
     518  
     519  static void
     520  must (int x)
     521  {
     522    if (!getone (x))
     523      printf (_("WANTED %x!!\n"), x);
     524  }
     525  
     526  static void
     527  tab (int i, char *s)
     528  {
     529    indent += i;
     530  
     531    if (s)
     532      {
     533        p ();
     534        puts (s);
     535      }
     536  }
     537  
     538  static void
     539  dump_symbol_info (void)
     540  {
     541    tab (1, _("SYMBOL INFO"));
     542  
     543    while (opt (IT_dsy_CODE))
     544      {
     545        if (opt (IT_dty_CODE))
     546  	{
     547  	  must (IT_dbt_CODE);
     548  	  derived_type ();
     549  	  must (IT_dty_CODE);
     550  	}
     551      }
     552  
     553    tab (-1, "");
     554  }
     555  
     556  static void
     557  derived_type (void)
     558  {
     559    tab (1, _("DERIVED TYPE"));
     560  
     561    while (1)
     562      {
     563        if (opt (IT_dpp_CODE))
     564  	{
     565  	  dump_symbol_info ();
     566  	  must (IT_dpp_CODE);
     567  	}
     568        else if (opt (IT_dfp_CODE))
     569  	{
     570  	  dump_symbol_info ();
     571  	  must (IT_dfp_CODE);
     572  	}
     573        else if (opt (IT_den_CODE))
     574  	{
     575  	  dump_symbol_info ();
     576  	  must (IT_den_CODE);
     577  	}
     578        else if (opt (IT_den_CODE))
     579  	{
     580  	  dump_symbol_info ();
     581  	  must (IT_den_CODE);
     582  	}
     583        else if (opt (IT_dds_CODE))
     584  	{
     585  	  dump_symbol_info ();
     586  	  must (IT_dds_CODE);
     587  	}
     588        else if (opt (IT_dar_CODE))
     589  	{
     590  	}
     591        else if (opt (IT_dpt_CODE))
     592  	{
     593  	}
     594        else if (opt (IT_dul_CODE))
     595  	{
     596  	}
     597        else if (opt (IT_dse_CODE))
     598  	{
     599  	}
     600        else if (opt (IT_dot_CODE))
     601  	{
     602  	}
     603        else
     604  	break;
     605      }
     606  
     607    tab (-1, "");
     608  }
     609  
     610  static void
     611  module (void)
     612  {
     613    int c = 0;
     614    int l = 0;
     615  
     616    tab (1, _("MODULE***\n"));
     617  
     618    do
     619      {
     620        c = getc (file);
     621        if (c == EOF)
     622  	break;
     623        ungetc (c, file);
     624  
     625        c &= 0x7f;
     626      }
     627    while (getone (c) && c != IT_tr_CODE);
     628  
     629    tab (-1, "");
     630  
     631    c = getc (file);
     632    while (c != EOF)
     633      {
     634        printf ("%02x ", c);
     635        l++;
     636        if (l == 32)
     637  	{
     638  	  printf ("\n");
     639  	  l = 0;
     640  	}
     641        c = getc (file);
     642      }
     643  }
     644  
     645  ATTRIBUTE_NORETURN static void
     646  show_usage (FILE *ffile, int status)
     647  {
     648    fprintf (ffile, _("Usage: %s [option(s)] in-file\n"), program_name);
     649    fprintf (ffile, _("Print a human readable interpretation of a SYSROFF object file\n"));
     650    fprintf (ffile, _(" The options are:\n\
     651    -h --help        Display this information\n\
     652    -v --version     Print the program's version number\n"));
     653  
     654    if (REPORT_BUGS_TO[0] && status == 0)
     655      fprintf (ffile, _("Report bugs to %s\n"), REPORT_BUGS_TO);
     656    exit (status);
     657  }
     658  
     659  int
     660  main (int ac, char **av)
     661  {
     662    char *input_file = NULL;
     663    int option;
     664    static struct option long_options[] =
     665    {
     666      {"help", no_argument, 0, 'h'},
     667      {"version", no_argument, 0, 'V'},
     668      {NULL, no_argument, 0, 0}
     669    };
     670  
     671  #ifdef HAVE_LC_MESSAGES
     672    setlocale (LC_MESSAGES, "");
     673  #endif
     674    setlocale (LC_CTYPE, "");
     675    bindtextdomain (PACKAGE, LOCALEDIR);
     676    textdomain (PACKAGE);
     677  
     678    program_name = av[0];
     679    xmalloc_set_program_name (program_name);
     680    bfd_set_error_program_name (program_name);
     681  
     682    expandargv (&ac, &av);
     683  
     684    while ((option = getopt_long (ac, av, "HhVv", long_options, (int *) NULL)) != EOF)
     685      {
     686        switch (option)
     687  	{
     688  	case 'H':
     689  	case 'h':
     690  	  show_usage (stdout, 0);
     691  	  /*NOTREACHED*/
     692  	case 'v':
     693  	case 'V':
     694  	  print_version ("sysdump");
     695  	  exit (0);
     696  	  /*NOTREACHED*/
     697  	case 0:
     698  	  break;
     699  	default:
     700  	  show_usage (stderr, 1);
     701  	  /*NOTREACHED*/
     702  	}
     703      }
     704  
     705    /* The input and output files may be named on the command line.  */
     706  
     707    if (optind < ac)
     708      input_file = av[optind];
     709  
     710    if (!input_file)
     711      fatal (_("no input file specified"));
     712  
     713    file = fopen (input_file, FOPEN_RB);
     714  
     715    if (!file)
     716      fatal (_("cannot open input file %s"), input_file);
     717  
     718    module ();
     719    return 0;
     720  }