More signed overflow fixes
[deliverable/binutils-gdb.git] / binutils / srconv.c
index d1f3efdb9e016a2d9fcf710243254d0688e87ced..a421f642e0be73f99a051e1457fab7df607cb219 100644 (file)
@@ -1,12 +1,11 @@
 /* srconv.c -- Sysroff conversion program
 /* srconv.c -- Sysroff conversion program
-   Copyright 1994, 1995, 1996, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
-   2005 Free Software Foundation, Inc.
+   Copyright (C) 1994-2019 Free Software Foundation, Inc.
 
    This file is part of GNU Binutils.
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
 
    This file is part of GNU Binutils.
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 2 of the License, or
+   the Free Software Foundation; either version 3 of the License, or
    (at your option) any later version.
 
    This program is distributed in the hope that it will be useful,
    (at your option) any later version.
 
    This program is distributed in the hope that it will be useful,
 
    All debugging information is preserved */
 
 
    All debugging information is preserved */
 
+#include "sysdep.h"
 #include "bfd.h"
 #include "bucomm.h"
 #include "sysroff.h"
 #include "coffgrok.h"
 #include "libiberty.h"
 #include "bfd.h"
 #include "bucomm.h"
 #include "sysroff.h"
 #include "coffgrok.h"
 #include "libiberty.h"
+#include "filenames.h"
 #include "getopt.h"
 
 #include "coff/internal.h"
 #include "getopt.h"
 
 #include "coff/internal.h"
@@ -42,52 +43,12 @@ static int addrsize;
 static char *toolname;
 static char **rnames;
 
 static char *toolname;
 static char **rnames;
 
-static int get_member_id (int);
-static int get_ordinary_id (int);
-static char *section_translate (char *);
-static char *strip_suffix (char *);
-static void checksum (FILE *, unsigned char *, int, int);
-static void writeINT (int, unsigned char *, int *, int, FILE *);
-static void writeBITS (int, unsigned char *, int *, int);
-static void writeBARRAY (barray, unsigned char *, int *, int, FILE *);
-static void writeCHARS (char *, unsigned char *, int *, int, FILE *);
-static void wr_tr (void);
-static void wr_un (struct coff_ofile *, struct coff_sfile *, int, int);
-static void wr_hd (struct coff_ofile *);
-static void wr_sh (struct coff_ofile *, struct coff_section *);
-static void wr_ob (struct coff_ofile *, struct coff_section *);
-static void wr_rl (struct coff_ofile *, struct coff_section *);
-static void wr_object_body (struct coff_ofile *);
-static void wr_dps_start
-  (struct coff_sfile *, struct coff_section *, struct coff_scope *, int, int);
-static void wr_dps_end (struct coff_section *, struct coff_scope *, int);
-static int *nints (int);
-static void walk_tree_type_1
-  (struct coff_sfile *, struct coff_symbol *, struct coff_type *, int);
-static void walk_tree_type
-  (struct coff_sfile *, struct coff_symbol *, struct coff_type *, int);
 static void walk_tree_symbol
   (struct coff_sfile *, struct coff_section *, struct coff_symbol *, int);
 static void walk_tree_scope
   (struct coff_section *, struct coff_sfile *, struct coff_scope *, int, int);
 static void walk_tree_symbol
   (struct coff_sfile *, struct coff_section *, struct coff_symbol *, int);
 static void walk_tree_scope
   (struct coff_section *, struct coff_sfile *, struct coff_scope *, int, int);
-static void walk_tree_sfile (struct coff_section *, struct coff_sfile *);
-static void wr_program_structure (struct coff_ofile *, struct coff_sfile *);
-static void wr_du (struct coff_ofile *, struct coff_sfile *, int);
-static void wr_dus (struct coff_ofile *, struct coff_sfile *);
 static int find_base (struct coff_sfile *, struct coff_section *);
 static int find_base (struct coff_sfile *, struct coff_section *);
-static void wr_dln (struct coff_ofile *, struct coff_sfile *, int);
 static void wr_globals (struct coff_ofile *, struct coff_sfile *, int);
 static void wr_globals (struct coff_ofile *, struct coff_sfile *, int);
