summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSriraman Tallam <tmsriram@google.com>2014-05-13 10:51:48 -0700
committerSriraman Tallam <tmsriram@google.com>2014-05-13 10:55:11 -0700
commita82bef932ec11cc16f205427f8a056c3c0ea517d (patch)
tree352f54fa01c8dc420676ee779b863fb457ba929d
parent033c337911594898b44678fa10b47ee19dd234b5 (diff)
downloadbinutils-gdb-a82bef932ec11cc16f205427f8a056c3c0ea517d.tar.gz
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<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.
-rw-r--r--gold/ChangeLog19
-rw-r--r--gold/arm.cc6
-rw-r--r--gold/i386.cc6
-rw-r--r--gold/powerpc.cc6
-rw-r--r--gold/sparc.cc6
-rw-r--r--gold/symtab.h3
-rw-r--r--gold/testsuite/Makefile.am10
-rw-r--r--gold/testsuite/Makefile.in42
-rw-r--r--gold/tilegx.cc6
-rw-r--r--gold/x86_64.cc6
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 <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.
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<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);
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<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,
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<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);
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<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);
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<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);