[AArch64] Relax TLS local dynamic traditional into local executable
authorJiong Wang <jiong.wang@arm.com>
Wed, 9 Sep 2015 13:19:28 +0000 (14:19 +0100)
committerJiong Wang <jiong.wang@arm.com>
Wed, 9 Sep 2015 13:19:28 +0000 (14:19 +0100)
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  <jiong.wang@arm.com>

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.

bfd/ChangeLog
bfd/elfnn-aarch64.c
ld/testsuite/ChangeLog
ld/testsuite/ld-aarch64/aarch64-elf.exp
ld/testsuite/ld-aarch64/tls-relax-ld-le-small.d [new file with mode: 0644]
ld/testsuite/ld-aarch64/tls-relax-ld-le-small.s [new file with mode: 0644]
ld/testsuite/ld-aarch64/tls-relax-ld-le-tiny.d [new file with mode: 0644]
ld/testsuite/ld-aarch64/tls-relax-ld-le-tiny.s [new file with mode: 0644]

index d51800e855df390a2ef18a680222b4a26f8c546c..1a07fbabb9e34e7c95905d708018173d15c0ac2a 100644 (file)
@@ -1,3 +1,10 @@
+2015-09-09  Jiong Wang  <jiong.wang@arm.com>
+
+       * 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  <hongjiu.lu@intel.com>
 
        * elf64-x86-64.c (elf_x86_64_convert_mov_to_lea): Remove
index 3c4392477c3506eb272992e1a012cd9d43ee6435..696fdcc13253e84561ab06e897ed125964be2c3c 100644 (file)
    || (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;
     }
index c92d1e4538b4845ff49e2be41771f5b2fea97747..ce7f8b711e647d6a84743c218ad75dd275becb3d 100644 (file)
@@ -1,3 +1,11 @@
+2015-09-09  Jiong Wang  <jiong.wang@arm.com>
+
+       * 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  <andrew.burgess@embecosm.com>
 
        * ld-elf/orphan-7.map: Allow for other discarded sections.
index cbbe6a914776bd8c6049318f64dd7b40ad0c5ebf..955484e1f598570793f0b2fa88af521af250dc06 100644 (file)
@@ -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 (file)
index 0000000..fa64829
--- /dev/null
@@ -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 (file)
index 0000000..ea58500
--- /dev/null
@@ -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 (file)
index 0000000..db22677
--- /dev/null
@@ -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 <main>
+ +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 (file)
index 0000000..2336f69
--- /dev/null
@@ -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