daily update
[binutils-gdb.git] / binutils / objcopy.c
index da197f3d8c28f2cb467ed879a4510315f2a08528..45072495c1ebf728b0503d05900e44395cd13655 100644 (file)
@@ -1,6 +1,6 @@
 /* objcopy.c -- copy object file from input to output, optionally massaging it.
    Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
-   2001, 2002
+   2001, 2002, 2003
    Free Software Foundation, Inc.
 
    This file is part of GNU Binutils.
@@ -60,33 +60,56 @@ section_rename;
 /* List of sections to be renamed.  */
 static section_rename * section_rename_list;
 
-static void copy_usage PARAMS ((FILE *, int));
-static void strip_usage PARAMS ((FILE *, int));
-static flagword parse_flags PARAMS ((const char *));
-static struct section_list *find_section_list PARAMS ((const char *, boolean));
-static void setup_section PARAMS ((bfd *, asection *, PTR));
-static void copy_section PARAMS ((bfd *, asection *, PTR));
-static void get_sections PARAMS ((bfd *, asection *, PTR));
-static int compare_section_lma PARAMS ((const PTR, const PTR));
-static void add_specific_symbol PARAMS ((const char *, struct symlist **));
-static void add_specific_symbols PARAMS ((const char *, struct symlist **));
-static boolean is_specified_symbol PARAMS ((const char *, struct symlist *));
-static boolean is_strip_section PARAMS ((bfd *, asection *));
+static void copy_usage
+  PARAMS ((FILE *, int));
+static void strip_usage
+  PARAMS ((FILE *, int));
+static flagword parse_flags
+  PARAMS ((const char *));
+static struct section_list *find_section_list
+  PARAMS ((const char *, bfd_boolean));
+static void setup_section
+  PARAMS ((bfd *, asection *, PTR));
+static void copy_section
+  PARAMS ((bfd *, asection *, PTR));
+static void get_sections
+  PARAMS ((bfd *, asection *, PTR));
+static int compare_section_lma
+  PARAMS ((const PTR, const PTR));
+static void add_specific_symbol
+  PARAMS ((const char *, struct symlist **));
+static void add_specific_symbols
+  PARAMS ((const char *, struct symlist **));
+static bfd_boolean is_specified_symbol
+  PARAMS ((const char *, struct symlist *));
+static bfd_boolean is_strip_section
+  PARAMS ((bfd *, asection *));
 static unsigned int filter_symbols
   PARAMS ((bfd *, bfd *, asymbol **, asymbol **, long));
-static void mark_symbols_used_in_relocations PARAMS ((bfd *, asection *, PTR));
-static void filter_bytes PARAMS ((char *, bfd_size_type *));
-static boolean write_debugging_info PARAMS ((bfd *, PTR, long *, asymbol ***));
-static void copy_object PARAMS ((bfd *, bfd *));
-static void copy_archive PARAMS ((bfd *, bfd *, const char *));
+static void mark_symbols_used_in_relocations
+  PARAMS ((bfd *, asection *, PTR));
+static void filter_bytes
+  PARAMS ((char *, bfd_size_type *));
+static bfd_boolean write_debugging_info
+  PARAMS ((bfd *, PTR, long *, asymbol ***));
+static void copy_object
+  PARAMS ((bfd *, bfd *));
+static void copy_archive
+  PARAMS ((bfd *, bfd *, const char *));
 static void copy_file
   PARAMS ((const char *, const char *, const char *, const char *));
-static int strip_main PARAMS ((int, char **));
-static int copy_main PARAMS ((int, char **));
-static const char *lookup_sym_redefinition PARAMS((const char *));
-static void redefine_list_append PARAMS ((const char *, const char *));
-static const char * find_section_rename PARAMS ((bfd *, sec_ptr, flagword *));
-static void add_section_rename PARAMS ((const char *, const char *, flagword));
+static int strip_main
+  PARAMS ((int, char **));
+static int copy_main
+  PARAMS ((int, char **));
+static const char *lookup_sym_redefinition
+  PARAMS((const char *));
+static void redefine_list_append
+  PARAMS ((const char *, const char *));
+static const char * find_section_rename
+  PARAMS ((bfd *, sec_ptr, flagword *));
+static void add_section_rename
+  PARAMS ((const char *, const char *, flagword));
 
 #define RETURN_NONFATAL(s) {bfd_nonfatal (s); status = 1; return;}
 
@@ -97,8 +120,8 @@ static asymbol **osympp = NULL;      /* Output symbols that survive stripping */
 static int copy_byte = -1;
 static int interleave = 4;
 
-static boolean verbose;                /* Print file and target names.  */
-static boolean preserve_dates; /* Preserve input file timestamp.  */
+static bfd_boolean verbose;            /* Print file and target names.  */
+static bfd_boolean preserve_dates;     /* Preserve input file timestamp.  */
 static int status = 0;         /* Exit status.  */
 
 enum strip_action
