Add --binary-architecture switch to objcopy to allow the output architecture
[binutils-gdb.git] / binutils / objcopy.c
index b8a49c8a34423aa309e0aa2b70f8e325b9997b9f..abcf6a3aad97af66a75fe8ee3d4d0b1a4decf5eb 100644 (file)
@@ -1,5 +1,5 @@
 /* objcopy.c -- copy object file from input to output, optionally massaging it.
 /* objcopy.c -- copy object file from input to output, optionally massaging it.
-   Copyright (C) 1991, 92, 93, 94, 95, 96, 97, 98, 99, 2000
+   Copyright (C) 1991, 92, 93, 94, 95, 96, 97, 98, 99, 2000, 2001
    Free Software Foundation, Inc.
 
    This file is part of GNU Binutils.
    Free Software Foundation, Inc.
 
    This file is part of GNU Binutils.
@@ -215,6 +215,8 @@ static boolean weaken = false;
 #define OPTION_STRIP_UNNEEDED (OPTION_SET_START + 1)
 #define OPTION_WEAKEN (OPTION_STRIP_UNNEEDED + 1)
 #define OPTION_REDEFINE_SYM (OPTION_WEAKEN + 1)
 #define OPTION_STRIP_UNNEEDED (OPTION_SET_START + 1)
 #define OPTION_WEAKEN (OPTION_STRIP_UNNEEDED + 1)
 #define OPTION_REDEFINE_SYM (OPTION_WEAKEN + 1)
+#define OPTION_SREC_LEN (OPTION_REDEFINE_SYM + 1)
+#define OPTION_SREC_FORCES3 (OPTION_SREC_LEN + 1)
 
 /* Options to handle if running as "strip".  */
 
 
 /* Options to handle if running as "strip".  */
 
@@ -250,6 +252,7 @@ static struct option copy_options[] =
   {"adjust-vma", required_argument, 0, OPTION_CHANGE_ADDRESSES},
   {"adjust-section-vma", required_argument, 0, OPTION_CHANGE_SECTION_ADDRESS},
   {"adjust-warnings", no_argument, 0, OPTION_CHANGE_WARNINGS},
   {"adjust-vma", required_argument, 0, OPTION_CHANGE_ADDRESSES},
   {"adjust-section-vma", required_argument, 0, OPTION_CHANGE_SECTION_ADDRESS},
   {"adjust-warnings", no_argument, 0, OPTION_CHANGE_WARNINGS},
+  {"binary-architecture", required_argument, 0, 'B'},
   {"byte", required_argument, 0, 'b'},
   {"change-addresses", required_argument, 0, OPTION_CHANGE_ADDRESSES},
   {"change-leading-char", no_argument, 0, OPTION_CHANGE_LEADING_CHAR},
   {"byte", required_argument, 0, 'b'},
   {"change-addresses", required_argument, 0, OPTION_CHANGE_ADDRESSES},
   {"change-leading-char", no_argument, 0, OPTION_CHANGE_LEADING_CHAR},
@@ -290,6 +293,8 @@ static struct option copy_options[] =
   {"weaken", no_argument, 0, OPTION_WEAKEN},
   {"weaken-symbol", required_argument, 0, 'W'},
   {"redefine-sym", required_argument, 0, OPTION_REDEFINE_SYM},
   {"weaken", no_argument, 0, OPTION_WEAKEN},
   {"weaken-symbol", required_argument, 0, 'W'},
   {"redefine-sym", required_argument, 0, OPTION_REDEFINE_SYM},
+  {"srec-len", required_argument, 0, OPTION_SREC_LEN},
+  {"srec-forceS3", no_argument, 0, OPTION_SREC_FORCES3},
   {0, no_argument, 0, 0}
 };
 
   {0, no_argument, 0, 0}
 };
 
@@ -301,6 +306,17 @@ extern char *program_name;
    -1 means if we should use argv[0] to decide. */
 extern int is_strip;
 
    -1 means if we should use argv[0] to decide. */
 extern int is_strip;
 
