From: Jiong Wang Date: Wed, 9 Sep 2015 13:19:28 +0000 (+0100) Subject: [AArch64] Relax TLS local dynamic traditional into local executable X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=259364adb8ced6dc0e3ae5bec2c6f76ec3faf955;p=binutils-gdb.git [AArch64] Relax TLS local dynamic traditional into local executable The linker relaxation logic will be: Code sequence I (tiny): 0x00 adr x0, :tlsldm:x 0x04 bl __tls_get_addr | V 0x00 mrs x0, tpidr_el0 0x04 add x0, x0, TCB_SIZE Code sequence II (small): 0x00 adrp a0, :tlsldm:x 0x04 add a0, #:tlsldm_lo12:x 0x08 bl __tls_get_addr | V 0x00 mrs x0, tpidr_el0 0x04 add x0, x0, TCB_SIZE 0x08 nop 2015-09-09 Jiong Wang bfd/ * elfnn-aarch64.c (aarch64_tls_transition_without_check): Support three TLS local dynamic traditional relocations types. (elfNN_aarch64_tls_relax): Support TLS local dynamic traditional to local executable relaxation. ld/testsuite/ * ld-aarch64/tls-relax-ld-le-tiny.s: New testcase. * ld-aarch64/tls-relax-ld-le-small.s: Likewise. * ld-aarch64/tls-relax-ld-le-tiny.d: New expectation file. * ld-aarch64/tls-relax-ld-le-small.d: Likewise. * ld-aarch64/aarch64-elf.exp: Run new testcases. --- diff --git a/bfd/ChangeLog b/bfd/ChangeLog index d51800e855d..1a07fbabb9e 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,10 @@ +2015-09-09 Jiong Wang + + * elfnn-aarch64.c (aarch64_tls_transition_without_check): Support three + TLS local dynamic traditional relocations types. + (elfNN_aarch64_tls_relax): Support TLS local dynamic traditional to + local executable relaxation. + 2015-09-03 H.J. Lu * elf64-x86-64.c (elf_x86_64_convert_mov_to_lea): Remove diff --git a/bfd/elfnn-aarch64.c b/bfd/elfnn-aarch64.c index 3c4392477c3..696fdcc1325 100644 --- a/bfd/elfnn-aarch64.c +++ b/bfd/elfnn-aarch64.c @@ -213,6 +213,9 @@ || (R_TYPE) == BFD_RELOC_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21 \ || (R_TYPE) == BFD_RELOC_AARCH64_TLSIE_LD_GOTTPREL_PREL19 \ || (R_TYPE) == BFD_RELOC_AARCH64_TLSIE_LDNN_GOTTPREL_LO12_NC \ + || (R_TYPE) == BFD_RELOC_AARCH64_TLSLD_ADD_LO12_NC \ + || (R_TYPE) == BFD_RELOC_AARCH64_TLSLD_ADR_PAGE21 \ + || (R_TYPE) == BFD_RELOC_AARCH64_TLSLD_ADR_PREL21 \ || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_ADR_PAGE21 \ || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_ADR_PREL21 \ || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_LD_PREL19 \ @@ -4390,6 +4393,11 @@ aarch64_tls_transition_without_check (bfd_reloc_code_real_type r_type, /* Instructions with these relocations will become NOPs. */ return BFD_RELOC_AARCH64_NONE; + case BFD_RELOC_AARCH64_TLSLD_ADD_LO12_NC: + case BFD_RELOC_AARCH64_TLSLD_ADR_PAGE21: + case BFD_RELOC_AARCH64_TLSLD_ADR_PREL21: + return is_local ? BFD_RELOC_AARCH64_NONE : r_type; + default: break; } @@ -5616,6 +5624,51 @@ elfNN_aarch64_tls_relax (struct elf_aarch64_link_hash_table *globals, } return bfd_reloc_continue; + case BFD_RELOC_AARCH64_TLSLD_ADR_PREL21: + /* LD->LE relaxation (tiny): + adr x0, :tlsldm:x => mrs x0, tpidr_el0 + bl __tls_get_addr => add x0, x0, TCB_SIZE + */ + if (is_local) + { + BFD_ASSERT (rel->r_offset + 4 == rel[1].r_offset); + BFD_ASSERT (ELFNN_R_TYPE (rel[1].r_info) == AARCH64_R (CALL26)); + /* No need of CALL26 relocation for tls_get_addr. */ + rel[1].r_info = ELFNN_R_INFO (STN_UNDEF, R_AARCH64_NONE); + bfd_putl32 (0xd53bd040, contents + rel->r_offset + 0); + bfd_putl32 (0x91004000, contents + rel->r_offset + 4); + return bfd_reloc_ok; + } + return bfd_reloc_continue; + + case BFD_RELOC_AARCH64_TLSLD_ADR_PAGE21: + /* LD->LE relaxation (small): + adrp x0, :tlsldm:x => mrs x0, tpidr_el0 + */ + if (is_local) + { + bfd_putl32 (0xd53bd040, contents + rel->r_offset); + return bfd_reloc_ok; + } + return bfd_reloc_continue; + + case BFD_RELOC_AARCH64_TLSLD_ADD_LO12_NC: + /* LD->LE relaxation (small): + add x0, #:tlsldm_lo12:x => add x0, x0, TCB_SIZE + bl __tls_get_addr => nop + */ + if (is_local) + { + BFD_ASSERT (rel->r_offset + 4 == rel[1].r_offset); + BFD_ASSERT (ELFNN_R_TYPE (rel[1].r_info) == AARCH64_R (CALL26)); + /* No need of CALL26 relocation for tls_get_addr. */ + rel[1].r_info = ELFNN_R_INFO (STN_UNDEF, R_AARCH64_NONE); + bfd_putl32 (0x91004000, contents + rel->r_offset + 0); + bfd_putl32 (0xd503201f, contents + rel->r_offset + 4); + return bfd_reloc_ok; + } + return bfd_reloc_continue; + default: return bfd_reloc_continue; } diff --git a/ld/testsuite/ChangeLog b/ld/testsuite/ChangeLog index c92d1e4538b..ce7f8b711e6 100644 --- a/ld/testsuite/ChangeLog +++ b/ld/testsuite/ChangeLog @@ -1,3 +1,11 @@ +2015-09-09 Jiong Wang + + * ld-aarch64/tls-relax-ld-le-tiny.s: New testcase. + * ld-aarch64/tls-relax-ld-le-small.s: Likewise. + * ld-aarch64/tls-relax-ld-le-tiny.d: New expectation file. + * ld-aarch64/tls-relax-ld-le-small.d: Likewise. + * ld-aarch64/aarch64-elf.exp: Run new testcases. + 2015-09-07 Andrew Burgess * ld-elf/orphan-7.map: Allow for other discarded sections. diff --git a/ld/testsuite/ld-aarch64/aarch64-elf.exp b/ld/testsuite/ld-aarch64/aarch64-elf.exp index cbbe6a91477..955484e1f59 100644 --- a/ld/testsuite/ld-aarch64/aarch64-elf.exp +++ b/ld/testsuite/ld-aarch64/aarch64-elf.exp @@ -178,6 +178,8 @@ run_dump_test "tls-relax-gdesc-le" run_dump_test "tls-relax-gd-ie" run_dump_test "tls-relax-gdesc-ie" run_dump_test "tls-relax-ie-le" +run_dump_test "tls-relax-ld-le-small" +run_dump_test "tls-relax-ld-le-tiny" run_dump_test "tls-desc-ie" run_dump_test "tls-relax-gdesc-ie-2" run_dump_test "tls-relax-gdesc-le-2" diff --git a/ld/testsuite/ld-aarch64/tls-relax-ld-le-small.d b/ld/testsuite/ld-aarch64/tls-relax-ld-le-small.d new file mode 100644 index 00000000000..fa648291fdb --- /dev/null +++ b/ld/testsuite/ld-aarch64/tls-relax-ld-le-small.d @@ -0,0 +1,13 @@ +#source: tls-relax-ld-le-small.s +#ld: -T relocs.ld -e0 +#objdump: -dr +#... + +10000: 910003fd mov x29, sp + +10004: d53bd040 mrs x0, tpidr_el0 + +10008: 91004000 add x0, x0, #0x10 + +1000c: d503201f nop + +10010: d503201f nop + +10014: 91400001 add x1, x0, #0x0, lsl #12 + +10018: 91000021 add x1, x1, #0x0 + +1001c: 90000000 adrp x0, 10000 <.*> + +10020: d65f03c0 ret diff --git a/ld/testsuite/ld-aarch64/tls-relax-ld-le-small.s b/ld/testsuite/ld-aarch64/tls-relax-ld-le-small.s new file mode 100644 index 00000000000..ea58500b748 --- /dev/null +++ b/ld/testsuite/ld-aarch64/tls-relax-ld-le-small.s @@ -0,0 +1,27 @@ + .cpu generic+fp+simd + .section .text.startup,"ax",%progbits + .align 2 + .p2align 3,,7 + .global main + .type main, %function +main: + add x29, sp, 0 + adrp x0, :tlsldm:global_a0 + add x0, x0, #:tlsldm_lo12_nc:global_a0 + bl __tls_get_addr + nop + add x1, x0, #:dtprel_hi12:global_a0, lsl #12 + add x1, x1, #:dtprel_lo12_nc:global_a0 + adrp x0, .LC0 + ret + .size main, .-main + .section .rodata.str1.8,"aMS",%progbits,1 + .align 3 +.LC0: + .string "Hello world %d\n" + .section .tdata,"awT",%progbits + .align 2 + .type global_a0, %object + .size global_a0, 4 +global_a0: + .word 16 diff --git a/ld/testsuite/ld-aarch64/tls-relax-ld-le-tiny.d b/ld/testsuite/ld-aarch64/tls-relax-ld-le-tiny.d new file mode 100644 index 00000000000..db226775346 --- /dev/null +++ b/ld/testsuite/ld-aarch64/tls-relax-ld-le-tiny.d @@ -0,0 +1,12 @@ +#source: tls-relax-ld-le-tiny.s +#ld: -T relocs.ld -e0 +#objdump: -dr +#... + +10000: 910003fd mov x29, sp + +10004: d53bd040 mrs x0, tpidr_el0 + +10008: 91004000 add x0, x0, #0x10 + +1000c: d503201f nop + +10010: 91400001 add x1, x0, #0x0, lsl #12 + +10014: 91000021 add x1, x1, #0x0 + +10018: 90000000 adrp x0, 10000
+ +1001c: d65f03c0 ret diff --git a/ld/testsuite/ld-aarch64/tls-relax-ld-le-tiny.s b/ld/testsuite/ld-aarch64/tls-relax-ld-le-tiny.s new file mode 100644 index 00000000000..2336f691d39 --- /dev/null +++ b/ld/testsuite/ld-aarch64/tls-relax-ld-le-tiny.s @@ -0,0 +1,26 @@ + .cpu generic+fp+simd + .section .text.startup,"ax",%progbits + .align 2 + .p2align 3,,7 + .global main + .type main, %function +main: + add x29, sp, 0 + adr x0, :tlsldm:global_a0 + bl __tls_get_addr + nop + add x1, x0, #:dtprel_hi12:global_a0, lsl #12 + add x1, x1, #:dtprel_lo12_nc:global_a0 + adrp x0, .LC0 + ret + .size main, .-main + .section .rodata.str1.8,"aMS",%progbits,1 + .align 3 +.LC0: + .string "Hello world %d\n" + .section .tdata,"awT",%progbits + .align 2 + .type global_a0, %object + .size global_a0, 4 +global_a0: + .word 16