@@ -134,41 +157,41 @@ enum change_action
 /* Structure used to hold lists of sections and actions to take.  */
 struct section_list
 {
-  struct section_list * next;      /* Next section to change.  */
-  const char *          name;      /* Section name.  */
-  boolean               used;      /* Whether this entry was used.  */
-  boolean               remove;    /* Whether to remove this section.  */
-  boolean              copy;      /* Whether to copy this section.  */
-  enum change_action    change_vma;/* Whether to change or set VMA.  */
-  bfd_vma              vma_val;   /* Amount to change by or set to.  */
-  enum change_action    change_lma;/* Whether to change or set LMA.  */
-  bfd_vma              lma_val;   /* Amount to change by or set to.  */
-  boolean              set_flags; /* Whether to set the section flags.  */
-  flagword             flags;     /* What to set the section flags to.  */
+  struct section_list * next;     /* Next section to change.  */
+  const char *         name;      /* Section name.  */
+  bfd_boolean          used;      /* Whether this entry was used.  */
+  bfd_boolean          remove;    /* Whether to remove this section.  */
+  bfd_boolean          copy;      /* Whether to copy this section.  */
+  enum change_action   change_vma;/* Whether to change or set VMA.  */
+  bfd_vma              vma_val;   /* Amount to change by or set to.  */
+  enum change_action   change_lma;/* Whether to change or set LMA.  */
+  bfd_vma              lma_val;   /* Amount to change by or set to.  */
+  bfd_boolean          set_flags; /* Whether to set the section flags.  */
+  flagword             flags;     /* What to set the section flags to.  */
 };
 
 static struct section_list *change_sections;
 
-/* True if some sections are to be removed.  */
-static boolean sections_removed;
+/* TRUE if some sections are to be removed.  */
+static bfd_boolean sections_removed;
 
-/* True if only some sections are to be copied.  */
-static boolean sections_copied;
+/* TRUE if only some sections are to be copied.  */
+static bfd_boolean sections_copied;
 
 /* Changes to the start address.  */
 static bfd_vma change_start = 0;
-static boolean set_start_set = false;
+static bfd_boolean set_start_set = FALSE;
 static bfd_vma set_start;
 
 /* Changes to section addresses.  */
 static bfd_vma change_section_address = 0;
 
 /* Filling gaps between sections.  */
-static boolean gap_fill_set = false;
+static bfd_boolean gap_fill_set = FALSE;
 static bfd_byte gap_fill = 0;
 
 /* Pad to a given address.  */
-static boolean pad_to_set = false;
+static bfd_boolean pad_to_set = FALSE;
 static bfd_vma pad_to;
 
 /* Use alternate machine code?  */
@@ -195,13 +218,13 @@ struct section_add
 static struct section_add *add_sections;
 
 /* Whether to convert debugging information.  */
-static boolean convert_debugging = false;
+static bfd_boolean convert_debugging = FALSE;
 
 /* Whether to change the leading character in symbol names.  */
-static boolean change_leading_char = false;
+static bfd_boolean change_leading_char = FALSE;
 
 /* Whether to remove the leading character from global symbol names.  */
-static boolean remove_leading_char = false;
+static bfd_boolean remove_leading_char = FALSE;
 
 /* List of symbols to strip, keep, localize, keep-global, weaken,
    or redefine.  */
@@ -212,8 +235,13 @@ static struct symlist *keepglobal_specific_list = NULL;
 static struct symlist *weaken_specific_list = NULL;
 static struct redefine_node *redefine_sym_list = NULL;
 
-/* If this is true, we weaken global symbols (set BSF_WEAK).  */
-static boolean weaken = false;
+/* If this is TRUE, we weaken global symbols (set BSF_WEAK).  */
+static bfd_boolean weaken = FALSE;
+
+/* Prefix symbols/sections.  */
+static char *prefix_symbols_string = 0;
+static char *prefix_sections_string = 0;
+static char *prefix_alloc_sections_string = 0;
 
 /* 150 isn't special; it's just an arbitrary non-ASCII char value.  */
 
@@ -244,6 +272,10 @@ static boolean weaken = false;
 #define OPTION_WEAKEN_SYMBOLS (OPTION_KEEPGLOBAL_SYMBOLS + 1)
 #define OPTION_RENAME_SECTION (OPTION_WEAKEN_SYMBOLS + 1)
 #define OPTION_ALT_MACH_CODE (OPTION_RENAME_SECTION + 1)
+#define OPTION_PREFIX_SYMBOLS (OPTION_ALT_MACH_CODE + 1)
+#define OPTION_PREFIX_SECTIONS (OPTION_PREFIX_SYMBOLS + 1)
+#define OPTION_PREFIX_ALLOC_SECTIONS (OPTION_PREFIX_SECTIONS + 1)
+#define OPTION_FORMATS_INFO (OPTION_PREFIX_ALLOC_SECTIONS + 1)
 
 /* Options to handle if running as "strip".  */
 
@@ -253,6 +285,7 @@ static struct option strip_options[] =
   {"discard-locals", no_argument, 0, 'X'},
   {"format", required_argument, 0, 'F'}, /* Obsolete */
   {"help", no_argument, 0, 'h'},
+  {"info", no_argument, 0, OPTION_FORMATS_INFO},
   {"input-format", required_argument, 0, 'I'}, /* Obsolete */
   {"input-target", required_argument, 0, 'I'},
   {"keep-symbol", required_argument, 0, 'K'},
