From b733bcb7f58c42e0e0d94a3f266a4193030e5f3a Mon Sep 17 00:00:00 2001 From: Cary Coutant Date: Tue, 27 Dec 2016 20:50:47 -0800 Subject: Place copy relocations in .dynbss when target is read-only. gold/ PR ld/20995 * copy-relocs.cc (Copy_relocs::make_copy_reloc): Use .dynbss for read-only data when linking with -z relro. * copy-relocs.h (Copy_relocs::dynrelro_): New data member. * testsuite/Makefile.am (copy_test_relro): New test case. * testsuite/Makefile.in: Regenerate. * testsuite/copy_test_relro.cc: New source file. * testsuite/copy_test_relro_1.cc: New source file. --- gold/ChangeLog | 11 +++++++++ gold/copy-relocs.cc | 44 +++++++++++++++++++++++++++++------- gold/copy-relocs.h | 8 +++++-- gold/testsuite/Makefile.am | 10 +++++++++ gold/testsuite/Makefile.in | 33 ++++++++++++++++++++++----- gold/testsuite/copy_test_relro.cc | 45 +++++++++++++++++++++++++++++++++++++ gold/testsuite/copy_test_relro_1.cc | 26 +++++++++++++++++++++ 7 files changed, 161 insertions(+), 16 deletions(-) create mode 100644 gold/testsuite/copy_test_relro.cc create mode 100644 gold/testsuite/copy_test_relro_1.cc (limited to 'gold') diff --git a/gold/ChangeLog b/gold/ChangeLog index 9243f2a..e711ff9 100644 --- a/gold/ChangeLog +++ b/gold/ChangeLog @@ -1,3 +1,14 @@ +2016-12-27 Cary Coutant + + PR ld/20995 + * copy-relocs.cc (Copy_relocs::make_copy_reloc): Use .dynbss for + read-only data when linking with -z relro. + * copy-relocs.h (Copy_relocs::dynrelro_): New data member. + * testsuite/Makefile.am (copy_test_relro): New test case. + * testsuite/Makefile.in: Regenerate. + * testsuite/copy_test_relro.cc: New source file. + * testsuite/copy_test_relro_1.cc: New source file. + 2016-12-23 Cary Coutant * NEWS: Add new features in 1.14. diff --git a/gold/copy-relocs.cc b/gold/copy-relocs.cc index ce019c4..4fe17e9 100644 --- a/gold/copy-relocs.cc +++ b/gold/copy-relocs.cc @@ -141,6 +141,7 @@ Copy_relocs::make_copy_reloc( unsigned int shndx = sym->shndx(&is_ordinary); gold_assert(is_ordinary); typename elfcpp::Elf_types::Elf_WXword addralign; + bool is_readonly = false; { // Lock the object so we can read from it. This is only called @@ -150,6 +151,17 @@ Copy_relocs::make_copy_reloc( Object* obj = sym->object(); Task_lock_obj tl(dummy_task, obj); addralign = obj->section_addralign(shndx); + if (parameters->options().relro()) + { + if ((obj->section_flags(shndx) & elfcpp::SHF_WRITE) == 0) + is_readonly = true; + else + { + // Symbols in .data.rel.ro should also be treated as read-only. + if (obj->section_name(shndx) == ".data.rel.ro") + is_readonly = true; + } + } } typename Sized_symbol::Value_type value = sym->value(); @@ -159,16 +171,32 @@ Copy_relocs::make_copy_reloc( // Mark the dynamic object as needed for the --as-needed option. sym->object()->set_is_needed(); - if (this->dynbss_ == NULL) + Output_data_space* dynbss; + + if (is_readonly) { - this->dynbss_ = new Output_data_space(addralign, "** dynbss"); - layout->add_output_section_data(".bss", - elfcpp::SHT_NOBITS, - elfcpp::SHF_ALLOC | elfcpp::SHF_WRITE, - this->dynbss_, ORDER_BSS, false); + if (this->dynrelro_ == NULL) + { + this->dynrelro_ = new Output_data_space(addralign, "** dynrelro"); + layout->add_output_section_data(".data.rel.ro", + elfcpp::SHT_PROGBITS, + elfcpp::SHF_ALLOC | elfcpp::SHF_WRITE, + this->dynrelro_, ORDER_RELRO, false); + } + dynbss = this->dynrelro_; + } + else + { + if (this->dynbss_ == NULL) + { + this->dynbss_ = new Output_data_space(addralign, "** dynbss"); + layout->add_output_section_data(".bss", + elfcpp::SHT_NOBITS, + elfcpp::SHF_ALLOC | elfcpp::SHF_WRITE, + this->dynbss_, ORDER_BSS, false); + } + dynbss = this->dynbss_; } - - Output_data_space* dynbss = this->dynbss_; if (addralign > dynbss->addralign()) dynbss->set_space_alignment(addralign); diff --git a/gold/copy-relocs.h b/gold/copy-relocs.h index aa42c7c..92b2ceb 100644 --- a/gold/copy-relocs.h +++ b/gold/copy-relocs.h @@ -54,7 +54,8 @@ class Copy_relocs public: Copy_relocs(unsigned int copy_reloc_type) - : entries_(), copy_reloc_type_(copy_reloc_type), dynbss_(NULL) + : entries_(), copy_reloc_type_(copy_reloc_type), dynbss_(NULL), + dynrelro_(NULL) { } // This is called while scanning relocs if we see a relocation @@ -152,8 +153,11 @@ class Copy_relocs // The target specific relocation type of the COPY relocation. const unsigned int copy_reloc_type_; // The dynamic BSS data which goes into the .bss section. This is - // where variables which require COPY relocations are placed. + // where writable variables which require COPY relocations are placed. Output_data_space* dynbss_; + // The dynamic read-only data, which goes into the .dynbss section. This + // is where read-only variables which require COPY relocations are placed. + Output_data_space* dynrelro_; }; } // End namespace gold. diff --git a/gold/testsuite/Makefile.am b/gold/testsuite/Makefile.am index 6a882ea..d9480ab 100644 --- a/gold/testsuite/Makefile.am +++ b/gold/testsuite/Makefile.am @@ -858,6 +858,16 @@ copy_test_2_pic.o: copy_test_2.cc copy_test_2.so: gcctestdir/ld copy_test_2_pic.o $(CXXLINK) -Bgcctestdir/ -shared copy_test_2_pic.o +check_PROGRAMS += copy_test_relro +copy_test_relro_SOURCES = copy_test_relro.cc +copy_test_relro_DEPENDENCIES = gcctestdir/ld copy_test_relro_1.so +copy_test_relro_LDFLAGS = -Bgcctestdir/ -Wl,-R,. -Wl,-z,relro +copy_test_relro_LDADD = copy_test_relro_1.so +copy_test_relro_1_pic.o: copy_test_relro_1.cc + $(CXXCOMPILE) -c -fpic -o $@ $< +copy_test_relro_1.so: gcctestdir/ld copy_test_relro_1_pic.o + $(CXXLINK) -Bgcctestdir/ -shared -Wl,-z,relro copy_test_relro_1_pic.o + if !DEFAULT_TARGET_POWERPC check_SCRIPTS += copy_test_protected.sh check_DATA += copy_test_protected.err diff --git a/gold/testsuite/Makefile.in b/gold/testsuite/Makefile.in index 202aa9a..2c67bf5 100644 --- a/gold/testsuite/Makefile.in +++ b/gold/testsuite/Makefile.in @@ -205,7 +205,7 @@ check_PROGRAMS = $(am__EXEEXT_1) $(am__EXEEXT_2) $(am__EXEEXT_3) \ @FN_PTRS_IN_SO_WITHOUT_PIC_TRUE@@GCC_TRUE@@NATIVE_LINKER_TRUE@am__append_16 = weak_undef_nonpic_test @FN_PTRS_IN_SO_WITHOUT_PIC_TRUE@@GCC_TRUE@@NATIVE_LINKER_TRUE@am__append_17 = alt/weak_undef_lib_nonpic.so @GCC_TRUE@@NATIVE_LINKER_TRUE@am__append_18 = weak_alias_test weak_plt \ -@GCC_TRUE@@NATIVE_LINKER_TRUE@ copy_test +@GCC_TRUE@@NATIVE_LINKER_TRUE@ copy_test copy_test_relro @DEFAULT_TARGET_POWERPC_FALSE@@GCC_TRUE@@NATIVE_LINKER_TRUE@am__append_19 = copy_test_protected.sh @DEFAULT_TARGET_POWERPC_FALSE@@GCC_TRUE@@NATIVE_LINKER_TRUE@am__append_20 = copy_test_protected.err @DEFAULT_TARGET_POWERPC_FALSE@@GCC_TRUE@@NATIVE_LINKER_TRUE@am__append_21 = copy_test_protected.err @@ -1085,7 +1085,8 @@ libgoldtest_a_OBJECTS = $(am_libgoldtest_a_OBJECTS) @GCC_TRUE@@NATIVE_LINKER_TRUE@am__EXEEXT_14 = \ @GCC_TRUE@@NATIVE_LINKER_TRUE@ weak_alias_test$(EXEEXT) \ @GCC_TRUE@@NATIVE_LINKER_TRUE@ weak_plt$(EXEEXT) \ -@GCC_TRUE@@NATIVE_LINKER_TRUE@ copy_test$(EXEEXT) +@GCC_TRUE@@NATIVE_LINKER_TRUE@ copy_test$(EXEEXT) \ +@GCC_TRUE@@NATIVE_LINKER_TRUE@ copy_test_relro$(EXEEXT) @GCC_TRUE@@NATIVE_LINKER_TRUE@@TLS_TRUE@am__EXEEXT_15 = \ @GCC_TRUE@@NATIVE_LINKER_TRUE@@TLS_TRUE@ tls_test$(EXEEXT) \ @GCC_TRUE@@NATIVE_LINKER_TRUE@@TLS_TRUE@ tls_pic_test$(EXEEXT) \ @@ -1298,6 +1299,11 @@ constructor_test_LINK = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) \ copy_test_OBJECTS = $(am_copy_test_OBJECTS) copy_test_LINK = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) \ $(copy_test_LDFLAGS) $(LDFLAGS) -o $@ +@GCC_TRUE@@NATIVE_LINKER_TRUE@am_copy_test_relro_OBJECTS = \ +@GCC_TRUE@@NATIVE_LINKER_TRUE@ copy_test_relro.$(OBJEXT) +copy_test_relro_OBJECTS = $(am_copy_test_relro_OBJECTS) +copy_test_relro_LINK = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) \ + $(copy_test_relro_LDFLAGS) $(LDFLAGS) -o $@ @GCC_TRUE@@NATIVE_LINKER_TRUE@am_discard_locals_test_OBJECTS = \ @GCC_TRUE@@NATIVE_LINKER_TRUE@ discard_locals_test.$(OBJEXT) discard_locals_test_OBJECTS = $(am_discard_locals_test_OBJECTS) @@ -2357,10 +2363,11 @@ SOURCES = $(libgoldtest_a_SOURCES) basic_pic_test.c basic_pie_test.c \ $(binary_test_SOURCES) $(binary_unittest_SOURCES) \ $(common_test_1_SOURCES) $(common_test_2_SOURCES) \ $(constructor_static_test_SOURCES) $(constructor_test_SOURCES) \ - $(copy_test_SOURCES) $(discard_locals_test_SOURCES) \ - $(dynamic_list_2_SOURCES) eh_test.c \ - $(ehdr_start_test_1_SOURCES) $(ehdr_start_test_2_SOURCES) \ - $(ehdr_start_test_3_SOURCES) $(ehdr_start_test_5_SOURCES) \ + $(copy_test_SOURCES) $(copy_test_relro_SOURCES) \ + $(discard_locals_test_SOURCES) $(dynamic_list_2_SOURCES) \ + eh_test.c $(ehdr_start_test_1_SOURCES) \ + $(ehdr_start_test_2_SOURCES) $(ehdr_start_test_3_SOURCES) \ + $(ehdr_start_test_5_SOURCES) \ $(exception_same_shared_test_SOURCES) \ $(exception_separate_shared_12_test_SOURCES) \ $(exception_separate_shared_21_test_SOURCES) \ @@ -3051,6 +3058,10 @@ LDADD = libgoldtest.a ../libgold.a ../../libiberty/libiberty.a $(LIBINTL) \ @GCC_TRUE@@NATIVE_LINKER_TRUE@copy_test_DEPENDENCIES = gcctestdir/ld copy_test_1.so copy_test_2.so @GCC_TRUE@@NATIVE_LINKER_TRUE@copy_test_LDFLAGS = -Bgcctestdir/ -Wl,-R,. @GCC_TRUE@@NATIVE_LINKER_TRUE@copy_test_LDADD = copy_test_1.so copy_test_2.so +@GCC_TRUE@@NATIVE_LINKER_TRUE@copy_test_relro_SOURCES = copy_test_relro.cc +@GCC_TRUE@@NATIVE_LINKER_TRUE@copy_test_relro_DEPENDENCIES = gcctestdir/ld copy_test_relro_1.so +@GCC_TRUE@@NATIVE_LINKER_TRUE@copy_test_relro_LDFLAGS = -Bgcctestdir/ -Wl,-R,. -Wl,-z,relro +@GCC_TRUE@@NATIVE_LINKER_TRUE@copy_test_relro_LDADD = copy_test_relro_1.so @GCC_TRUE@@NATIVE_LINKER_TRUE@@TLS_TRUE@tls_test_SOURCES = tls_test.cc tls_test_file2.cc tls_test_main.cc tls_test.h @GCC_TRUE@@NATIVE_LINKER_TRUE@@TLS_TRUE@tls_test_DEPENDENCIES = gcctestdir/ld tls_test_c.o @GCC_TRUE@@NATIVE_LINKER_TRUE@@TLS_TRUE@tls_test_LDFLAGS = -Bgcctestdir/ @@ -3468,6 +3479,9 @@ constructor_test$(EXEEXT): $(constructor_test_OBJECTS) $(constructor_test_DEPEND copy_test$(EXEEXT): $(copy_test_OBJECTS) $(copy_test_DEPENDENCIES) $(EXTRA_copy_test_DEPENDENCIES) @rm -f copy_test$(EXEEXT) $(copy_test_LINK) $(copy_test_OBJECTS) $(copy_test_LDADD) $(LIBS) +copy_test_relro$(EXEEXT): $(copy_test_relro_OBJECTS) $(copy_test_relro_DEPENDENCIES) $(EXTRA_copy_test_relro_DEPENDENCIES) + @rm -f copy_test_relro$(EXEEXT) + $(copy_test_relro_LINK) $(copy_test_relro_OBJECTS) $(copy_test_relro_LDADD) $(LIBS) discard_locals_test$(EXEEXT): $(discard_locals_test_OBJECTS) $(discard_locals_test_DEPENDENCIES) $(EXTRA_discard_locals_test_DEPENDENCIES) @rm -f discard_locals_test$(EXEEXT) $(discard_locals_test_LINK) $(discard_locals_test_OBJECTS) $(discard_locals_test_LDADD) $(LIBS) @@ -4343,6 +4357,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/common_test_1.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/constructor_test.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/copy_test.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/copy_test_relro.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/discard_locals_test.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dynamic_list_2.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eh_test.Po@am__quote@ @@ -5396,6 +5411,8 @@ weak_plt.log: weak_plt$(EXEEXT) @p='weak_plt$(EXEEXT)'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post) copy_test.log: copy_test$(EXEEXT) @p='copy_test$(EXEEXT)'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post) +copy_test_relro.log: copy_test_relro$(EXEEXT) + @p='copy_test_relro$(EXEEXT)'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post) tls_test.log: tls_test$(EXEEXT) @p='tls_test$(EXEEXT)'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post) tls_pic_test.log: tls_pic_test$(EXEEXT) @@ -6115,6 +6132,10 @@ uninstall-am: @GCC_TRUE@@NATIVE_LINKER_TRUE@ $(CXXCOMPILE) -c -fpic -o $@ $< @GCC_TRUE@@NATIVE_LINKER_TRUE@copy_test_2.so: gcctestdir/ld copy_test_2_pic.o @GCC_TRUE@@NATIVE_LINKER_TRUE@ $(CXXLINK) -Bgcctestdir/ -shared copy_test_2_pic.o +@GCC_TRUE@@NATIVE_LINKER_TRUE@copy_test_relro_1_pic.o: copy_test_relro_1.cc +@GCC_TRUE@@NATIVE_LINKER_TRUE@ $(CXXCOMPILE) -c -fpic -o $@ $< +@GCC_TRUE@@NATIVE_LINKER_TRUE@copy_test_relro_1.so: gcctestdir/ld copy_test_relro_1_pic.o +@GCC_TRUE@@NATIVE_LINKER_TRUE@ $(CXXLINK) -Bgcctestdir/ -shared -Wl,-z,relro copy_test_relro_1_pic.o @DEFAULT_TARGET_POWERPC_FALSE@@GCC_TRUE@@NATIVE_LINKER_TRUE@copy_test_protected.err: copy_test_protected.o copy_test_2.so gcctestdir/ld @DEFAULT_TARGET_POWERPC_FALSE@@GCC_TRUE@@NATIVE_LINKER_TRUE@ @echo $(CXXLINK) -Bgcctestdir/ -o copy_test_protected copy_test_protected.o copy_test_2.so -Wl,-R,. "2>$@" @DEFAULT_TARGET_POWERPC_FALSE@@GCC_TRUE@@NATIVE_LINKER_TRUE@ @if $(CXXLINK) -Bgcctestdir/ -o copy_test_protected copy_test_protected.o copy_test_2.so -Wl,-R,. 2>$@; \ diff --git a/gold/testsuite/copy_test_relro.cc b/gold/testsuite/copy_test_relro.cc new file mode 100644 index 0000000..297b578 --- /dev/null +++ b/gold/testsuite/copy_test_relro.cc @@ -0,0 +1,45 @@ +// copy_test_relro.cc -- test copy relocs against read-only and relro symbols. + +// Copyright (C) 2016 Free Software Foundation, Inc. +// Written by Cary Coutant . + +// 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. + +#include +#include + +extern char* _etext; +extern char* __data_start; +extern char* _edata; +extern char* _end; + +extern int* const p; +extern const int b[]; +int a = 123; + +int main() +{ + assert(*p == 123); + assert(b[0] == 100); + assert(b[1] == 200); + assert(b[2] == 300); + assert(b[3] == 400); + assert(reinterpret_cast(&p) < reinterpret_cast(&__data_start)); + assert(reinterpret_cast(b) < reinterpret_cast(&__data_start)); + return 0; +} diff --git a/gold/testsuite/copy_test_relro_1.cc b/gold/testsuite/copy_test_relro_1.cc new file mode 100644 index 0000000..d154534 --- /dev/null +++ b/gold/testsuite/copy_test_relro_1.cc @@ -0,0 +1,26 @@ +// copy_test_relro_1.cc -- test copy relocs variables for gold + +// Copyright (C) 2016 Free Software Foundation, Inc. +// Written by Cary Coutant . + +// 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. + +extern int a; +extern int* const p = &a; + +extern const int b[] = { 100, 200, 300, 400 }; -- cgit v1.1