Hi, While trying to build git HEAD of radare2, I found us objcopy(1) doesn't have the --localize-hidden option.
As the option was proposed in https://sourceware.org/ml/binutils/2006-06/msg00204.html (in 2006), and commited in GPLv2 tree of binutils, I think the patch is suitable for us too. Diff to add the option below. Link to the backported commit: https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;a=commitdiff;h=d58c2e3acdba2aadf3a47d741236fa02d7bb04ff;hp=22a84b55803f2adae036b553f7ca347ba02744be Thanks. -- Sebastien Marie https://sourceware.org/ml/binutils/2006-06/msg00204.html from Richard Sandiford This patch adds a --localize-hidden option to objcopy. As its name suggests, it converts all global or weak STV_HIDDEN or STV_INTERNAL symbols into local symbols. It is equivalent to listing all such symbols using separate -L options. Index: objcopy.c =================================================================== RCS file: /cvs/src/gnu/usr.bin/binutils-2.17/binutils/objcopy.c,v retrieving revision 1.4 diff -u -p -r1.4 objcopy.c --- objcopy.c 15 Nov 2015 04:13:17 -0000 1.4 +++ objcopy.c 20 May 2018 08:06:13 -0000 @@ -190,6 +190,9 @@ static bfd_boolean remove_leading_char = /* 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_statu --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\ @@ -809,6 +815,24 @@ is_strip_section (bfd *abfd ATTRIBUTE_UN 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, as && (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; @@ -1532,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 @@ -3059,6 +3085,10 @@ copy_main (int argc, char *argv[]) case OPTION_KEEP_SYMBOLS: 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); Index: doc/binutils.texi =================================================================== RCS file: /cvs/src/gnu/usr.bin/binutils-2.17/binutils/doc/binutils.texi,v retrieving revision 1.1.1.1 diff -u -p -r1.1.1.1 binutils.texi --- doc/binutils.texi 24 Apr 2011 20:14:40 -0000 1.1.1.1 +++ doc/binutils.texi 20 May 2018 08:06:17 -0000 @@ -952,6 +952,7 @@ objcopy [@option{-F} @var{bfdname}|@opti [@option{-N} @var{symbolname}|@option{--strip-symbol=}@var{symbolname}] [@option{--strip-unneeded-symbol=}@var{symbolname}] [@option{-G} @var{symbolname}|@option{--keep-global-symbol=}@var{symbolname}] + [@option{--localize-hidden}] [@option{-L} @var{symbolname}|@option{--localize-symbol=}@var{symbolname}] [@option{--globalize-symbol=}@var{symbolname}] [@option{-W} @var{symbolname}|@option{--weaken-symbol=}@var{symbolname}] @@ -1123,6 +1124,11 @@ by a relocation. This option may be giv Keep only symbol @var{symbolname} global. Make all other symbols local to the file, so that they are not visible externally. This option may be given more than once. + +@item --localize-hidden +In an ELF object, mark all symbols that have hidden or internal visibility +as local. This option applies on top of symbol-specific localization options +such as @option{-L}. @item -L @var{symbolname} @itemx --localize-symbol=@var{symbolname}