Fix AArch64 relocation handling in ILP32 mode.
authorYury Norov <ynorov@caviumnetworks.com>
Mon, 23 Jan 2017 17:07:13 +0000 (17:07 +0000)
committerNick Clifton <nickc@redhat.com>
Mon, 23 Jan 2017 17:07:13 +0000 (17:07 +0000)
bfd * elfnn-aarch64.c: Fix relaxations for ILP32 mode.

ld * testsuite/ld-aarch64/aarch64-elf.exp: Run new tests.
* testsuite/ld-aarch64/tls-desc-ie-ilp32.d: New test.
* testsuite/ld-aarch64/tls-relax-all-ilp32.d: New test.
* testsuite/ld-aarch64/tls-relax-gd-le-ilp32.d: New test.
* testsuite/ld-aarch64/tls-relax-gdesc-le-2-ilp32.d: New test.
* testsuite/ld-aarch64/tls-relax-gdesc-le-ilp32.d: New test.
* testsuite/ld-aarch64/tls-relax-ie-le-2-ilp32.d: New test.
* testsuite/ld-aarch64/tls-relax-ie-le-3-ilp32.d: New test.
* testsuite/ld-aarch64/tls-relax-ie-le-ilp32.d: New test.
* testsuite/ld-aarch64/tls-tiny-desc-ie-ilp32.d: New test.
* testsuite/ld-aarch64/tls-tiny-desc-le-ilp32.d: New test.
* testsuite/ld-aarch64/tls-tiny-gd-ie-ilp32.d: New test.
* testsuite/ld-aarch64/tls-tiny-gd-le-ilp32.d: New test.

16 files changed:
bfd/ChangeLog
bfd/elfnn-aarch64.c
ld/ChangeLog
ld/testsuite/ld-aarch64/aarch64-elf.exp
ld/testsuite/ld-aarch64/tls-desc-ie-ilp32.d [new file with mode: 0644]
ld/testsuite/ld-aarch64/tls-relax-all-ilp32.d [new file with mode: 0644]
ld/testsuite/ld-aarch64/tls-relax-gd-le-ilp32.d [new file with mode: 0644]
ld/testsuite/ld-aarch64/tls-relax-gdesc-le-2-ilp32.d [new file with mode: 0644]
ld/testsuite/ld-aarch64/tls-relax-gdesc-le-ilp32.d [new file with mode: 0644]
ld/testsuite/ld-aarch64/tls-relax-ie-le-2-ilp32.d [new file with mode: 0644]
ld/testsuite/ld-aarch64/tls-relax-ie-le-3-ilp32.d [new file with mode: 0644]
ld/testsuite/ld-aarch64/tls-relax-ie-le-ilp32.d [new file with mode: 0644]
ld/testsuite/ld-aarch64/tls-tiny-desc-ie-ilp32.d [new file with mode: 0644]
ld/testsuite/ld-aarch64/tls-tiny-desc-le-ilp32.d [new file with mode: 0644]
ld/testsuite/ld-aarch64/tls-tiny-gd-ie-ilp32.d [new file with mode: 0644]
ld/testsuite/ld-aarch64/tls-tiny-gd-le-ilp32.d [new file with mode: 0644]

index f6841ef..857f57a 100644 (file)
@@ -1,3 +1,7 @@
+2017-01-23  Yury Norov  <ynorov@caviumnetworks.com>
+
+       * elfnn-aarch64.c: Fix relaxations for ILP32 mode.
+
 2017-01-20  Jiong Wang <jiong.wang@arm.com>
 
        * elfnn-aarch64.c (elf_aarch64_hash_symbol): New function.
index 213cf55..c86a3e1 100644 (file)
 #define PLT_SMALL_ENTRY_SIZE            (16)
 #define PLT_TLSDESC_ENTRY_SIZE          (32)
 
-/* Encoding of the nop instruction */
+/* Encoding of the nop instruction */
 #define INSN_NOP 0xd503201f
 
 #define aarch64_compute_jump_table_size(htab)          \
@@ -3266,9 +3266,7 @@ group_sections (struct elf_aarch64_link_hash_table *htab,
    For scalar LD/ST instructions PAIR is FALSE, RT is returned and RT2
    is set equal to RT.
 
-   For LD/ST pair instructions PAIR is TRUE, RT and RT2 are returned.
-
- */
+   For LD/ST pair instructions PAIR is TRUE, RT and RT2 are returned.  */
 
 static bfd_boolean
 aarch64_mem_op_p (uint32_t insn, unsigned int *rt, unsigned int *rt2,
@@ -5630,6 +5628,35 @@ elfNN_aarch64_final_link_relocate (reloc_howto_type *howto,
                                      howto, value);
 }
 
+/* LP64 and ILP32 operates on x- and w-registers respectively.
+   Next definitions take into account the difference between
+   corresponding machine codes. R means x-register if the target
+   arch is LP64, and w-register if the target is ILP32.  */
+
+#if ARCH_SIZE == 64
+# define add_R0_R0     (0x91000000)
+# define add_R0_R0_R1  (0x8b000020)
+# define add_R0_R1     (0x91400020)
+# define ldr_R0                (0x58000000)
+# define ldr_R0_mask(i)        (i & 0xffffffe0)
+# define ldr_R0_x0     (0xf9400000)
+# define ldr_hw_R0     (0xf2a00000)
+# define movk_R0       (0xf2800000)
+# define movz_R0       (0xd2a00000)
+# define movz_hw_R0    (0xd2c00000)
+#else /*ARCH_SIZE == 32 */
+# define add_R0_R0     (0x11000000)
+# define add_R0_R0_R1  (0x0b000020)
+# define add_R0_R1     (0x11400020)
+# define ldr_R0                (0x18000000)
+# define ldr_R0_mask(i)        (i & 0xbfffffe0)
+# define ldr_R0_x0     (0xb9400000)
+# define ldr_hw_R0     (0x72a00000)
+# define movk_R0       (0x72800000)
+# define movz_R0       (0x52a00000)
+# define movz_hw_R0    (0x52c00000)
+#endif
+
 /* Handle TLS relaxations.  Relaxing is possible for symbols that use
    R_AARCH64_TLSDESC_ADR_{PAGE, LD64_LO12_NC, ADD_LO12_NC} during a static
    link.
@@ -5656,11 +5683,12 @@ elfNN_aarch64_tls_relax (struct elf_aarch64_link_hash_table *globals,
       if (is_local)
        {
          /* GD->LE relaxation:
-            adrp x0, :tlsgd:var     =>   movz x0, :tprel_g1:var
+            adrp x0, :tlsgd:var     =>   movz R0, :tprel_g1:var
             or
-            adrp x0, :tlsdesc:var   =>   movz x0, :tprel_g1:var
-          */
-         bfd_putl32 (0xd2a00000, contents + rel->r_offset);
+            adrp x0, :tlsdesc:var   =>   movz R0, :tprel_g1:var
+
+            Where R is x for LP64, and w for ILP32.  */
+         bfd_putl32 (movz_R0, contents + rel->r_offset);
          return bfd_reloc_continue;
        }
       else
