*** empty log message ***
[deliverable/binutils-gdb.git] / binutils / objcopy.c
index 1d19fa8cebf74c2731b414ddb6e8dd7e8d78b10c..06e500d4754a7303ae788e03b4acd1b1d5c5c5ba 100644 (file)
@@ -147,8 +147,8 @@ static bfd_byte gap_fill = 0;
 static bfd_boolean pad_to_set = FALSE;
 static bfd_vma pad_to;
 
-/* Use alternate machine code?  */
-static int use_alt_mach_code = 0;
+/* Use alternative machine code?  */
+static unsigned long use_alt_mach_code = 0;
 
 /* Output BFD flags user wants to set or clear */
 static flagword bfd_flags_to_set;
@@ -190,6 +190,9 @@ static bfd_boolean remove_leading_char = FALSE;
 /* Whether to permit wildcard in symbol comparison.  */
 static bfd_boolean wildcard = FALSE;
 
+/* True if --localize-hidden is in effect.  */
+static bfd_boolean localize_hidden = FALSE;
+
 /* List of symbols to strip, keep, localize, keep-global, weaken,
    or redefine.  */
 static struct symlist *strip_specific_list = NULL;
@@ -240,6 +243,7 @@ enum command_line_switch
     OPTION_STRIP_UNNEEDED_SYMBOL,
     OPTION_STRIP_UNNEEDED_SYMBOLS,
     OPTION_KEEP_SYMBOLS,
+    OPTION_LOCALIZE_HIDDEN,
     OPTION_LOCALIZE_SYMBOLS,
     OPTION_GLOBALIZE_SYMBOL,
     OPTION_GLOBALIZE_SYMBOLS,
@@ -328,6 +332,7 @@ static struct option copy_options[] =
   {"keep-global-symbols", required_argument, 0, OPTION_KEEPGLOBAL_SYMBOLS},
   {"keep-symbol", required_argument, 0, 'K'},
   {"keep-symbols", required_argument, 0, OPTION_KEEP_SYMBOLS},
+  {"localize-hidden", no_argument, 0, OPTION_LOCALIZE_HIDDEN},
   {"localize-symbol", required_argument, 0, 'L'},
   {"localize-symbols", required_argument, 0, OPTION_LOCALIZE_SYMBOLS},
   {"no-adjust-warnings", no_argument, 0, OPTION_NO_CHANGE_WARNINGS},
@@ -428,6 +433,7 @@ copy_usage (FILE *stream, int exit_status)
      --only-keep-debug             Strip everything but the debug information\n\
   -K --keep-symbol <name>          Do not strip symbol <name>\n\
      --keep-file-symbols           Do not strip file symbol(s)\n\
+     --localize-hidden             Turn all ELF hidden symbols into locals\n\
   -L --localize-symbol <name>      Force symbol <name> to be marked as a local\n\
      --globalize-symbol <name>     Force symbol <name> to be marked as a global\n\
   -G --keep-global-symbol <name>   Localize all symbols except <name>\n\
@@ -473,7 +479,7 @@ copy_usage (FILE *stream, int exit_status)
      --globalize-symbols <file>    --globalize-symbol for all in <file>\n\
      --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\
+     --alt-machine-code <index>    Use the target's <index>'th alternative machine\n\
      --writable-text               Mark the output text as writable\n\
      --readonly-text               Make the output text write protected\n\
      --pure                        Mark the output file as demand paged\n\
@@ -809,6 +815,24 @@ is_strip_section (bfd *abfd ATTRIBUTE_UNUSED, asection *sec)
   return FALSE;
 }
 
+/* Return true if SYM is a hidden symbol.  */
+
+static bfd_boolean
+is_hidden_symbol (asymbol *sym)
+{
+  elf_symbol_type *elf_sym;
+
+  elf_sym = elf_symbol_from (sym->the_bfd, sym);
+  if (elf_sym != NULL)
+    switch (ELF_ST_VISIBILITY (elf_sym->internal_elf_sym.st_other))
+      {
+      case STV_HIDDEN:
+      case STV_INTERNAL:
+       return TRUE;
+      }
+  return FALSE;
+}
+
 /* Choose which symbol entries to copy; put the result in OSYMS.
    We don't copy in place, because that confuses the relocs.
    Return the number of symbols to print.  */
