document --disassembler-options=force-thumb
[deliverable/binutils-gdb.git] / binutils / srconv.c
index cb62657e7ca82b365d2639bf0e77146575a04888..8b0f2b7b5ee0265af53cf20c9de4e29352a8d3f0 100644 (file)
@@ -1,5 +1,5 @@
 /* srconv.c -- Sysroff conversion program
-   Copyright (C) 1994 Free Software Foundation, Inc.
+   Copyright (C) 1994, 95, 96, 98, 1999 Free Software Foundation, Inc.
 
    This file is part of GNU Binutils.
 
@@ -15,7 +15,8 @@
 
    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
-   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
+   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+   02111-1307, USA.  */
 
 /* Written by Steve Chamberlain (sac@cygnus.com)
 
    All debugging information is preserved */
 
 #include <bfd.h>
-#include <getopt.h>
-#include <stdio.h>
-#include <time.h>
-#include <libiberty.h>
 #include "bucomm.h"
 #include "sysroff.h"
 #include "coffgrok.h"
+#include <libiberty.h>
+#include <getopt.h>
 
 #include "coff/internal.h"
 #include "../bfd/libcoff.h"
 
 #define PROGRAM_VERSION "1.5"
-/*#define FOOP1 1*/
+/*#define FOOP1 1 */
+
+static int addrsize;
+static char *toolname;
+static char **rnames;
 
-static int sh;
-static int h8300;
 static void wr_cs ();
 static void walk_tree_scope ();
 static void wr_globals ();
@@ -50,10 +51,12 @@ static FILE *file;
 static bfd *abfd;
 static int debug = 0;
 static int quick = 0;
-
+static int noprescan = 0;
 static struct coff_ofile *tree;
+/* Obsolete ?? 
+   static int absolute_p;
+ */
 
-static int absolute_p;
 static int segmented_p;
 static int code;
 
@@ -63,16 +66,6 @@ static int ids2[20000];
 static int base1 = 0x18;
 static int base2 = 0x2018;
 
-char *
-xcalloc (a, b)
-     int a;
-     int b;
-{
-  char *r = xmalloc (a * b);
-  memset (r, 0, a * b);
-  return r;
-}
-
 static int
 get_member_id (x)
      int x;
@@ -171,8 +164,8 @@ writeINT (n, ptr, idx, size, file)
   int byte = *idx / 8;
 
   if (size == -2)
-    size = 4;
-  if (size == -1)
+    size = addrsize;
+  else if (size == -1)
     size = 0;
 
   if (byte > 240)
@@ -240,11 +233,9 @@ writeBARRAY (data, ptr, idx, size, file)
     {
       writeINT (data.data[i], ptr, idx, 1, file);
     }
+}
 
 
-
-
-}
 static void
 writeCHARS (string, ptr, idx, size, file)
      char *string;
@@ -270,7 +261,7 @@ writeCHARS (string, ptr, idx, size, file)
       ptr[i++] = size;
     }
 
-
+  /* BUG WAITING TO HAPPEN */
   memcpy (ptr + i, string, size);
   i += size;
   *idx = i * 8;
@@ -293,15 +284,22 @@ static char *rname_h8300[] =
 static void
 wr_tr ()
 {
-  struct IT_tr t;
-  sysroff_swap_tr_out (file, &t);
+  /* The TR block is not normal - it doesn't have any contents. */
+
+  static char b[] = {
+    0xff,                      /* IT */
+    0x03,                      /* RL */
+    0xfd,                      /* CS */
+  };
+  fwrite (b, 1, sizeof (b), file);
 }
 
 static void
-wr_un (ptr, sfile, first)
+wr_un (ptr, sfile, first, nsecs)
      struct coff_ofile *ptr;
      struct coff_sfile *sfile;
      int first;