@@ -280,6 +313,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},
+  {"alt-machine-code", required_argument, 0, OPTION_ALT_MACH_CODE},
   {"binary-architecture", required_argument, 0, 'B'},
   {"byte", required_argument, 0, 'b'},
   {"change-addresses", required_argument, 0, OPTION_CHANGE_ADDRESSES},
@@ -292,45 +326,48 @@ static struct option copy_options[] =
   {"debugging", no_argument, 0, OPTION_DEBUGGING},
   {"discard-all", no_argument, 0, 'x'},
   {"discard-locals", no_argument, 0, 'X'},
-  {"only-section", required_argument, 0, 'j'},
   {"format", required_argument, 0, 'F'}, /* Obsolete */
   {"gap-fill", required_argument, 0, OPTION_GAP_FILL},
   {"help", no_argument, 0, 'h'},
+  {"info", no_argument, 0, OPTION_FORMATS_INFO},
   {"input-format", required_argument, 0, 'I'}, /* Obsolete */
   {"input-target", required_argument, 0, 'I'},
   {"interleave", required_argument, 0, 'i'},
+  {"keep-global-symbol", required_argument, 0, 'G'},
+  {"keep-global-symbols", required_argument, 0, OPTION_KEEPGLOBAL_SYMBOLS},
   {"keep-symbol", required_argument, 0, 'K'},
+  {"keep-symbols", required_argument, 0, OPTION_KEEP_SYMBOLS},
+  {"localize-symbol", required_argument, 0, 'L'},
+  {"localize-symbols", required_argument, 0, OPTION_LOCALIZE_SYMBOLS},
   {"no-adjust-warnings", no_argument, 0, OPTION_NO_CHANGE_WARNINGS},
   {"no-change-warnings", no_argument, 0, OPTION_NO_CHANGE_WARNINGS},
+  {"only-section", required_argument, 0, 'j'},
   {"output-format", required_argument, 0, 'O'},        /* Obsolete */
   {"output-target", required_argument, 0, 'O'},
   {"pad-to", required_argument, 0, OPTION_PAD_TO},
+  {"prefix-symbols", required_argument, 0, OPTION_PREFIX_SYMBOLS},
+  {"prefix-sections", required_argument, 0, OPTION_PREFIX_SECTIONS},
+  {"prefix-alloc-sections", required_argument, 0, OPTION_PREFIX_ALLOC_SECTIONS},
   {"preserve-dates", no_argument, 0, 'p'},
-  {"localize-symbol", required_argument, 0, 'L'},
-  {"keep-global-symbol", required_argument, 0, 'G'},
+  {"redefine-sym", required_argument, 0, OPTION_REDEFINE_SYM},
   {"remove-leading-char", no_argument, 0, OPTION_REMOVE_LEADING_CHAR},
   {"remove-section", required_argument, 0, 'R'},
   {"rename-section", required_argument, 0, OPTION_RENAME_SECTION},
   {"set-section-flags", required_argument, 0, OPTION_SET_SECTION_FLAGS},
   {"set-start", required_argument, 0, OPTION_SET_START},
+  {"srec-len", required_argument, 0, OPTION_SREC_LEN},
+  {"srec-forceS3", no_argument, 0, OPTION_SREC_FORCES3},
   {"strip-all", no_argument, 0, 'S'},
   {"strip-debug", no_argument, 0, 'g'},
   {"strip-unneeded", no_argument, 0, OPTION_STRIP_UNNEEDED},
   {"strip-symbol", required_argument, 0, 'N'},
+  {"strip-symbols", required_argument, 0, OPTION_STRIP_SYMBOLS},
   {"target", required_argument, 0, 'F'},
   {"verbose", no_argument, 0, 'v'},
   {"version", no_argument, 0, 'V'},
   {"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},
-  {"keep-symbols", required_argument, 0, OPTION_KEEP_SYMBOLS},
-  {"strip-symbols", required_argument, 0, OPTION_STRIP_SYMBOLS},
-  {"keep-global-symbols", required_argument, 0, OPTION_KEEPGLOBAL_SYMBOLS},
-  {"localize-symbols", required_argument, 0, OPTION_LOCALIZE_SYMBOLS},
   {"weaken-symbols", required_argument, 0, OPTION_WEAKEN_SYMBOLS},
-  {"alt-machine-code", required_argument, 0, OPTION_ALT_MACH_CODE},
   {0, no_argument, 0, 0}
 };
 
@@ -349,7 +386,7 @@ 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;
+extern bfd_boolean S3Forced;
 
 /* Defined in bfd/binary.c.  Used to set architecture of input binary files.  */
 extern enum bfd_architecture bfd_external_binary_architecture;
@@ -415,9 +452,15 @@ copy_usage (stream, exit_status)
      --keep-global-symbols <file>  -G for all symbols listed in <file>\n\
      --weaken-symbols <file>       -W for all symbols listed in <file>\n\
      --alt-machine-code <index>    Use alternate machine code for output\n\
+     --prefix-symbols <prefix>     Add <prefix> to start of every symbol name\n\
+     --prefix-sections <prefix>    Add <prefix> to start of every section name\n\
+     --prefix-alloc-sections <prefix>\n\
+                                   Add <prefix> to start of every allocatable\n\
+                                     section name\n\
   -v --verbose                     List all object files modified\n\
   -V --version                     Display this program's version number\n\
   -h --help                        Display this output\n\
+     --info                        List object formats & architectures supported\n\
 "));
   list_supported_targets (program_name, stream);
   if (exit_status == 0)
