[binutils] binutils-2.24-aarch64-fix-ie-relax.patch: fix GD to IE relaxation under register pressure
Kyle McMartin
kyle at fedoraproject.org
Tue Aug 26 18:55:27 UTC 2014
commit 422f7b79608d866025083cc17e0c18e844178451
Author: Kyle McMartin <kyle at mcmartin.ca>
Date: Fri Aug 22 11:52:55 2014 -0400
binutils-2.24-aarch64-fix-ie-relax.patch: fix GD to IE relaxation under register pressure
split some fixes out, so it's easier to see what's backported
...tils-2.24-aarch64-fix-gotplt-offset-ifunc.patch | 103 +++++++++++++++++
binutils-2.24-aarch64-fix-ie-relax.patch | 40 +++++++
binutils-2.24-aarch64-fix-static-ifunc.patch | 118 ++++++++++++++++++++
binutils-2.24-elfnn-aarch64.patch | 72 ------------
binutils.spec | 16 +++-
5 files changed, 276 insertions(+), 73 deletions(-)
---
diff --git a/binutils-2.24-aarch64-fix-gotplt-offset-ifunc.patch b/binutils-2.24-aarch64-fix-gotplt-offset-ifunc.patch
new file mode 100644
index 0000000..64a1d9c
--- /dev/null
+++ b/binutils-2.24-aarch64-fix-gotplt-offset-ifunc.patch
@@ -0,0 +1,103 @@
+commit 67428c4aa56d4183d0f531e0d752040745a94423
+Author: Will Newton <will.newton at linaro.org>
+Date: Mon Nov 25 11:07:07 2013 +0000
+
+ bfd/elfnn-aarch64.c: Fix miscalculation of GOTPLT offset for ifunc syms.
+
+ The .got.plt header size was not being correctly taken into account
+ when calculating the offset for relocations against ifunc symbols.
+
+ bfd/ChangeLog:
+
+ 2013-11-26 Will Newton <will.newton at linaro.org>
+
+ * elfnn-aarch64.c (elfNN_aarch64_final_link_relocate): Ensure
+ PLT_INDEX is calculated using correct header size.
+
+ ld/testsuite/ChangeLog:
+
+ 2013-11-26 Will Newton <will.newton at linaro.org>
+
+ * ld-aarch64/aarch64-elf.exp: Add ifunc-21 test.
+ * ld-aarch64/ifunc-21.d: New file.
+ * ld-aarch64/ifunc-21.s: Likewise.
+
+diff --git a/bfd/elfnn-aarch64.c b/bfd/elfnn-aarch64.c
+index 6bc414e..3cd3a18 100644
+--- a/bfd/elfnn-aarch64.c
++++ b/bfd/elfnn-aarch64.c
+@@ -3589,7 +3589,8 @@ elfNN_aarch64_final_link_relocate (reloc_howto_type *howto,
+
+ if (globals->root.splt != NULL)
+ {
+- plt_index = h->plt.offset / globals->plt_entry_size - 1;
++ plt_index = ((h->plt.offset - globals->plt_header_size) /
++ globals->plt_entry_size);
+ off = (plt_index + 3) * GOT_ENTRY_SIZE;
+ base_got = globals->root.sgotplt;
+ }
+diff --git a/ld/testsuite/ld-aarch64/aarch64-elf.exp b/ld/testsuite/ld-aarch64/aarch64-elf.exp
+index 5c150dd..a6b3ea2 100644
+--- a/ld/testsuite/ld-aarch64/aarch64-elf.exp
++++ b/ld/testsuite/ld-aarch64/aarch64-elf.exp
+@@ -155,3 +155,4 @@ run_dump_test "ifunc-18b"
+ run_dump_test "ifunc-19a"
+ run_dump_test "ifunc-19b"
+ run_dump_test "ifunc-20"
++run_dump_test "ifunc-21"
+diff --git a/ld/testsuite/ld-aarch64/ifunc-21.d b/ld/testsuite/ld-aarch64/ifunc-21.d
+new file mode 100644
+index 0000000..fa139b2
+--- /dev/null
++++ b/ld/testsuite/ld-aarch64/ifunc-21.d
+@@ -0,0 +1,31 @@
++#source: ifunc-21.s
++#ld: -shared -z nocombreloc
++#objdump: -d -s -j .got.plt -j .text
++#target: aarch64*-*-*
++
++# Ensure the .got.plt slot used is correct
++
++.*: file format elf64-(little|big)aarch64
++
++Contents of section .text:
++ 02a0 .*
++Contents of section .got.plt:
++ 103a8 0+ 0+ 0+ 0+ .*
++ 103b8 0+ 0+ [0-9a-f]+ 0+ .*
++
++Disassembly of section .text:
++
++0+2a0 <ifunc>:
++ 2a0: d65f03c0 ret
++
++0+2a4 <bar>:
++ 2a4: 90000080 adrp x0, 10000 <.*>
++ 2a8: f941e000 ldr x0, \[x0,#960\]
++ 2ac: d65f03c0 ret
++
++Disassembly of section .got.plt:
++
++.*:
++.*
++.*
++.*
+diff --git a/ld/testsuite/ld-aarch64/ifunc-21.s b/ld/testsuite/ld-aarch64/ifunc-21.s
+new file mode 100644
+index 0000000..a1563dc
+--- /dev/null
++++ b/ld/testsuite/ld-aarch64/ifunc-21.s
+@@ -0,0 +1,13 @@
++ .text
++ .type ifunc, @gnu_indirect_function
++ .hidden ifunc
++ifunc:
++ ret
++ .size ifunc, .-ifunc
++ .type bar, @function
++ .globl bar
++bar:
++ adrp x0, :got:ifunc
++ ldr x0, [x0, #:got_lo12:ifunc]
++ ret
++ .size bar, .-bar
diff --git a/binutils-2.24-aarch64-fix-ie-relax.patch b/binutils-2.24-aarch64-fix-ie-relax.patch
new file mode 100644
index 0000000..d9157ea
--- /dev/null
+++ b/binutils-2.24-aarch64-fix-ie-relax.patch
@@ -0,0 +1,40 @@
+commit 44f814ce5066f10a3bed29c45d10e0d38f4fa433
+Author: Marcus Shawcroft <marcus.shawcroft at arm.com>
+Date: Tue Apr 15 17:46:07 2014 +0100
+
+ [AArch64] Fix off by one error in instruction relaxation mask.
+
+ The AArch64 TLSDESC to IE relaxation code uses a bit mask intended to
+ ensure that destination register in a relaxed ldr instruction is
+ always X0. The mask has an off by one error resulting in the most
+ significant bit of the destination register being retained in the
+ relaxed instruction. The issue generally appears when the compiler
+ emits TLS accesses code under high register pressure resulting in a
+ broken code sequence.
+
+diff --git a/bfd/elfnn-aarch64.c b/bfd/elfnn-aarch64.c
+index 42c83fb..8503419 100644
+--- a/bfd/elfnn-aarch64.c
++++ b/bfd/elfnn-aarch64.c
+@@ -3957,7 +3957,7 @@ elfNN_aarch64_tls_relax (struct elf_aarch64_link_hash_table *globals,
+ ldr xd, [x0, #:tlsdesc_lo12:var] => ldr x0, [x0, #:gottprel_lo12:var]
+ */
+ insn = bfd_getl32 (contents + rel->r_offset);
+- insn &= 0xfffffff0;
++ insn &= 0xffffffe0;
+ bfd_putl32 (insn, contents + rel->r_offset);
+ return bfd_reloc_continue;
+ }
+diff --git a/ld/testsuite/ld-aarch64/tls-relax-gdesc-ie.s b/ld/testsuite/ld-aarch64/tls-relax-gdesc-ie.s
+index c20690c..38b3721 100644
+--- a/ld/testsuite/ld-aarch64/tls-relax-gdesc-ie.s
++++ b/ld/testsuite/ld-aarch64/tls-relax-gdesc-ie.s
+@@ -4,7 +4,7 @@ var:
+ .word 2
+ .text
+ adrp x0, :tlsdesc:var
+- ldr x1, [x0, #:tlsdesc_lo12:var]
++ ldr x17, [x0, #:tlsdesc_lo12:var]
+ add x0, x0, :tlsdesc_lo12:var
+ .tlsdesccall var
+ blr x1
diff --git a/binutils-2.24-aarch64-fix-static-ifunc.patch b/binutils-2.24-aarch64-fix-static-ifunc.patch
new file mode 100644
index 0000000..296f162
--- /dev/null
+++ b/binutils-2.24-aarch64-fix-static-ifunc.patch
@@ -0,0 +1,118 @@
+commit 14d96265dd8fd934d868c0b8e1991e2fefbe9fc8
+Author: Will Newton <will.newton at linaro.org>
+Date: Mon Nov 25 14:44:59 2013 +0000
+
+ bfd/elfnn-aarch64.c: Handle static links with ifunc correctly.
+
+ The code for handling GOT references to ifunc symbols in static links
+ was missing.
+
+ bfd/ChangeLog:
+
+ 2013-11-26 Will Newton <will.newton at linaro.org>
+
+ * elfnn-aarch64.c (elfNN_aarch64_finish_dynamic_symbol):
+ Handle STT_GNU_IFUNC symbols correctly in static links.
+
+ ld/testsuite/ChangeLog:
+
+ 2013-11-26 Will Newton <will.newton at linaro.org>
+
+ * ld-aarch64/aarch64-elf.exp: Add ifunc-22.
+ * ld-aarch64/ifunc-22.d: New file.
+ * ld-aarch64/ifunc-22.s: Likewise.
+
+diff --git a/bfd/elfnn-aarch64.c b/bfd/elfnn-aarch64.c
+index 3cd3a18..9053635 100644
+--- a/bfd/elfnn-aarch64.c
++++ b/bfd/elfnn-aarch64.c
+@@ -6824,7 +6824,34 @@ elfNN_aarch64_finish_dynamic_symbol (bfd *output_bfd,
+ + htab->root.sgot->output_offset
+ + (h->got.offset & ~(bfd_vma) 1));
+
+- if (info->shared && SYMBOL_REFERENCES_LOCAL (info, h))
++ if (h->def_regular
++ && h->type == STT_GNU_IFUNC)
++ {
++ if (info->shared)
++ {
++ /* Generate R_AARCH64_GLOB_DAT. */
++ goto do_glob_dat;
++ }
++ else
++ {
++ asection *plt;
++
++ if (!h->pointer_equality_needed)
++ abort ();
++
++ /* For non-shared object, we can't use .got.plt, which
++ contains the real function address if we need pointer
++ equality. We load the GOT entry with the PLT entry. */
++ plt = htab->root.splt ? htab->root.splt : htab->root.iplt;
++ bfd_put_NN (output_bfd, (plt->output_section->vma
++ + plt->output_offset
++ + h->plt.offset),
++ htab->root.sgot->contents
++ + (h->got.offset & ~(bfd_vma) 1));
++ return TRUE;
++ }
++ }
++ else if (info->shared && SYMBOL_REFERENCES_LOCAL (info, h))
+ {
+ if (!h->def_regular)
+ return FALSE;
+@@ -6837,6 +6864,7 @@ elfNN_aarch64_finish_dynamic_symbol (bfd *output_bfd,
+ }
+ else
+ {
++do_glob_dat:
+ BFD_ASSERT ((h->got.offset & 1) == 0);
+ bfd_put_NN (output_bfd, (bfd_vma) 0,
+ htab->root.sgot->contents + h->got.offset);
+diff --git a/ld/testsuite/ld-aarch64/aarch64-elf.exp b/ld/testsuite/ld-aarch64/aarch64-elf.exp
+index a6b3ea2..692bf34 100644
+--- a/ld/testsuite/ld-aarch64/aarch64-elf.exp
++++ b/ld/testsuite/ld-aarch64/aarch64-elf.exp
+@@ -156,3 +156,4 @@ run_dump_test "ifunc-19a"
+ run_dump_test "ifunc-19b"
+ run_dump_test "ifunc-20"
+ run_dump_test "ifunc-21"
++run_dump_test "ifunc-22"
+diff --git a/ld/testsuite/ld-aarch64/ifunc-22.d b/ld/testsuite/ld-aarch64/ifunc-22.d
+new file mode 100644
+index 0000000..f28b039
+--- /dev/null
++++ b/ld/testsuite/ld-aarch64/ifunc-22.d
+@@ -0,0 +1,11 @@
++#source: ifunc-22.s
++#objdump: -s -j .got
++#ld: -static
++#target: aarch64*-*-*
++
++# Ensure GOT is populated correctly in static link
++
++.*: file format elf64-(little|big)aarch64
++
++Contents of section \.got:
++ 4100f0 00000000 00000000 d0004000 00000000 .......... at .....
+diff --git a/ld/testsuite/ld-aarch64/ifunc-22.s b/ld/testsuite/ld-aarch64/ifunc-22.s
+new file mode 100644
+index 0000000..69a87bb
+--- /dev/null
++++ b/ld/testsuite/ld-aarch64/ifunc-22.s
+@@ -0,0 +1,14 @@
++ .text
++ .type ifunc, @gnu_indirect_function
++ .global ifunc
++ifunc:
++ ret
++ .size ifunc, .-ifunc
++ .type _start, @function
++ .globl _start
++_start:
++ adrp x0, :got:ifunc
++ ldr x0, [x0, #:got_lo12:ifunc]
++ .size _start, .-_start
++ .data
++ .xword ifunc
diff --git a/binutils-2.24-elfnn-aarch64.patch b/binutils-2.24-elfnn-aarch64.patch
index 2491e0f..469387b 100644
--- a/binutils-2.24-elfnn-aarch64.patch
+++ b/binutils-2.24-elfnn-aarch64.patch
@@ -19,75 +19,3 @@
struct elf_aarch64_local_symbol
{
-*************** elfNN_aarch64_final_link_relocate (reloc
-*** 3589,3595 ****
-
- if (globals->root.splt != NULL)
- {
-! plt_index = h->plt.offset / globals->plt_entry_size - 1;
- off = (plt_index + 3) * GOT_ENTRY_SIZE;
- base_got = globals->root.sgotplt;
- }
---- 3589,3596 ----
-
- if (globals->root.splt != NULL)
- {
-! plt_index = ((h->plt.offset - globals->plt_header_size) /
-! globals->plt_entry_size);
- off = (plt_index + 3) * GOT_ENTRY_SIZE;
- base_got = globals->root.sgotplt;
- }
-*************** elfNN_aarch64_finish_dynamic_symbol (bfd
-*** 6823,6829 ****
- + htab->root.sgot->output_offset
- + (h->got.offset & ~(bfd_vma) 1));
-
-! if (info->shared && SYMBOL_REFERENCES_LOCAL (info, h))
- {
- if (!h->def_regular)
- return FALSE;
---- 6824,6857 ----
- + htab->root.sgot->output_offset
- + (h->got.offset & ~(bfd_vma) 1));
-
-! if (h->def_regular
-! && h->type == STT_GNU_IFUNC)
-! {
-! if (info->shared)
-! {
-! /* Generate R_AARCH64_GLOB_DAT. */
-! goto do_glob_dat;
-! }
-! else
-! {
-! asection *plt;
-!
-! if (!h->pointer_equality_needed)
-! abort ();
-!
-! /* For non-shared object, we can't use .got.plt, which
-! contains the real function address if we need pointer
-! equality. We load the GOT entry with the PLT entry. */
-! plt = htab->root.splt ? htab->root.splt : htab->root.iplt;
-! bfd_put_NN (output_bfd, (plt->output_section->vma
-! + plt->output_offset
-! + h->plt.offset),
-! htab->root.sgot->contents
-! + (h->got.offset & ~(bfd_vma) 1));
-! return TRUE;
-! }
-! }
-! else if (info->shared && SYMBOL_REFERENCES_LOCAL (info, h))
- {
- if (!h->def_regular)
- return FALSE;
-*************** elfNN_aarch64_finish_dynamic_symbol (bfd
-*** 6836,6841 ****
---- 6864,6870 ----
- }
- else
- {
-+ do_glob_dat:
- BFD_ASSERT ((h->got.offset & 1) == 0);
- bfd_put_NN (output_bfd, (bfd_vma) 0,
- htab->root.sgot->contents + h->got.offset);
diff --git a/binutils.spec b/binutils.spec
index b56aaf0..8d0305c 100644
--- a/binutils.spec
+++ b/binutils.spec
@@ -19,7 +19,7 @@
Summary: A GNU collection of binary utilities
Name: %{?cross}binutils%{?_with_debug:-debug}
Version: 2.24
-Release: 22%{?dist}
+Release: 23%{?dist}
License: GPLv3+
Group: Development/Tools
URL: http://sources.redhat.com/binutils
@@ -68,6 +68,9 @@ Patch23: binutils-2.24-aarch64-ld-shared-non-PIC-xfail.patch
Patch24: binutils-2.24-weak-sym-merge.patch
Patch25: binutils-2.24-indirect-chain.patch
Patch26: binutils-2.24-aarch64-fix-final_link_relocate.patch
+Patch27: binutils-2.24-aarch64-fix-gotplt-offset-ifunc.patch
+Patch28: binutils-2.24-aarch64-fix-static-ifunc.patch
+Patch29: binutils-2.24-aarch64-fix-ie-relax.patch
Provides: bundled(libiberty)
@@ -198,6 +201,9 @@ using libelf instead of BFD.
%patch24 -p0 -b .weak-sym-merge~
%patch25 -p0 -b .indirect-chain~
%patch26 -p1 -b .aa64-final-link~
+%patch27 -p1 -b .aa64-1~
+%patch28 -p1 -b .aa64-2~
+%patch29 -p1 -b .aa64-3~
# We cannot run autotools as there is an exact requirement of autoconf-2.59.
@@ -511,6 +517,14 @@ exit 0
%endif # %{isnative}
%changelog
+* Fri Aug 22 2014 Kyle McMartin <kmcmarti at redhat.com> - 2.24-23
+- binutils-2.24-aarch64-fix-gotplt-offset-ifunc.patch
+ binutils-2.24-aarch64-fix-static-ifunc.patch, split elfnn-aarch64 patches
+ into upstream git commits, to make it easier to figure out what's
+ backported already
+- binutils-2.24-aarch64-fix-ie-relax.patch: add fix for gd to ie relaxation
+ when target register is >16 (pretty unlikely, but...)
+
* Thu Aug 21 2014 Kyle McMartin <kmcmarti at redhat.com> - 2.24-22
- bfd/elfnn-aarch64.c: use correct offsets in final_link_relocate
Resolves: BZ #1126199
More information about the scm-commits
mailing list