+     int nsecs;
 {
   struct IT_un un;
 
@@ -309,12 +307,20 @@ wr_un (ptr, sfile, first)
 
   un.spare1 = 0;
 
-  if (abfd->flags & EXEC_P)
+  if (bfd_get_file_flags (abfd) & EXEC_P)
     un.format = FORMAT_LM;
   else
     un.format = FORMAT_OM;
   un.spare1 = 0;
+
+
+#if 1
   un.nsections = ptr->nsections - 1;   /*  Don't count the abs section */
+#else
+  /*NEW - only count sections with size */
+  un.nsections = nsecs;
+#endif
+
   un.nextdefs = 0;
   un.nextrefs = 0;
   /* Count all the undefined and defined variables with global scope */
@@ -331,14 +337,7 @@ wr_un (ptr, sfile, first)
            un.nextrefs++;
        }
     }
-  if (sh)
-    {
-      un.tool = "C_SH";
-    }
-  if (h8300)
-    {
-      un.tool = "C_H8/300H";
-    }
+  un.tool = toolname;
   un.tcd = DATE;
   un.linker = "L_GX00";
   un.lcd = DATE;
@@ -354,7 +353,7 @@ wr_hd (p)
   struct IT_hd hd;
 
   hd.spare1 = 0;
-  if (abfd->flags & EXEC_P)
+  if (bfd_get_file_flags (abfd) & EXEC_P)
     {
       hd.mt = MTYPE_ABS_LM;
     }
@@ -367,33 +366,56 @@ wr_hd (p)
   hd.nu = p->nsources;         /* Always one unit */
   hd.code = 0;                 /* Always ASCII */
   hd.ver = "0200";             /* Version 2.00 */
-  switch (abfd->arch_info->arch)
+  switch (bfd_get_arch (abfd))
     {
     case bfd_arch_h8300:
       hd.au = 8;
-      hd.si = 32;
-      hd.afl = 2;
-      hd.spcsz = 0;
+      hd.si = 0;
+      hd.spcsz = 32;
       hd.segsz = 0;
       hd.segsh = 0;
-      hd.cpu = "H8300H";
-      h8300 = 1;
+      switch (bfd_get_mach (abfd))
+       {
+       case bfd_mach_h8300:
+         hd.cpu = "H8300";
+         hd.afl = 2;
+         addrsize = 2;
+         toolname = "C_H8/300";
+         break;
+       case bfd_mach_h8300h:
+         hd.cpu = "H8300H";
+         hd.afl = 4;
+         addrsize = 4;
+         toolname = "C_H8/300H";
+         break;
+       case bfd_mach_h8300s:
+         hd.cpu = "H8300S";
+         hd.afl = 4;
+         addrsize = 4;
+         toolname = "C_H8/300S";
+         break;
+       default:
+         abort();
+       }
+      rnames = rname_h8300;
       break;
     case bfd_arch_sh:
       hd.au = 8;
-      hd.si = 32;
-      hd.afl = 2;
-      hd.spcsz = 0;
+      hd.si = 0;
+      hd.afl = 4;
+      hd.spcsz = 32;
       hd.segsz = 0;
       hd.segsh = 0;
       hd.cpu = "SH";
-      sh = 1;
+      addrsize = 4;
+      toolname = "C_SH";
+      rnames = rname_sh;
       break;
     default:
       abort ();
     }
 
-  if (!abfd->flags & EXEC_P)
+  if (! bfd_get_file_flags(abfd) & EXEC_P)
     {
       hd.ep = 0;
     }
@@ -408,8 +430,7 @@ wr_hd (p)
 
   hd.os = "";
   hd.sys = "";
-  hd.mn = strip_suffix (abfd->filename);
-
+  hd.mn = strip_suffix (bfd_get_filename (abfd));
 
   sysroff_swap_hd_out (file, &hd);
 }