@@ -449,6 +492,7 @@ strip_usage (stream, exit_status)
   -v --verbose                     List all object files modified\n\
   -V --version                     Display this program's version number\n\
   -h --help                        Display this output\n\
+     --info                        List object formats & architectures supported\n\
   -o <file>                        Place stripped output into <file>\n\
 "));
 
@@ -520,7 +564,7 @@ parse_flags (s)
 static struct section_list *
 find_section_list (name, add)
      const char *name;
-     boolean add;
+     bfd_boolean add;
 {
   register struct section_list *p;
 
@@ -533,14 +577,14 @@ find_section_list (name, add)
 
   p = (struct section_list *) xmalloc (sizeof (struct section_list));
   p->name = name;
-  p->used = false;
-  p->remove = false;
-  p->copy = false;
+  p->used = FALSE;
+  p->remove = FALSE;
+  p->copy = FALSE;
   p->change_vma = CHANGE_IGNORE;
   p->change_lma = CHANGE_IGNORE;
   p->vma_val = 0;
   p->lma_val = 0;
-  p->set_flags = false;
+  p->set_flags = FALSE;
   p->flags = 0;
 
   p->next = change_sections;
@@ -604,7 +648,7 @@ add_specific_symbols (filename, list)
       char * eol;
       char * name;
       char * name_end;
-      int finished = false;
+      int finished = FALSE;
 
       for (eol = line;; eol ++)
        {
@@ -615,7 +659,7 @@ add_specific_symbols (filename, list)
              /* Cope with \n\r.  */
              if (eol[1] == '\r')
                ++ eol;
-             finished = true;
+             finished = TRUE;
              break;
 
            case '\r':
@@ -623,11 +667,11 @@ add_specific_symbols (filename, list)
              /* Cope with \r\n.  */
              if (eol[1] == '\n')
                ++ eol;
-             finished = true;
+             finished = TRUE;
              break;
 
            case 0:
-             finished = true;
+             finished = TRUE;
              break;
 
            case '#':
@@ -683,7 +727,7 @@ add_specific_symbols (filename, list)
 /* See whether a symbol should be stripped or kept based on
    strip_specific_list and keep_symbols.  */
 
-static boolean
+static bfd_boolean
 is_specified_symbol (name, list)
      const char *name;
      struct symlist *list;
@@ -692,14 +736,14 @@ is_specified_symbol (name, list)
 
   for (tmp_list = list; tmp_list; tmp_list = tmp_list->next)
     if (strcmp (name, tmp_list->name) == 0)
-      return true;
+      return TRUE;
 
-  return false;
+  return FALSE;
 }
 
 /* See if a section is being removed.  */
 
-static boolean
+static bfd_boolean
 is_strip_section (abfd, sec)
      bfd *abfd ATTRIBUTE_UNUSED;
      asection *sec;
@@ -712,17 +756,17 @@ is_strip_section (abfd, sec)
          || strip_symbols == STRIP_ALL
          || discard_locals == LOCALS_ALL
          || convert_debugging))
-    return true;
+    return TRUE;
 
   if (! sections_removed && ! sections_copied)
-    return false;
+    return FALSE;
 
-  p = find_section_list (bfd_get_section_name (abfd, sec), false);
+  p = find_section_list (bfd_get_section_name (abfd, sec), FALSE);
   if (sections_removed && p != NULL && p->remove)
-    return true;
+    return TRUE;
   if (sections_copied && (p == NULL || ! p->copy))
