422f7b7960
split some fixes out, so it's easier to see what's backported
41 lines
1.6 KiB
Diff
41 lines
1.6 KiB
Diff
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
|