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.
-   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.
@@ -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_SREC_LEN (OPTION_REDEFINE_SYM + 1)
+#define OPTION_SREC_FORCES3 (OPTION_SREC_LEN + 1)
 
 /* 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},
+  {"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},
@@ -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},
+  {"srec-len", required_argument, 0, OPTION_SREC_LEN},
+  {"srec-forceS3", no_argument, 0, OPTION_SREC_FORCES3},
   {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;
 
+/* 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)
@@ -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\
+  -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\
@@ -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\
+     --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\
@@ -751,6 +770,13 @@ copy_object (ibfd, obfd)
   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));
@@ -1668,7 +1694,7 @@ strip_main (argc, argv)
   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)
@@ -1692,6 +1718,7 @@ strip_main (argc, argv)
          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:
@@ -1791,6 +1818,7 @@ copy_main (argc, 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;
@@ -1799,7 +1827,7 @@ copy_main (argc, argv)
   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)
@@ -1810,6 +1838,10 @@ copy_main (argc, argv)
            fatal (_("byte number must be non-negative"));
          break;
 
+        case 'B':
+          binary_architecture = optarg;
+          break;
+
        case 'i':
          interleave = atoi (optarg);
          if (interleave < 1)
@@ -2128,6 +2160,14 @@ copy_main (argc, argv)
          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 */
 
@@ -2159,12 +2199,30 @@ copy_main (argc, argv)
   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.  */