-    return true;
-  return false;
+    return TRUE;
+  return FALSE;
 }
 
 /* Choose which symbol entries to copy; put the result in OSYMS.
@@ -745,51 +789,73 @@ filter_symbols (abfd, obfd, osyms, isyms, symcount)
     {
       asymbol *sym = from[src_count];
       flagword flags = sym->flags;
-      const char *name = bfd_asymbol_name (sym);
+      char *name = (char *) bfd_asymbol_name (sym);
       int keep;
-      boolean undefined;
+      bfd_boolean undefined;
+      bfd_boolean rem_leading_char;
+      bfd_boolean add_leading_char;
+
+      undefined = bfd_is_und_section (bfd_get_section (sym));
 
       if (redefine_sym_list)
        {
-         const char *old_name, *new_name;
+         char *old_name, *new_name;
 
-         old_name = bfd_asymbol_name (sym);
-         new_name = lookup_sym_redefinition (old_name);
-         name = bfd_asymbol_name (sym) = new_name;
+         old_name = (char *) bfd_asymbol_name (sym);
+         new_name = (char *) lookup_sym_redefinition (old_name);
+         bfd_asymbol_name (sym) = new_name;
+         name = new_name;
        }
 
-      if (change_leading_char
-         && (bfd_get_symbol_leading_char (abfd)
-             != bfd_get_symbol_leading_char (obfd))
-         && (bfd_get_symbol_leading_char (abfd) == '\0'
-             || (name[0] == bfd_get_symbol_leading_char (abfd))))
-       {
-         if (bfd_get_symbol_leading_char (obfd) == '\0')
-           name = bfd_asymbol_name (sym) = name + 1;
-         else
-           {
-             char *n;
-
-             n = xmalloc (strlen (name) + 2);
-             n[0] = bfd_get_symbol_leading_char (obfd);
-             if (bfd_get_symbol_leading_char (abfd) == '\0')
-               strcpy (n + 1, name);
-             else
-               strcpy (n + 1, name + 1);
-             name = bfd_asymbol_name (sym) = n;
-           }
+      /* Check if we will remove the current leading character.  */
+      rem_leading_char =
+       (name[0] == bfd_get_symbol_leading_char (abfd))
+       && (change_leading_char
+           || (remove_leading_char
+               && ((flags & (BSF_GLOBAL | BSF_WEAK)) != 0
+                   || undefined
+                   || bfd_is_com_section (bfd_get_section (sym)))));
+
+      /* Check if we will add a new leading character.  */
+      add_leading_char =
+       change_leading_char
+       && (bfd_get_symbol_leading_char (obfd) != '\0')
+       && (bfd_get_symbol_leading_char (abfd) == '\0'
+           || (name[0] == bfd_get_symbol_leading_char (abfd)));
+
+      /* Short circuit for change_leading_char if we can do it in-place.  */
+      if (rem_leading_char && add_leading_char && !prefix_symbols_string)
+        {
+         name[0] = bfd_get_symbol_leading_char (obfd);
+         bfd_asymbol_name (sym) = name;
+         rem_leading_char = FALSE;
+         add_leading_char = FALSE;
+        }
+
+      /* Remove leading char.  */
+      if (rem_leading_char)
+       bfd_asymbol_name (sym) = ++name;
+
+      /* Add new leading char and/or prefix.  */
+      if (add_leading_char || prefix_symbols_string)
+        {
+          char *n, *ptr;
+
+          ptr = n = xmalloc (1 + strlen (prefix_symbols_string) + strlen (name) + 1);
+          if (add_leading_char)
+           *ptr++ = bfd_get_symbol_leading_char (obfd);
+
+          if (prefix_symbols_string)
+            {
+              strcpy (ptr, prefix_symbols_string);
+              ptr += strlen (prefix_symbols_string);
+           }
+
+          strcpy (ptr, name);
+          bfd_asymbol_name (sym) = n;
+          name = n;
        }
 
