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.
This commit is contained in:
Yury Norov 2016-12-01 12:31:51 +00:00 committed by Nick Clifton
parent 40a0bfddf0
commit 5cd1d8bcc2
6 changed files with 55 additions and 6 deletions

View File

@ -1,3 +1,9 @@
2016-12-01 Yury Norov <ynorov@caviumnetworks.com>
PR ld/20868
* elfnn-aarch64.c (elfNN_aarch64_tls_relax): Use 32-bit accesses
to the GOT when operating in 32-bit mode.
2016-12-01 Ma Jiang <ma.jiang@zte.com.cn> 2016-12-01 Ma Jiang <ma.jiang@zte.com.cn>
PR ld/16720 PR ld/16720

View File

@ -5841,24 +5841,29 @@ elfNN_aarch64_tls_relax (struct elf_aarch64_link_hash_table *globals,
else else
{ {
/* GD->IE relaxation /* 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 BL __tls_get_addr => mrs x1, tpidr_el0
R_AARCH64_CALL26 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)); BFD_ASSERT (ELFNN_R_TYPE (rel[1].r_info) == AARCH64_R (CALL26));
/* Remove the relocation on the BL instruction. */ /* Remove the relocation on the BL instruction. */
rel[1].r_info = ELFNN_R_INFO (STN_UNDEF, R_AARCH64_NONE); 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 /* We choose to fixup the BL and NOP instructions using the
offset from the second relocation to allow flexibility in offset from the second relocation to allow flexibility in
scheduling instructions between the ADD and BL. */ 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); bfd_putl32 (0x8b000020, contents + rel[1].r_offset + 4);
#endif
bfd_putl32 (0xd53bd041, contents + rel[1].r_offset);
return bfd_reloc_continue; return bfd_reloc_continue;
} }

View File

@ -1,3 +1,11 @@
2016-12-01 Yury Norov <ynorov@caviumnetworks.com>
PR ld/20868
* 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.
2016-11-28 Andrew Burgess <andrew.burgess@embecosm.com> 2016-11-28 Andrew Burgess <andrew.burgess@embecosm.com>
* emulparams/arclinux_prof.sh: Remove duplicate TEMPLATE_NAME. * emulparams/arclinux_prof.sh: Remove duplicate TEMPLATE_NAME.

View File

@ -189,6 +189,7 @@ run_dump_test "farcall-bl-section"
run_dump_test "tls-relax-all" run_dump_test "tls-relax-all"
run_dump_test "tls-relax-gd-le" run_dump_test "tls-relax-gd-le"
run_dump_test "tls-relax-gdesc-le" run_dump_test "tls-relax-gdesc-le"
run_dump_test "tls-relax-gd-ie-ilp32"
run_dump_test "tls-relax-gd-ie" run_dump_test "tls-relax-gd-ie"
run_dump_test "tls-relax-large-gd-ie" run_dump_test "tls-relax-large-gd-ie"
run_dump_test "tls-relax-large-gd-ie-be" run_dump_test "tls-relax-large-gd-ie-be"

View File

@ -0,0 +1,19 @@
/* Script for ld testsuite. */
OUTPUT_ARCH(aarch64:ilp32)
ENTRY(_start)
SECTIONS
{
/* Read-only sections, merged into text segment: */
PROVIDE (__executable_start = 0x8000); . = 0x10000;
.text :
{
*(.before)
*(.text)
*(.after)
} =0
. = 0x20000;
.got : { *(.got) *(.got.plt)}
. = 0x12340000;
.far : { *(.far) }
.ARM.attributes 0 : { *(.ARM.atttributes) }
}

View File

@ -0,0 +1,10 @@
#source: tls-relax-gd-ie.s
#as: -mabi=ilp32
#ld: -m [aarch64_choose_ilp32_emul] -T relocs-ilp32.ld -e0
#objdump: -dr
#...
+10000: 90000080 adrp x0, 20000 <_GLOBAL_OFFSET_TABLE_>
+10004: b9400400 ldr w0, \[x0, #4\]
+10008: d53bd041 mrs x1, tpidr_el0
+1000c: 0b000020 add w0, w1, w0
+10010: b9400000 ldr w0, \[x0\]