From f9853190c8d90e9f7d43fae90478a0db291f9c03 Mon Sep 17 00:00:00 2001 From: Alan Modra Date: Mon, 10 Sep 2018 11:57:08 +0930 Subject: PR23611, objcopy is not removing executable relocatable sections BFD handles ELF relocation sections in an executable differently to relocation sections in a relocatable object. For a relocatable object, BFD carries the relocations as data associated with the section to which they apply; The relocation section doesn't appear as a separate section. For an executable, dynamic relocation sections do appear as separate sections. This means that objcopy needs to use different strategies when dealing with relocations. When --remove-relocations was added to objcopy with commit d3e5f6c8f1e, objcopy lost the ability to remove dynamic relocation sections such as .rela.plt from executables using the option "--remove-section=.rela.plt". This patch reinstates that functionality. I thought it best to keep --remove-relocations as is, rather than extending to handle dynamic relocations as per the patch in the PR, because executables linked with --emit-relocs may have both dynamic and non-dynamic relocations. In that case --remove-relocataions=* is useful to remove all the non-dynamic relocations. PR binutils/23611 * objcopy.c (handle_remove_section_option): Consider .rela and .rel sections for stripping directly as well as attached to the associated section they relocate. * doc/binutils.texi (remove-relocations): Specify that this option removes non-dynamic relocation sections. * testsuite/binutils-all/objcopy.exp (objcopy_remove_relocations_from_executable): New test. --- binutils/ChangeLog | 17 ++++++++++++--- binutils/doc/binutils.texi | 13 +++++++----- binutils/objcopy.c | 10 ++++----- binutils/testsuite/binutils-all/objcopy.exp | 33 +++++++++++++++++++++++++++++ 4 files changed, 59 insertions(+), 14 deletions(-) diff --git a/binutils/ChangeLog b/binutils/ChangeLog index c58d70e..d77b3ab 100644 --- a/binutils/ChangeLog +++ b/binutils/ChangeLog @@ -1,3 +1,14 @@ +2018-09-10 Alan Modra + + PR binutils/23611 + * objcopy.c (handle_remove_section_option): Consider .rela and + .rel sections for stripping directly as well as attached to the + associated section they relocate. + * doc/binutils.texi (remove-relocations): Specify that this + option removes non-dynamic relocation sections. + * testsuite/binutils-all/objcopy.exp + (objcopy_remove_relocations_from_executable): New test. + 2018-09-03 Nick Clifton * po/ja.po: Updated Japanese translation. @@ -234,8 +245,8 @@ 2018-08-08 Kevin Buettner - * dwarf.c (decode_location_expresion): Add case for - DW_OP_GNU_variable_value. + * dwarf.c (decode_location_expresion): Add case for + DW_OP_GNU_variable_value. 2018-08-06 Claudiu Zissulescu @@ -914,7 +925,7 @@ 2018-02-19 Matthias Klose * strings.c (long_options): Include-all-whitespace does not take - an extra agument. + an extra agument. 2018-02-13 Alan Modra diff --git a/binutils/doc/binutils.texi b/binutils/doc/binutils.texi index e40ccb0..76cbed0 100644 --- a/binutils/doc/binutils.texi +++ b/binutils/doc/binutils.texi @@ -1321,17 +1321,20 @@ will remove all sections matching the pattern '.text.*', but will not remove the section '.text.foo'. @item --remove-relocations=@var{sectionpattern} -Remove relocations from the output file for any section matching -@var{sectionpattern}. This option may be given more than once. Note -that using this option inappropriately may make the output file -unusable. Wildcard characters are accepted in @var{sectionpattern}. +Remove non-dynamic relocations from the output file for any section +matching @var{sectionpattern}. This option may be given more than +once. Note that using this option inappropriately may make the output +file unusable, and attempting to remove a dynamic relocation section +such as @samp{.rela.plt} from an executable or shared library with +@option{--remove-relocations=.plt} will not work. Wildcard characters +are accepted in @var{sectionpattern}. For example: @smallexample --remove-relocations=.text.* @end smallexample -will remove the relocations for all sections matching the patter +will remove the relocations for all sections matching the pattern '.text.*'. If the first character of @var{sectionpattern} is the exclamation diff --git a/binutils/objcopy.c b/binutils/objcopy.c index 6bd9339..f712ffe 100644 --- a/binutils/objcopy.c +++ b/binutils/objcopy.c @@ -3943,7 +3943,7 @@ discard_relocations (bfd *ibfd ATTRIBUTE_UNUSED, asection *isection) /* Wrapper for dealing with --remove-section (-R) command line arguments. A special case is detected here, if the user asks to remove a relocation section (one starting with ".rela." or ".rel.") then this removal must - be done using a different technique. */ + be done using a different technique in a relocatable object. */ static void handle_remove_section_option (const char *section_pattern) @@ -3952,11 +3952,9 @@ handle_remove_section_option (const char *section_pattern) handle_remove_relocations_option (section_pattern + 5); else if (strncmp (section_pattern, ".rel.", 5) == 0) handle_remove_relocations_option (section_pattern + 4); - else - { - find_section_list (section_pattern, TRUE, SECTION_CONTEXT_REMOVE); - sections_removed = TRUE; - } + + find_section_list (section_pattern, TRUE, SECTION_CONTEXT_REMOVE); + sections_removed = TRUE; } /* Copy relocations in input section ISECTION of IBFD to an output diff --git a/binutils/testsuite/binutils-all/objcopy.exp b/binutils/testsuite/binutils-all/objcopy.exp index d979648..61793d9 100644 --- a/binutils/testsuite/binutils-all/objcopy.exp +++ b/binutils/testsuite/binutils-all/objcopy.exp @@ -1223,3 +1223,36 @@ proc objcopy_test_without_global_symbol { } { setup_xfail aarch64*-*-* arm*-*-* objcopy_test_without_global_symbol + +# objcopy remove relocation from executable test + +proc objcopy_remove_relocations_from_executable { } { + global OBJCOPY + global srcdir + global subdir + global READELF + + set test "remove-section relocation sections" + + if { [target_compile $srcdir/$subdir/testprog.c tmpdir/pr23611 executable debug] != "" } { + untested $test + return + } + + if [is_remote host] { + set objfile [remote_download host tmpdir/pr23611] + } else { + set objfile tmpdir/pr23611 + } + set out tmpdir/pr23611.out + + set exec_output1 [binutils_run $OBJCOPY "-R .rela.plt -R .rela.dyn -R .rel.plt -R .rel.dyn $objfile $out"] + set exec_output2 [binutils_run $READELF "-S $out"] + if { [string match "*.rel.plt*" $exec_output2] || [string match "*.rela.plt*" $exec_output2] || [string match "*.rel.dyn*" $exec_output2] || [string match "*.rela.dyn*" $exec_output2] } { + fail $test + return + } + pass $test +} + +objcopy_remove_relocations_from_executable -- cgit v1.1