From a82bef932ec11cc16f205427f8a056c3c0ea517d Mon Sep 17 00:00:00 2001 From: Sriraman Tallam Date: Tue, 13 May 2014 10:51:48 -0700 Subject: [PATCH] With -pie and x86, the linker complains if it sees a PC-relative relocation to access a global as it expects a GOTPCREL relocation. This is really not necessary as the linker could use a copy relocation to get around it. This patch enables copy relocations with pie. Context: This is useful because currently the GCC compiler with option -fpie makes every extern global access go through the GOT. That is because the compiler cannot tell if a global will end up being defined in the executable or not and is conservative. This ends up hurting performance when the binary is linked as mostly static where most of the globals do end up being defined in the executable. By allowing copy relocs with fPIE, the compiler need not generate a GOTPCREL(GOT access) for any global access. It can safely assume that all globals will be defined in the executable and generate a PC-relative access instead. Gold can then create a copy reloc for only the undefined globals. gold/ * symtab.h (may_need_copy_reloc): Remove check for position independent code. * x86_64.cc (Target_x86_64::Scan::global): Add check for no position independence before pc absolute may_need_copy_reloc call. Add check for executable output befor pc relative may_need_copy_reloc call. * i386.cc: Ditto. * arm.cc: Ditto. * sparc.cc: Ditto. * tilegx.cc: Ditto. * powerpc.cc: Add check for no position independence before may_need_copy_reloc calls. * testsuite/pie_copyrelocs_test.cc: New file. * testsuite/pie_copyrelocs_shared_test.cc: New file. * Makefile.am (pie_copyrelocs_test): New test. * Makefile.in: Regenerate. --- gold/ChangeLog | 19 +++++++++++++++++ gold/arm.cc | 6 ++++-- gold/i386.cc | 6 ++++-- gold/powerpc.cc | 6 ++++-- gold/sparc.cc | 6 ++++-- gold/symtab.h | 3 +-- gold/testsuite/Makefile.am | 10 +++++++++ gold/testsuite/Makefile.in | 42 +++++++++++++++++++++++++++++--------- gold/tilegx.cc | 6 ++++-- gold/x86_64.cc | 6 ++++-- 10 files changed, 86 insertions(+), 24 deletions(-) diff --git a/gold/ChangeLog b/gold/ChangeLog index 4bad36ef57a..6d1c14b7e7a 100644 --- a/gold/ChangeLog +++ b/gold/ChangeLog @@ -1,3 +1,22 @@ +2014-05-13 Sriraman Tallam + + * symtab.h (may_need_copy_reloc): Remove check for position independent + code. + * x86_64.cc (Target_x86_64::Scan::global): Add check for no + position independence before pc absolute may_need_copy_reloc call. + Add check for executable output befor pc relative may_need_copy_reloc + call. + * i386.cc: Ditto. + * arm.cc: Ditto. + * sparc.cc: Ditto. + * tilegx.cc: Ditto. + * powerpc.cc: Add check for no position independence before + may_need_copy_reloc calls. + * testsuite/pie_copyrelocs_test.cc: New file. + * testsuite/pie_copyrelocs_shared_test.cc: New file. + * Makefile.am (pie_copyrelocs_test): New test. + * Makefile.in: Regenerate. + 2014-05-08 Martin Liška * output.cc (Sized_relobj_file::do_layout): Fix typo in info message. diff --git a/gold/arm.cc b/gold/arm.cc index 70e27892df4..607f9d6c1d9 100644 --- a/gold/arm.cc +++ b/gold/arm.cc @@ -8301,7 +8301,8 @@ Target_arm::Scan::global(Symbol_table* symtab, // Make a dynamic relocation if necessary. if (gsym->needs_dynamic_reloc(Scan::get_reference_flags(r_type))) { - if (gsym->may_need_copy_reloc()) + if (!parameters->options().output_is_position_independent() + && gsym->may_need_copy_reloc()) { target->copy_reloc(symtab, layout, object, data_shndx, output_section, gsym, reloc); @@ -8382,7 +8383,8 @@ Target_arm::Scan::global(Symbol_table* symtab, // Make a dynamic relocation if necessary. if (gsym->needs_dynamic_reloc(Scan::get_reference_flags(r_type))) { - if (target->may_need_copy_reloc(gsym)) + if (parameters->options().output_is_executable() + && target->may_need_copy_reloc(gsym)) { target->copy_reloc(symtab, layout, object, data_shndx, output_section, gsym, reloc); diff --git a/gold/i386.cc b/gold/i386.cc index ed7f3f981ea..d28c4442be6 100644 --- a/gold/i386.cc +++ b/gold/i386.cc @@ -2149,7 +2149,8 @@ Target_i386::Scan::global(Symbol_table* symtab, // Make a dynamic relocation if necessary. if (gsym->needs_dynamic_reloc(Scan::get_reference_flags(r_type))) { - if (gsym->may_need_copy_reloc()) + if (!parameters->options().output_is_position_independent() + && gsym->may_need_copy_reloc()) { target->copy_reloc(symtab, layout, object, data_shndx, output_section, gsym, reloc); @@ -2210,7 +2211,8 @@ Target_i386::Scan::global(Symbol_table* symtab, // Make a dynamic relocation if necessary. if (gsym->needs_dynamic_reloc(Scan::get_reference_flags(r_type))) { - if (gsym->may_need_copy_reloc()) + if (parameters->options().output_is_executable() + && gsym->may_need_copy_reloc()) { target->copy_reloc(symtab, layout, object, data_shndx, output_section, gsym, reloc); diff --git a/gold/powerpc.cc b/gold/powerpc.cc index 0589d0c13bd..b9ee86e15be 100644 --- a/gold/powerpc.cc +++ b/gold/powerpc.cc @@ -5819,7 +5819,8 @@ Target_powerpc::Scan::global( if (gsym->needs_dynamic_reloc(Scan::get_reference_flags(r_type, target)) || (size == 64 && is_ifunc && target->abiversion() < 2)) { - if (gsym->may_need_copy_reloc()) + if (!parameters->options().output_is_position_independent() + && gsym->may_need_copy_reloc()) { target->copy_reloc(symtab, layout, object, data_shndx, output_section, gsym, reloc); @@ -5882,7 +5883,8 @@ Target_powerpc::Scan::global( // Make a dynamic relocation if necessary. if (gsym->needs_dynamic_reloc(Scan::get_reference_flags(r_type, target))) { - if (gsym->may_need_copy_reloc()) + if (!parameters->options().output_is_position_independent() + && gsym->may_need_copy_reloc()) { target->copy_reloc(symtab, layout, object, data_shndx, output_section, gsym, diff --git a/gold/sparc.cc b/gold/sparc.cc index 2056f506876..5a5f76a6409 100644 --- a/gold/sparc.cc +++ b/gold/sparc.cc @@ -2634,7 +2634,8 @@ Target_sparc::Scan::global( // Make a dynamic relocation if necessary. if (gsym->needs_dynamic_reloc(Scan::get_reference_flags(r_type))) { - if (gsym->may_need_copy_reloc()) + if (parameters->options().output_is_executable() + && gsym->may_need_copy_reloc()) { target->copy_reloc(symtab, layout, object, data_shndx, output_section, gsym, @@ -2723,7 +2724,8 @@ Target_sparc::Scan::global( break; } - if (gsym->may_need_copy_reloc()) + if (!parameters->options().output_is_position_independent() + && gsym->may_need_copy_reloc()) { target->copy_reloc(symtab, layout, object, data_shndx, output_section, gsym, reloc); diff --git a/gold/symtab.h b/gold/symtab.h index b6366d4c9d2..ab5b5f97d7f 100644 --- a/gold/symtab.h +++ b/gold/symtab.h @@ -847,8 +847,7 @@ class Symbol bool may_need_copy_reloc() const { - return (!parameters->options().output_is_position_independent() - && parameters->options().copyreloc() + return (parameters->options().copyreloc() && this->is_from_dynobj() && !this->is_func()); } diff --git a/gold/testsuite/Makefile.am b/gold/testsuite/Makefile.am index 1f275b04131..0373464ffba 100644 --- a/gold/testsuite/Makefile.am +++ b/gold/testsuite/Makefile.am @@ -517,6 +517,16 @@ two_file_pie_test: two_file_test_1_pie.o two_file_test_1b_pie.o \ two_file_test_2_pie.o two_file_test_main_pie.o gcctestdir/ld $(CXXLINK) -Bgcctestdir/ -pie two_file_test_1_pie.o two_file_test_1b_pie.o two_file_test_2_pie.o two_file_test_main_pie.o +check_PROGRAMS += pie_copyrelocs_test +pie_copyrelocs_test_SOURCES = pie_copyrelocs_test.cc +pie_copyrelocs_test_DEPENDENCIES = gcctestdir/ld pie_copyrelocs_shared_test.so +pie_copyrelocs_test_LDFLAGS = -Bgcctestdir/ -Wl,-R,. -pie +pie_copyrelocs_test_LDADD = pie_copyrelocs_shared_test.so +pie_copyrelocs_shared_test.o: pie_copyrelocs_shared_test.cc + $(CXXCOMPILE) -O2 -fpic -c -o $@ $< +pie_copyrelocs_shared_test.so: pie_copyrelocs_shared_test.o gcctestdir/ld + $(CXXLINK) -Bgcctestdir/ -shared pie_copyrelocs_shared_test.o + check_SCRIPTS += two_file_shared.sh check_DATA += two_file_shared.dbg MOSTLYCLEANFILES += two_file_shared.dbg diff --git a/gold/testsuite/Makefile.in b/gold/testsuite/Makefile.in index 028c2621063..11403ac885e 100644 --- a/gold/testsuite/Makefile.in +++ b/gold/testsuite/Makefile.in @@ -181,7 +181,8 @@ check_PROGRAMS = $(am__EXEEXT_1) $(am__EXEEXT_2) $(am__EXEEXT_3) \ @GCC_TRUE@@NATIVE_LINKER_TRUE@ two_file_separate_shared_12_test \ @GCC_TRUE@@NATIVE_LINKER_TRUE@ two_file_separate_shared_21_test \ @GCC_TRUE@@NATIVE_LINKER_TRUE@ two_file_relocatable_test \ -@GCC_TRUE@@NATIVE_LINKER_TRUE@ two_file_pie_test +@GCC_TRUE@@NATIVE_LINKER_TRUE@ two_file_pie_test \ +@GCC_TRUE@@NATIVE_LINKER_TRUE@ pie_copyrelocs_test # The nonpic tests will fail on platforms which can not put non-PIC # code into shared libraries, so we just don't run them in that case. @@ -782,7 +783,8 @@ libgoldtest_a_OBJECTS = $(am_libgoldtest_a_OBJECTS) @GCC_TRUE@@NATIVE_LINKER_TRUE@ two_file_separate_shared_12_test$(EXEEXT) \ @GCC_TRUE@@NATIVE_LINKER_TRUE@ two_file_separate_shared_21_test$(EXEEXT) \ @GCC_TRUE@@NATIVE_LINKER_TRUE@ two_file_relocatable_test$(EXEEXT) \ -@GCC_TRUE@@NATIVE_LINKER_TRUE@ two_file_pie_test$(EXEEXT) +@GCC_TRUE@@NATIVE_LINKER_TRUE@ two_file_pie_test$(EXEEXT) \ +@GCC_TRUE@@NATIVE_LINKER_TRUE@ pie_copyrelocs_test$(EXEEXT) @FN_PTRS_IN_SO_WITHOUT_PIC_TRUE@@GCC_TRUE@@NATIVE_LINKER_TRUE@am__EXEEXT_9 = two_file_shared_1_nonpic_test$(EXEEXT) \ @FN_PTRS_IN_SO_WITHOUT_PIC_TRUE@@GCC_TRUE@@NATIVE_LINKER_TRUE@ two_file_shared_2_nonpic_test$(EXEEXT) \ @FN_PTRS_IN_SO_WITHOUT_PIC_TRUE@@GCC_TRUE@@NATIVE_LINKER_TRUE@ two_file_same_shared_nonpic_test$(EXEEXT) \ @@ -1407,6 +1409,11 @@ permission_test_LDADD = $(LDADD) permission_test_DEPENDENCIES = libgoldtest.a ../libgold.a \ ../../libiberty/libiberty.a $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) +@GCC_TRUE@@NATIVE_LINKER_TRUE@am_pie_copyrelocs_test_OBJECTS = \ +@GCC_TRUE@@NATIVE_LINKER_TRUE@ pie_copyrelocs_test.$(OBJEXT) +pie_copyrelocs_test_OBJECTS = $(am_pie_copyrelocs_test_OBJECTS) +pie_copyrelocs_test_LINK = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) \ + $(pie_copyrelocs_test_LDFLAGS) $(LDFLAGS) -o $@ plugin_test_1_SOURCES = plugin_test_1.c plugin_test_1_OBJECTS = plugin_test_1.$(OBJEXT) plugin_test_1_LDADD = $(LDADD) @@ -1875,14 +1882,15 @@ SOURCES = $(libgoldtest_a_SOURCES) basic_pic_test.c basic_pie_test.c \ $(large_symbol_alignment_SOURCES) $(leb128_unittest_SOURCES) \ local_labels_test.c many_sections_r_test.c \ $(many_sections_test_SOURCES) $(object_unittest_SOURCES) \ - permission_test.c plugin_test_1.c plugin_test_2.c \ - plugin_test_3.c plugin_test_4.c plugin_test_5.c \ - plugin_test_6.c plugin_test_7.c plugin_test_8.c \ - plugin_test_tls.c $(protected_1_SOURCES) \ - $(protected_2_SOURCES) $(relro_now_test_SOURCES) \ - $(relro_script_test_SOURCES) $(relro_strip_test_SOURCES) \ - $(relro_test_SOURCES) $(script_test_1_SOURCES) \ - script_test_11.c $(script_test_2_SOURCES) script_test_3.c \ + permission_test.c $(pie_copyrelocs_test_SOURCES) \ + plugin_test_1.c plugin_test_2.c plugin_test_3.c \ + plugin_test_4.c plugin_test_5.c plugin_test_6.c \ + plugin_test_7.c plugin_test_8.c plugin_test_tls.c \ + $(protected_1_SOURCES) $(protected_2_SOURCES) \ + $(relro_now_test_SOURCES) $(relro_script_test_SOURCES) \ + $(relro_strip_test_SOURCES) $(relro_test_SOURCES) \ + $(script_test_1_SOURCES) script_test_11.c \ + $(script_test_2_SOURCES) script_test_3.c \ $(searched_file_test_SOURCES) start_lib_test.c \ $(thin_archive_test_1_SOURCES) $(thin_archive_test_2_SOURCES) \ $(tls_phdrs_script_test_SOURCES) $(tls_pic_test_SOURCES) \ @@ -2312,6 +2320,10 @@ LDADD = libgoldtest.a ../libgold.a ../../libiberty/libiberty.a $(LIBINTL) \ @GCC_TRUE@@NATIVE_LINKER_TRUE@two_file_relocatable_test_LDFLAGS = -Bgcctestdir/ -Wl,-R,. @GCC_TRUE@@NATIVE_LINKER_TRUE@two_file_relocatable_test_LDADD = two_file_relocatable.o +@GCC_TRUE@@NATIVE_LINKER_TRUE@pie_copyrelocs_test_SOURCES = pie_copyrelocs_test.cc +@GCC_TRUE@@NATIVE_LINKER_TRUE@pie_copyrelocs_test_DEPENDENCIES = gcctestdir/ld pie_copyrelocs_shared_test.so +@GCC_TRUE@@NATIVE_LINKER_TRUE@pie_copyrelocs_test_LDFLAGS = -Bgcctestdir/ -Wl,-R,. -pie +@GCC_TRUE@@NATIVE_LINKER_TRUE@pie_copyrelocs_test_LDADD = pie_copyrelocs_shared_test.so @FN_PTRS_IN_SO_WITHOUT_PIC_TRUE@@GCC_TRUE@@NATIVE_LINKER_TRUE@two_file_shared_1_nonpic_test_SOURCES = \ @FN_PTRS_IN_SO_WITHOUT_PIC_TRUE@@GCC_TRUE@@NATIVE_LINKER_TRUE@ two_file_test_2.cc two_file_test_main.cc @@ -3245,6 +3257,9 @@ object_unittest$(EXEEXT): $(object_unittest_OBJECTS) $(object_unittest_DEPENDENC @NATIVE_LINKER_FALSE@permission_test$(EXEEXT): $(permission_test_OBJECTS) $(permission_test_DEPENDENCIES) @NATIVE_LINKER_FALSE@ @rm -f permission_test$(EXEEXT) @NATIVE_LINKER_FALSE@ $(LINK) $(permission_test_OBJECTS) $(permission_test_LDADD) $(LIBS) +pie_copyrelocs_test$(EXEEXT): $(pie_copyrelocs_test_OBJECTS) $(pie_copyrelocs_test_DEPENDENCIES) + @rm -f pie_copyrelocs_test$(EXEEXT) + $(pie_copyrelocs_test_LINK) $(pie_copyrelocs_test_OBJECTS) $(pie_copyrelocs_test_LDADD) $(LIBS) @GCC_FALSE@plugin_test_1$(EXEEXT): $(plugin_test_1_OBJECTS) $(plugin_test_1_DEPENDENCIES) @GCC_FALSE@ @rm -f plugin_test_1$(EXEEXT) @GCC_FALSE@ $(LINK) $(plugin_test_1_OBJECTS) $(plugin_test_1_LDADD) $(LIBS) @@ -3635,6 +3650,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/many_sections_test.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/object_unittest.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/permission_test.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pie_copyrelocs_test.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/plugin_test_1.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/plugin_test_2.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/plugin_test_3.Po@am__quote@ @@ -4202,6 +4218,8 @@ two_file_relocatable_test.log: two_file_relocatable_test$(EXEEXT) @p='two_file_relocatable_test$(EXEEXT)'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post) two_file_pie_test.log: two_file_pie_test$(EXEEXT) @p='two_file_pie_test$(EXEEXT)'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post) +pie_copyrelocs_test.log: pie_copyrelocs_test$(EXEEXT) + @p='pie_copyrelocs_test$(EXEEXT)'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post) two_file_shared_1_nonpic_test.log: two_file_shared_1_nonpic_test$(EXEEXT) @p='two_file_shared_1_nonpic_test$(EXEEXT)'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post) two_file_shared_2_nonpic_test.log: two_file_shared_2_nonpic_test$(EXEEXT) @@ -4805,6 +4823,10 @@ uninstall-am: @GCC_TRUE@@NATIVE_LINKER_TRUE@two_file_pie_test: two_file_test_1_pie.o two_file_test_1b_pie.o \ @GCC_TRUE@@NATIVE_LINKER_TRUE@ two_file_test_2_pie.o two_file_test_main_pie.o gcctestdir/ld @GCC_TRUE@@NATIVE_LINKER_TRUE@ $(CXXLINK) -Bgcctestdir/ -pie two_file_test_1_pie.o two_file_test_1b_pie.o two_file_test_2_pie.o two_file_test_main_pie.o +@GCC_TRUE@@NATIVE_LINKER_TRUE@pie_copyrelocs_shared_test.o: pie_copyrelocs_shared_test.cc +@GCC_TRUE@@NATIVE_LINKER_TRUE@ $(CXXCOMPILE) -O2 -fpic -c -o $@ $< +@GCC_TRUE@@NATIVE_LINKER_TRUE@pie_copyrelocs_shared_test.so: pie_copyrelocs_shared_test.o gcctestdir/ld +@GCC_TRUE@@NATIVE_LINKER_TRUE@ $(CXXLINK) -Bgcctestdir/ -shared pie_copyrelocs_shared_test.o @GCC_TRUE@@NATIVE_LINKER_TRUE@two_file_shared.dbg: two_file_shared.so @GCC_TRUE@@NATIVE_LINKER_TRUE@ $(TEST_READELF) -w $< >$@ 2>/dev/null @FN_PTRS_IN_SO_WITHOUT_PIC_TRUE@@GCC_TRUE@@NATIVE_LINKER_TRUE@two_file_shared_1_nonpic.so: two_file_test_1.o gcctestdir/ld diff --git a/gold/tilegx.cc b/gold/tilegx.cc index c1945872d60..1a14deaf7de 100644 --- a/gold/tilegx.cc +++ b/gold/tilegx.cc @@ -3758,7 +3758,8 @@ Target_tilegx::Scan::global(Symbol_table* symtab, // Make a dynamic relocation if necessary. if (gsym->needs_dynamic_reloc(Scan::get_reference_flags(r_type))) { - if (gsym->may_need_copy_reloc()) + if (!parameters->options().output_is_position_independent() + && gsym->may_need_copy_reloc()) { target->copy_reloc(symtab, layout, object, data_shndx, output_section, gsym, reloc); @@ -3832,7 +3833,8 @@ Target_tilegx::Scan::global(Symbol_table* symtab, // Make a dynamic relocation if necessary. if (gsym->needs_dynamic_reloc(Scan::get_reference_flags(r_type))) { - if (gsym->may_need_copy_reloc()) + if (parameters->options().output_is_executable() + && gsym->may_need_copy_reloc()) { target->copy_reloc(symtab, layout, object, data_shndx, output_section, gsym, reloc); diff --git a/gold/x86_64.cc b/gold/x86_64.cc index 255ebb90c37..479fb420b98 100644 --- a/gold/x86_64.cc +++ b/gold/x86_64.cc @@ -2774,7 +2774,8 @@ Target_x86_64::Scan::global(Symbol_table* symtab, // Make a dynamic relocation if necessary. if (gsym->needs_dynamic_reloc(Scan::get_reference_flags(r_type))) { - if (gsym->may_need_copy_reloc()) + if (!parameters->options().output_is_position_independent() + && gsym->may_need_copy_reloc()) { target->copy_reloc(symtab, layout, object, data_shndx, output_section, gsym, reloc); @@ -2835,7 +2836,8 @@ Target_x86_64::Scan::global(Symbol_table* symtab, // Make a dynamic relocation if necessary. if (gsym->needs_dynamic_reloc(Scan::get_reference_flags(r_type))) { - if (gsym->may_need_copy_reloc()) + if (parameters->options().output_is_executable() + && gsym->may_need_copy_reloc()) { target->copy_reloc(symtab, layout, object, data_shndx, output_section, gsym, reloc); -- 2.30.2