-      undefined = bfd_is_und_section (bfd_get_section (sym));
-
-      if (remove_leading_char
-         && ((flags & BSF_GLOBAL) != 0
-             || (flags & BSF_WEAK) != 0
-             || undefined
-             || bfd_is_com_section (bfd_get_section (sym)))
-         && name[0] == bfd_get_symbol_leading_char (abfd))
-       name = bfd_asymbol_name (sym) = name + 1;
-
       if (strip_symbols == STRIP_ALL)
        keep = 0;
       else if ((flags & BSF_KEEP) != 0         /* Used in relocation.  */
@@ -802,7 +868,7 @@ filter_symbols (abfd, obfd, osyms, isyms, symcount)
        keep = 1;
       else if (bfd_decode_symclass (sym) == 'I')
        /* Global symbols in $idata sections need to be retained
-          even if relocatable is false.  External users of the
+          even if relocatable is FALSE.  External users of the
           library containing the $idata section may reference these
           symbols.  */
        keep = 1;
@@ -937,6 +1003,8 @@ copy_object (ibfd, obfd)
   bfd_size_type max_gap = 0;
   long symsize;
   PTR dhandle;
+  enum bfd_architecture iarch;
+  unsigned int imach;
 
   if (ibfd->xvec->byteorder != obfd->xvec->byteorder
       && ibfd->xvec->byteorder != BFD_ENDIAN_UNKNOWN
@@ -972,8 +1040,11 @@ copy_object (ibfd, obfd)
     }
 
   /* Copy architecture of input file to output file.  */
-  if (!bfd_set_arch_mach (obfd, bfd_get_arch (ibfd),
-                         bfd_get_mach (ibfd)))
+  iarch = bfd_get_arch (ibfd);
+  imach = bfd_get_mach (ibfd);
+  if (!bfd_set_arch_mach (obfd, iarch, imach)
+      && (ibfd->target_defaulted
+         || bfd_get_arch (ibfd) != bfd_get_arch (obfd)))
     non_fatal (_("Warning: Output file cannot represent architecture %s"),
               bfd_printable_arch_mach (bfd_get_arch (ibfd),
                                        bfd_get_mach (ibfd)));
@@ -1013,9 +1084,9 @@ copy_object (ibfd, obfd)
              if (! bfd_set_section_size (obfd, padd->section, padd->size))
                RETURN_NONFATAL (bfd_get_filename (obfd));
 
-             pset = find_section_list (padd->name, false);
+             pset = find_section_list (padd->name, FALSE);
              if (pset != NULL)
-               pset->used = true;
+               pset->used = TRUE;
 
              if (pset != NULL && pset->set_flags)
                flags = pset->flags | SEC_HAS_CONTENTS;
@@ -1151,6 +1222,7 @@ copy_object (ibfd, obfd)
       || localize_specific_list != NULL
       || keepglobal_specific_list != NULL
       || weaken_specific_list != NULL
+      || prefix_symbols_string
       || sections_removed
       || sections_copied
       || convert_debugging
@@ -1357,7 +1429,7 @@ copy_archive (ibfd, obfd, output_target)
       if (output_bfd == (bfd *) NULL)
        RETURN_NONFATAL (output_name);
 
-      if (bfd_check_format (this_element, bfd_object) == true)
+      if (bfd_check_format (this_element, bfd_object))
        copy_object (this_element, output_bfd);
 
       if (!bfd_close (output_bfd))
@@ -1416,7 +1488,8 @@ copy_file (input_filename, output_filename, input_target, output_target)
      const char *output_target;
 {
   bfd *ibfd;
-  char **matching;
+  char **obj_matching;
+  char **core_matching;
 
   /* To allow us to do "strip *" without dying on the first
      non-object file, failures are nonfatal.  */
@@ -1439,11 +1512,10 @@ copy_file (input_filename, output_filename, input_target, output_target)
 
       copy_archive (ibfd, obfd, output_target);
     }
-  else if (bfd_check_format_matches (ibfd, bfd_object, &matching)
-          || bfd_check_format_matches (ibfd, bfd_core, &matching))
+  else if (bfd_check_format_matches (ibfd, bfd_object, &obj_matching))
     {
       bfd *obfd;
-
+    do_copy:
       /* bfd_get_target does not return the correct value until
          bfd_check_format succeeds.  */
       if (output_target == NULL)
@@ -1463,12 +1535,33 @@ copy_file (input_filename, output_filename, input_target, output_target)
     }
   else
     {
+      bfd_error_type obj_error = bfd_get_error ();
+      bfd_error_type core_error;
+
+      if (bfd_check_format_matches (ibfd, bfd_core, &core_matching))
+       {
+         /* This probably can't happen..  */
+         if (obj_error == bfd_error_file_ambiguously_recognized)
+           free (obj_matching);
+         goto do_copy;
+       }
+
+      core_error = bfd_get_error ();
+      /* Report the object error in preference to the core error.  */
+      if (obj_error != core_error)
+       bfd_set_error (obj_error);
+
       bfd_nonfatal (input_filename);
 
-      if (bfd_get_error () == bfd_error_file_ambiguously_recognized)
+      if (obj_error == bfd_error_file_ambiguously_recognized)
        {
-         list_matching_formats (matching);
-         free (matching);
+         list_matching_formats (obj_matching);
+         free (obj_matching);
+       }
+      if (core_error == bfd_error_file_ambiguously_recognized)
+       {
+         list_matching_formats (core_matching);
+         free (core_matching);
        }
 
       status = 1;
@@ -1553,6 +1646,7 @@ setup_section (ibfd, isection, obfdarg)
   flagword flags;
   const char *err;
   const char * name;
+  char *prefix = NULL;
 
   if ((bfd_get_section_flags (ibfd, isection) & SEC_DEBUGGING) != 0
       && (strip_symbols == STRIP_DEBUG
@@ -1562,9 +1656,9 @@ setup_section (ibfd, isection, obfdarg)
          || convert_debugging))
     return;
 
-  p = find_section_list (bfd_section_name (ibfd, isection), false);
+  p = find_section_list (bfd_section_name (ibfd, isection), FALSE);
   if (p != NULL)
-    p->used = true;
+    p->used = TRUE;
 
   if (sections_removed && p != NULL && p->remove)
     return;
@@ -1574,6 +1668,22 @@ setup_section (ibfd, isection, obfdarg)
   /* Get the, possibly new, name of the output section.  */
   name = find_section_rename (ibfd, isection, & flags);
 
+  /* Prefix sections.  */
+  if ((prefix_alloc_sections_string) && (bfd_get_section_flags (ibfd, isection) & SEC_ALLOC))
+    prefix = prefix_alloc_sections_string;
+  else if (prefix_sections_string)
+    prefix = prefix_sections_string;
+
+  if (prefix)
+    {
+      char *n;
+
+      n = xmalloc (strlen (prefix) + strlen (name) + 1);
+      strcpy (n, prefix);
+      strcat (n, name);
+      name = n;
+    }
+
   osection = bfd_make_section_anyway (obfd, name);
 
   if (osection == NULL)
@@ -1622,10 +1732,9 @@ setup_section (ibfd, isection, obfdarg)
 
   /* FIXME: This is probably not enough.  If we change the LMA we
      may have to recompute the header for the file as well.  */
-  if (bfd_set_section_alignment (obfd,
-                                osection,
-                                bfd_section_alignment (ibfd, isection))
-      == false)
+  if (!bfd_set_section_alignment (obfd,
+                                 osection,
+                                 bfd_section_alignment (ibfd, isection)))
     {
       err = _("alignment");
       goto loser;
@@ -1684,13 +1793,15 @@ copy_section (ibfd, isection, obfdarg)
   sec_ptr osection;
   bfd_size_type size;
   long relsize;
+  flagword flags;
 
   /* If we have already failed earlier on,
      do not keep on generating complaints now.  */
   if (status != 0)
     return;
 
-  if ((bfd_get_section_flags (ibfd, isection) & SEC_DEBUGGING) != 0
+  flags = bfd_get_section_flags (ibfd, isection);
+  if ((flags & SEC_DEBUGGING) != 0
       && (strip_symbols == STRIP_DEBUG
          || strip_symbols == STRIP_UNNEEDED
          || strip_symbols == STRIP_ALL
@@ -1698,7 +1809,10 @@ copy_section (ibfd, isection, obfdarg)
          || convert_debugging))
     return;
 
-  p = find_section_list (bfd_section_name (ibfd, isection), false);
+  if ((flags & SEC_GROUP) != 0)
+    return;
+
+  p = find_section_list (bfd_section_name (ibfd, isection), FALSE);
 
   if (sections_removed && p != NULL && p->remove)
     return;
@@ -1753,7 +1867,7 @@ copy_section (ibfd, isection, obfdarg)
     }
 
   isection->_cooked_size = isection->_raw_size;
-  isection->reloc_done = true;
+  isection->reloc_done = TRUE;
 
   if (bfd_get_section_flags (ibfd, isection) & SEC_HAS_CONTENTS
       && bfd_get_section_flags (obfd, osection) & SEC_HAS_CONTENTS)
@@ -1899,7 +2013,7 @@ mark_symbols_used_in_relocations (ibfd, isection, symbolsarg)
 
 /* Write out debugging information.  */
 
-static boolean
+static bfd_boolean
 write_debugging_info (obfd, dhandle, symcountp, symppp)
      bfd *obfd;
      PTR dhandle;
@@ -1919,7 +2033,7 @@ write_debugging_info (obfd, dhandle, symcountp, symppp)
       if (! write_stabs_in_sections_debugging_info (obfd, dhandle, &syms,
                                                    &symsize, &strings,
                                                    &stringsize))
-       return false;
+       return FALSE;
 
       stabsec = bfd_make_section (obfd, ".stab");
       stabstrsec = bfd_make_section (obfd, ".stabstr");
@@ -1941,7 +2055,7 @@ write_debugging_info (obfd, dhandle, symcountp, symppp)
          non_fatal (_("%s: can't create debugging section: %s"),
                     bfd_get_filename (obfd),
                     bfd_errmsg (bfd_get_error ()));
-         return false;
+         return FALSE;
        }
 
       /* We can get away with setting the section contents now because
@@ -1956,15 +2070,15 @@ write_debugging_info (obfd, dhandle, symcountp, symppp)
          non_fatal (_("%s: can't set debugging section contents: %s"),
                     bfd_get_filename (obfd),
                     bfd_errmsg (bfd_get_error ()));
-         return false;
+         return FALSE;
        }
 
-      return true;
+      return TRUE;
     }
 
   non_fatal (_("%s: don't know how to write debugging information for %s"),
             bfd_get_filename (obfd), bfd_get_target (obfd));
-  return false;
+  return FALSE;
 }
 
 static int
@@ -1972,9 +2086,12 @@ strip_main (argc, argv)
      int argc;
      char *argv[];
 {
-  char *input_target = NULL, *output_target = NULL;
-  boolean show_version = false;
-  int c, i;
+  char *input_target = NULL;
+  char *output_target = NULL;
+  bfd_boolean show_version = FALSE;
+  bfd_boolean formats_info = FALSE;
+  int c;
+  int i;
   struct section_list *p;
   char *output_file = NULL;
 
@@ -1993,9 +2110,9 @@ strip_main (argc, argv)
          input_target = output_target = optarg;
          break;
        case 'R':
-         p = find_section_list (optarg, true);
-         p->remove = true;
-         sections_removed = true;
+         p = find_section_list (optarg, TRUE);
+         p->remove = TRUE;
+         sections_removed = TRUE;
          break;
        case 's':
          strip_symbols = STRIP_ALL;
@@ -2018,7 +2135,7 @@ strip_main (argc, argv)
          output_file = optarg;
          break;
        case 'p':
-         preserve_dates = true;
+         preserve_dates = TRUE;
          break;
        case 'x':
          discard_locals = LOCALS_ALL;
@@ -2027,10 +2144,13 @@ strip_main (argc, argv)
          discard_locals = LOCALS_START_L;
          break;
        case 'v':
-         verbose = true;
+         verbose = TRUE;
          break;
        case 'V':
-         show_version = true;
+         show_version = TRUE;
+         break;
+       case OPTION_FORMATS_INFO:
+         formats_info = TRUE;
          break;
        case 0:
          /* We've been given a long option.  */
@@ -2043,6 +2163,12 @@ strip_main (argc, argv)
        }
     }
 