-static void wr_debug (struct coff_ofile *);
-static void wr_cs (void);
-static int wr_sc (struct coff_ofile *, struct coff_sfile *);
-static void wr_er (struct coff_ofile *, struct coff_sfile *, int);
-static void wr_ed (struct coff_ofile *, struct coff_sfile *, int);
-static void wr_unit_info (struct coff_ofile *);
-static void wr_module (struct coff_ofile *);
-static int align (int);
-static void prescan (struct coff_ofile *);
-static void show_usage (FILE *, int);
-extern int main (int, char **);
 
 static FILE *file;
 static bfd *abfd;
 
 static FILE *file;
 static bfd *abfd;
@@ -141,9 +102,8 @@ section_translate (char *n)
 
 #define DATE "940201073000";   /* Just a time on my birthday */
 
 
 #define DATE "940201073000";   /* Just a time on my birthday */
 
-static
-char *
-strip_suffix (char *name)
+static char *
+strip_suffix (const char *name)
 {
   int i;
   char *res;
 {
   int i;
   char *res;
@@ -158,17 +118,18 @@ strip_suffix (char *name)
 
 /* IT LEN stuff CS */
 static void
 
 /* IT LEN stuff CS */
 static void
-checksum (FILE *file, unsigned char *ptr, int size, int code)
+checksum (FILE *ffile, unsigned char *ptr, int size, int ccode)
 {
   int j;
   int last;
   int sum = 0;
   int bytes = size / 8;
 
 {
   int j;
   int last;
   int sum = 0;
   int bytes = size / 8;
 
-  last = !(code & 0xff00);
+  last = !(ccode & 0xff00);
   if (size & 0x7)
   if (size & 0x7)
-    abort ();
-  ptr[0] = code | (last ? 0x80 : 0);
+    fatal (_("Checksum failure"));
+
+  ptr[0] = ccode | (last ? 0x80 : 0);
   ptr[1] = bytes + 1;
 
   for (j = 0; j < bytes; j++)
   ptr[1] = bytes + 1;
 
   for (j = 0; j < bytes; j++)
@@ -176,12 +137,14 @@ checksum (FILE *file, unsigned char *ptr, int size, int code)
 
   /* Glue on a checksum too.  */
   ptr[bytes] = ~sum;
 
   /* Glue on a checksum too.  */
   ptr[bytes] = ~sum;
-  fwrite (ptr, bytes + 1, 1, file);
+  if (fwrite (ptr, bytes + 1, 1, ffile) != 1)
+    /* FIXME: Return error status.  */
+    fatal (_("Failed to write checksum"));
 }
 
 
 static void
 }
 
 
 static void
-writeINT (int n, unsigned char *ptr, int *idx, int size, FILE *file)
+writeINT (int n, unsigned char *ptr, int *idx, int size, FILE *ffile)
 {
   int byte = *idx / 8;
 
 {
   int byte = *idx / 8;
 
@@ -193,7 +156,7 @@ writeINT (int n, unsigned char *ptr, int *idx, int size, FILE *file)
   if (byte > 240)
     {
       /* Lets write out that record and do another one.  */
   if (byte > 240)
     {
       /* Lets write out that record and do another one.  */
-      checksum (file, ptr, *idx, code | 0x1000);
+      checksum (ffile, ptr, *idx, code | 0x1000);
       *idx = 16;
       byte = *idx / 8;
     }
       *idx = 16;
       byte = *idx / 8;
     }
@@ -216,7 +179,7 @@ writeINT (int n, unsigned char *ptr, int *idx, int size, FILE *file)
       ptr[byte + 3] = n >> 0;
       break;
     default:
       ptr[byte + 3] = n >> 0;
       break;
     default:
-      abort ();
+      fatal (_("Unsupported integer write size: %d"), size);
     }
   *idx += size * 8;
 }
     }
   *idx += size * 8;
 }
@@ -240,24 +203,24 @@ writeBITS (int val, unsigned char *ptr, int *idx, int size)
 
 static void
 writeBARRAY (barray data, unsigned char *ptr, int *idx,
 
 static void
 writeBARRAY (barray data, unsigned char *ptr, int *idx,
-            int size ATTRIBUTE_UNUSED, FILE *file)
+            int size ATTRIBUTE_UNUSED, FILE *ffile)
 {
   int i;
 
 {
   int i;
 
-  writeINT (data.len, ptr, idx, 1, file);
+  writeINT (data.len, ptr, idx, 1, ffile);
   for (i = 0; i < data.len; i++)
   for (i = 0; i < data.len; i++)
-    writeINT (data.data[i], ptr, idx, 1, file);
+    writeINT (data.data[i], ptr, idx, 1, ffile);
 }
 
 static void
 }
 
 static void
