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 4bad36e..6d1c14b 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 70e2789..607f9d6 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 ed7f3f9..d28c444 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 0589d0c..b9ee86e 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 2056f50..5a5f76a 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 b6366d4..ab5b5f9 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 1f275b0..0373464 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 028c262..11403ac 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 c194587..1a14dea 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 255ebb9..479fb42 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);