@@ -435,23 +456,23 @@ wr_ob (p, section)
      struct coff_ofile *p;
      struct coff_section *section;
 {
-  int i;
+  bfd_size_type i;
   int first = 1;
   unsigned char stuff[200];
 
   i = 0;
-  while (i < section->size)
+  while (i < section->bfd_section->_raw_size)
     {
       struct IT_ob ob;
       int todo = 200;          /* Copy in 200 byte lumps */
       ob.spare = 0;
-      if (i + todo > section->size)
-       todo = section->size - i;
+      if (i + todo > section->bfd_section->_raw_size)
+       todo = section->bfd_section->_raw_size - i;
 
       if (first)
        {
          ob.saf = 1;
-         if (abfd->flags & EXEC_P)
+         if (bfd_get_file_flags (abfd) & EXEC_P)
            ob.address = section->address;
          else
            ob.address = 0;
@@ -467,9 +488,28 @@ wr_ob (p, section)
       ob.data.len = todo;
       bfd_get_section_contents (abfd, section->bfd_section, stuff, i, todo);
       ob.data.data = stuff;
-      sysroff_swap_ob_out (file, &ob /*, i + todo < section->size*/ );
+      sysroff_swap_ob_out (file, &ob /*, i + todo < section->size */ );
       i += todo;
     }
+  /* Now fill the rest with blanks */
+  while (i < (bfd_size_type) section->size)
+    {
+      struct IT_ob ob;
+      int todo = 200;          /* Copy in 200 byte lumps */
+      ob.spare = 0;
+      if (i + todo > (bfd_size_type) section->size)
+       todo = section->size - i;
+      ob.saf = 0;
+
+      ob.cpf = 0;              /* Never compress */
+      ob.data.len = todo;
+      memset (stuff, 0, todo);
+      ob.data.data = stuff;
+      sysroff_swap_ob_out (file, &ob);
+      i += todo;
+    }
+  /* Now fill the rest with blanks */
+
 }
 
 static void
@@ -824,42 +864,43 @@ walk_tree_type_1 (sfile, symbol, type, nest)
     }
 }
 
-static void
-dty_start ()
-{
-  struct IT_dty dty;
-  dty.end = 0;
-  dty.neg = 0x1001;
-  dty.spare = 0;
-  sysroff_swap_dty_out (file, &dty);
-}
-
-static void
-dty_stop ()
-{
-  struct IT_dty dty;
-  dty.end = 0;
-  dty.neg = 0x1001;
-  dty.end = 1;
-  sysroff_swap_dty_out (file, &dty);
-}
-
-
-static void
-dump_tree_structure (sfile, symbol, type, nest)
-     struct coff_sfile *sfile;
-     struct coff_symbol *symbol;
-     struct coff_type *type;
-     int nest;
-{
-  if (symbol->type->type == coff_function_type)
-    {
-
-
-    }
-
-}
-
+/* Obsolete ? 
+   static void
+   dty_start ()
+   {
+   struct IT_dty dty;
+   dty.end = 0;
+   dty.neg = 0x1001;
+   dty.spare = 0;
+   sysroff_swap_dty_out (file, &dty);
+   }
+
+   static void
+   dty_stop ()
+   {
+   struct IT_dty dty;
+   dty.end = 0;
+   dty.neg = 0x1001;
+   dty.end = 1;
+   sysroff_swap_dty_out (file, &dty);
+   }
+
+
+   static void
+   dump_tree_structure (sfile, symbol, type, nest)
+   struct coff_sfile *sfile;
+   struct coff_symbol *symbol;
+   struct coff_type *type;
+   int nest;
+   {
+   if (symbol->type->type == coff_function_type)
+   {
+
+
+   }
+
+   }
+ */
 
 static void
 walk_tree_type (sfile, symbol, type, nest)
