* v850-opc.c (v850_operands): Add "B3" support.
[deliverable/binutils-gdb.git] / binutils / srconv.c
index cb62657e7ca82b365d2639bf0e77146575a04888..fca3dfdefdaf66b5225e19837e02ebdac87c662c 100644 (file)
@@ -15,7 +15,7 @@
 
    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 sh;
 static int h8300;
@@ -50,10 +48,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;
 
@@ -171,8 +171,13 @@ writeINT (n, ptr, idx, size, file)
   int byte = *idx / 8;
 
   if (size == -2)
-    size = 4;
-  if (size == -1)
+    {
+      if (sh)  
+       size = 4;
+      else if (h8300)
+       size = 2;
+    }
+  else if (size == -1)
     size = 0;
 
   if (byte > 240)
@@ -240,11 +245,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 +273,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 +296,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;
 
@@ -314,7 +324,15 @@ wr_un (ptr, sfile, first)
   else
     un.format = FORMAT_OM;
   un.spare1 = 0;
+
+
+#if 0
   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 */
@@ -332,13 +350,9 @@ wr_un (ptr, sfile, first)
        }
     }
   if (sh)
-    {
-      un.tool = "C_SH";
-    }
-  if (h8300)
-    {
-      un.tool = "C_H8/300H";
-    }
+    un.tool = "C_SH";
+  else if (h8300)
+    un.tool = "C_H8/300H";
   un.tcd = DATE;
   un.linker = "L_GX00";
   un.lcd = DATE;
@@ -371,9 +385,9 @@ wr_hd (p)
     {
     case bfd_arch_h8300:
       hd.au = 8;
-      hd.si = 32;
+      hd.si = 0;
       hd.afl = 2;
-      hd.spcsz = 0;
+      hd.spcsz = 32;
       hd.segsz = 0;
       hd.segsh = 0;
       hd.cpu = "H8300H";
@@ -381,9 +395,9 @@ wr_hd (p)
       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";
@@ -440,13 +454,13 @@ wr_ob (p, section)
   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)
        {
@@ -467,9 +481,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 < section->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;
+      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 +857,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)
@@ -967,8 +1001,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 +1101,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:
@@ -1085,7 +1119,7 @@ walk_tree_symbol (sfile, section, symbol, nest)
     {
       if (sh)
        dsy.reg = rname_sh[symbol->where->offset];
-      if (h8300)
+      else if (h8300)
        dsy.reg = rname_h8300[symbol->where->offset];
     }
 
@@ -1327,7 +1361,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 +1555,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 +1603,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 +1622,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));
 
 
 
@@ -1646,16 +1713,17 @@ wr_sc (ptr, sfile)
        {
          sc.contents = CONTENTS_CODE;
        }
-
-
-      sysroff_swap_sc_out (file, &sc);
-
-
-
+      /* NEW */
+      if (sc.length) {
+       sysroff_swap_sc_out (file, &sc);
+       scount++;
+      }
     }
-
+return scount;
 }
 
+
+/* Write out the ER records for a unit. */
 static void
 wr_er (ptr, sfile, first)
      struct coff_ofile *ptr;
@@ -1676,12 +1744,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 +1799,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 +1852,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;
@@ -1817,6 +1893,7 @@ 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}
@@ -1828,7 +1905,7 @@ main (ac, av)
   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 +1914,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);
          exit (0);
-         /*NOTREACHED*/
+         /*NOTREACHED */
        case 0:
          break;
        default:
          show_usage (stderr, 1);
-         /*NOTREACHED*/
+         /*NOTREACHED */
        }
     }
 
@@ -1889,7 +1969,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,7 +2004,7 @@ main (ac, av)
       exit (1);
     }
 
-  file = fopen (output_file, "wb");
+  file = fopen (output_file, FOPEN_WB);
 
   if (!file)
     {
@@ -1936,7 +2016,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.030359 seconds and 4 git commands to generate.