+/* The maximum length of an S record.  This variable is declared in srec.c
+   and can be modified by the --srec-len parameter.  */
+extern unsigned int Chunk;
+
+/* Restrict the generation of Srecords to type S3 only.
+   This variable is declare in bfd/srec.c and can be toggled
+   on by the --srec-forceS3 command line switch.  */
+extern boolean S3Forced;
+
+/* Defined in bfd/binary.c.  Used to set architecture of input binary files.  */
+extern enum bfd_architecture bfd_external_binary_architecture;
 
 static void
 copy_usage (stream, exit_status)
 
 static void
 copy_usage (stream, exit_status)
@@ -312,6 +328,7 @@ copy_usage (stream, exit_status)
   fprintf (stream, _("\
   -I --input-target <bfdname>      Assume input file is in format <bfdname>\n\
   -O --output-target <bfdname>     Create an output file in format <bfdname>\n\
   fprintf (stream, _("\
   -I --input-target <bfdname>      Assume input file is in format <bfdname>\n\
   -O --output-target <bfdname>     Create an output file in format <bfdname>\n\
+  -B --binary-architecture <arch>  Set arch of output file, when input is binary\n\
   -F --target <bfdname>            Set both input and output format to <bfdname>\n\
      --debugging                   Convert debugging information, if possible\n\
   -p --preserve-dates              Copy modified/access timestamps to the output\n\
   -F --target <bfdname>            Set both input and output format to <bfdname>\n\
      --debugging                   Convert debugging information, if possible\n\
   -p --preserve-dates              Copy modified/access timestamps to the output\n\
@@ -350,6 +367,8 @@ copy_usage (stream, exit_status)
      --change-leading-char         Force output format's leading character style\n\
      --remove-leading-char         Remove leading character from global symbols\n\
      --redefine-sym <old>=<new>    Redefine symbol name <old> to <new>\n\
      --change-leading-char         Force output format's leading character style\n\
      --remove-leading-char         Remove leading character from global symbols\n\
      --redefine-sym <old>=<new>    Redefine symbol name <old> to <new>\n\
+     --srec-len <number>           Restrict the length of generated Srecords\n\
+     --srec-forceS3                Restrict the type of generated Srecords to S3\n\
   -v --verbose                     List all object files modified\n\
   -V --version                     Display this program's version number\n\
   -h --help                        Display this output\n\
   -v --verbose                     List all object files modified\n\
   -V --version                     Display this program's version number\n\
   -h --help                        Display this output\n\
@@ -751,6 +770,13 @@ copy_object (ibfd, obfd)
   long symsize;
   PTR dhandle;
 
   long symsize;
   PTR dhandle;
 
+  if (ibfd->xvec->byteorder != obfd->xvec->byteorder
+      && ibfd->xvec->byteorder != BFD_ENDIAN_UNKNOWN
+      && obfd->xvec->byteorder != BFD_ENDIAN_UNKNOWN)
+    {
+      fatal (_("Unable to change endianness of input file(s)"));
+      return;
+    }
 
   if (!bfd_set_format (obfd, bfd_get_format (ibfd)))
     RETURN_NONFATAL (bfd_get_filename (obfd));
 
   if (!bfd_set_format (obfd, bfd_get_format (ibfd)))
     RETURN_NONFATAL (bfd_get_filename (obfd));
@@ -1668,7 +1694,7 @@ strip_main (argc, argv)
   struct section_list *p;
   char *output_file = NULL;
 
   struct section_list *p;
   char *output_file = NULL;
 
-  while ((c = getopt_long (argc, argv, "I:O:F:K:N:R:o:sSpgxXVv",
+  while ((c = getopt_long (argc, argv, "I:O:F:K:N:R:o:sSpdgxXVv",
                           strip_options, (int *) 0)) != EOF)
     {
       switch (c)
                           strip_options, (int *) 0)) != EOF)
     {
       switch (c)
@@ -1692,6 +1718,7 @@ strip_main (argc, argv)
          break;
        case 'S':
        case 'g':
          break;
        case 'S':
        case 'g':
+       case 'd':       /* Historic BSD alias for -g.  Used by early NetBSD.  */
          strip_symbols = STRIP_DEBUG;
          break;
        case OPTION_STRIP_UNNEEDED:
          strip_symbols = STRIP_DEBUG;
          break;
        case OPTION_STRIP_UNNEEDED:
@@ -1791,6 +1818,7 @@ copy_main (argc, argv)
      int argc;
      char *argv[];
 {
      int argc;
      char *argv[];
 {
+  char * binary_architecture = NULL;
   char *input_filename = NULL, *output_filename = NULL;
   char *input_target = NULL, *output_target = NULL;
   boolean show_version = false;
   char *input_filename = NULL, *output_filename = NULL;
   char *input_target = NULL, *output_target = NULL;
   boolean show_version = false;
@@ -1799,7 +1827,7 @@ copy_main (argc, argv)
   struct section_list *p;
   struct stat statbuf;
 
   struct section_list *p;
   struct stat statbuf;
 
-  while ((c = getopt_long (argc, argv, "b:i:I:j:K:N:s:O:d:F:L:R:SpgxXVvW:",
+  while ((c = getopt_long (argc, argv, "b:B:i:I:j:K:N:s:O:d:F:L:R:SpgxXVvW:",
                           copy_options, (int *) 0)) != EOF)
     {
       switch (c)
                           copy_options, (int *) 0)) != EOF)
     {
       switch (c)
@@ -1810,6 +1838,10 @@ copy_main (argc, argv)
            fatal (_("byte number must be non-negative"));
          break;
 
            fatal (_("byte number must be non-negative"));
          break;
 
+        case 'B':
+          binary_architecture = optarg;
+          break;
+
        case 'i':
          interleave = atoi (optarg);
          if (interleave < 1)
        case 'i':
          interleave = atoi (optarg);
          if (interleave < 1)
@@ -2128,6 +2160,14 @@ copy_main (argc, argv)
          set_start_set = true;
          break;
 
          set_start_set = true;
          break;
 
+        case OPTION_SREC_LEN:
+          Chunk = parse_vma (optarg, "--srec-len");
+          break;
+
+        case OPTION_SREC_FORCES3:
+         S3Forced = true;
+          break;
+
        case 0:
          break;                /* we've been given a long option */
 
        case 0:
          break;                /* we've been given a long option */
 
@@ -2159,12 +2199,30 @@ copy_main (argc, argv)
   if (output_target == (char *) NULL)
     output_target = input_target;
 
   if (output_target == (char *) NULL)
     output_target = input_target;
 
-  if (preserve_dates)
+  if (binary_architecture != (char *) NULL)
     {
     {
-      if (stat (input_filename, &statbuf) < 0)
-       fatal (_("Cannot stat: %s: %s"), input_filename, strerror (errno));
+      if (input_target && strcmp (input_target, "binary") == 0)
+        {
+          const bfd_arch_info_type * temp_arch_info;
+
+         temp_arch_info = bfd_scan_arch (binary_architecture);
+
+          if (temp_arch_info != NULL)
+            bfd_external_binary_architecture = temp_arch_info->arch;
+          else
+            fatal (_("architecture %s unknown"), binary_architecture);
+        }
+      else
+       {
+         non_fatal (_("Warning: input target 'binary' required for binary architecture parameter."));
+         non_fatal (_(" Argument %s ignored"), binary_architecture);
+       }
     }
 
     }
 
+  if (preserve_dates)
+    if (stat (input_filename, & statbuf) < 0)
+      fatal (_("Cannot stat: %s: %s"), input_filename, strerror (errno));
+
   /* If there is no destination file then create a temp and rename
      the result into the input.  */
 
   /* If there is no destination file then create a temp and rename
      the result into the input.  */