diff --git a/gold/object.cc b/gold/object.cc index a631c99..022aa97 100644 --- a/gold/object.cc +++ b/gold/object.cc @@ -1616,7 +1616,8 @@ Sized_relobj_file::do_layout(Symbol_table* symtab, if (is_pass_one && parameters->options().gc_sections()) { if (this->is_section_name_included(name) - || layout->keep_input_section (this, name) + || (layout->keep_input_section (this, name) + && !is_prefix_of(".eh_frame", name)) || shdr.get_sh_type() == elfcpp::SHT_INIT_ARRAY || shdr.get_sh_type() == elfcpp::SHT_FINI_ARRAY) { diff --git a/gold/testsuite/Makefile.am b/gold/testsuite/Makefile.am index 2a7228b..456bef0 100644 --- a/gold/testsuite/Makefile.am +++ b/gold/testsuite/Makefile.am @@ -240,6 +240,16 @@ gc_dynamic_list_test: gc_dynamic_list_test.o gcctestdir/ld $(srcdir)/gc_dynamic_ gc_dynamic_list_test.stdout: gc_dynamic_list_test $(TEST_NM) gc_dynamic_list_test > $@ +check_SCRIPTS += gc_keep_eh_frame.sh +check_DATA += gc_keep_eh_frame.stdout +MOSTLYCLEANFILES += gc_keep_eh_frame +gc_keep_eh_frame.o: gc_keep_eh_frame.cc + $(CXXCOMPILE) -O0 -c -ffunction-sections -g -o $@ $< +gc_keep_eh_frame: gc_keep_eh_frame.o gcctestdir/ld $(srcdir)/gc_keep_eh_frame.t + $(CXXLINK) -Bgcctestdir/ -Wl,--gc-sections -Wl,-T,$(srcdir)/gc_keep_eh_frame.t $< +gc_keep_eh_frame.stdout: gc_keep_eh_frame + $(TEST_NM) -C $< > $@ + check_SCRIPTS += icf_test.sh check_DATA += icf_test.map MOSTLYCLEANFILES += icf_test icf_test.map diff --git a/gold/testsuite/Makefile.in b/gold/testsuite/Makefile.in index a07fd22..c7034e1 100644 --- a/gold/testsuite/Makefile.in +++ b/gold/testsuite/Makefile.in @@ -78,7 +78,7 @@ check_PROGRAMS = $(am__EXEEXT_1) $(am__EXEEXT_2) $(am__EXEEXT_3) \ @GCC_TRUE@@NATIVE_LINKER_TRUE@ gc_orphan_section_test.sh \ @GCC_TRUE@@NATIVE_LINKER_TRUE@ pr14265.sh pr20717.sh \ @GCC_TRUE@@NATIVE_LINKER_TRUE@ gc_dynamic_list_test.sh \ -@GCC_TRUE@@NATIVE_LINKER_TRUE@ icf_test.sh \ +@GCC_TRUE@@NATIVE_LINKER_TRUE@ gc_keep_eh_frame.sh icf_test.sh \ @GCC_TRUE@@NATIVE_LINKER_TRUE@ icf_keep_unique_test.sh \ @GCC_TRUE@@NATIVE_LINKER_TRUE@ icf_safe_test.sh \ @GCC_TRUE@@NATIVE_LINKER_TRUE@ icf_safe_so_test.sh \ @@ -97,6 +97,7 @@ check_PROGRAMS = $(am__EXEEXT_1) $(am__EXEEXT_2) $(am__EXEEXT_3) \ @GCC_TRUE@@NATIVE_LINKER_TRUE@ gc_orphan_section_test.stdout \ @GCC_TRUE@@NATIVE_LINKER_TRUE@ pr14265.stdout pr20717.stdout \ @GCC_TRUE@@NATIVE_LINKER_TRUE@ gc_dynamic_list_test.stdout \ +@GCC_TRUE@@NATIVE_LINKER_TRUE@ gc_keep_eh_frame.stdout \ @GCC_TRUE@@NATIVE_LINKER_TRUE@ icf_test.map \ @GCC_TRUE@@NATIVE_LINKER_TRUE@ icf_keep_unique_test.stdout \ @GCC_TRUE@@NATIVE_LINKER_TRUE@ icf_safe_test_1.stdout \ @@ -121,7 +122,8 @@ check_PROGRAMS = $(am__EXEEXT_1) $(am__EXEEXT_2) $(am__EXEEXT_3) \ @GCC_TRUE@@NATIVE_LINKER_TRUE@ gc_comdat_test gc_tls_test \ @GCC_TRUE@@NATIVE_LINKER_TRUE@ gc_orphan_section_test pr14265 \ @GCC_TRUE@@NATIVE_LINKER_TRUE@ pr20717 gc_dynamic_list_test \ -@GCC_TRUE@@NATIVE_LINKER_TRUE@ icf_test icf_test.map \ +@GCC_TRUE@@NATIVE_LINKER_TRUE@ gc_keep_eh_frame icf_test \ +@GCC_TRUE@@NATIVE_LINKER_TRUE@ icf_test.map \ @GCC_TRUE@@NATIVE_LINKER_TRUE@ icf_keep_unique_test \ @GCC_TRUE@@NATIVE_LINKER_TRUE@ icf_safe_test icf_safe_test.map \ @GCC_TRUE@@NATIVE_LINKER_TRUE@ icf_safe_so_test \ @@ -4993,6 +4995,8 @@ pr20717.sh.log: pr20717.sh @p='pr20717.sh'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post) gc_dynamic_list_test.sh.log: gc_dynamic_list_test.sh @p='gc_dynamic_list_test.sh'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post) +gc_keep_eh_frame.sh.log: gc_keep_eh_frame.sh + @p='gc_keep_eh_frame.sh'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post) icf_test.sh.log: icf_test.sh @p='icf_test.sh'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post) icf_keep_unique_test.sh.log: icf_keep_unique_test.sh @@ -5768,6 +5772,12 @@ uninstall-am: @GCC_TRUE@@NATIVE_LINKER_TRUE@ $(LINK) -Bgcctestdir/ -Wl,--gc-sections -Wl,--dynamic-list,$(srcdir)/gc_dynamic_list_test.t gc_dynamic_list_test.o @GCC_TRUE@@NATIVE_LINKER_TRUE@gc_dynamic_list_test.stdout: gc_dynamic_list_test @GCC_TRUE@@NATIVE_LINKER_TRUE@ $(TEST_NM) gc_dynamic_list_test > $@ +@GCC_TRUE@@NATIVE_LINKER_TRUE@gc_keep_eh_frame.o: gc_keep_eh_frame.cc +@GCC_TRUE@@NATIVE_LINKER_TRUE@ $(CXXCOMPILE) -O0 -c -ffunction-sections -g -o $@ $< +@GCC_TRUE@@NATIVE_LINKER_TRUE@gc_keep_eh_frame: gc_keep_eh_frame.o gcctestdir/ld $(srcdir)/gc_keep_eh_frame.t +@GCC_TRUE@@NATIVE_LINKER_TRUE@ $(CXXLINK) -Bgcctestdir/ -Wl,--gc-sections -Wl,-T,$(srcdir)/gc_keep_eh_frame.t $< +@GCC_TRUE@@NATIVE_LINKER_TRUE@gc_keep_eh_frame.stdout: gc_keep_eh_frame +@GCC_TRUE@@NATIVE_LINKER_TRUE@ $(TEST_NM) -C $< > $@ @GCC_TRUE@@NATIVE_LINKER_TRUE@icf_test.o: icf_test.cc @GCC_TRUE@@NATIVE_LINKER_TRUE@ $(CXXCOMPILE) -O0 -c -ffunction-sections -g -o $@ $< @GCC_TRUE@@NATIVE_LINKER_TRUE@icf_test: icf_test.o gcctestdir/ld diff --git a/gold/testsuite/gc_keep_eh_frame.cc b/gold/testsuite/gc_keep_eh_frame.cc new file mode 100644 index 0000000..18786f2 --- /dev/null +++ b/gold/testsuite/gc_keep_eh_frame.cc @@ -0,0 +1,3 @@ +void unused() {} + +int main() {return 0;} diff --git a/gold/testsuite/gc_keep_eh_frame.sh b/gold/testsuite/gc_keep_eh_frame.sh new file mode 100755 index 0000000..59d5565 --- /dev/null +++ b/gold/testsuite/gc_keep_eh_frame.sh @@ -0,0 +1,44 @@ +#!/bin/sh + +# gc_keep_eh_frame.sh -- test --gc-sections with KEEP(*(.eh_frame)). + +# Copyright (C) 2016 Free Software Foundation, Inc. +# Written by Igor Kudrin . + +# This file is part of gold. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, +# MA 02110-1301, USA. + +# The goal of this test is to check that function "unused()" is +# discarded even though it is referenced from section ".eh_frame" +# which is marked to be KEPT in the linker script. + +check() +{ + file=$1 + pattern=$2 + if grep -q "$pattern" "$file" + then + echo "Garbage collection failed to collect :" + echo " $pattern" + echo "" + echo "Actual output below:" + cat "$file" + exit 1 + fi +} + +check gc_keep_eh_frame.stdout "unused()" diff --git a/gold/testsuite/gc_keep_eh_frame.t b/gold/testsuite/gc_keep_eh_frame.t new file mode 100644 index 0000000..0b5109a --- /dev/null +++ b/gold/testsuite/gc_keep_eh_frame.t @@ -0,0 +1,26 @@ +/* gc_keep_eh_frame.t -- test --gc-sections with KEEP(*(.eh_frame)). + + Copyright (C) 2016 Free Software Foundation, Inc. + Written by Igor Kudrin . + + This file is part of gold. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, + MA 02110-1301, USA. */ + +SECTIONS +{ + .eh_frame : { KEEP(*(.eh_frame)) } +}