@@ -955,7 +979,8 @@ filter_symbols (bfd *abfd, bfd *obfd, asymbol **osyms,
              && (flags & (BSF_GLOBAL | BSF_WEAK))
              && (is_specified_symbol (name, localize_specific_list)
                  || (keepglobal_specific_list != NULL
-                     && ! is_specified_symbol (name, keepglobal_specific_list))))
+                     && ! is_specified_symbol (name, keepglobal_specific_list))
+                 || (localize_hidden && is_hidden_symbol (sym))))
            {
              sym->flags &= ~ (BSF_GLOBAL | BSF_WEAK);
              sym->flags |= BSF_LOCAL;
@@ -1313,13 +1338,23 @@ copy_object (bfd *ibfd, bfd *obfd)
          if (pset != NULL && pset->set_flags)
            flags = pset->flags | SEC_HAS_CONTENTS;
 
-         padd->section = bfd_make_section_with_flags (obfd, padd->name, flags);
-         if (padd->section == NULL)
+         /* bfd_make_section_with_flags() does not return very helpful
+            error codes, so check for the most likely user error first.  */
+         if (bfd_get_section_by_name (obfd, padd->name))
            {
-             non_fatal (_("can't create section `%s': %s"),
-                      padd->name, bfd_errmsg (bfd_get_error ()));
+             non_fatal (_("can't add section '%s' - it already exists!"), padd->name);
              return FALSE;
            }
+         else
+           {
+             padd->section = bfd_make_section_with_flags (obfd, padd->name, flags);
+             if (padd->section == NULL)
+               {
+                 non_fatal (_("can't create section `%s': %s"),
+                            padd->name, bfd_errmsg (bfd_get_error ()));
+                 return FALSE;
+               }
+           }
 
          if (! bfd_set_section_size (obfd, padd->section, padd->size))
            {
@@ -1522,6 +1557,7 @@ copy_object (bfd *ibfd, bfd *obfd)
       || strip_symbols == STRIP_UNNEEDED
       || strip_symbols == STRIP_NONDEBUG
       || discard_locals != LOCALS_UNDEF
+      || localize_hidden
       || strip_specific_list != NULL
       || keep_specific_list != NULL
       || localize_specific_list != NULL
@@ -1657,9 +1693,21 @@ copy_object (bfd *ibfd, bfd *obfd)
   /* Switch to the alternate machine code.  We have to do this at the
      very end, because we only initialize the header when we create
      the first section.  */
-  if (use_alt_mach_code != 0
-      && ! bfd_alt_mach_code (obfd, use_alt_mach_code))
-    non_fatal (_("unknown alternate machine code, ignored"));
+  if (use_alt_mach_code != 0)
+    {
+      if (! bfd_alt_mach_code (obfd, use_alt_mach_code))
+       {
+         non_fatal (_("this target does not support %lu alternative machine codes"),
+                    use_alt_mach_code);
+         if (bfd_get_flavour (obfd) == bfd_target_elf_flavour)
+           {
+             non_fatal (_("treating that number as an absolute e_machine value instead"));
+             elf_elfheader (obfd)->e_machine = use_alt_mach_code;
+           }
+         else
+           non_fatal (_("ignoring the alternative value"));
+       }
+    }
 
   return TRUE;
 }
@@ -3042,6 +3090,10 @@ copy_main (int argc, char *argv[])
          add_specific_symbols (optarg, &keep_specific_list);
          break;
 
+       case OPTION_LOCALIZE_HIDDEN:
+         localize_hidden = TRUE;
+         break;
+
        case OPTION_LOCALIZE_SYMBOLS:
          add_specific_symbols (optarg, &localize_specific_list);
          break;
@@ -3059,9 +3111,9 @@ copy_main (int argc, char *argv[])
          break;
 
        case OPTION_ALT_MACH_CODE:
-         use_alt_mach_code = atoi (optarg);
-         if (use_alt_mach_code <= 0)
-           fatal (_("alternate machine code index must be positive"));
+         use_alt_mach_code = strtoul (optarg, NULL, 0);
+         if (use_alt_mach_code == 0)
+           fatal (_("unable to parse alternative machine code"));
          break;
 
        case OPTION_PREFIX_SYMBOLS:
This page took 0.025075 seconds and 4 git commands to generate.