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
This commit is contained in:
parent
404956d0f6
commit
422f7b7960
103
binutils-2.24-aarch64-fix-gotplt-offset-ifunc.patch
Normal file
103
binutils-2.24-aarch64-fix-gotplt-offset-ifunc.patch
Normal file
@ -0,0 +1,103 @@
|
||||
commit 67428c4aa56d4183d0f531e0d752040745a94423
|
||||
Author: Will Newton <will.newton@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@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@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
|
40
binutils-2.24-aarch64-fix-ie-relax.patch
Normal file
40
binutils-2.24-aarch64-fix-ie-relax.patch
Normal file
@ -0,0 +1,40 @@
|
||||
commit 44f814ce5066f10a3bed29c45d10e0d38f4fa433
|
||||
Author: Marcus Shawcroft <marcus.shawcroft@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
|
118
binutils-2.24-aarch64-fix-static-ifunc.patch
Normal file
118
binutils-2.24-aarch64-fix-static-ifunc.patch
Normal file
@ -0,0 +1,118 @@
|
||||
commit 14d96265dd8fd934d868c0b8e1991e2fefbe9fc8
|
||||
Author: Will Newton <will.newton@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@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@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 ..........@.....
|
||||
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
|
@ -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);
|
||||
|
@ -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@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@redhat.com> - 2.24-22
|
||||
- bfd/elfnn-aarch64.c: use correct offsets in final_link_relocate
|
||||
Resolves: BZ #1126199
|
||||
|
Loading…
Reference in New Issue
Block a user