@@ -925,7 +966,7 @@ walk_tree_symbol (sfile, section, symbol, nest)
 {
   struct IT_dsy dsy;
 
-  dsy.spare2 = 0;
+  memset(&dsy, 0, sizeof(dsy));
   dsy.nesting = nest;
 
   switch (symbol->type->type)
@@ -967,8 +1008,8 @@ walk_tree_symbol (sfile, section, symbol, nest)
     {
       dsy.type = STYPE_ENUM;
       dsy.assign = 0;
-      dsy.vallen = 4;
-      dsy.value = symbol->where->offset;
+      dsy.evallen = 4;
+      dsy.evalue = symbol->where->offset;
     }
 
   if (symbol->type->type == coff_structdef_type
@@ -1067,8 +1108,8 @@ walk_tree_symbol (sfile, section, symbol, nest)
       break;
     case coff_where_member_of_enum:
       /*      dsy.bitunit = 0;
-               dsy.field_len  = symbol->type->size;
-               dsy.field_off = symbol->where->offset;*/
+         dsy.field_len  = symbol->type->size;
+         dsy.field_off = symbol->where->offset; */
       break;
     case coff_where_register:
     case coff_where_unknown:
@@ -1082,12 +1123,7 @@ walk_tree_symbol (sfile, section, symbol, nest)
     }
 
   if (symbol->where->where == coff_where_register)
-    {
-      if (sh)
-       dsy.reg = rname_sh[symbol->where->offset];
-      if (h8300)
-       dsy.reg = rname_h8300[symbol->where->offset];
-    }
+    dsy.reg = rnames[symbol->where->offset];
 
   switch (symbol->visible->type)
     {
@@ -1196,9 +1232,10 @@ wr_du (p, sfile, n)
   int j;
   unsigned int *lowest = (unsigned *) nints (p->nsections);
   unsigned int *highest = (unsigned *) nints (p->nsections);
-  du.spare = 0;
-  du.format = abfd->flags & EXEC_P ? 0 : 1;
+  du.format = bfd_get_file_flags (abfd) & EXEC_P ? 0 : 1;
   du.optimized = 0;
+  du.stackfrmt = 0;
+  du.spare = 0;
   du.unit = n;
   du.sections = p->nsections - 1;
   du.san = (int *) xcalloc (sizeof (int), du.sections);
@@ -1241,7 +1278,7 @@ wr_du (p, sfile, n)
        }
       du.san[used] = i;
       du.length[used] = highest[i] - lowest[i];
-      du.address[used] = abfd->flags & EXEC_P ? lowest[i] : 0;
+      du.address[used] = bfd_get_file_flags (abfd) & EXEC_P ? lowest[i] : 0;
       if (debug)
        {
          printf (" section %6s 0x%08x..0x%08x\n",
@@ -1327,7 +1364,7 @@ wr_dus (p, sfile)
 }
 
 /* Find the offset of the .text section for this sfile in the
-    .text section for the output file */
+   .text section for the output file */
 
 static int
 find_base (sfile, section)
@@ -1521,15 +1558,47 @@ wr_debug (p)
       n++;
     }
 }
+
 static void
 wr_cs ()
 {
   /* It seems that the CS struct is not normal - the size is wrong
      heres one I prepared earlier.. */
-  static char b[] =
-  {0x80, 0x21, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x80, 0x80,
-   0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x80, 0x00,
-   0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0xde};
+  static char b[] = {
+    0x80,                      /* IT */
+    0x21,                      /* RL */
+    0x00,                      /* number of chars in variable length part */
+    0x80,                      /* hd */ 
+    0x00,                      /* hs */ 
+    0x80,                      /* un */ 
+    0x00,                      /* us */ 
+    0x80,                      /* sc */ 
+    0x00,                      /* ss */ 
+    0x80,                      /* er */ 
+    0x80,                      /* ed */ 
+    0x80,                      /* sh */ 
+    0x80,                      /* ob */ 
+    0x80,                      /* rl */ 
+    0x80,                      /* du */
+    0x80,                      /* dps */
+    0x80,                      /* dsy */
+    0x80,                      /* dty */
+    0x80,                      /* dln */
+    0x80,                      /* dso */
+    0x80,                      /* dus */
+    0x00,                      /* dss */
+    0x80,                      /* dbt */
+    0x00,                      /* dpp */
+    0x80,                      /* dfp */
+    0x80,                      /* den */
+    0x80,                      /* dds */
+    0x80,                      /* dar */
+    0x80,                      /* dpt */
+    0x00,                      /* dul */
+    0x00,                      /* dse */
+    0x00,                      /* dot */
+    0xDE                       /* CS */
+  };
   fwrite (b, 1, sizeof (b), file);
 }
 
