diff options
author | Nick Clifton <nickc@redhat.com> | 2018-03-09 14:37:36 +0000 |
---|---|---|
committer | Nick Clifton <nickc@redhat.com> | 2018-03-09 14:37:36 +0000 |
commit | f657f8c4a1dc0ac69b16b1dc6eacbf5286f1f0a0 (patch) | |
tree | cd660cfaf14687bc4785722975206591959142d8 | |
parent | 9bd8e0b072ad5fc5b8956fd5d3e51dc5a9b0f236 (diff) | |
download | gdb-f657f8c4a1dc0ac69b16b1dc6eacbf5286f1f0a0.zip gdb-f657f8c4a1dc0ac69b16b1dc6eacbf5286f1f0a0.tar.gz gdb-f657f8c4a1dc0ac69b16b1dc6eacbf5286f1f0a0.tar.bz2 |
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/ChangeLog | 11 | ||||
-rw-r--r-- | bfd/elf32-s390.c | 6 | ||||
-rw-r--r-- | bfd/elf64-s390.c | 6 | ||||
-rw-r--r-- | bfd/elfnn-aarch64.c | 6 | ||||
-rw-r--r-- | bfd/elfxx-sparc.c | 9 | ||||
-rw-r--r-- | ld/ChangeLog | 9 | ||||
-rw-r--r-- | ld/testsuite/ld-ifunc/ifunc.exp | 3 | ||||
-rw-r--r-- | ld/testsuite/ld-ifunc/ifuncmod5.d | 8 | ||||
-rw-r--r-- | ld/testsuite/ld-ifunc/ifuncmod5.s | 105 |
9 files changed, 156 insertions, 7 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 74af690..672143b 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 d077104..18010c0 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 9eca035..2d02e82 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 beef91a..c1986b7 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 30e7bd3..849182f 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 f37bdab..3b54069 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 cb019d9..6eec579 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 0000000..654d583 --- /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 0000000..97f5263 --- /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 + + |