+ if (formats_info)
+   {
+     display_info ();
+     return 0;
+   }
   if (show_version)
     print_version ("strip");
 
@@ -2105,10 +2231,13 @@ copy_main (argc, argv)
      char *argv[];
 {
   char * binary_architecture = NULL;
-  char *input_filename = NULL, *output_filename = NULL;
-  char *input_target = NULL, *output_target = NULL;
-  boolean show_version = false;
-  boolean change_warn = true;
+  char *input_filename = NULL;
+  char *output_filename = NULL;
+  char *input_target = NULL;
+  char *output_target = NULL;
+  bfd_boolean show_version = FALSE;
+  bfd_boolean change_warn = TRUE;
+  bfd_boolean formats_info = FALSE;
   int c;
   struct section_list *p;
   struct stat statbuf;
@@ -2149,19 +2278,19 @@ copy_main (argc, argv)
          break;
 
        case 'j':
-         p = find_section_list (optarg, true);
+         p = find_section_list (optarg, TRUE);
          if (p->remove)
            fatal (_("%s both copied and removed"), optarg);
-         p->copy = true;
-         sections_copied = true;
+         p->copy = TRUE;
+         sections_copied = TRUE;
          break;
 
        case 'R':
-         p = find_section_list (optarg, true);
+         p = find_section_list (optarg, TRUE);
          if (p->copy)
            fatal (_("%s both copied and removed"), optarg);
-         p->remove = true;
-         sections_removed = true;
+         p->remove = TRUE;
+         sections_removed = TRUE;
          break;
 
        case 'S':
@@ -2197,7 +2326,7 @@ copy_main (argc, argv)
          break;
 
        case 'p':
-         preserve_dates = true;
+         preserve_dates = TRUE;
          break;
 
        case 'x':
@@ -2209,15 +2338,19 @@ copy_main (argc, argv)
          break;
 
        case 'v':
-         verbose = true;
+         verbose = TRUE;
          break;
 
        case 'V':
-         show_version = true;
+         show_version = TRUE;
+         break;
+
+       case OPTION_FORMATS_INFO:
+         formats_info = TRUE;
          break;
 
        case OPTION_WEAKEN:
-         weaken = true;
+         weaken = TRUE;
          break;
 
        case OPTION_ADD_SECTION:
@@ -2311,7 +2444,7 @@ copy_main (argc, argv)
            strncpy (name, optarg, len);
            name[len] = '\0';
 
-           p = find_section_list (name, true);
+           p = find_section_list (name, TRUE);
 
            val = parse_vma (s + 1, option);
 
@@ -2348,15 +2481,15 @@ copy_main (argc, argv)
          break;
 
        case OPTION_CHANGE_WARNINGS:
-         change_warn = true;
+         change_warn = TRUE;
          break;
 
        case OPTION_CHANGE_LEADING_CHAR:
-         change_leading_char = true;
+         change_leading_char = TRUE;
          break;
 
        case OPTION_DEBUGGING:
-         convert_debugging = true;
+         convert_debugging = TRUE;
          break;
 
        case OPTION_GAP_FILL:
@@ -2374,21 +2507,21 @@ copy_main (argc, argv)
                non_fatal (_("Warning: truncating gap-fill from 0x%s to 0x%x"),
                           buff, gap_fill);
              }
