diff --git a/binutils/ChangeLog b/binutils/ChangeLog index 7d63df82dbb..84336258762 100644 --- a/binutils/ChangeLog +++ b/binutils/ChangeLog @@ -1,3 +1,15 @@ +2006-06-23 Richard Sandiford + + * objcopy.c (localize_hidden): New variable. + (OPTION_LOCALIZE_HIDDEN): New command_line_switch value. + (copy_options): Add --localize-hidden. + (copy_usage): Mention --localize-hidden. + (is_hidden_symbol): New function. + (filter_symbols): Handle localize_hidden. + (copy_object): Call filter_symbols if localize_hidden. + (copy_main): Handle OPTION_LOCALIZE_HIDDEN. + * doc/binutils.texi (--localize-hidden): Document new option. + 2006-06-23 Daniel Jacobowitz * Makefile.am (ar_DEPENDENCIES, ranlib_DEPENDENCIES) diff --git a/binutils/doc/binutils.texi b/binutils/doc/binutils.texi index f6a97430a51..0abcef5362e 100644 --- a/binutils/doc/binutils.texi +++ b/binutils/doc/binutils.texi @@ -952,6 +952,7 @@ objcopy [@option{-F} @var{bfdname}|@option{--target=}@var{bfdname}] [@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}] @@ -1124,6 +1125,11 @@ 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} Make symbol @var{symbolname} local to the file, so that it is not diff --git a/binutils/objcopy.c b/binutils/objcopy.c index 0e0cfaaccf5..06e500d4754 100644 --- a/binutils/objcopy.c +++ b/binutils/objcopy.c @@ -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 Do not strip symbol \n\ --keep-file-symbols Do not strip file symbol(s)\n\ + --localize-hidden Turn all ELF hidden symbols into locals\n\ -L --localize-symbol Force symbol to be marked as a local\n\ --globalize-symbol Force symbol to be marked as a global\n\ -G --keep-global-symbol Localize all symbols except \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; @@ -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 @@ -3064,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; diff --git a/binutils/testsuite/ChangeLog b/binutils/testsuite/ChangeLog index 0fabcdafc19..dac114f1685 100644 --- a/binutils/testsuite/ChangeLog +++ b/binutils/testsuite/ChangeLog @@ -1,3 +1,11 @@ +2006-06-23 Richard Sandiford + + * binutils-all/localize-hidden-1.s, + * binutils-all/localize-hidden-1.d, + * binutils-all/localize-hidden-2.s, + * binutils-all/localize-hidden-2.d: New tests. + * binutils-all/objcopy.exp: Run them. + 2006-06-06 Paul Brook * binutils-all/arm/objdump.exp: New file. diff --git a/binutils/testsuite/binutils-all/localize-hidden-1.d b/binutils/testsuite/binutils-all/localize-hidden-1.d new file mode 100644 index 00000000000..846df4b657d --- /dev/null +++ b/binutils/testsuite/binutils-all/localize-hidden-1.d @@ -0,0 +1,17 @@ +#PROG: objcopy +#readelf: --symbols +#objcopy: --localize-hidden +#name: --localize-hidden test 1 +#... +.*: 0+1200 +0 +NOTYPE +LOCAL +HIDDEN +ABS +Lhidden +.*: 0+1300 +0 +NOTYPE +LOCAL +INTERNAL +ABS +Linternal +.*: 0+1400 +0 +NOTYPE +LOCAL +PROTECTED +ABS +Lprotected +.*: 0+1100 +0 +NOTYPE +LOCAL +DEFAULT +ABS +Ldefault +.*: 0+2200 +0 +NOTYPE +LOCAL +HIDDEN +ABS +Ghidden +.*: 0+2300 +0 +NOTYPE +LOCAL +INTERNAL +ABS +Ginternal +.*: 0+3200 +0 +NOTYPE +LOCAL +HIDDEN +ABS +Whidden +.*: 0+3300 +0 +NOTYPE +LOCAL +INTERNAL +ABS +Winternal +.*: 0+2100 +0 +NOTYPE +GLOBAL +DEFAULT +ABS +Gdefault +.*: 0+2400 +0 +NOTYPE +GLOBAL +PROTECTED +ABS +Gprotected +.*: 0+3100 +0 +NOTYPE +WEAK +DEFAULT +ABS +Wdefault +.*: 0+3400 +0 +NOTYPE +WEAK +PROTECTED +ABS +Wprotected diff --git a/binutils/testsuite/binutils-all/localize-hidden-1.s b/binutils/testsuite/binutils-all/localize-hidden-1.s new file mode 100644 index 00000000000..bdaa69d0c08 --- /dev/null +++ b/binutils/testsuite/binutils-all/localize-hidden-1.s @@ -0,0 +1,36 @@ + .globl Gdefault + .globl Ghidden + .globl Ginternal + .globl Gprotected + + .weak Wdefault + .weak Whidden + .weak Winternal + .weak Wprotected + + .hidden Lhidden + .hidden Ghidden + .hidden Whidden + + .internal Linternal + .internal Ginternal + .internal Winternal + + .protected Lprotected + .protected Gprotected + .protected Wprotected + + .equ Ldefault, 0x1100 + .equ Lhidden, 0x1200 + .equ Linternal, 0x1300 + .equ Lprotected, 0x1400 + + .equ Gdefault, 0x2100 + .equ Ghidden, 0x2200 + .equ Ginternal, 0x2300 + .equ Gprotected, 0x2400 + + .equ Wdefault, 0x3100 + .equ Whidden, 0x3200 + .equ Winternal, 0x3300 + .equ Wprotected, 0x3400 diff --git a/binutils/testsuite/binutils-all/localize-hidden-2.d b/binutils/testsuite/binutils-all/localize-hidden-2.d new file mode 100644 index 00000000000..ed3807aefbc --- /dev/null +++ b/binutils/testsuite/binutils-all/localize-hidden-2.d @@ -0,0 +1,7 @@ +#PROG: objcopy +#nm: -n +#objcopy: --localize-hidden +#name: --localize-hidden test 2 +#... +0+100 A G +#pass diff --git a/binutils/testsuite/binutils-all/localize-hidden-2.s b/binutils/testsuite/binutils-all/localize-hidden-2.s new file mode 100644 index 00000000000..d428c3aa470 --- /dev/null +++ b/binutils/testsuite/binutils-all/localize-hidden-2.s @@ -0,0 +1,2 @@ + .globl G + .equ G,0x100 diff --git a/binutils/testsuite/binutils-all/objcopy.exp b/binutils/testsuite/binutils-all/objcopy.exp index 969249d96a9..679eea59889 100644 --- a/binutils/testsuite/binutils-all/objcopy.exp +++ b/binutils/testsuite/binutils-all/objcopy.exp @@ -728,3 +728,8 @@ if [is_elf_format] { run_dump_test "copy-2" run_dump_test "copy-3" + +if [is_elf_format] { + run_dump_test "localize-hidden-1" +} +run_dump_test "localize-hidden-2"