@@ -1537,12 +1606,13 @@ wr_cs ()
    for all the sections which appear in the output file, even
    if there isn't an equivalent one on the input */
 
-static void
+static int
 wr_sc (ptr, sfile)
      struct coff_ofile *ptr;
      struct coff_sfile *sfile;
 {
   int i;
+int scount = 0;
   /* First work out the total number of sections */
 
   int total_sec = ptr->nsections;
@@ -1555,7 +1625,7 @@ wr_sc (ptr, sfile)
   struct coff_symbol *symbol;
 
   struct myinfo *info
-  = (struct myinfo *) calloc (total_sec, sizeof (struct myinfo));
+    = (struct myinfo *) calloc (total_sec, sizeof (struct myinfo));
 
 
 
@@ -1597,14 +1667,14 @@ wr_sc (ptr, sfile)
        {
          /* Don't have a symbol set aside for this section, which means that nothing
             in this file does anything for the section. */
-         sc.format = !(abfd->flags & EXEC_P);
+         sc.format = !(bfd_get_file_flags (abfd) & EXEC_P);
          sc.addr = 0;
          sc.length = 0;
          name = info[i].sec->name;
        }
       else
        {
-         if (abfd->flags & EXEC_P)
+         if (bfd_get_file_flags (abfd) & EXEC_P)
            {
              sc.format = 0;
              sc.addr = symbol->where->offset;
@@ -1646,16 +1716,21 @@ wr_sc (ptr, sfile)
        {
          sc.contents = CONTENTS_CODE;
        }
-
-
-      sysroff_swap_sc_out (file, &sc);
-
-
-
+#if 0
+      /* NEW */
+      if (sc.length) {
+#endif
+       sysroff_swap_sc_out (file, &sc);
+       scount++;
+#if 0
+      }
+#endif
     }
-
+return scount;
 }
 
+
+/* Write out the ER records for a unit. */
 static void
 wr_er (ptr, sfile, first)
      struct coff_ofile *ptr;
@@ -1676,12 +1751,12 @@ wr_er (ptr, sfile, first)
              er.name = sym->name;
              sysroff_swap_er_out (file, &er);
              sym->er_number = idx++;
-
            }
        }
     }
 }
 
+/* Write out the ED records for a unit. */
 static void
 wr_ed (ptr, sfile, first)
      struct coff_ofile *ptr;