-writeCHARS (char *string, unsigned char *ptr, int *idx, int size, FILE *file)
+writeCHARS (char *string, unsigned char *ptr, int *idx, int size, FILE *ffile)
 {
   int i = *idx / 8;
 
   if (i > 240)
     {
       /* Lets write out that record and do another one.  */
 {
   int i = *idx / 8;
 
   if (i > 240)
     {
       /* Lets write out that record and do another one.  */
-      checksum (file, ptr, *idx, code | 0x1000);
+      checksum (ffile, ptr, *idx, code | 0x1000);
       *idx = 16;
       i = *idx / 8;
     }
       *idx = 16;
       i = *idx / 8;
     }
@@ -299,7 +262,10 @@ wr_tr (void)
       0x03,                    /* RL */
       0xfd,                    /* CS */
     };
       0x03,                    /* RL */
       0xfd,                    /* CS */
     };
-  fwrite (b, 1, sizeof (b), file);
+
+  if (fwrite (b, sizeof (b), 1, file) != 1)
+    /* FIXME: Return error status.  */
+    fatal (_("Failed to write TR block"));
 }
 
 static void
 }
 
 static void
@@ -390,7 +356,8 @@ wr_hd (struct coff_ofile *p)
          toolname = "C_H8/300S";
          break;
        default:
          toolname = "C_H8/300S";
          break;
        default:
-         abort();
+         fatal (_("Unrecognized H8300 sub-architecture: %ld"),
+                bfd_get_mach (abfd));
        }
       rnames = rname_h8300;
       break;
        }
       rnames = rname_h8300;
       break;
@@ -407,10 +374,10 @@ wr_hd (struct coff_ofile *p)
       rnames = rname_sh;
       break;
     default:
       rnames = rname_sh;
       break;
     default:
-      abort ();
+      fatal (_("Unsupported architecture: %d"), bfd_get_arch (abfd));
     }
 
     }
 
-  if (! bfd_get_file_flags(abfd) & EXEC_P)
+  if (! (bfd_get_file_flags(abfd) & EXEC_P))
     {
       hd.ep = 0;
     }
     {
       hd.ep = 0;
     }
@@ -452,14 +419,14 @@ wr_ob (struct coff_ofile *p ATTRIBUTE_UNUSED, struct coff_section *section)
   unsigned char stuff[200];
 
   i = 0;
   unsigned char stuff[200];
 
   i = 0;
