From 312aaa3cfecbfd9f73e3f8f41096e3ad8162e978 Mon Sep 17 00:00:00 2001 From: Nick Clifton Date: Tue, 24 Apr 2007 10:56:58 +0000 Subject: [PATCH] * objcopy.c (filter_symbols): Explicitly stripping a symbol used in relocations is an error. Retype 'keep' to bfd_boolean. * binutils-all/objcopy.exp: Add test for stripping a symbol used in a relocation. * binutils-all/needed-by-reloc.s: New file. --- binutils/ChangeLog | 7 ++++ binutils/objcopy.c | 37 ++++++++++++++----- binutils/testsuite/ChangeLog | 7 ++++ .../testsuite/binutils-all/needed-by-reloc.s | 7 ++++ binutils/testsuite/binutils-all/objcopy.exp | 21 ++++++++++- 5 files changed, 68 insertions(+), 11 deletions(-) create mode 100644 binutils/testsuite/binutils-all/needed-by-reloc.s diff --git a/binutils/ChangeLog b/binutils/ChangeLog index 4d75c01aa97..e186ac7696b 100644 --- a/binutils/ChangeLog +++ b/binutils/ChangeLog @@ -1,3 +1,10 @@ +2007-04-24 Nathan Froyd + Phil Edwards + + * objcopy.c (filter_symbols): Explicitly stripping a symbol + used in relocations is an error. + Retype 'keep' to bfd_boolean. + 2007-04-24 Alan Modra * Makefile.in: Regenerate. diff --git a/binutils/objcopy.c b/binutils/objcopy.c index 92ccbbe2e62..cd229386321 100644 --- a/binutils/objcopy.c +++ b/binutils/objcopy.c @@ -917,7 +917,8 @@ filter_symbols (bfd *abfd, bfd *obfd, asymbol **osyms, asymbol *sym = from[src_count]; flagword flags = sym->flags; char *name = (char *) bfd_asymbol_name (sym); - int keep; + bfd_boolean keep; + bfd_boolean used_in_reloc = FALSE; bfd_boolean undefined; bfd_boolean rem_leading_char; bfd_boolean add_leading_char; @@ -985,21 +986,24 @@ filter_symbols (bfd *abfd, bfd *obfd, asymbol **osyms, } if (strip_symbols == STRIP_ALL) - keep = 0; + keep = FALSE; else if ((flags & BSF_KEEP) != 0 /* Used in relocation. */ || ((flags & BSF_SECTION_SYM) != 0 && ((*bfd_get_section (sym)->symbol_ptr_ptr)->flags & BSF_KEEP) != 0)) - keep = 1; + { + keep = TRUE; + used_in_reloc = TRUE; + } else if (relocatable /* Relocatable file. */ && (flags & (BSF_GLOBAL | BSF_WEAK)) != 0) - keep = 1; + keep = TRUE; 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 library containing the $idata section may reference these symbols. */ - keep = 1; + keep = TRUE; else if ((flags & BSF_GLOBAL) != 0 /* Global symbol. */ || (flags & BSF_WEAK) != 0 || undefined @@ -1012,7 +1016,7 @@ filter_symbols (bfd *abfd, bfd *obfd, asymbol **osyms, else if (bfd_coff_get_comdat_section (abfd, bfd_get_section (sym))) /* COMDAT sections store special information in local symbols, so we cannot risk stripping any of them. */ - keep = 1; + keep = TRUE; else /* Local symbol. */ keep = (strip_symbols != STRIP_UNNEEDED && (discard_locals != LOCALS_ALL @@ -1020,17 +1024,30 @@ filter_symbols (bfd *abfd, bfd *obfd, asymbol **osyms, || ! bfd_is_local_label (abfd, sym)))); if (keep && is_specified_symbol (name, strip_specific_list)) - keep = 0; + { + /* There are multiple ways to set 'keep' above, but if it + was the relocatable symbol case, then that's an error. */ + if (used_in_reloc) + { + non_fatal (_("not stripping symbol `%s' because it is named in a relocation"), name); + status = 1; + } + else + keep = FALSE; + } + if (keep && !(flags & BSF_KEEP) && is_specified_symbol (name, strip_unneeded_list)) - keep = 0; + keep = FALSE; + if (!keep && ((keep_file_symbols && (flags & BSF_FILE)) || is_specified_symbol (name, keep_specific_list))) - keep = 1; + keep = TRUE; + if (keep && is_strip_section (abfd, bfd_get_section (sym))) - keep = 0; + keep = FALSE; if (keep) { diff --git a/binutils/testsuite/ChangeLog b/binutils/testsuite/ChangeLog index 7fb53d75254..7ec2ceae29b 100644 --- a/binutils/testsuite/ChangeLog +++ b/binutils/testsuite/ChangeLog @@ -1,3 +1,10 @@ +2007-04-24 Nathan Froyd + Phil Edwards + + * binutils-all/objcopy.exp: Add test for stripping a symbol + used in a relocation. + * binutils-all/needed-by-reloc.s: New file. + 2007-04-20 Nathan Froyd Phil Edwards Thomas de Lellis diff --git a/binutils/testsuite/binutils-all/needed-by-reloc.s b/binutils/testsuite/binutils-all/needed-by-reloc.s new file mode 100644 index 00000000000..8251e8c0f8a --- /dev/null +++ b/binutils/testsuite/binutils-all/needed-by-reloc.s @@ -0,0 +1,7 @@ + .globl foo + + .data + .4byte foo + .text +foo: + .long 1 diff --git a/binutils/testsuite/binutils-all/objcopy.exp b/binutils/testsuite/binutils-all/objcopy.exp index 510f6cedbe5..0493d86be94 100644 --- a/binutils/testsuite/binutils-all/objcopy.exp +++ b/binutils/testsuite/binutils-all/objcopy.exp @@ -1,5 +1,5 @@ # Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, -# 2004, 2006 +# 2004, 2006, 2007 # Free Software Foundation, Inc. # This program is free software; you can redistribute it and/or modify @@ -774,3 +774,22 @@ if [is_elf_format] { run_dump_test "strip-3" } run_dump_test "localize-hidden-2" + +if { [istarget "i*86-*"] || [istarget "x86_64-*-*"] } { + # Check to make sure we don't strip a symbol named in relocations. + set test "objcopy doesn't strip needed symbols" + + set srcfile $srcdir/$subdir/needed-by-reloc.s + + if {![binutils_assemble $srcfile tmpdir/bintest.o]} then { + unresolved $test + } else { + set got [binutils_run $OBJCOPY "$OBJCOPYFLAGS --strip-symbol=foo tmpdir/bintest.o ${copyfile}.o"] + + if [regexp "not stripping symbol `foo' because it is named in a relocation" $got] { + pass $test + } else { + fail $test + } + } +} -- 2.30.2