summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNick Clifton <nickc@redhat.com>2018-03-09 14:37:36 +0000
committerNick Clifton <nickc@redhat.com>2018-03-09 14:37:36 +0000
commitf657f8c4a1dc0ac69b16b1dc6eacbf5286f1f0a0 (patch)
treecd660cfaf14687bc4785722975206591959142d8
parent9bd8e0b072ad5fc5b8956fd5d3e51dc5a9b0f236 (diff)
downloadbinutils-gdb-f657f8c4a1dc0ac69b16b1dc6eacbf5286f1f0a0.tar.gz
Fix Sparc, s390 and AArch64 targets so that they can handle relocs against ifunc symbols found in note sections.
Following on from PR 22929, I have found the same problem exists with other ifunc supporting targets too. Plus see this link for the bug being reported against the s390x binutils for Fedora rawhide: https://bugzilla.redhat.com/show_bug.cgi?id=1553705 So I am going to check in the patch below which applies the same change that H.J. made for the x86_64 target to the other affected targets. (Specifically: S390, AArch64 and Sparc). Plus it adds a new test to the linker testsuite to make sure that this problem stays fixed. bfd * elf64-s390.c (elf_s390_relocate_section): Move check for relocations against non-allocated sections to before the code that handles ifunc relocations. * elf32-s390.c (elf_s390_relocate_section): Likewise. * elfnn-aarch64.c (elfNN_aarch64_final_link_relocate): Treat relocs against IFUNC symbols in non-allocated sections as relocs against FUNC symbols. * elfxx-sparc.c (_bfd_sparc_elf_relocate_section): Likewise. ld * testsuite/ld-ifunc/ifuncmod5.s: New test. Checks that targets that support IFUNC symbols can handle relocations against those symbols in NOTE sections. * testsuite/ld-ifunc/ifuncmod5.d: New file: Driver for the new test. * testsuite/ld-ifunc/ifunc.exp: Run the new test.
-rw-r--r--bfd/ChangeLog11
-rw-r--r--bfd/elf32-s390.c6
-rw-r--r--bfd/elf64-s390.c6
-rw-r--r--bfd/elfnn-aarch64.c6
-rw-r--r--bfd/elfxx-sparc.c9
-rw-r--r--ld/ChangeLog9
-rw-r--r--ld/testsuite/ld-ifunc/ifunc.exp3
-rw-r--r--ld/testsuite/ld-ifunc/ifuncmod5.d8
-rw-r--r--ld/testsuite/ld-ifunc/ifuncmod5.s105
9 files changed, 156 insertions, 7 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index 74af690bbaf..672143b3ffe 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,3 +1,14 @@
+2018-03-09 Nick Clifton <nickc@redhat.com>
+
+ * elf64-s390.c (elf_s390_relocate_section): Move check for
+ relocations against non-allocated sections to before the code that
+ handles ifunc relocations.
+ * elf32-s390.c (elf_s390_relocate_section): Likewise.
+ * elfnn-aarch64.c (elfNN_aarch64_final_link_relocate): Treat
+ relocs against IFUNC symbols in non-allocated sections as relocs
+ against FUNC symbols.
+ * elfxx-sparc.c (_bfd_sparc_elf_relocate_section): Likewise.
+
2018-03-08 H.J. Lu <hongjiu.lu@intel.com>
PR ld/22929
diff --git a/bfd/elf32-s390.c b/bfd/elf32-s390.c
index d0771042f48..18010c0b45b 100644
--- a/bfd/elf32-s390.c
+++ b/bfd/elf32-s390.c
@@ -2605,6 +2605,9 @@ elf_s390_relocate_section (bfd *output_bfd,
case R_390_8:
case R_390_16:
case R_390_32:
+ if ((input_section->flags & SEC_ALLOC) == 0)
+ break;
+
if (h != NULL
&& s390_is_ifunc_symbol_p (h)
&& h->def_regular)
@@ -2666,9 +2669,6 @@ elf_s390_relocate_section (bfd *output_bfd,
}
}
- if ((input_section->flags & SEC_ALLOC) == 0)
- break;
-
if ((bfd_link_pic (info)
&& (h == NULL
|| (ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
diff --git a/bfd/elf64-s390.c b/bfd/elf64-s390.c
index 9eca0351523..2d02e82c544 100644
--- a/bfd/elf64-s390.c
+++ b/bfd/elf64-s390.c
@@ -2565,6 +2565,9 @@ elf_s390_relocate_section (bfd *output_bfd,
case R_390_32:
case R_390_64:
+ if ((input_section->flags & SEC_ALLOC) == 0)
+ break;
+
if (h != NULL
&& s390_is_ifunc_symbol_p (h)
&& h->def_regular)
@@ -2627,9 +2630,6 @@ elf_s390_relocate_section (bfd *output_bfd,
}
}
- if ((input_section->flags & SEC_ALLOC) == 0)
- break;
-
if ((bfd_link_pic (info)
&& (h == NULL
|| (ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
diff --git a/bfd/elfnn-aarch64.c b/bfd/elfnn-aarch64.c
index beef91a22d0..c1986b72f2a 100644
--- a/bfd/elfnn-aarch64.c
+++ b/bfd/elfnn-aarch64.c
@@ -5110,6 +5110,11 @@ elfNN_aarch64_final_link_relocate (reloc_howto_type *howto,
if ((input_section->flags & SEC_ALLOC) == 0)
{
+ /* If this is a SHT_NOTE section without SHF_ALLOC, treat
+ STT_GNU_IFUNC symbol as STT_FUNC. */
+ if (elf_section_type (input_section) == SHT_NOTE)
+ goto skip_ifunc;
+
/* Dynamic relocs are not propagated for SEC_DEBUGGING
sections because such sections are not SEC_ALLOC and
thus ld.so will not process them. */
@@ -5305,6 +5310,7 @@ bad_ifunc_reloc:
}
}
+ skip_ifunc:
resolved_to_zero = (h != NULL
&& UNDEFWEAK_NO_DYNAMIC_RELOC (info, h));
diff --git a/bfd/elfxx-sparc.c b/bfd/elfxx-sparc.c
index 30e7bd3c31a..849182fc8cc 100644
--- a/bfd/elfxx-sparc.c
+++ b/bfd/elfxx-sparc.c
@@ -3001,7 +3001,13 @@ _bfd_sparc_elf_relocate_section (bfd *output_bfd,
if ((input_section->flags & SEC_ALLOC) == 0
|| h->plt.offset == (bfd_vma) -1)
- abort ();
+ {
+ /* If this is a SHT_NOTE section without SHF_ALLOC, treat
+ STT_GNU_IFUNC symbol as STT_FUNC. */
+ if (elf_section_type (input_section) == SHT_NOTE)
+ goto skip_ifunc;
+ abort ();
+ }
plt_sec = htab->elf.splt;
if (! plt_sec)
@@ -3105,6 +3111,7 @@ _bfd_sparc_elf_relocate_section (bfd *output_bfd,
}
}
+ skip_ifunc:
eh = (struct _bfd_sparc_elf_link_hash_entry *) h;
resolved_to_zero = eh && UNDEFINED_WEAK_RESOLVED_TO_ZERO (info, eh);
diff --git a/ld/ChangeLog b/ld/ChangeLog
index f37bdab6845..3b54069b265 100644
--- a/ld/ChangeLog
+++ b/ld/ChangeLog
@@ -1,3 +1,12 @@
+2018-03-09 Nick Clifton <nickc@redhat.com>
+
+ * testsuite/ld-ifunc/ifuncmod5.s: New test. Checks that targets
+ that support IFUNC symbols can handle relocations against those
+ symbols in NOTE sections.
+ * testsuite/ld-ifunc/ifuncmod5.d: New file: Driver for the new
+ test.
+ * testsuite/ld-ifunc/ifunc.exp: Run the new test.
+
2018-03-08 H.J. Lu <hongjiu.lu@intel.com>
PR ld/22929
diff --git a/ld/testsuite/ld-ifunc/ifunc.exp b/ld/testsuite/ld-ifunc/ifunc.exp
index cb019d9d911..6eec579e159 100644
--- a/ld/testsuite/ld-ifunc/ifunc.exp
+++ b/ld/testsuite/ld-ifunc/ifunc.exp
@@ -47,6 +47,9 @@ if ![check_shared_lib_support] {
return
}
+# This test does not need a compiler...
+run_dump_test "ifuncmod5"
+
# We need a working compiler. (Strictly speaking this is
# not true, we could use target specific assembler files).
if { [which $CC] == 0 } {
diff --git a/ld/testsuite/ld-ifunc/ifuncmod5.d b/ld/testsuite/ld-ifunc/ifuncmod5.d
new file mode 100644
index 00000000000..654d583f163
--- /dev/null
+++ b/ld/testsuite/ld-ifunc/ifuncmod5.d
@@ -0,0 +1,8 @@
+# name: Reloc against IFUNC symbol in NOTE section
+# ld: -shared
+# nm: -p
+
+# We do not actually care about the notes at the moment.
+# The purpose of this test is to make sure that the link completes successfully.
+#pass
+
diff --git a/ld/testsuite/ld-ifunc/ifuncmod5.s b/ld/testsuite/ld-ifunc/ifuncmod5.s
new file mode 100644
index 00000000000..97f5263769d
--- /dev/null
+++ b/ld/testsuite/ld-ifunc/ifuncmod5.s
@@ -0,0 +1,105 @@
+ .file "ifuncmod5.c"
+
+ .text
+ .type ifuncmod5.c, STT_NOTYPE
+ifuncmod5.c:
+ .size ifuncmod5.c, 0
+
+ .pushsection .gnu.build.attributes, "", %note
+ .balign 4
+ .dc.l 8
+ .dc.l 16
+ .dc.l 0x100
+ .asciz "GA$3p4"
+ .dc.a ifuncmod5.c
+ .dc.a ifuncmod5.c_end
+ .popsection
+
+.Ltext0:
+#APP
+ .protected global
+ .type foo, %gnu_indirect_function
+ .type foo_hidden, %gnu_indirect_function
+ .type foo_protected, %gnu_indirect_function
+ .hidden foo_hidden
+ .protected foo_protected
+#NO_APP
+ .align 8
+ .type one, %function
+one:
+ .dc.l 0
+ .size one, .-one
+ .align 8
+
+.globl foo
+ .type foo, %function
+foo:
+ .dc.l 0
+ .size foo, .-foo
+
+ .pushsection .gnu.build.attributes
+ .dc.l 6
+ .dc.l 16
+ .dc.l 0x101
+ .dc.b 0x47, 0x41, 0x2a, 0x2, 0, 0
+ .dc.b 0, 0
+ .dc.a foo
+ .dc.a foo_end
+ .popsection
+
+foo_end:
+ .align 8
+.globl foo_hidden
+ .type foo_hidden, %function
+foo_hidden:
+ .dc.l 0
+ .size foo_hidden, .-foo_hidden
+
+ .pushsection .gnu.build.attributes
+ .dc.l 6
+ .dc.l 16
+ .dc.l 0x101
+ .dc.b 0x47, 0x41, 0x2a, 0x2, 0, 0
+ .dc.b 0, 0
+ .dc.a foo_hidden
+ .dc.a foo_hidden_end
+ .popsection
+
+foo_hidden_end:
+ .align 8
+
+ .globl foo_protected
+ .type foo_protected, %function
+foo_protected:
+ .dc.l 0
+
+ .size foo_protected, .-foo_protected
+
+ .pushsection .gnu.build.attributes
+ .dc.l 6
+ .dc.l 16
+ .dc.l 0x101
+ .dc.b 0x47, 0x41, 0x2a, 0x2, 0, 0
+ .dc.b 0, 0
+ .dc.a foo_protected
+ .dc.a foo_protected_end
+ .popsection
+
+foo_protected_end:
+ .globl global
+
+ .data
+ .align 4
+ .type global, %object
+ .size global, 4
+global:
+ .long -1
+
+ .text
+ .Letext0:
+
+ifuncmod5.c_end:
+ .type ifuncmod5.c_end, STT_NOTYPE
+ .size ifuncmod5.c_end, 0
+
+