-           gap_fill_set = true;
+           gap_fill_set = TRUE;
          }
          break;
 
        case OPTION_NO_CHANGE_WARNINGS:
-         change_warn = false;
+         change_warn = FALSE;
          break;
 
        case OPTION_PAD_TO:
          pad_to = parse_vma (optarg, "--pad-to");
-         pad_to_set = true;
+         pad_to_set = TRUE;
          break;
 
        case OPTION_REMOVE_LEADING_CHAR:
-         remove_leading_char = true;
+         remove_leading_char = TRUE;
          break;
 
        case OPTION_REDEFINE_SYM:
@@ -2436,9 +2569,9 @@ copy_main (argc, argv)
            strncpy (name, optarg, len);
            name[len] = '\0';
 
-           p = find_section_list (name, true);
+           p = find_section_list (name, TRUE);
 
-           p->set_flags = true;
+           p->set_flags = TRUE;
            p->flags = parse_flags (s + 1);
          }
          break;
@@ -2489,7 +2622,7 @@ copy_main (argc, argv)
 
        case OPTION_SET_START:
          set_start = parse_vma (optarg, "--set-start");
-         set_start_set = true;
+         set_start_set = TRUE;
          break;
 
        case OPTION_SREC_LEN:
@@ -2497,7 +2630,7 @@ copy_main (argc, argv)
          break;
 
        case OPTION_SREC_FORCES3:
-         S3Forced = true;
+         S3Forced = TRUE;
          break;
 
        case OPTION_STRIP_SYMBOLS:
@@ -2526,6 +2659,18 @@ copy_main (argc, argv)
            fatal (_("alternate machine code index must be positive"));
          break;
 
+       case OPTION_PREFIX_SYMBOLS:
+         prefix_symbols_string = optarg;
+         break;
+
+       case OPTION_PREFIX_SECTIONS:
+         prefix_sections_string = optarg;
+         break;
+
+       case OPTION_PREFIX_ALLOC_SECTIONS:
+         prefix_alloc_sections_string = optarg;
+         break;
+
        case 0:
          break;                /* we've been given a long option */
 
@@ -2538,6 +2683,12 @@ copy_main (argc, argv)
        }
     }
 
+  if (formats_info)
+    {
+      display_info ();
+      return 0;
+    }
   if (show_version)
     print_version ("objcopy");
 
@@ -2584,7 +2735,6 @@ copy_main (argc, argv)
 
   /* If there is no destination file then create a temp and rename
      the result into the input.  */
-
   if (output_filename == (char *) NULL)
     {
       char *tmpname = make_tempname (input_filename);