@@ -5681,11 +5709,12 @@ elfNN_aarch64_tls_relax (struct elf_aarch64_link_hash_table *globals,
       if (is_local)
        {
          /* Tiny TLSDESC->LE relaxation:
-            ldr   x1, :tlsdesc:var      =>  movz  x0, #:tprel_g1:var
-            adr   x0, :tlsdesc:var      =>  movk  x0, #:tprel_g0_nc:var
+            ldr   x1, :tlsdesc:var      =>  movz  R0, #:tprel_g1:var
+            adr   x0, :tlsdesc:var      =>  movk  R0, #:tprel_g0_nc:var
             .tlsdesccall var
             blr   x1                    =>  nop
-          */
+
+            Where R is x for LP64, and w for ILP32.  */
          BFD_ASSERT (ELFNN_R_TYPE (rel[1].r_info) == AARCH64_R (TLSDESC_ADR_PREL21));
          BFD_ASSERT (ELFNN_R_TYPE (rel[2].r_info) == AARCH64_R (TLSDESC_CALL));
 
@@ -5693,8 +5722,8 @@ elfNN_aarch64_tls_relax (struct elf_aarch64_link_hash_table *globals,
                                        AARCH64_R (TLSLE_MOVW_TPREL_G0_NC));
          rel[2].r_info = ELFNN_R_INFO (STN_UNDEF, R_AARCH64_NONE);
 
-         bfd_putl32 (0xd2a00000, contents + rel->r_offset);
-         bfd_putl32 (0xf2800000, contents + rel->r_offset + 4);
+         bfd_putl32 (movz_R0, contents + rel->r_offset);
+         bfd_putl32 (movk_R0, contents + rel->r_offset + 4);
          bfd_putl32 (INSN_NOP, contents + rel->r_offset + 8);
          return bfd_reloc_continue;
        }
@@ -5712,7 +5741,7 @@ elfNN_aarch64_tls_relax (struct elf_aarch64_link_hash_table *globals,
          rel[1].r_info = ELFNN_R_INFO (STN_UNDEF, R_AARCH64_NONE);
          rel[2].r_info = ELFNN_R_INFO (STN_UNDEF, R_AARCH64_NONE);
 
-         bfd_putl32 (0x58000000, contents + rel->r_offset);
+         bfd_putl32 (ldr_R0, contents + rel->r_offset);
          bfd_putl32 (INSN_NOP, contents + rel->r_offset + 4);
          bfd_putl32 (INSN_NOP, contents + rel->r_offset + 8);
          return bfd_reloc_continue;
@@ -5723,16 +5752,17 @@ elfNN_aarch64_tls_relax (struct elf_aarch64_link_hash_table *globals,
        {
          /* Tiny GD->LE relaxation:
             adr x0, :tlsgd:var      =>   mrs  x1, tpidr_el0
-             bl   __tls_get_addr     =>   add  x0, x1, #:tprel_hi12:x, lsl #12
-             nop                     =>   add  x0, x0, #:tprel_lo12_nc:x
-          */
+             bl   __tls_get_addr     =>   add  R0, R1, #:tprel_hi12:x, lsl #12
+             nop                     =>   add  R0, R0, #:tprel_lo12_nc:x
+
+            Where R is x for LP64, and x for Ilp32.  */
 
          /* First kill the tls_get_addr reloc on the bl instruction.  */
          BFD_ASSERT (rel->r_offset + 4 == rel[1].r_offset);
 
          bfd_putl32 (0xd53bd041, contents + rel->r_offset + 0);
-         bfd_putl32 (0x91400020, contents + rel->r_offset + 4);
-         bfd_putl32 (0x91000000, contents + rel->r_offset + 8);
+         bfd_putl32 (add_R0_R1, contents + rel->r_offset + 4);
+         bfd_putl32 (add_R0_R0, contents + rel->r_offset + 8);
 
          rel[1].r_info = ELFNN_R_INFO (ELFNN_R_SYM (rel->r_info),
                                        AARCH64_R (TLSLE_ADD_TPREL_LO12_NC));
@@ -5748,18 +5778,19 @@ elfNN_aarch64_tls_relax (struct elf_aarch64_link_hash_table *globals,
       else
        {
          /* Tiny GD->IE relaxation:
-            adr x0, :tlsgd:var      =>   ldr  x0, :gottprel:var
+            adr x0, :tlsgd:var      =>   ldr  R0, :gottprel:var
             bl   __tls_get_addr     =>   mrs  x1, tpidr_el0
-            nop                     =>   add  x0, x0, x1
-          */
+            nop                     =>   add  R0, R0, R1
+
+            Where R is x for LP64, and w for Ilp32.  */
 
          /* First kill the tls_get_addr reloc on the bl instruction.  */
          BFD_ASSERT (rel->r_offset + 4 == rel[1].r_offset);
          rel[1].r_info = ELFNN_R_INFO (STN_UNDEF, R_AARCH64_NONE);
 
-         bfd_putl32 (0x58000000, contents + rel->r_offset);
+         bfd_putl32 (ldr_R0, contents + rel->r_offset);
          bfd_putl32 (0xd53bd041, contents + rel->r_offset + 4);
-         bfd_putl32 (0x8b000020, contents + rel->r_offset + 8);
+         bfd_putl32 (add_R0_R0_R1, contents + rel->r_offset + 8);
          return bfd_reloc_continue;
        }
 
@@ -5782,11 +5813,11 @@ elfNN_aarch64_tls_relax (struct elf_aarch64_link_hash_table *globals,
                                        AARCH64_R (TLSLE_MOVW_TPREL_G0_NC));
          rel[2].r_offset = rel->r_offset + 8;
 
-         bfd_putl32 (0xd2c00000, contents + rel->r_offset + 0);
-         bfd_putl32 (0xf2a00000, contents + rel->r_offset + 4);
-         bfd_putl32 (0xf2800000, contents + rel->r_offset + 8);
+         bfd_putl32 (movz_hw_R0, contents + rel->r_offset + 0);
+         bfd_putl32 (ldr_hw_R0, contents + rel->r_offset + 4);
+         bfd_putl32 (movk_R0, contents + rel->r_offset + 8);
          bfd_putl32 (0xd53bd041, contents + rel->r_offset + 12);
-         bfd_putl32 (0x8b000020, contents + rel->r_offset + 16);
+         bfd_putl32 (add_R0_R0_R1, contents + rel->r_offset + 16);
        }
       else
        {
@@ -5799,9 +5830,9 @@ elfNN_aarch64_tls_relax (struct elf_aarch64_link_hash_table *globals,
           */
          rel[2].r_info = ELFNN_R_INFO (STN_UNDEF, R_AARCH64_NONE);
          bfd_putl32 (0xd2a80000, contents + rel->r_offset + 0);
-         bfd_putl32 (0x58000000, contents + rel->r_offset + 8);
+         bfd_putl32 (ldr_R0, contents + rel->r_offset + 8);
          bfd_putl32 (0xd53bd041, contents + rel->r_offset + 12);
-         bfd_putl32 (0x8b000020, contents + rel->r_offset + 16);
+         bfd_putl32 (add_R0_R0_R1, contents + rel->r_offset + 16);
        }
       return bfd_reloc_continue;
 
@@ -5817,18 +5848,19 @@ elfNN_aarch64_tls_relax (struct elf_aarch64_link_hash_table *globals,
        {
          /* GD->LE relaxation:
             ldr xd, [x0, #:tlsdesc_lo12:var]   =>   movk x0, :tprel_g0_nc:var
-          */
-         bfd_putl32 (0xf2800000, contents + rel->r_offset);
+
+            Where R is x for lp64 mode, and w for ILP32 mode.  */
+         bfd_putl32 (movk_R0, contents + rel->r_offset);
          return bfd_reloc_continue;
        }
       else
        {
          /* GD->IE relaxation:
-            ldr xd, [x0, #:tlsdesc_lo12:var] => ldr x0, [x0, #:gottprel_lo12:var]
-          */
+            ldr xd, [x0, #:tlsdesc_lo12:var] => ldr R0, [x0, #:gottprel_lo12:var]
+
+            Where R is x for lp64 mode, and w for ILP32 mode.  */
          insn = bfd_getl32 (contents + rel->r_offset);
-         insn &= 0xffffffe0;
-         bfd_putl32 (insn, contents + rel->r_offset);
+         bfd_putl32 (ldr_R0_mask (insn), contents + rel->r_offset);
          return bfd_reloc_continue;
        }
 
@@ -5836,18 +5868,19 @@ elfNN_aarch64_tls_relax (struct elf_aarch64_link_hash_table *globals,
       if (is_local)
        {
          /* GD->LE relaxation
-            add  x0, #:tlsgd_lo12:var  => movk x0, :tprel_g0_nc:var
+            add  x0, #:tlsgd_lo12:var  => movk R0, :tprel_g0_nc:var
             bl   __tls_get_addr        => mrs  x1, tpidr_el0
-            nop                        => add  x0, x1, x0
-          */
+            nop                        => add  R0, R1, R0
+
+            Where R is x for lp64 mode, and w for ILP32 mode.  */
 
          /* First kill the tls_get_addr reloc on the bl instruction.  */
          BFD_ASSERT (rel->r_offset + 4 == rel[1].r_offset);
          rel[1].r_info = ELFNN_R_INFO (STN_UNDEF, R_AARCH64_NONE);
 
-         bfd_putl32 (0xf2800000, contents + rel->r_offset);
+         bfd_putl32 (movk_R0, contents + rel->r_offset);
          bfd_putl32 (0xd53bd041, contents + rel->r_offset + 4);
-         bfd_putl32 (0x8b000020, contents + rel->r_offset + 8);
+         bfd_putl32 (add_R0_R0_R1, contents + rel->r_offset + 8);
          return bfd_reloc_continue;
        }
       else
@@ -5868,14 +5901,9 @@ elfNN_aarch64_tls_relax (struct elf_aarch64_link_hash_table *globals,
          /* 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.  */
-#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 (ldr_R0_x0, contents + rel->r_offset);
          bfd_putl32 (0xd53bd041, contents + rel[1].r_offset);
+         bfd_putl32 (add_R0_R0_R1, contents + rel[1].r_offset + 4);
          return bfd_reloc_continue;
        }
 
@@ -5893,70 +5921,76 @@ elfNN_aarch64_tls_relax (struct elf_aarch64_link_hash_table *globals,
       if (is_local)
        {
          /* GD->LE relaxation:
-            ldr xd, [gp, xn]   =>   movk x0, #:tprel_g0_nc:var
-          */
-         bfd_putl32 (0xf2800000, contents + rel->r_offset);
+            ldr xd, [gp, xn]   =>   movk R0, #:tprel_g0_nc:var
+
+            Where R is x for lp64 mode, and w for ILP32 mode.  */
+         bfd_putl32 (movk_R0, contents + rel->r_offset);
          return bfd_reloc_continue;
        }
       else
        {
          /* GD->IE relaxation:
-            ldr xd, [gp, xn]   =>   ldr x0, [gp, xn]
-          */
+            ldr xd, [gp, xn]   =>   ldr R0, [gp, xn]
+
+            Where R is x for lp64 mode, and w for ILP32 mode.  */
          insn = bfd_getl32 (contents + rel->r_offset);
-         insn &= 0xffffffe0;
-         bfd_putl32 (insn, contents + rel->r_offset);
+         bfd_putl32 (ldr_R0_mask (insn), contents + rel->r_offset);
          return bfd_reloc_ok;
        }
 
     case BFD_RELOC_AARCH64_TLSDESC_OFF_G0_NC:
       /* GD->LE relaxation:
-        movk xd, #:tlsdesc_off_g0_nc:var => movk x0, #:tprel_g1_nc:var, lsl #16
+        movk xd, #:tlsdesc_off_g0_nc:var => movk R0, #:tprel_g1_nc:var, lsl #16
         GD->IE relaxation:
-        movk xd, #:tlsdesc_off_g0_nc:var => movk xd, #:gottprel_g0_nc:var
-      */
+        movk xd, #:tlsdesc_off_g0_nc:var => movk Rd, #:gottprel_g0_nc:var
+
+        Where R is x for lp64 mode, and w for ILP32 mode.  */
       if (is_local)
-       bfd_putl32 (0xf2a00000, contents + rel->r_offset);
+       bfd_putl32 (ldr_hw_R0, contents + rel->r_offset);
       return bfd_reloc_continue;
 
     case BFD_RELOC_AARCH64_TLSDESC_OFF_G1:
       if (is_local)
        {
          /* GD->LE relaxation:
-            movz xd, #:tlsdesc_off_g1:var => movz x0, #:tprel_g2:var, lsl #32
-         */
-         bfd_putl32 (0xd2c00000, contents + rel->r_offset);
+            movz xd, #:tlsdesc_off_g1:var => movz R0, #:tprel_g2:var, lsl #32
+
+            Where R is x for lp64 mode, and w for ILP32 mode.  */
+         bfd_putl32 (movz_hw_R0, contents + rel->r_offset);
          return bfd_reloc_continue;
        }
       else
        {
          /*  GD->IE relaxation:
-             movz xd, #:tlsdesc_off_g1:var => movz xd, #:gottprel_g1:var, lsl #16
-         */
+             movz xd, #:tlsdesc_off_g1:var => movz Rd, #:gottprel_g1:var, lsl #16
+
+            Where R is x for lp64 mode, and w for ILP32 mode.  */
          insn = bfd_getl32 (contents + rel->r_offset);
-         bfd_putl32 (0xd2a00000 | (insn & 0x1f), contents + rel->r_offset);
+         bfd_putl32 (movz_R0 | (insn & 0x1f), contents + rel->r_offset);
          return bfd_reloc_continue;
        }
 
     case BFD_RELOC_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21:
       /* IE->LE relaxation:
-         adrp xd, :gottprel:var   =>   movz xd, :tprel_g1:var
-       */
+         adrp xd, :gottprel:var   =>   movz Rd, :tprel_g1:var
+
+        Where R is x for lp64 mode, and w for ILP32 mode.  */
       if (is_local)
        {
          insn = bfd_getl32 (contents + rel->r_offset);
-         bfd_putl32 (0xd2a00000 | (insn & 0x1f), contents + rel->r_offset);
+         bfd_putl32 (movz_R0 | (insn & 0x1f), contents + rel->r_offset);
        }
       return bfd_reloc_continue;
 
     case BFD_RELOC_AARCH64_TLSIE_LDNN_GOTTPREL_LO12_NC:
       /* IE->LE relaxation:
-         ldr  xd, [xm, #:gottprel_lo12:var]   =>   movk xd, :tprel_g0_nc:var
-       */
+         ldr  xd, [xm, #:gottprel_lo12:var]   =>   movk Rd, :tprel_g0_nc:var
+
+        Where R is x for lp64 mode, and w for ILP32 mode.  */
       if (is_local)
        {
          insn = bfd_getl32 (contents + rel->r_offset);
-         bfd_putl32 (0xf2800000 | (insn & 0x1f), contents + rel->r_offset);
+         bfd_putl32 (movk_R0 | (insn & 0x1f), contents + rel->r_offset);
        }
       return bfd_reloc_continue;
 
@@ -5973,11 +6007,8 @@ elfNN_aarch64_tls_relax (struct elf_aarch64_link_hash_table *globals,
          /* 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);
-#if ARCH_SIZE == 64
-         bfd_putl32 (0x91004000, contents + rel->r_offset + 4);
-#else
-         bfd_putl32 (0x11002000, contents + rel->r_offset + 4);
-#endif
+         bfd_putl32 (add_R0_R0 | (TCB_SIZE << 10),
+                     contents + rel->r_offset + 4);
          return bfd_reloc_ok;
        }
       return bfd_reloc_continue;
@@ -6005,11 +6036,8 @@ elfNN_aarch64_tls_relax (struct elf_aarch64_link_hash_table *globals,
          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);
-#if ARCH_SIZE == 64
-         bfd_putl32 (0x91004000, contents + rel->r_offset + 0);
-#else
-         bfd_putl32 (0x11002000, contents + rel->r_offset + 0);
-#endif
+         bfd_putl32 (add_R0_R0 | (TCB_SIZE << 10),
+                     contents + rel->r_offset + 0);
          bfd_putl32 (INSN_NOP, contents + rel->r_offset + 4);
          return bfd_reloc_ok;
        }
@@ -7158,7 +7186,7 @@ elfNN_aarch64_check_relocs (bfd *abfd, struct bfd_link_info *info,
              break;
            }
 
-         /* It is referenced by a non-shared object. */
+         /* It is referenced by a non-shared object.  */
          h->ref_regular = 1;
          h->root.non_ir_ref = 1;
        }
@@ -7961,8 +7989,7 @@ elfNN_aarch64_allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
      because we will also be presented with the concrete instance of
      the symbol and elfNN_aarch64_copy_indirect_symbol () will have been
      called to copy all relevant data from the generic to the concrete
-     symbol instance.
-   */
+     symbol instance.  */
   if (h->root.type == bfd_link_hash_indirect)
     return TRUE;
 
@@ -8251,8 +8278,7 @@ elfNN_aarch64_allocate_ifunc_dynrelocs (struct elf_link_hash_entry *h,
      because we will also be presented with the concrete instance of
      the symbol and elfNN_aarch64_copy_indirect_symbol () will have been
      called to copy all relevant data from the generic to the concrete
-     symbol instance.
-   */
+     symbol instance.  */
   if (h->root.type == bfd_link_hash_indirect)
     return TRUE;
 
@@ -8344,6 +8370,7 @@ aarch64_readonly_dynrelocs (struct elf_link_hash_entry * h, void * inf)
 
 /* This is the most important function of all . Innocuosly named
    though !  */
+
 static bfd_boolean
 elfNN_aarch64_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
                                     struct bfd_link_info *info)
@@ -8574,7 +8601,6 @@ elfNN_aarch64_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
             adjust_dynamic_symbol is called, and it is that
             function which decides whether anything needs to go
             into these sections.  */
-
          s->flags |= SEC_EXCLUDE;
          continue;
        }
@@ -8814,6 +8840,7 @@ elfNN_aarch64_always_size_sections (bfd *output_bfd,
 
 /* Finish up dynamic symbol handling.  We set the contents of various
    dynamic sections here.  */
+
 static bfd_boolean
 elfNN_aarch64_finish_dynamic_symbol (bfd *output_bfd,
                                     struct bfd_link_info *info,
@@ -8950,7 +8977,6 @@ do_glob_dat:
       bfd_byte *loc;
 
       /* This symbol needs a copy reloc.  Set it up.  */
-
       if (h->dynindx == -1
          || (h->root.type != bfd_link_hash_defined
              && h->root.type != bfd_link_hash_defweak)
@@ -9013,8 +9039,7 @@ elfNN_aarch64_init_small_plt0_entry (bfd *output_bfd ATTRIBUTE_UNUSED,
                                        // GOTPLT entry for this.
      br   x17
      PLT0 will be slightly different in ELF32 due to different got entry
-     size.
-   */
+     size.  */
   bfd_vma plt_got_2nd_ent;     /* Address of GOT[2].  */
   bfd_vma plt_base;
 
index 8615343..cf1d670 100644 (file)
@@ -1,3 +1,19 @@
+2017-01-23  Yury Norov  <ynorov@caviumnetworks.com>
+
+       * testsuite/ld-aarch64/aarch64-elf.exp: Run new tests.
+       * testsuite/ld-aarch64/tls-desc-ie-ilp32.d: New test.
+       * testsuite/ld-aarch64/tls-relax-all-ilp32.d: New test.
+       * testsuite/ld-aarch64/tls-relax-gd-le-ilp32.d: New test.
+       * testsuite/ld-aarch64/tls-relax-gdesc-le-2-ilp32.d: New test.
+       * testsuite/ld-aarch64/tls-relax-gdesc-le-ilp32.d: New test.
+       * testsuite/ld-aarch64/tls-relax-ie-le-2-ilp32.d: New test.
+       * testsuite/ld-aarch64/tls-relax-ie-le-3-ilp32.d: New test.
+       * testsuite/ld-aarch64/tls-relax-ie-le-ilp32.d: New test.
+       * testsuite/ld-aarch64/tls-tiny-desc-ie-ilp32.d: New test.
+       * testsuite/ld-aarch64/tls-tiny-desc-le-ilp32.d: New test.
+       * testsuite/ld-aarch64/tls-tiny-gd-ie-ilp32.d: New test.
+       * testsuite/ld-aarch64/tls-tiny-gd-le-ilp32.d: New test.
+
 2017-01-23  Nick Clifton  <nickc@redhat.com>
 
        * po/ga.po: Updated Irish translation.
index f77b169..ca21e17 100644 (file)
@@ -213,10 +213,13 @@ run_dump_test "farcall-b-section"
 run_dump_test "farcall-bl-section"
 
 run_dump_test "tls-relax-all"
+run_dump_test "tls-relax-all-ilp32"
 run_dump_test "tls-relax-gd-le"
+run_dump_test "tls-relax-gd-le-ilp32"
 run_dump_test "tls-relax-gdesc-le"
-run_dump_test "tls-relax-gd-ie-ilp32"
+run_dump_test "tls-relax-gdesc-le-ilp32"
 run_dump_test "tls-relax-gd-ie"
+run_dump_test "tls-relax-gd-ie-ilp32"
 run_dump_test_lp64 "tls-relax-large-gd-ie"
 run_dump_test_lp64 "tls-relax-large-gd-ie-be"
 run_dump_test_lp64 "tls-relax-large-gd-le"
@@ -227,21 +230,30 @@ run_dump_test_lp64 "tls-relax-large-desc-le"
 run_dump_test_lp64 "tls-relax-large-desc-le-be"
 run_dump_test "tls-relax-gdesc-ie"
 run_dump_test "tls-relax-ie-le"
+run_dump_test "tls-relax-ie-le-ilp32"
 run_dump_test "tls-relax-ld-le-small"
 run_dump_test "tls-relax-ld-le-small-ilp32"
 run_dump_test "tls-relax-ld-le-tiny"
 run_dump_test "tls-relax-ld-le-tiny-ilp32"
 run_dump_test "tls-desc-ie"
+run_dump_test "tls-desc-ie-ilp32"
 run_dump_test "tls-relax-gdesc-ie-2"
 run_dump_test "tls-relax-gdesc-le-2"
+run_dump_test "tls-relax-gdesc-le-2-ilp32"
 run_dump_test "tls-relax-ie-le-2"
+run_dump_test "tls-relax-ie-le-2-ilp32"
 run_dump_test "tls-relax-ie-le-3"
+run_dump_test "tls-relax-ie-le-3-ilp32"
 run_dump_test "tls-tiny-gd"
 run_dump_test "tls-tiny-gd-ie"
+run_dump_test "tls-tiny-gd-ie-ilp32"
 run_dump_test "tls-tiny-gd-le"
+run_dump_test "tls-tiny-gd-le-ilp32"
 run_dump_test "tls-tiny-desc"
 run_dump_test "tls-tiny-desc-ie"
+run_dump_test "tls-tiny-desc-ie-ilp32"
 run_dump_test "tls-tiny-desc-le"
+run_dump_test "tls-tiny-desc-le-ilp32"
 run_dump_test "tls-tiny-ie"
 run_dump_test_lp64 "tls-large-ie"
 run_dump_test_lp64 "tls-large-ie-be"
diff --git a/ld/testsuite/ld-aarch64/tls-desc-ie-ilp32.d b/ld/testsuite/ld-aarch64/tls-desc-ie-ilp32.d
new file mode 100644 (file)
index 0000000..40680a6
--- /dev/null
@@ -0,0 +1,37 @@
+#source: tls-desc-ie.s
+#as: -mabi=ilp32
+#ld: -shared -m [aarch64_choose_ilp32_emul] -T relocs-ilp32.ld -e0
+#objdump: -dr
+#...
+ +10000:       90000080        adrp    x0, 20000 <_GLOBAL_OFFSET_TABLE_>
+ +10004:       91002000        add     x0, x0, #0x8
+ +10008:       94000016        bl      10060 <.*>
+ +1000c:       d503201f        nop
+ +10010:       90000080        adrp    x0, 20000 <_GLOBAL_OFFSET_TABLE_>
+ +10014:       b9400400        ldr     w0, \[x0, #4\]
+ +10018:       d503201f        nop
+ +1001c:       d503201f        nop
+ +10020:       d53bd041        mrs     x1, tpidr_el0
+ +10024:       8b000020        add     x0, x1, x0
+ +10028:       d53bd042        mrs     x2, tpidr_el0
+ +1002c:       90000080        adrp    x0, 20000 <_GLOBAL_OFFSET_TABLE_>
+ +10030:       f9400400        ldr     x0, \[x0, #8\]
+ +10034:       8b000040        add     x0, x2, x0
+ +10038:       b9400000        ldr     w0, \[x0\]
+ +1003c:       0b000020        add     w0, w1, w0
+
+Disassembly of section .plt:
+
+00010040 <.plt>:
+ +10040:       a9bf7bf0        stp     x16, x30, \[sp, #-16\]!
+ +10044:       90000090        adrp    x16, 20000 <_GLOBAL_OFFSET_TABLE_>
+ +10048:       b9401a11        ldr     w17, \[x16, #24\]
+ +1004c:       11006210        add     w16, w16, #0x18
+ +10050:       d61f0220        br      x17
+ +10054:       d503201f        nop
+ +10058:       d503201f        nop
+ +1005c:       d503201f        nop
+ +10060:       90000090        adrp    x16, 20000 <_GLOBAL_OFFSET_TABLE_>
+ +10064:       b9401e11        ldr     w17, \[x16, #28\]
+ +10068:       11007210        add     w16, w16, #0x1c
+ +1006c:       d61f0220        br      x17
diff --git a/ld/testsuite/ld-aarch64/tls-relax-all-ilp32.d b/ld/testsuite/ld-aarch64/tls-relax-all-ilp32.d
new file mode 100644 (file)
index 0000000..1cb4ef4
--- /dev/null
@@ -0,0 +1,40 @@
+#source: tls-relax-all.s
+#as: -mabi=ilp32
+#ld: -m [aarch64_choose_ilp32_emul] -T relocs-ilp32.ld -e0
+#objdump: -dr
+#...
+ +10000:       a9bf7bfd        stp     x29, x30, \[sp, #-16\]!
+ +10004:       910003fd        mov     x29, sp
+ +10008:       90000080        adrp    x0, 20000 <_GLOBAL_OFFSET_TABLE_>
+ +1000c:       b9400400        ldr     w0, \[x0, #4\]
+ +10010:       d503201f        nop
+ +10014:       d503201f        nop
+ +10018:       d53bd041        mrs     x1, tpidr_el0
+ +1001c:       8b000020        add     x0, x1, x0
+ +10020:       b9400001        ldr     w1, \[x0\]
+ +10024:       52a00000        movz    w0, #0x0, lsl #16
+ +10028:       72800180        movk    w0, #0xc
+ +1002c:       d503201f        nop
+ +10030:       d503201f        nop
+ +10034:       d53bd042        mrs     x2, tpidr_el0
+ +10038:       8b000040        add     x0, x2, x0
+ +1003c:       b9400000        ldr     w0, \[x0\]
+ +10040:       0b000021        add     w1, w1, w0
+ +10044:       90000080        adrp    x0, 20000 <_GLOBAL_OFFSET_TABLE_>
+ +10048:       b9400800        ldr     w0, \[x0, #8\]
+ +1004c:       d53bd041        mrs     x1, tpidr_el0
+ +10050:       0b000020        add     w0, w1, w0
+ +10054:       b9400000        ldr     w0, \[x0\]
+ +10058:       0b000021        add     w1, w1, w0
+ +1005c:       52a00000        movz    w0, #0x0, lsl #16
+ +10060:       72800280        movk    w0, #0x14
+ +10064:       d53bd041        mrs     x1, tpidr_el0
+ +10068:       0b000020        add     w0, w1, w0
+ +1006c:       b9400000        ldr     w0, \[x0\]
+ +10070:       0b000021        add     w1, w1, w0
+ +10074:       d53bd042        mrs     x2, tpidr_el0
+ +10078:       52a00000        movz    w0, #0x0, lsl #16
+ +1007c:       72800300        movk    w0, #0x18
+ +10080:       8b000040        add     x0, x2, x0
+ +10084:       b9400000        ldr     w0, \[x0\]
+ +10088:       0b000020        add     w0, w1, w0
diff --git a/ld/testsuite/ld-aarch64/tls-relax-gd-le-ilp32.d b/ld/testsuite/ld-aarch64/tls-relax-gd-le-ilp32.d
new file mode 100644 (file)
index 0000000..dd91cb4
--- /dev/null
@@ -0,0 +1,10 @@
+#source: tls-relax-gd-le.s
+#as: -mabi=ilp32
+#ld: -m [aarch64_choose_ilp32_emul] -T relocs-ilp32.ld -e0
+#objdump: -dr
+#...
+ +10000:       52a00000        movz    w0, #0x0, lsl #16
+ +10004:       72800100        movk    w0, #0x8
+ +10008:       d53bd041        mrs     x1, tpidr_el0
+ +1000c:       0b000020        add     w0, w1, w0
+ +10010:       b9400000        ldr     w0, \[x0\]
diff --git a/ld/testsuite/ld-aarch64/tls-relax-gdesc-le-2-ilp32.d b/ld/testsuite/ld-aarch64/tls-relax-gdesc-le-2-ilp32.d
new file mode 100644 (file)
index 0000000..903b0b4
--- /dev/null
@@ -0,0 +1,19 @@
+#source: tls-relax-gdesc-le-2.s
+#as: -mabi=ilp32
+#ld: -m [aarch64_choose_ilp32_emul] -T relocs-ilp32.ld -e0
+#objdump: -dr
+#...
+ +10000:       52a00000        movz    w0, #0x0, lsl #16
+ +10004:       d503201f        nop
+ +10008:       d503201f        nop
+ +1000c:       72800100        movk    w0, #0x8
+ +10010:       d503201f        nop
+ +10014:       d503201f        nop
+ +10018:       d503201f        nop
+ +1001c:       d503201f        nop
+ +10020:       d503201f        nop
+ +10024:       d503201f        nop
+ +10028:       d503201f        nop
+ +1002c:       d53bd041        mrs     x1, tpidr_el0
+ +10030:       8b000020        add     x0, x1, x0
+ +10034:       b9400000        ldr     w0, \[x0\]
diff --git a/ld/testsuite/ld-aarch64/tls-relax-gdesc-le-ilp32.d b/ld/testsuite/ld-aarch64/tls-relax-gdesc-le-ilp32.d
new file mode 100644 (file)
index 0000000..020554b
--- /dev/null
@@ -0,0 +1,12 @@
+#source: tls-relax-gdesc-le.s
+#as: -mabi=ilp32
+#ld: -m [aarch64_choose_ilp32_emul] -T relocs-ilp32.ld -e0
+#objdump: -dr
+#...
+ +10000:       52a00000        movz    w0, #0x0, lsl #16
+ +10004:       72800100        movk    w0, #0x8
+ +10008:       d503201f        nop
+ +1000c:       d503201f        nop
+ +10010:       d53bd041        mrs     x1, tpidr_el0
+ +10014:       8b000020        add     x0, x1, x0
+ +10018:       b9400000        ldr     w0, \[x0\]
diff --git a/ld/testsuite/ld-aarch64/tls-relax-ie-le-2-ilp32.d b/ld/testsuite/ld-aarch64/tls-relax-ie-le-2-ilp32.d
new file mode 100644 (file)
index 0000000..71ee72c
--- /dev/null
@@ -0,0 +1,18 @@
+#source: tls-relax-ie-le-2.s
+#as: -mabi=ilp32
+#ld: -m [aarch64_choose_ilp32_emul] -T relocs-ilp32.ld -e0
+#objdump: -dr
+#...
+ +10000:       d53bd041        mrs     x1, tpidr_el0
+ +10004:       d503201f        nop
+ +10008:       d503201f        nop
+ +1000c:       52a00000        movz    w0, #0x0, lsl #16
+ +10010:       d503201f        nop
+ +10014:       d503201f        nop
+ +10018:       d503201f        nop
+ +1001c:       72800100        movk    w0, #0x8
+ +10020:       d503201f        nop
+ +10024:       8b000020        add     x0, x1, x0
+ +10028:       d503201f        nop
+ +1002c:       d503201f        nop
+ +10030:       b9400000        ldr     w0, \[x0\]
diff --git a/ld/testsuite/ld-aarch64/tls-relax-ie-le-3-ilp32.d b/ld/testsuite/ld-aarch64/tls-relax-ie-le-3-ilp32.d
new file mode 100644 (file)
index 0000000..e0bc05d
--- /dev/null
@@ -0,0 +1,10 @@
+#source: tls-relax-ie-le-3.s
+#as: -mabi=ilp32
+#ld: -m [aarch64_choose_ilp32_emul] -T relocs-ilp32.ld -e0
+#objdump: -dr
+#...
+ +10000:       d53bd042        mrs     x2, tpidr_el0
+ +10004:       52a0000f        movz    w15, #0x0, lsl #16
+ +10008:       7280010f        movk    w15, #0x8
+ +1000c:       8b0f004f        add     x15, x2, x15
+ +10010:       b94001e0        ldr     w0, \[x15\]
diff --git a/ld/testsuite/ld-aarch64/tls-relax-ie-le-ilp32.d b/ld/testsuite/ld-aarch64/tls-relax-ie-le-ilp32.d
new file mode 100644 (file)
index 0000000..ede3d8c
--- /dev/null
@@ -0,0 +1,10 @@
+#source: tls-relax-ie-le.s
+#as: -mabi=ilp32
+#ld: -m [aarch64_choose_ilp32_emul] -T relocs-ilp32.ld -e0
+#objdump: -dr
+#...
+ +10000:       d53bd041        mrs     x1, tpidr_el0
+ +10004:       52a00000        movz    w0, #0x0, lsl #16
+ +10008:       72800100        movk    w0, #0x8
+ +1000c:       8b000020        add     x0, x1, x0
+ +10010:       b9400000        ldr     w0, \[x0\]
diff --git a/ld/testsuite/ld-aarch64/tls-tiny-desc-ie-ilp32.d b/ld/testsuite/ld-aarch64/tls-tiny-desc-ie-ilp32.d
new file mode 100644 (file)
index 0000000..ebbaf85
--- /dev/null
@@ -0,0 +1,12 @@
+#source: tls-tiny-desc-ie.s
+#as: -mabi=ilp32
+#ld: -m [aarch64_choose_ilp32_emul] -T relocs-ilp32.ld -e0
+#objdump: -dr
+#...
+
+Disassembly of section .text:
+
+00010000 \<test\>:
+ +10000:       18080020        ldr     w0, 20004 \<_GLOBAL_OFFSET_TABLE_\+0x4\>
+ +10004:       d503201f        nop
+ +10008:       d503201f        nop
diff --git a/ld/testsuite/ld-aarch64/tls-tiny-desc-le-ilp32.d b/ld/testsuite/ld-aarch64/tls-tiny-desc-le-ilp32.d
new file mode 100644 (file)
index 0000000..79a6f5c
--- /dev/null
@@ -0,0 +1,12 @@
+#source: tls-tiny-desc-le.s
+#as: -mabi=ilp32
+#ld: -m [aarch64_choose_ilp32_emul] -T relocs-ilp32.ld -e0
+#objdump: -dr
+#...
+
+Disassembly of section .text:
+
+00010000 \<test\>:
+ +10000:       52a00000        movz    w0, #0x0, lsl #16
+ +10004:       72800100        movk    w0, #0x8
+ +10008:       d503201f        nop
diff --git a/ld/testsuite/ld-aarch64/tls-tiny-gd-ie-ilp32.d b/ld/testsuite/ld-aarch64/tls-tiny-gd-ie-ilp32.d
new file mode 100644 (file)
index 0000000..1ea6110
--- /dev/null
@@ -0,0 +1,12 @@
+#source: tls-tiny-gd-ie.s
+#as: -mabi=ilp32
+#ld: -m [aarch64_choose_ilp32_emul] -T relocs-ilp32.ld -e0
+#objdump: -dr
+#...
+
+Disassembly of section .text:
+
+00010000 \<test\>:
+ +10000:       18080020        ldr     w0, 20004 \<_GLOBAL_OFFSET_TABLE_\+0x4\>
+ +10004:       d53bd041        mrs     x1, tpidr_el0
+ +10008:       0b000020        add     w0, w1, w0
diff --git a/ld/testsuite/ld-aarch64/tls-tiny-gd-le-ilp32.d b/ld/testsuite/ld-aarch64/tls-tiny-gd-le-ilp32.d
new file mode 100644 (file)
index 0000000..5213a04
--- /dev/null
@@ -0,0 +1,12 @@
+#source: tls-tiny-gd-le.s
+#as: -mabi=ilp32
+#ld: -m [aarch64_choose_ilp32_emul] -T relocs-ilp32.ld -e0
+#objdump: -dr
+#...
+
+Disassembly of section .text:
+
+00010000 \<test\>:
+ +10000:       d53bd041        mrs     x1, tpidr_el0
+ +10004:       11400020        add     w0, w1, #0x0, lsl #12
+ +10008:       11002000        add     w0, w0, #0x8