From 5cd1d8bcc24e948e86a636161e6d72f6316545a7 Mon Sep 17 00:00:00 2001 From: Yury Norov Date: Thu, 1 Dec 2016 12:31:51 +0000 Subject: 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. --- bfd/elfnn-aarch64.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) (limited to 'bfd/elfnn-aarch64.c') 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; } -- cgit v1.1