-  while (i < bfd_get_section_size (section->bfd_section))
+  while (i < bfd_section_size (section->bfd_section))
     {
       struct IT_ob ob;
       int todo = 200;          /* Copy in 200 byte lumps.  */
 
       ob.spare = 0;
     {
       struct IT_ob ob;
       int todo = 200;          /* Copy in 200 byte lumps.  */
 
       ob.spare = 0;
-      if (i + todo > bfd_get_section_size (section->bfd_section))
-       todo = bfd_get_section_size (section->bfd_section) - i;
+      if (i + todo > bfd_section_size (section->bfd_section))
+       todo = bfd_section_size (section->bfd_section) - i;
 
       if (first)
        {
 
       if (first)
        {
@@ -704,6 +671,7 @@ walk_tree_type_1 (struct coff_sfile *sfile, struct coff_symbol *symbol,
       {
        struct IT_dpt dpt;
 
       {
        struct IT_dpt dpt;
 
+       dpt.dunno = 0;
        walk_tree_type_1 (sfile, symbol, type->u.pointer.points_to, nest + 1);
        dpt.neg = 0x1001;
        sysroff_swap_dpt_out (file, &dpt);
        walk_tree_type_1 (sfile, symbol, type->u.pointer.points_to, nest + 1);
        dpt.neg = 0x1001;
        sysroff_swap_dpt_out (file, &dpt);
@@ -860,7 +828,7 @@ walk_tree_type_1 (struct coff_sfile *sfile, struct coff_symbol *symbol,
       break;
 
     default:
       break;
 
     default:
-      abort ();
+      fatal (_("Unrecognised type: %d"), type->type);
     }
 }
 
     }
 }
 
@@ -906,13 +874,14 @@ static void
 walk_tree_type (struct coff_sfile *sfile, struct coff_symbol *symbol,
                struct coff_type *type, int nest)
 {
 walk_tree_type (struct coff_sfile *sfile, struct coff_symbol *symbol,
                struct coff_type *type, int nest)
 {
-  if (symbol->type->type == coff_function_type)
-    {
-      struct IT_dty dty;
+  struct IT_dty dty;
 
 
-      dty.end = 0;
-      dty.neg = 0x1001;
+  dty.spare = 0;
+  dty.end = 0;
+  dty.neg = 0x1001;
 
 
+  if (symbol->type->type == coff_function_type)
+    {
       sysroff_swap_dty_out (file, &dty);
       walk_tree_type_1 (sfile, symbol, type, nest);
       dty.end = 1;
       sysroff_swap_dty_out (file, &dty);
       walk_tree_type_1 (sfile, symbol, type, nest);
       dty.end = 1;
@@ -938,10 +907,6 @@ walk_tree_type (struct coff_sfile *sfile, struct coff_symbol *symbol,
     }
   else
     {
     }
   else
     {
-      struct IT_dty dty;
-
-      dty.end = 0;
-      dty.neg = 0x1001;
       sysroff_swap_dty_out (file, &dty);
       walk_tree_type_1 (sfile, symbol, type, nest);
       dty.end = 1;
       sysroff_swap_dty_out (file, &dty);
       walk_tree_type_1 (sfile, symbol, type, nest);
       dty.end = 1;
@@ -989,7 +954,7 @@ walk_tree_symbol (struct coff_sfile *sfile, struct coff_section *section ATTRIBU
       return;
 
     default:
       return;
 
     default:
-      abort ();
+      fatal (_("Unrecognised coff symbol type: %d"), symbol->type->type);
     }
 
   if (symbol->where->where == coff_where_member_of_struct)
     }
 
   if (symbol->where->where == coff_where_member_of_struct)
@@ -1051,7 +1016,7 @@ walk_tree_symbol (struct coff_sfile *sfile, struct coff_section *section ATTRIBU
       break;
 
     default:
       break;
 
     default:
-      abort ();
+      fatal (_("Unrecognised coff symbol visibility: %d"), symbol->visible->type);
     }
 
   dsy.dlength = symbol->type->size;
     }
 
   dsy.dlength = symbol->type->size;
@@ -1077,7 +1042,7 @@ walk_tree_symbol (struct coff_sfile *sfile, struct coff_section *section ATTRIBU
       break;
 
     default:
       break;
 
     default:
-      abort ();
+      fatal (_("Unrecognised coff symbol location: %d"), symbol->where->where);
     }
 
   switch (symbol->where->where)
     }
 
   switch (symbol->where->where)
@@ -1122,7 +1087,7 @@ walk_tree_symbol (struct coff_sfile *sfile, struct coff_section *section ATTRIBU
       break;
 
     default:
       break;
 
     default:
-      abort ();
+      fatal (_("Unrecognised coff symbol location: %d"), symbol->where->where);
     }
 
   if (symbol->where->where == coff_where_register)
     }
 
   if (symbol->where->where == coff_where_register)
@@ -1151,7 +1116,7 @@ walk_tree_symbol (struct coff_sfile *sfile, struct coff_section *section ATTRIBU
       break;
 
     default:
       break;
 
     default:
-      abort ();
+      fatal (_("Unrecognised coff symbol visibility: %d"), symbol->visible->type);
     }
 
   dsy.sfn = 0;
     }
 
   dsy.sfn = 0;
@@ -1196,6 +1161,8 @@ walk_tree_sfile (struct coff_section *section, struct coff_sfile *sfile)
 static void
 wr_program_structure (struct coff_ofile *p, struct coff_sfile *sfile)
 {
 static void
 wr_program_structure (struct coff_ofile *p, struct coff_sfile *sfile)
 {
+  if (p->nsections < 4)
+    return;
   walk_tree_sfile (p->sections + 4, sfile);
 }
 
   walk_tree_sfile (p->sections + 4, sfile);
 }
 
@@ -1451,7 +1418,10 @@ wr_cs (void)
     0x00,                      /* dot */
     0xDE                       /* CS */
   };
     0x00,                      /* dot */
     0xDE                       /* CS */
   };
-  fwrite (b, 1, sizeof (b), file);
+
+  if (fwrite (b, sizeof (b), 1, file) != 1)
+    /* FIXME: Return error status.  */
+    fatal (_("Failed to write CS struct"));
 }
 
 /* Write out the SC records for a unit.  Create an SC
 }
 
 /* Write out the SC records for a unit.  Create an SC
@@ -1568,6 +1538,7 @@ wr_sc (struct coff_ofile *ptr, struct coff_sfile *sfile)
       sysroff_swap_sc_out (file, &sc);
       scount++;
     }
       sysroff_swap_sc_out (file, &sc);
       scount++;
     }
+  free (info);
   return scount;
 }
 
   return scount;
 }
 
@@ -1688,15 +1659,18 @@ align (int x)
    ordinary defs - dunno why, but thats what hitachi does with 'em.  */
 
 static void
    ordinary defs - dunno why, but thats what hitachi does with 'em.  */
 
 static void
-prescan (struct coff_ofile *tree)
+prescan (struct coff_ofile *otree)
 {
   struct coff_symbol *s;
   struct coff_section *common_section;
 
 {
   struct coff_symbol *s;
   struct coff_section *common_section;
 
+  if (otree->nsections < 3)
+    return;
+
   /* Find the common section - always section 3.  */
   /* Find the common section - always section 3.  */
-  common_section = tree->sections + 3;
+  common_section = otree->sections + 3;
 
 
-  for (s = tree->symbol_list_head;
+  for (s = otree->symbol_list_head;
        s;
        s = s->next_in_ofile_list)
     {
        s;
        s = s->next_in_ofile_list)
     {
@@ -1715,12 +1689,12 @@ prescan (struct coff_ofile *tree)
 
 char *program_name;
 
 
 char *program_name;
 
-static void
-show_usage (FILE *file, int status)
+ATTRIBUTE_NORETURN static void
+show_usage (FILE *ffile, int status)
 {
 {
-  fprintf (file, _("Usage: %s [option(s)] in-file [out-file]\n"), program_name);
-  fprintf (file, _("Convert a COFF object file into a SYSROFF object file\n"));
-  fprintf (file, _(" The options are:\n\
+  fprintf (ffile, _("Usage: %s [option(s)] in-file [out-file]\n"), program_name);
+  fprintf (ffile, _("Convert a COFF object file into a SYSROFF object file\n"));
+  fprintf (ffile, _(" The options are:\n\
   -q --quick       (Obsolete - ignored)\n\
   -n --noprescan   Do not perform a scan to convert commons into defs\n\
   -d --debug       Display information about what is being done\n\
   -q --quick       (Obsolete - ignored)\n\
   -n --noprescan   Do not perform a scan to convert commons into defs\n\
   -d --debug       Display information about what is being done\n\
@@ -1728,8 +1702,8 @@ show_usage (FILE *file, int status)
   -h --help        Display this information\n\
   -v --version     Print the program's version number\n"));
 
   -h --help        Display this information\n\
   -v --version     Print the program's version number\n"));
 
-  if (status == 0)
-    fprintf (file, _("Report bugs to %s\n"), REPORT_BUGS_TO);
+  if (REPORT_BUGS_TO[0] && status == 0)
+    fprintf (ffile, _("Report bugs to %s\n"), REPORT_BUGS_TO);
   exit (status);
 }
 
   exit (status);
 }
 
@@ -1761,6 +1735,7 @@ main (int ac, char **av)
 
   program_name = av[0];
   xmalloc_set_program_name (program_name);
 
   program_name = av[0];
   xmalloc_set_program_name (program_name);
+  bfd_set_error_program_name (program_name);
 
   expandargv (&ac, &av);
 
 
   expandargv (&ac, &av);
 
@@ -1808,7 +1783,7 @@ main (int ac, char **av)
          ++optind;
          if (optind < ac)
            show_usage (stderr, 1);
          ++optind;
          if (optind < ac)
            show_usage (stderr, 1);
-         if (strcmp (input_file, output_file) == 0)
+         if (filename_cmp (input_file, output_file) == 0)
            {
              fatal (_("input and output files must be different"));
            }
            {
              fatal (_("input and output files must be different"));
            }
@@ -1872,10 +1847,12 @@ main (int ac, char **av)
     printf ("ids %d %d\n", base1, base2);
 
   tree = coff_grok (abfd);
     printf ("ids %d %d\n", base1, base2);
 
   tree = coff_grok (abfd);
+  if (tree)
+    {
+      if (!noprescan)
+       prescan (tree);
 
 
-  if (!noprescan)
-    prescan (tree);
-
-  wr_module (tree);
+      wr_module (tree);
+    }
   return 0;
 }
   return 0;
 }
This page took 0.033108 seconds and 4 git commands to generate.