Index: binutils/objcopy.c =================================================================== RCS file: /cvs/src/src/binutils/objcopy.c,v retrieving revision 1.107 diff -u -p -r1.107 objcopy.c --- binutils/objcopy.c 12 Apr 2007 19:20:46 -0000 1.107 +++ binutils/objcopy.c 23 Apr 2007 16:09:35 -0000 @@ -910,6 +910,7 @@ filter_symbols (bfd *abfd, bfd *obfd, as flagword flags = sym->flags; char *name = (char *) bfd_asymbol_name (sym); int keep; + int used_in_reloc = 0; bfd_boolean undefined; bfd_boolean rem_leading_char; bfd_boolean add_leading_char; @@ -982,7 +983,10 @@ filter_symbols (bfd *abfd, bfd *obfd, as || ((flags & BSF_SECTION_SYM) != 0 && ((*bfd_get_section (sym)->symbol_ptr_ptr)->flags & BSF_KEEP) != 0)) - keep = 1; + { + keep = 1; + used_in_reloc = 1; + } else if (relocatable /* Relocatable file. */ && (flags & (BSF_GLOBAL | BSF_WEAK)) != 0) keep = 1; @@ -1012,7 +1016,18 @@ filter_symbols (bfd *abfd, bfd *obfd, as || ! 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; + keep = 1; + } + else + keep = 0; + } if (keep && !(flags & BSF_KEEP) && is_specified_symbol (name, strip_unneeded_list)) Index: binutils/testsuite/binutils-all/needed-reloc.s =================================================================== RCS file: binutils/testsuite/binutils-all/needed-reloc.s diff -N binutils/testsuite/binutils-all/needed-reloc.s --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ binutils/testsuite/binutils-all/needed-reloc.s 23 Apr 2007 16:09:35 -0000 @@ -0,0 +1,7 @@ + .globl foo + + .data + .4byte foo + .text +foo: + .long 1 Index: binutils/testsuite/binutils-all/objcopy.exp =================================================================== RCS file: /cvs/src/src/binutils/testsuite/binutils-all/objcopy.exp,v retrieving revision 1.41 diff -u -p -r1.41 objcopy.exp --- binutils/testsuite/binutils-all/objcopy.exp 12 Apr 2007 19:20:46 -0000 1.41 +++ binutils/testsuite/binutils-all/objcopy.exp 23 Apr 2007 16:09:35 -0000 @@ -723,6 +723,25 @@ if { ([istarget "ia64-*-elf*"] objcopy_test "ia64 link order" link-order.s } +if { [istarget "i*86-*"] } { + # 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-reloc.s + + if {![binutils_assemble $srcfile tmpdir/bintest.o]} then { + unresolved $test + } else { + set got [binutils_run $OBJCOPY "$OBJCOPYFLAGS -N 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 + } + } +} + # ELF specific tests if [is_elf_format] { objcopy_test "ELF unknown section type" unknown.s