From: Nick Clifton Date: Fri, 9 Mar 2018 14:37:36 +0000 (+0000) Subject: Fix Sparc, s390 and AArch64 targets so that they can handle relocs against ifunc... X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=f657f8c4a1dc0ac69b16b1dc6eacbf5286f1f0a0;p=binutils-gdb.git 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. --- 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 + + * 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 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 + + * 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 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 + +