aboutsummaryrefslogtreecommitdiff
path: root/bfd/elfnn-aarch64.c
diff options
context:
space:
mode:
authorYury Norov <ynorov@caviumnetworks.com>2016-12-01 12:31:51 +0000
committerNick Clifton <nickc@redhat.com>2016-12-01 12:31:51 +0000
commit5cd1d8bcc24e948e86a636161e6d72f6316545a7 (patch)
tree7808d35833e73ee1e3de1c96d540ebb51226bc79 /bfd/elfnn-aarch64.c
parent40a0bfddf07620f5321927b3231502debb3b73bc (diff)
downloadgdb-5cd1d8bcc24e948e86a636161e6d72f6316545a7.zip
gdb-5cd1d8bcc24e948e86a636161e6d72f6316545a7.tar.gz
gdb-5cd1d8bcc24e948e86a636161e6d72f6316545a7.tar.bz2
Fix accesses to the GOT for AARCH64 operating in 32-bit mode.
PR ld/20868 bfd * elfnn-aarch64.c (elfNN_aarch64_tls_relax): Use 32-bit accesses to the GOT when operating in 32-bit mode. ld * testsuite/ld-aarch64/tls-relax-gd-ie-ilp32.d: New test. * testsuite/ld-aarch64/relocs-ilp32.ld: Linker script for the new test. * testsuite/ld-aarch64/aarch64-elf.exp: Run the new test.
Diffstat (limited to 'bfd/elfnn-aarch64.c')
-rw-r--r--bfd/elfnn-aarch64.c17
1 files changed, 11 insertions, 6 deletions
diff --git a/bfd/elfnn-aarch64.c b/bfd/elfnn-aarch64.c
index 99b2a04..ffa8e6a 100644
--- a/bfd/elfnn-aarch64.c
+++ b/bfd/elfnn-aarch64.c
@@ -5841,24 +5841,29 @@ elfNN_aarch64_tls_relax (struct elf_aarch64_link_hash_table *globals,
else
{
/* GD->IE relaxation
- ADD x0, #:tlsgd_lo12:var => ldr x0, [x0, #:gottprel_lo12:var]
+ ADD x0, #:tlsgd_lo12:var => ldr R0, [x0, #:gottprel_lo12:var]
BL __tls_get_addr => mrs x1, tpidr_el0
R_AARCH64_CALL26
- NOP => add x0, x1, x0
- */
+ NOP => add R0, R1, R0
+
+ Where R is x for lp64 mode, and w for ilp32 mode. */
BFD_ASSERT (ELFNN_R_TYPE (rel[1].r_info) == AARCH64_R (CALL26));
/* Remove the relocation on the BL instruction. */
rel[1].r_info = ELFNN_R_INFO (STN_UNDEF, R_AARCH64_NONE);
- bfd_putl32 (0xf9400000, contents + rel->r_offset);
-
/* We choose to fixup the BL and NOP instructions using the
offset from the second relocation to allow flexibility in
scheduling instructions between the ADD and BL. */
- bfd_putl32 (0xd53bd041, contents + rel[1].r_offset);
+#if ARCH_SIZE == 32
+ bfd_putl32 (0xb9400000, contents + rel->r_offset);
+ bfd_putl32 (0x0b000020, contents + rel[1].r_offset + 4);
+#else
+ bfd_putl32 (0xf9400000, contents + rel->r_offset);
bfd_putl32 (0x8b000020, contents + rel[1].r_offset + 4);
+#endif
+ bfd_putl32 (0xd53bd041, contents + rel[1].r_offset);
return bfd_reloc_continue;
}