With -pie and x86, the linker complains if it sees a PC-relative relocation
authorSriraman Tallam <tmsriram@google.com>
Tue, 13 May 2014 17:51:48 +0000 (10:51 -0700)
committerSriraman Tallam <tmsriram@google.com>
Tue, 13 May 2014 17:55:11 +0000 (10:55 -0700)
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<size>::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
gold/arm.cc
gold/i386.cc
gold/powerpc.cc
gold/sparc.cc
gold/symtab.h
gold/testsuite/Makefile.am
gold/testsuite/Makefile.in
gold/tilegx.cc
gold/x86_64.cc

index 4bad36ef57a81b37dcf4ce861a6b28a35397bb70..6d1c14b7e7a496d4ac8590add88dde60116c5734 100644 (file)
@@ -1,3 +1,22 @@
+2014-05-13  Sriraman Tallam  <tmsriram@google.com>
+
+       * symtab.h (may_need_copy_reloc): Remove check for position independent
+       code.
+       * x86_64.cc (Target_x86_64<size>::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  <mliska@suse.cz>
 
        * output.cc (Sized_relobj_file::do_layout): Fix typo in info message.
index 70e27892df4778736121901d99de9284c4c0954a..607f9d6c1d92114d1a680f9375668bd27b27bd36 100644 (file)
@@ -8301,7 +8301,8 @@ Target_arm<big_endian>::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<big_endian>::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);
index ed7f3f981ea2577fcbc001f4bcd8edf340bf654f..d28c4442be6e38402f46adcd963e267104b82a25 100644 (file)
@@ -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);
index 0589d0c13bd0632ccd139c48bb52bc961a8a4773..b9ee86e15be6dba28b49d486be1e2c6efe3f457a 100644 (file)
@@ -5819,7 +5819,8 @@ Target_powerpc<size, big_endian>::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<size, big_endian>::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,
index 2056f506876ca720285356a2f62e645d7954d0ee..5a5f76a6409ad7ab608586dfecf301f351650a62 100644 (file)
@@ -2634,7 +2634,8 @@ Target_sparc<size, big_endian>::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<size, big_endian>::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);
index b6366d4c9d2747529862e8e2930e002d1a61ae85..ab5b5f97d7fcafb0dfe49f9757baea4b18122749 100644 (file)
@@ -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());
   }
index 1f275b04131aef7523862ce7bcb73da525a52b46..0373464ffbaf1877fa7f9b8b8700af697d1e1fb4 100644 (file)
@@ -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
index 028c262106383da64a6063afcb38272536251059..11403ac885ec6fcbf336f13c465127103ac7e86b 100644 (file)
@@ -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
index c1945872d601112e6849b618060fb54ff025ab0f..1a14deaf7de30e55e3bf11f4792ef23e2b9a2bf7 100644 (file)
@@ -3758,7 +3758,8 @@ Target_tilegx<size, big_endian>::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<size, big_endian>::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);
index 255ebb90c376eb6c45b61e98a55c43732d6a32ab..479fb420b986aa2095babe5cad47b74ad5e780f3 100644 (file)
@@ -2774,7 +2774,8 @@ Target_x86_64<size>::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<size>::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);