@@ -1731,8 +1806,16 @@ wr_unit_info (ptr)
        sfile;
        sfile = sfile->next)
     {
-      wr_un (ptr, sfile, first);
-      wr_sc (ptr, sfile);
+      long p1;
+      long p2;
+      int nsecs;
+      p1 = ftell (file);
+      wr_un (ptr, sfile, first, 0);
+      nsecs = wr_sc (ptr, sfile);
+      p2 = ftell (file);
+      fseek (file, p1, SEEK_SET);
+      wr_un (ptr, sfile, first, nsecs);
+      fseek (file, p2, SEEK_SET); 
       wr_er (ptr, sfile, first);
       wr_ed (ptr, sfile, first);
       first = 0;
@@ -1776,7 +1859,7 @@ prescan (tree)
       if (s->visible->type == coff_vis_common)
        {
          struct coff_where *w = s->where;
-         /*      s->visible->type = coff_vis_ext_def; leave it as common */
+         /*      s->visible->type = coff_vis_ext_def; leave it as common */
          common_section->size = align (common_section->size);
          w->offset = common_section->size + common_section->address;
          w->section = common_section;
@@ -1793,14 +1876,14 @@ show_usage (file, status)
      FILE *file;
      int status;
 {
-  fprintf (file, "Usage: %s [-dhVq] in-file [out-file]\n", program_name);
+  fprintf (file, _("Usage: %s [-dhVq] in-file [out-file]\n"), program_name);
   exit (status);
 }
 
 static void
 show_help ()
 {
-  printf ("%s: Convert a COFF object file into a SYSROFF object file\n",
+  printf (_("%s: Convert a COFF object file into a SYSROFF object file\n"),
          program_name);
   show_usage (stdout, 0);
 }
@@ -1817,18 +1900,25 @@ main (ac, av)
   {
     {"debug", no_argument, 0, 'd'},
     {"quick", no_argument, 0, 'q'},
+    {"noprescan", no_argument, 0, 'n'},
     {"help", no_argument, 0, 'h'},
     {"version", no_argument, 0, 'V'},
     {NULL, no_argument, 0, 0}
   };
   char **matching;
   char *input_file;
-
   char *output_file;
+
+#if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
+  setlocale (LC_MESSAGES, "");
+#endif
+  bindtextdomain (PACKAGE, LOCALEDIR);
+  textdomain (PACKAGE);
+
   program_name = av[0];
   xmalloc_set_program_name (program_name);
 
-  while ((opt = getopt_long (ac, av, "dhVq", long_options,
+  while ((opt = getopt_long (ac, av, "dhVqn", long_options,
                             (int *) NULL))
         != EOF)
     {
@@ -1837,21 +1927,24 @@ main (ac, av)
        case 'q':
          quick = 1;
          break;
+       case 'n':
+         noprescan = 1;
+         break;
        case 'd':
          debug = 1;
          break;
        case 'h':
          show_help ();
-         /*NOTREACHED*/
+         /*NOTREACHED */
        case 'V':
-         printf ("GNU %s version %s\n", program_name, PROGRAM_VERSION);
+         printf (_("GNU %s version %s\n"), program_name, PROGRAM_VERSION);
          exit (0);
-         /*NOTREACHED*/
+         /*NOTREACHED */
        case 0:
          break;
        default:
          show_usage (stderr, 1);
-         /*NOTREACHED*/
+         /*NOTREACHED */
        }
     }
 
@@ -1870,7 +1963,7 @@ main (ac, av)
          if (strcmp (input_file, output_file) == 0)
            {
              fprintf (stderr,
-                      "%s: input and output files must be different\n",
+                      _("%s: input and output files must be different\n"),
                       program_name);
              exit (1);
            }
@@ -1881,7 +1974,7 @@ main (ac, av)
 
   if (!input_file)
     {
-      fprintf (stderr, "%s: no input file specified\n",
+      fprintf (stderr, _("%s: no input file specified\n"),
               program_name);
       exit (1);
     }
@@ -1889,7 +1982,7 @@ main (ac, av)
   if (!output_file)
     {
       /* Take a .o off the input file and stick on a .obj.  If
-        it doesn't end in .o, then stick a .obj on anyway */
+         it doesn't end in .o, then stick a .obj on anyway */
 
       int len = strlen (input_file);
       output_file = xmalloc (len + 5);
@@ -1924,11 +2017,11 @@ main (ac, av)
       exit (1);
     }
 
-  file = fopen (output_file, "wb");
+  file = fopen (output_file, FOPEN_WB);
 
   if (!file)
     {
-      fprintf (stderr, "%s: unable to open output file %s\n",
+      fprintf (stderr, _("%s: unable to open output file %s\n"),
               program_name, output_file);
       exit (1);
     }
@@ -1936,7 +2029,8 @@ main (ac, av)
   if (debug)
     printf ("ids %d %d\n", base1, base2);
   tree = coff_grok (abfd);
-  prescan (tree);
+  if (!noprescan)
+    prescan (tree);
   wr_module (tree);
   return 0;
 }
This page took 0.033117 seconds and 4 git commands to generate.