Handle symbolic link when copying source file
[deliverable/binutils-gdb.git] / binutils / srconv.c
index ef1b8c7c80a95ed982c0dc4510e2451c0e96266b..7abbb66c55c66c6d70546854fc3c0eabd9ba5a3e 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, 2007 Free Software Foundation, Inc.
+   Copyright (C) 1994-2015 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"
@@ -45,7 +46,7 @@ static char **rnames;
 static int get_member_id (int);
 static int get_ordinary_id (int);
 static char *section_translate (char *);
 static int get_member_id (int);
 static int get_ordinary_id (int);
 static char *section_translate (char *);
-static char *strip_suffix (char *);
+static char *strip_suffix (const 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 checksum (FILE *, unsigned char *, int, int);
 static void writeINT (int, unsigned char *, int *, int, FILE *);
 static void writeBITS (int, unsigned char *, int *, int);
@@ -141,9 +142,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 +158,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 +177,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 +196,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 +219,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 +243,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 +302,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 +396,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 +414,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;
     }
@@ -704,6 +711,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 +868,7 @@ walk_tree_type_1 (struct coff_sfile *sfile, struct coff_symbol *symbol,
       break;
 
     default:
       break;
 
     default:
-      abort ();
+      fatal (_("Unrecognised type: %d"), type->type);
     }
 }
 
     }
 }
 
@@ -989,7 +997,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 +1059,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 +1085,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 +1130,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 +1159,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 +1204,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 +1461,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 +1581,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 +1702,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)
     {
@@ -1716,11 +1733,11 @@ prescan (struct coff_ofile *tree)
 char *program_name;
 
 static void
 char *program_name;
 
 static void
-show_usage (FILE *file, int status)
+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\
@@ -1729,7 +1746,7 @@ show_usage (FILE *file, int status)
   -v --version     Print the program's version number\n"));
 
   if (REPORT_BUGS_TO[0] && status == 0)
   -v --version     Print the program's version number\n"));
 
   if (REPORT_BUGS_TO[0] && status == 0)
-    fprintf (file, _("Report bugs to %s\n"), REPORT_BUGS_TO);
+    fprintf (ffile, _("Report bugs to %s\n"), REPORT_BUGS_TO);
   exit (status);
 }
 
   exit (status);
 }
 
@@ -1761,6 +1778,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 +1826,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 +1890,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.027918 seconds and 4 git commands to generate.