]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
[Morello] TLS Descriptor support
authorSiddhesh Poyarekar <siddesh.poyarekar@arm.com>
Fri, 11 Sep 2020 03:48:11 +0000 (09:18 +0530)
committerJohn Baldwin <jhb@FreeBSD.org>
Thu, 1 Sep 2022 22:53:21 +0000 (15:53 -0700)
This change adds basic support for TLS descriptors.  Relaxation of
TLSDESC_GD to other relocations is limited to TLS_LE, other cases end
up retaining TLSDESC_GD.

There is one key difference from A64 for TLSDESC_GD -> LE transition
and that is in the case of static non-pie binaries.  Morello
TLSDESC_GD relocations are relaxed to LE for static non-pie binaries
since it ought to be safe to do so and it aligns with llvm behaviour.

bfd/ChangeLog:

2020-10-20  Siddhesh Poyarekar  <siddesh.poyarekar@arm.com>

* elfnn-aarch64.c (IS_AARCH64_TLSDESC_RELOC): Add Morello
relocations.
(elfNN_aarch64_tlsdesc_small_plt_c64_entry): New Morello
tlsdesc PLT entry.
(elfNN_aarch64_howto_table): Add TLSDESC_ADR_PAGE20,
TLSDESC_LD128_LO12, TLSDESC_CALL, TLSDESC relocations for
Morello.
(aarch64_tls_transition_without_check): Add INFO and
MORELLO_RELOC arguments.  Add morello TLSDESC relocations.
(aarch64_reloc_got_type, elfNN_aarch64_final_link_relocate,
elfNN_aarch64_tls_relax, elfNN_aarch64_check_relocs,
aarch64_can_relax_tls): Add morello TLSDESC relocations.
(aarch64_tls_transition): Add transitions for morello TLSDESC
relocations.
(elfNN_aarch64_tls_relax): Add relaxations for morello
TLSDESC.
(elfNN_aarch64_relocate_section): Emit dynamic relocation for
Morello static relocations.
(elfNN_aarch64_allocate_dynrelocs): Allocate dynamic
relocation space for Morello TLSDESC.
(elfNN_aarch64_finish_dynamic_sections): Emit Morello tlsdesc
PLT entry.
* elfxx-aarch64.c (_bfd_aarch64_elf_put_addend,
_bfd_aarch64_elf_resolve_relocation): Add Morello relocations.
* reloc.c: Add Morello relocations.
* bfd-in2.h: Regenerate.
* libbfd.h: Regenerate.

gas/ChangeLog:

2020-10-20  Siddhesh Poyarekar  <siddesh.poyarekar@arm.com>

* config/tc-aarch64.c (s_tlsdesccall): Emit Morello
TLSDESC_CALL in C64 code.
(reloc_table): Add Morello relocation.
(md_apply_fix): Emit Morello TLSDESC_LD128_LO12 in C64 code.
(aarch64_force_relocation): Add Morello TLSDESC relocations.
* testsuite/gas/aarch64/morello-tlsdesc-c64.d: New file.
* testsuite/gas/aarch64/morello-tlsdesc.d: New file.
* testsuite/gas/aarch64/morello-tlsdesc.s: New file.

include/ChangeLog:

2020-10-20  Siddhesh Poyarekar  <siddesh.poyarekar@arm.com>

* elf/aarch64.h: New Morello TLSDESC relocations.

ld/ChangeLog:

2020-10-20  Siddhesh Poyarekar  <siddesh.poyarekar@arm.com>

* testsuite/ld-aarch64/morello-tlsdesc.s: New file.
* testsuite/ld-aarch64/morello-tlsdesc.d: New test.
* testsuite/ld-aarch64/morello-tlsdesc-static.d: New test.
* testsuite/ld-aarch64/morello-tlsdesc-staticpie.d: New test.
* testsuite/ld-aarch64/aarch64-elf.exp: Add them.

18 files changed:
bfd/ChangeLog
bfd/bfd-in2.h
bfd/elfnn-aarch64.c
bfd/elfxx-aarch64.c
bfd/libbfd.h
bfd/reloc.c
gas/ChangeLog
gas/config/tc-aarch64.c
gas/testsuite/gas/aarch64/morello-tlsdesc.d [new file with mode: 0644]
gas/testsuite/gas/aarch64/morello-tlsdesc.s [new file with mode: 0644]
include/ChangeLog
include/elf/aarch64.h
ld/ChangeLog
ld/testsuite/ld-aarch64/aarch64-elf.exp
ld/testsuite/ld-aarch64/morello-tlsdesc-static.d [new file with mode: 0644]
ld/testsuite/ld-aarch64/morello-tlsdesc-staticpie.d [new file with mode: 0644]
ld/testsuite/ld-aarch64/morello-tlsdesc.d [new file with mode: 0644]
ld/testsuite/ld-aarch64/morello-tlsdesc.s [new file with mode: 0644]

index d8312a4e2f477d13d79103daf237ab47dcdc7811..e4a674e4fc45287a99d943cc0eda3dba4289ccdb 100644 (file)
@@ -1,3 +1,33 @@
+2020-10-20  Siddhesh Poyarekar  <siddesh.poyarekar@arm.com>
+
+       * elfnn-aarch64.c (IS_AARCH64_TLSDESC_RELOC): Add Morello
+       relocations.
+       (elfNN_aarch64_tlsdesc_small_plt_c64_entry): New Morello
+       tlsdesc PLT entry.
+       (elfNN_aarch64_howto_table): Add TLSDESC_ADR_PAGE20,
+       TLSDESC_LD128_LO12, TLSDESC_CALL, TLSDESC relocations for
+       Morello.
+       (aarch64_tls_transition_without_check): Add INFO and
+       MORELLO_RELOC arguments.  Add morello TLSDESC relocations.
+       (aarch64_reloc_got_type, elfNN_aarch64_final_link_relocate,
+       elfNN_aarch64_tls_relax, elfNN_aarch64_check_relocs,
+       aarch64_can_relax_tls): Add morello TLSDESC relocations.
+       (aarch64_tls_transition): Add transitions for morello TLSDESC
+       relocations.
+       (elfNN_aarch64_tls_relax): Add relaxations for morello
+       TLSDESC.
+       (elfNN_aarch64_relocate_section): Emit dynamic relocation for
+       Morello static relocations.
+       (elfNN_aarch64_allocate_dynrelocs): Allocate dynamic
+       relocation space for Morello TLSDESC.
+       (elfNN_aarch64_finish_dynamic_sections): Emit Morello tlsdesc
+       PLT entry.
+       * elfxx-aarch64.c (_bfd_aarch64_elf_put_addend,
+       _bfd_aarch64_elf_resolve_relocation): Add Morello relocations.
+       * reloc.c: Add Morello relocations.
+       * bfd-in2.h: Regenerate.
+       * libbfd.h: Regenerate.
+
 2020-10-20  Siddhesh Poyarekar  <siddesh.poyarekar@arm.com>
 
        * elfnn-aarch64.c (elf_aarch64_link_hash_table): New member.
index 715013762f7c6edce68f2f06c65394bbc772fef0..c296277db88d94ad9308beb2c3bd3211c9fa1f28 100644 (file)
@@ -5947,6 +5947,16 @@ instructions.  */
 /* AArch64 TLS DESC relocation.  */
   BFD_RELOC_AARCH64_TLSDESC_CALL,
 
+/* Morello TLS DESC relocation.  */
+  BFD_RELOC_MORELLO_TLSDESC_ADR_PAGE20,
+
+/* bit[11:4] of byte offset to TLS base address, encoded in ldst instructions.  */
+  BFD_RELOC_MORELLO_TLSDESC_LD128_LO12,
+
+/* Relocation to identify the BLR call which performs an indirect call to the
+TLS descriptor function.  */
+  BFD_RELOC_MORELLO_TLSDESC_CALL,
+
 /* AArch64 TLS relocation.  */
   BFD_RELOC_AARCH64_COPY,
 
@@ -5989,6 +5999,9 @@ instructions.  */
 /* C64 support for STT_GNU_IFUNC.  */
   BFD_RELOC_MORELLO_IRELATIVE,
 
+/* Morello TLS relocation, identifies the TLS descriptor to be filled.  */
+  BFD_RELOC_MORELLO_TLSDESC,
+
 /* AArch64 pseudo relocation code to mark the end of the AArch64
 relocation enumerators that have direct mapping to ELF reloc codes.
 There are a few more enumerators after this one; those are mainly
index 949b08bfa10c511405cb546de585352b44526b78..d3b53395d9310466e1db07839c88bf30cb3a2403 100644 (file)
 #define IS_AARCH64_TLS_RELAX_RELOC(R_TYPE)                     \
   ((R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_ADD                   \
    || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_ADD_LO12           \
+   || (R_TYPE) == BFD_RELOC_MORELLO_TLSDESC_ADR_PAGE20         \
    || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_ADR_PAGE21         \
    || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_ADR_PREL21         \
+   || (R_TYPE) == BFD_RELOC_MORELLO_TLSDESC_CALL               \
    || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_CALL               \
    || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_LD_PREL19          \
+   || (R_TYPE) == BFD_RELOC_MORELLO_TLSDESC_LD128_LO12         \
    || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_LDNN_LO12_NC       \
    || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_LDR                        \
    || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_OFF_G0_NC          \
    || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_ADD                        \
    || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_ADD_LO12           \
    || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_ADR_PAGE21         \
+   || (R_TYPE) == BFD_RELOC_MORELLO_TLSDESC_ADR_PAGE20         \
    || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_ADR_PREL21         \
    || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_CALL               \
+   || (R_TYPE) == BFD_RELOC_MORELLO_TLSDESC_CALL               \
    || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_LD32_LO12_NC       \
    || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_LD64_LO12          \
+   || (R_TYPE) == BFD_RELOC_MORELLO_TLSDESC_LD128_LO12         \
    || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_LDR                        \
    || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_LD_PREL19          \
    || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_OFF_G0_NC          \
@@ -447,6 +453,19 @@ elfNN_aarch64_tlsdesc_small_plt_bti_entry[PLT_TLSDESC_ENTRY_SIZE] =
   0x1f, 0x20, 0x03, 0xd5,      /* nop */
 };
 
+static const bfd_byte
+elfNN_aarch64_tlsdesc_small_plt_c64_entry[PLT_TLSDESC_ENTRY_SIZE] =
+{
+  0xe2, 0x8f, 0xbf, 0x62,      /* stp c2, c3, [sp, #-16]! */
+  0x02, 0x00, 0x80, 0x90,      /* adrp c2, 0 */
+  0x03, 0x00, 0x80, 0x90,      /* adrp c3, 0 */
+  0x42, 0x00, 0x40, 0xc2,      /* ldr c2, [c2, #0] */
+  0x63, 0x00, 0x00, 0x02,      /* add c3, c3, 0 */
+  0x40, 0x10, 0xc2, 0xc2,      /* br c2 */
+  0x1f, 0x20, 0x03, 0xd5,      /* nop */
+  0x1f, 0x20, 0x03, 0xd5,      /* nop */
+};
+
 #define elf_info_to_howto              elfNN_aarch64_info_to_howto
 #define elf_info_to_howto_rel          elfNN_aarch64_info_to_howto
 
@@ -2173,6 +2192,51 @@ static reloc_howto_type elfNN_aarch64_howto_table[] =
         0x0,                   /* dst_mask */
         false),                /* pcrel_offset */
 
+  /* Get to the page for the GOT entry for the symbol
+     (G(S) - P) using an ADRP instruction.  */
+  HOWTO64 (MORELLO_R (TLSDESC_ADR_PAGE20),     /* type */
+        12,                    /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        20,                    /* bitsize */
+        true,                  /* pc_relative */
+        0,                     /* bitpos */
+        complain_overflow_dont,        /* complain_on_overflow */
+        bfd_elf_generic_reloc, /* special_function */
+        MORELLO_R_STR (TLSDESC_ADR_PAGE20),    /* name */
+        false,                 /* partial_inplace */
+        0xfffff,               /* src_mask */
+        0xfffff,               /* dst_mask */
+        true),                 /* pcrel_offset */
+
+  /* LD128: GOT offset G(S) & 0xff0.  */
+  HOWTO64 (MORELLO_R (TLSDESC_LD128_LO12),     /* type */
+        4,                     /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        12,                    /* bitsize */
+        false,                 /* pc_relative */
+        0,                     /* bitpos */
+        complain_overflow_dont,        /* complain_on_overflow */
+        bfd_elf_generic_reloc, /* special_function */
+        MORELLO_R_STR (TLSDESC_LD128_LO12),    /* name */
+        false,                 /* partial_inplace */
+        0xff0,                 /* src_mask */
+        0xff0,                 /* dst_mask */
+        false),                /* pcrel_offset */
+
+  HOWTO64 (MORELLO_R (TLSDESC_CALL),   /* type */
+        0,                     /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        0,                     /* bitsize */
+        false,                 /* pc_relative */
+        0,                     /* bitpos */
+        complain_overflow_dont,        /* complain_on_overflow */
+        bfd_elf_generic_reloc, /* special_function */
+        MORELLO_R_STR (TLSDESC_CALL),  /* name */
+        false,                 /* partial_inplace */
+        0x0,                   /* src_mask */
+        0x0,                   /* dst_mask */
+        false),                /* pcrel_offset */
+
   HOWTO (AARCH64_R (COPY),     /* type */
         0,                     /* rightshift */
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
@@ -2381,6 +2445,20 @@ static reloc_howto_type elfNN_aarch64_howto_table[] =
         ALL_ONES,              /* dst_mask */
         false),                /* pcrel_offset */
 
+  HOWTO64 (MORELLO_R (TLSDESC),        /* type */
+        0,                     /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        64,                    /* bitsize */
+        false,                 /* pc_relative */
+        0,                     /* bitpos */
+        complain_overflow_dont,        /* complain_on_overflow */
+        bfd_elf_generic_reloc, /* special_function */
+        MORELLO_R_STR (TLSDESC),       /* name */
+        false,                 /* partial_inplace */
+        0,                     /* src_mask */
+        ALL_ONES,              /* dst_mask */
+        false),                /* pcrel_offset */
+
   EMPTY_HOWTO (0),
 };
 
@@ -5701,12 +5779,19 @@ aarch64_calculate_got_entry_vma (struct elf_link_hash_entry *h,
 
 static bfd_reloc_code_real_type
 aarch64_tls_transition_without_check (bfd_reloc_code_real_type r_type,
-                                     struct elf_link_hash_entry *h)
+                                     struct bfd_link_info *info,
+                                     struct elf_link_hash_entry *h,
+                                     bool morello_reloc)
 {
   bool is_local = h == NULL;
 
   switch (r_type)
     {
+    case BFD_RELOC_MORELLO_TLSDESC_ADR_PAGE20:
+      return (is_local || !bfd_link_pic (info)
+             ? BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1
+             : r_type);
+
     case BFD_RELOC_AARCH64_TLSDESC_ADR_PAGE21:
     case BFD_RELOC_AARCH64_TLSGD_ADR_PAGE21:
       return (is_local
@@ -5738,6 +5823,10 @@ aarch64_tls_transition_without_check (bfd_reloc_code_real_type r_type,
              ? BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G2
              : BFD_RELOC_AARCH64_TLSIE_MOVW_GOTTPREL_G1);
 
+    case BFD_RELOC_MORELLO_TLSDESC_LD128_LO12:
+      return ((is_local || !bfd_link_pie (info)
+              ? BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G0_NC : r_type));
+
     case BFD_RELOC_AARCH64_TLSDESC_LDNN_LO12_NC:
     case BFD_RELOC_AARCH64_TLSGD_ADD_LO12_NC:
       return (is_local
@@ -5758,10 +5847,19 @@ aarch64_tls_transition_without_check (bfd_reloc_code_real_type r_type,
              ? BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_HI12
              : BFD_RELOC_AARCH64_TLSIE_LD_GOTTPREL_PREL19);
 
-    case BFD_RELOC_AARCH64_TLSDESC_ADD:
+    case BFD_RELOC_MORELLO_TLSDESC_CALL:
+      return ((is_local || !bfd_link_pie (info))
+             ? BFD_RELOC_AARCH64_NONE : r_type);
+
     case BFD_RELOC_AARCH64_TLSDESC_ADD_LO12:
+      if (morello_reloc && !is_local && bfd_link_pie (info))
+       return r_type;
+      /* Fall through.  */
+    case BFD_RELOC_AARCH64_TLSDESC_ADD:
     case BFD_RELOC_AARCH64_TLSDESC_CALL:
-      /* Instructions with these relocations will become NOPs.  */
+      /* Instructions with these relocations will be fully resolved during the
+         transition into either a NOP in the A64 case or movk and add in
+        C64.  */
       return BFD_RELOC_AARCH64_NONE;
 
     case BFD_RELOC_AARCH64_TLSLD_ADD_LO12_NC:
@@ -5818,6 +5916,11 @@ aarch64_reloc_got_type (bfd_reloc_code_real_type r_type)
     case BFD_RELOC_AARCH64_TLSLD_ADR_PREL21:
       return GOT_TLS_GD;
 
+    case BFD_RELOC_MORELLO_TLSDESC_ADR_PAGE20:
+    case BFD_RELOC_MORELLO_TLSDESC_CALL:
+    case BFD_RELOC_MORELLO_TLSDESC_LD128_LO12:
+      return GOT_TLSDESC_GD | GOT_CAP;
+
     case BFD_RELOC_AARCH64_TLSDESC_ADD:
     case BFD_RELOC_AARCH64_TLSDESC_ADD_LO12:
     case BFD_RELOC_AARCH64_TLSDESC_ADR_PAGE21:
@@ -5848,18 +5951,22 @@ aarch64_reloc_got_type (bfd_reloc_code_real_type r_type)
 static bool
 aarch64_can_relax_tls (bfd *input_bfd,
                       struct bfd_link_info *info,
-                      bfd_reloc_code_real_type r_type,
+                      const Elf_Internal_Rela *rel,
                       struct elf_link_hash_entry *h,
                       unsigned long r_symndx)
 {
   unsigned int symbol_got_type;
   unsigned int reloc_got_type;
 
-  if (! IS_AARCH64_TLS_RELAX_RELOC (r_type))
+  bfd_reloc_code_real_type bfd_r_type
+    = elfNN_aarch64_bfd_reloc_from_type (input_bfd,
+                                        ELFNN_R_TYPE (rel->r_info));
+
+  if (! IS_AARCH64_TLS_RELAX_RELOC (bfd_r_type))
     return false;
 
   symbol_got_type = elfNN_aarch64_symbol_got_type (h, input_bfd, r_symndx);
-  reloc_got_type = aarch64_reloc_got_type (r_type);
+  reloc_got_type = aarch64_reloc_got_type (bfd_r_type);
 
   if (symbol_got_type == GOT_TLS_IE && GOT_TLS_GD_ANY_P (reloc_got_type))
     return true;
@@ -5879,17 +5986,29 @@ aarch64_can_relax_tls (bfd *input_bfd,
 static bfd_reloc_code_real_type
 aarch64_tls_transition (bfd *input_bfd,
                        struct bfd_link_info *info,
-                       unsigned int r_type,
+                       const Elf_Internal_Rela *rel,
                        struct elf_link_hash_entry *h,
                        unsigned long r_symndx)
 {
   bfd_reloc_code_real_type bfd_r_type
-    = elfNN_aarch64_bfd_reloc_from_type (input_bfd, r_type);
+    = elfNN_aarch64_bfd_reloc_from_type (input_bfd,
+                                        ELFNN_R_TYPE (rel->r_info));
+
+  if (! aarch64_can_relax_tls (input_bfd, info, rel, h, r_symndx))
+    return bfd_r_type;
 
-  if (! aarch64_can_relax_tls (input_bfd, info, bfd_r_type, h, r_symndx))
+  bool morello_reloc = (bfd_r_type == BFD_RELOC_AARCH64_TLSDESC_ADD_LO12
+                       && (ELFNN_R_TYPE (rel[1].r_info)
+                           == MORELLO_R (TLSDESC_CALL)));
+
+  /* GD -> IE is not supported for Morello TLSDESC yet.  We do however allow
+     lowering of GD -> LE for static non-pie executables.  XXX It ought to be
+     safe to do this for A64 as well but it is not implemented yet.  */
+  if (h != NULL && morello_reloc && bfd_link_pie (info))
     return bfd_r_type;
 
-  return aarch64_tls_transition_without_check (bfd_r_type, h);
+  return aarch64_tls_transition_without_check (bfd_r_type, info, h,
+                                              morello_reloc);
 }
 
 /* Return the base VMA address which should be subtracted from real addresses
@@ -6664,6 +6783,7 @@ elfNN_aarch64_final_link_relocate (reloc_howto_type *howto,
     case BFD_RELOC_AARCH64_TLSDESC_ADD:
     case BFD_RELOC_AARCH64_TLSDESC_CALL:
     case BFD_RELOC_AARCH64_TLSDESC_LDR:
+    case BFD_RELOC_MORELLO_TLSDESC_CALL:
       *unresolved_reloc_p = false;
       return bfd_reloc_ok;
 
@@ -7211,10 +7331,12 @@ elfNN_aarch64_final_link_relocate (reloc_howto_type *howto,
 
     case BFD_RELOC_AARCH64_TLSDESC_ADD_LO12:
     case BFD_RELOC_AARCH64_TLSDESC_ADR_PAGE21:
+    case BFD_RELOC_MORELLO_TLSDESC_ADR_PAGE20:
     case BFD_RELOC_AARCH64_TLSDESC_ADR_PREL21:
     case BFD_RELOC_AARCH64_TLSDESC_LD32_LO12_NC:
     case BFD_RELOC_AARCH64_TLSDESC_LD64_LO12:
     case BFD_RELOC_AARCH64_TLSDESC_LD_PREL19:
+    case BFD_RELOC_MORELLO_TLSDESC_LD128_LO12:
       if (globals->root.sgot == NULL)
        return bfd_reloc_notsupported;
       value = (symbol_tlsdesc_got_offset (input_bfd, h, r_symndx)
@@ -7402,6 +7524,11 @@ clear_erratum_843419_entry (struct elf_aarch64_link_hash_table *globals,
     }
 }
 
+#define BUILD_MOVZ(_reg, _imm) (movz_R0 \
+                               | ((((_imm) >> 16) & 0xffff) << 5) \
+                               | (_reg))
+#define BUILD_MOVK(_reg, _imm) (movk_R0 | (((_imm) & 0xffff) << 5) | (_reg))
+
 /* 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.
@@ -7411,19 +7538,56 @@ clear_erratum_843419_entry (struct elf_aarch64_link_hash_table *globals,
    case of error.  */
 
 static bfd_reloc_status_type
-elfNN_aarch64_tls_relax (struct elf_aarch64_link_hash_table *globals,
-                        bfd *input_bfd, asection *input_section,
+elfNN_aarch64_tls_relax (bfd *input_bfd, struct bfd_link_info *info,
+                        asection *input_section,
                         bfd_byte *contents, Elf_Internal_Rela *rel,
-                        struct elf_link_hash_entry *h)
+                        struct elf_link_hash_entry *h, unsigned long r_symndx)
 {
   bool is_local = h == NULL;
+
   unsigned int r_type = ELFNN_R_TYPE (rel->r_info);
   unsigned long insn;
+  bfd_vma sym_size = 0;
+  struct elf_aarch64_link_hash_table *globals = elf_aarch64_hash_table (info);
 
   BFD_ASSERT (globals && input_bfd && contents && rel);
 
+  if (is_local)
+    {
+      if (h != NULL)
+       sym_size = h->size;
+      else
+       {
+         Elf_Internal_Sym *sym;
+
+         sym = bfd_sym_from_r_symndx (&globals->root.sym_cache, input_bfd,
+                                      r_symndx);
+         BFD_ASSERT (sym != NULL);
+         sym_size = sym->st_size;
+       }
+    }
+
   switch (elfNN_aarch64_bfd_reloc_from_type (input_bfd, r_type))
     {
+    case BFD_RELOC_MORELLO_TLSDESC_ADR_PAGE20:
+      if (is_local || !bfd_link_pic (info))
+       {
+         /* GD->LE relaxation:
+            nop                     =>   movz x1, objsize_hi16
+            adrp x0, :tlsdesc:var   =>   movz x0, :tprel_g1:var  */
+         bfd_putl32 (BUILD_MOVZ(1, sym_size), contents + rel->r_offset - 4);
+         bfd_putl32 (movz_R0, contents + rel->r_offset);
+
+         /* We have relaxed the adrp into a mov, we may have to clear any
+            pending erratum fixes.  */
+         clear_erratum_843419_entry (globals, rel->r_offset, input_section);
+         return bfd_reloc_continue;
+       }
+      else
+       {
+         /* GD->IE relaxation: Not implemented.  */
+         return bfd_reloc_continue;
+       }
     case BFD_RELOC_AARCH64_TLSDESC_ADR_PAGE21:
     case BFD_RELOC_AARCH64_TLSGD_ADR_PAGE21:
       if (is_local)
@@ -7592,6 +7756,19 @@ elfNN_aarch64_tls_relax (struct elf_aarch64_link_hash_table *globals,
     case BFD_RELOC_AARCH64_TLSIE_LD_GOTTPREL_PREL19:
       return bfd_reloc_continue;
 
+    case BFD_RELOC_MORELLO_TLSDESC_LD128_LO12:
+      if (is_local || !bfd_link_pic (info))
+       {
+         /* GD->LE relaxation:
+            ldr xd, [x0, #:tlsdesc_lo12:var] => movk x0, :tprel_g0_nc:var  */
+         bfd_putl32 (movk_R0, contents + rel->r_offset);
+         return bfd_reloc_continue;
+       }
+      else
+       {
+         /* GD->IE relaxation: not implemented.  */
+         return bfd_reloc_continue;
+       }
     case BFD_RELOC_AARCH64_TLSDESC_LDNN_LO12_NC:
       if (is_local)
        {
@@ -7656,13 +7833,35 @@ elfNN_aarch64_tls_relax (struct elf_aarch64_link_hash_table *globals,
          return bfd_reloc_continue;
        }
 
-    case BFD_RELOC_AARCH64_TLSDESC_ADD:
+    case BFD_RELOC_MORELLO_TLSDESC_CALL:
+      /* GD->LE relaxation:
+        blr cd                           =>   add c0, c2, x0  */
+      if (is_local || !bfd_link_pic (info))
+       {
+         bfd_putl32 (0xc2a06040, contents + rel->r_offset);
+         return bfd_reloc_ok;
+       }
+      else
+       goto set_nop;
+
     case BFD_RELOC_AARCH64_TLSDESC_ADD_LO12:
+      /* GD->LE relaxation:
+        ldr cd, [c0, #:tlsdesc_lo12:var] => movk x1, objsize_lo16  */
+      if ((is_local || !bfd_link_pic (info))
+         && ELFNN_R_TYPE (rel[1].r_info) == MORELLO_R (TLSDESC_CALL))
+       {
+         bfd_putl32 (BUILD_MOVK(1, sym_size), contents + rel->r_offset);
+         return bfd_reloc_continue;
+       }
+
+      /* Fall through.  */
+    case BFD_RELOC_AARCH64_TLSDESC_ADD:
     case BFD_RELOC_AARCH64_TLSDESC_CALL:
       /* GD->IE/LE relaxation:
         add x0, x0, #:tlsdesc_lo12:var   =>   nop
         blr xd                           =>   nop
        */
+set_nop:
       bfd_putl32 (INSN_NOP, contents + rel->r_offset);
       return bfd_reloc_ok;
 
@@ -7947,7 +8146,7 @@ elfNN_aarch64_relocate_section (bfd *output_bfd,
         We call elfNN_aarch64_final_link_relocate unless we're completely
         done, i.e., the relaxation produced the final output we want.  */
 
-      relaxed_bfd_r_type = aarch64_tls_transition (input_bfd, info, r_type,
+      relaxed_bfd_r_type = aarch64_tls_transition (input_bfd, info, rel,
                                                   h, r_symndx);
       if (relaxed_bfd_r_type != bfd_r_type)
        {
@@ -7955,8 +8154,8 @@ elfNN_aarch64_relocate_section (bfd *output_bfd,
          howto = elfNN_aarch64_howto_from_bfd_reloc (bfd_r_type);
          BFD_ASSERT (howto != NULL);
          r_type = howto->type;
-         r = elfNN_aarch64_tls_relax (globals, input_bfd, input_section,
-                                      contents, rel, h);
+         r = elfNN_aarch64_tls_relax (input_bfd, info, input_section,
+                                      contents, rel, h, r_symndx);
          unresolved_reloc = 0;
        }
       else
@@ -7980,6 +8179,8 @@ elfNN_aarch64_relocate_section (bfd *output_bfd,
                                               h, &unresolved_reloc,
                                               save_addend, &addend, sym);
 
+      bool c64_rtype = false;
+
       switch (elfNN_aarch64_bfd_reloc_from_type (input_bfd, r_type))
        {
        case BFD_RELOC_AARCH64_TLSGD_ADD_LO12_NC:
@@ -8133,6 +8334,11 @@ elfNN_aarch64_relocate_section (bfd *output_bfd,
            }
          break;
 
+       case BFD_RELOC_MORELLO_TLSDESC_ADR_PAGE20:
+       case BFD_RELOC_MORELLO_TLSDESC_LD128_LO12:
+         c64_rtype = true;
+         /* Fall through.  */
+
        case BFD_RELOC_AARCH64_TLSDESC_ADD_LO12:
        case BFD_RELOC_AARCH64_TLSDESC_ADR_PAGE21:
        case BFD_RELOC_AARCH64_TLSDESC_ADR_PREL21:
@@ -8157,7 +8363,10 @@ elfNN_aarch64_relocate_section (bfd *output_bfd,
                {
                  bfd_byte *loc;
                  Elf_Internal_Rela rela;
-                 rela.r_info = ELFNN_R_INFO (indx, AARCH64_R (TLSDESC));
+
+                 rela.r_info = ELFNN_R_INFO (indx,
+                                             (c64_rtype ? MORELLO_R (TLSDESC)
+                                              : AARCH64_R (TLSDESC)));
 
                  rela.r_addend = 0;
                  rela.r_offset = (globals->root.sgotplt->output_section->vma
@@ -8741,12 +8950,10 @@ elfNN_aarch64_check_relocs (bfd *abfd, struct bfd_link_info *info,
     {
       struct elf_link_hash_entry *h;
       unsigned int r_symndx;
-      unsigned int r_type;
       bfd_reloc_code_real_type bfd_r_type;
       Elf_Internal_Sym *isym;
 
       r_symndx = ELFNN_R_SYM (rel->r_info);
-      r_type = ELFNN_R_TYPE (rel->r_info);
 
       if (r_symndx >= NUM_SHDR_ENTRIES (symtab_hdr))
        {
@@ -8790,7 +8997,7 @@ elfNN_aarch64_check_relocs (bfd *abfd, struct bfd_link_info *info,
        }
 
       /* Could be done earlier, if h were already available.  */
-      bfd_r_type = aarch64_tls_transition (abfd, info, r_type, h, r_symndx);
+      bfd_r_type = aarch64_tls_transition (abfd, info, rel, h, r_symndx);
 
       if (h != NULL)
        {
@@ -9038,6 +9245,8 @@ elfNN_aarch64_check_relocs (bfd *abfd, struct bfd_link_info *info,
             there are no dangling GOT_PAGE relocs.  */
        case BFD_RELOC_MORELLO_ADR_GOT_PAGE:
        case BFD_RELOC_MORELLO_LD128_GOT_LO12_NC:
+       case BFD_RELOC_MORELLO_TLSDESC_ADR_PAGE20:
+       case BFD_RELOC_MORELLO_TLSDESC_LD128_LO12:
          htab->c64_rel = 1;
          /* Fall through.  */
 
@@ -9117,10 +9326,14 @@ elfNN_aarch64_check_relocs (bfd *abfd, struct bfd_link_info *info,
            if ((got_type & GOT_TLS_IE) && GOT_TLS_GD_ANY_P (got_type))
              got_type &= ~ (GOT_TLSDESC_GD | GOT_TLS_GD);
 
-           /* GOT_CAP has higher precedence due to higher alignment and size
-              requirements, so do not overwrite it.  XXX This should be
-              revisited when we add TLS relocations.  */
-           if (old_got_type != got_type && old_got_type != GOT_CAP)
+           /* Prefer the capability reference.  */
+           if ((old_got_type & GOT_CAP) && (got_type & GOT_NORMAL))
+             {
+               got_type &= ~GOT_NORMAL;
+               got_type |= GOT_CAP;
+             }
+
+           if (old_got_type != got_type)
              {
                if (h != NULL)
                  elf_aarch64_hash_entry (h)->got_type = got_type;
@@ -9879,7 +10092,10 @@ elfNN_aarch64_allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
               || h->root.type != bfd_link_hash_undefweak)
              && (!bfd_link_executable (info)
                  || indx != 0
-                 || WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, 0, h)))
+                 || WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, 0, h)
+                 /* On Morello support only TLSDESC_GD to TLSLE relaxation;
+                    for everything else we must emit a dynamic relocation.  */
+                 || got_type & GOT_CAP))
            {
              if (got_type & GOT_TLSDESC_GD)
                {
@@ -10927,8 +11143,17 @@ elfNN_aarch64_finish_dynamic_sections (bfd *output_bfd,
          const bfd_byte *entry = elfNN_aarch64_tlsdesc_small_plt_entry;
          htab->tlsdesc_plt_entry_size = PLT_TLSDESC_ENTRY_SIZE;
 
+         unsigned adrp_rtype = BFD_RELOC_AARCH64_ADR_HI21_PCREL;
+         unsigned ldr_rtype = BFD_RELOC_AARCH64_LDSTNN_LO12;
+
          aarch64_plt_type type = elf_aarch64_tdata (output_bfd)->plt_type;
-         if (type == PLT_BTI || type == PLT_BTI_PAC)
+         if (htab->c64_rel)
+           {
+             entry = elfNN_aarch64_tlsdesc_small_plt_c64_entry;
+             adrp_rtype = BFD_RELOC_MORELLO_ADR_HI20_PCREL;
+             ldr_rtype = BFD_RELOC_AARCH64_LDST128_LO12;
+           }
+         else if (type == PLT_BTI || type == PLT_BTI_PAC)
            {
              entry = elfNN_aarch64_tlsdesc_small_plt_bti_entry;
            }
@@ -10968,21 +11193,21 @@ elfNN_aarch64_finish_dynamic_sections (bfd *output_bfd,
 
            /* adrp x2, DT_TLSDESC_GOT */
            elf_aarch64_update_plt_entry (output_bfd,
-                                         BFD_RELOC_AARCH64_ADR_HI21_PCREL,
+                                         adrp_rtype,
                                          plt_entry + 4,
                                          (PG (dt_tlsdesc_got)
                                           - PG (adrp1_addr)));
 
            /* adrp x3, 0 */
            elf_aarch64_update_plt_entry (output_bfd,
-                                         BFD_RELOC_AARCH64_ADR_HI21_PCREL,
+                                         adrp_rtype,
                                          plt_entry + 8,
                                          (PG (pltgot_addr)
                                           - PG (adrp2_addr)));
 
            /* ldr x2, [x2, #0] */
            elf_aarch64_update_plt_entry (output_bfd,
-                                         BFD_RELOC_AARCH64_LDSTNN_LO12,
+                                         ldr_rtype,
                                          plt_entry + 12,
                                          PG_OFFSET (dt_tlsdesc_got));
 
index f3dae319682f04f8bbacb0fad9292d04d98a4bf6..db3ed690652df3416b8a1b278920c150a88b37f2 100644 (file)
@@ -263,11 +263,13 @@ _bfd_aarch64_elf_put_addend (bfd *abfd,
       break;
 
     case BFD_RELOC_AARCH64_TLSDESC_CALL:
+    case BFD_RELOC_MORELLO_TLSDESC_CALL:
       break;
 
     case BFD_RELOC_MORELLO_ADR_GOT_PAGE:
     case BFD_RELOC_MORELLO_ADR_HI20_NC_PCREL:
     case BFD_RELOC_MORELLO_ADR_HI20_PCREL:
+    case BFD_RELOC_MORELLO_TLSDESC_ADR_PAGE20:
       contents = _bfd_aarch64_reencode_adr_imm (contents, addend, 1);
       break;
 
@@ -315,6 +317,7 @@ _bfd_aarch64_elf_put_addend (bfd *abfd,
     case BFD_RELOC_AARCH64_LDST8_LO12:
     case BFD_RELOC_AARCH64_TLSDESC_LD32_LO12_NC:
     case BFD_RELOC_AARCH64_TLSDESC_LD64_LO12:
+    case BFD_RELOC_MORELLO_TLSDESC_LD128_LO12:
     case BFD_RELOC_AARCH64_TLSIE_LD32_GOTTPREL_LO12_NC:
     case BFD_RELOC_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC:
     case BFD_RELOC_AARCH64_TLSLD_LDST16_DTPREL_LO12:
@@ -447,6 +450,7 @@ _bfd_aarch64_elf_resolve_relocation (bfd *input_bfd,
     {
     case BFD_RELOC_AARCH64_NONE:
     case BFD_RELOC_AARCH64_TLSDESC_CALL:
+    case BFD_RELOC_MORELLO_TLSDESC_CALL:
       break;
 
     case BFD_RELOC_MORELLO_LD_LO17_PCREL:
@@ -543,6 +547,7 @@ _bfd_aarch64_elf_resolve_relocation (bfd *input_bfd,
       break;
 
     case BFD_RELOC_MORELLO_ADR_GOT_PAGE:
+    case BFD_RELOC_MORELLO_TLSDESC_ADR_PAGE20:
     case BFD_RELOC_AARCH64_ADR_GOT_PAGE:
     case BFD_RELOC_AARCH64_TLSDESC_ADR_PAGE21:
     case BFD_RELOC_AARCH64_TLSGD_ADR_PAGE21:
@@ -575,6 +580,7 @@ _bfd_aarch64_elf_resolve_relocation (bfd *input_bfd,
     case BFD_RELOC_AARCH64_TLSDESC_ADD_LO12:
     case BFD_RELOC_AARCH64_TLSDESC_LD32_LO12_NC:
     case BFD_RELOC_AARCH64_TLSDESC_LD64_LO12:
+    case BFD_RELOC_MORELLO_TLSDESC_LD128_LO12:
     case BFD_RELOC_AARCH64_TLSDESC_LDR:
     case BFD_RELOC_AARCH64_TLSGD_ADD_LO12_NC:
     case BFD_RELOC_AARCH64_TLSIE_LD32_GOTTPREL_LO12_NC:
index b1e045faf98c1c8ab861e2d21f97fda3f9912d2b..e86a2152d9893e995221f541799ff720144ca7d9 100644 (file)
@@ -3124,6 +3124,9 @@ static const char *const bfd_reloc_code_real_names[] = { "@@uninitialized@@",
   "BFD_RELOC_AARCH64_TLSDESC_LDR",
   "BFD_RELOC_AARCH64_TLSDESC_ADD",
   "BFD_RELOC_AARCH64_TLSDESC_CALL",
+  "BFD_RELOC_MORELLO_TLSDESC_ADR_PAGE20",
+  "BFD_RELOC_MORELLO_TLSDESC_LD128_LO12",
+  "BFD_RELOC_MORELLO_TLSDESC_CALL",
   "BFD_RELOC_AARCH64_COPY",
   "BFD_RELOC_AARCH64_GLOB_DAT",
   "BFD_RELOC_AARCH64_JUMP_SLOT",
@@ -3138,6 +3141,7 @@ static const char *const bfd_reloc_code_real_names[] = { "@@uninitialized@@",
   "BFD_RELOC_MORELLO_JUMP_SLOT",
   "BFD_RELOC_MORELLO_RELATIVE",
   "BFD_RELOC_MORELLO_IRELATIVE",
+  "BFD_RELOC_MORELLO_TLSDESC",
   "BFD_RELOC_AARCH64_RELOC_END",
   "BFD_RELOC_AARCH64_GAS_INTERNAL_FIXUP",
   "BFD_RELOC_AARCH64_LDST_LO12",
index 8c9bdcd122e06a7cf87acd0c111a6ecd804fc0fc..1694459ed606df352928f105601929c1b4423581 100644 (file)
@@ -7536,6 +7536,19 @@ ENUM
   BFD_RELOC_AARCH64_TLSDESC_CALL
 ENUMDOC
   AArch64 TLS DESC relocation.
+ENUM
+  BFD_RELOC_MORELLO_TLSDESC_ADR_PAGE20
+ENUMDOC
+  Morello TLS DESC relocation.
+ENUM
+  BFD_RELOC_MORELLO_TLSDESC_LD128_LO12
+ENUMDOC
+  bit[11:4] of byte offset to TLS base address, encoded in ldst instructions.
+ENUM
+  BFD_RELOC_MORELLO_TLSDESC_CALL
+ENUMDOC
+  Relocation to identify the BLR call which performs an indirect call to the
+  TLS descriptor function.
 ENUM
   BFD_RELOC_AARCH64_COPY
 ENUMDOC
@@ -7592,6 +7605,10 @@ ENUM
   BFD_RELOC_MORELLO_IRELATIVE
 ENUMDOC
   C64 support for STT_GNU_IFUNC.
+ENUM
+  BFD_RELOC_MORELLO_TLSDESC
+ENUMDOC
+  Morello TLS relocation, identifies the TLS descriptor to be filled.
 ENUM
   BFD_RELOC_AARCH64_RELOC_END
 ENUMDOC
index f4470e7e25337f447f470e88048a46ed9e4747f1..bdbf538e69171da8faa1710d59aa3c73ff7b1774 100644 (file)
@@ -1,3 +1,14 @@
+2020-10-20  Siddhesh Poyarekar  <siddesh.poyarekar@arm.com>
+
+       * config/tc-aarch64.c (s_tlsdesccall): Emit Morello
+       TLSDESC_CALL in C64 code.
+       (reloc_table): Add Morello relocation.
+       (md_apply_fix): Emit Morello TLSDESC_LD128_LO12 in C64 code.
+       (aarch64_force_relocation): Add Morello TLSDESC relocations.
+       * testsuite/gas/aarch64/morello-tlsdesc-c64.d: New file.
+       * testsuite/gas/aarch64/morello-tlsdesc.d: New file.
+       * testsuite/gas/aarch64/morello-tlsdesc.s: New file.
+
 2020-10-20  Siddhesh Poyarekar  <siddesh.poyarekar@arm.com>
 
        * config/tc-aarch64.c (REG_DW_CSP, REG_DW_CLR): New macros.
index d57775561695260af06771f23fccaf03af0f32f1..2270b40727dfca007edf4d6349105cd978ca2092 100644 (file)
@@ -2112,7 +2112,8 @@ s_tlsdesccall (int ignored ATTRIBUTE_UNUSED)
      the .tlsdesc directive.  */
   frag_grow (4);
   fix_new_aarch64 (frag_now, frag_more (0) - frag_now->fr_literal, 4, &exp, 0,
-                  BFD_RELOC_AARCH64_TLSDESC_CALL);
+                  (IS_C64 ? BFD_RELOC_MORELLO_TLSDESC_CALL
+                   : BFD_RELOC_AARCH64_TLSDESC_CALL));
 
   demand_empty_rest_of_line ();
 }
@@ -2885,7 +2886,7 @@ static struct reloc_table_entry reloc_table[] =
   {"tlsdesc", 0,
    BFD_RELOC_AARCH64_TLSDESC_ADR_PREL21, /* adr_type */
    BFD_RELOC_AARCH64_TLSDESC_ADR_PAGE21,
-   0,
+   BFD_RELOC_MORELLO_TLSDESC_ADR_PAGE20,
    0,
    0,
    0,
@@ -3222,10 +3223,12 @@ aarch64_force_reloc (unsigned int type)
     case BFD_RELOC_AARCH64_LDST64_LO12:
     case BFD_RELOC_AARCH64_LDST8_LO12:
     case BFD_RELOC_AARCH64_TLSDESC_ADD_LO12:
+    case BFD_RELOC_MORELLO_TLSDESC_ADR_PAGE20:
     case BFD_RELOC_AARCH64_TLSDESC_ADR_PAGE21:
     case BFD_RELOC_AARCH64_TLSDESC_ADR_PREL21:
     case BFD_RELOC_AARCH64_TLSDESC_LD32_LO12_NC:
     case BFD_RELOC_AARCH64_TLSDESC_LD64_LO12:
+    case BFD_RELOC_MORELLO_TLSDESC_LD128_LO12:
     case BFD_RELOC_AARCH64_TLSDESC_LD_PREL19:
     case BFD_RELOC_AARCH64_TLSDESC_OFF_G0_NC:
     case BFD_RELOC_AARCH64_TLSDESC_OFF_G1:
@@ -7603,7 +7606,8 @@ addr_uimm:
 
              inst.reloc.type = ldst_lo12_determine_real_reloc_type ();
            }
-         else if (inst.reloc.type == BFD_RELOC_AARCH64_LD_GOT_LO12_NC
+         else if ((inst.reloc.type == BFD_RELOC_AARCH64_LD_GOT_LO12_NC
+                   || inst.reloc.type == BFD_RELOC_AARCH64_TLSDESC_LD_LO12_NC)
                   && inst.base.operands[0].qualifier == AARCH64_OPND_QLF_CA)
            inst.reloc.flags = FIXUP_F_C64;
 
@@ -9648,9 +9652,12 @@ md_apply_fix (fixS * fixP, valueT * valP, segT seg)
       break;
 
     case BFD_RELOC_AARCH64_TLSDESC_LD_LO12_NC:
-      fixP->fx_r_type = (ilp32_p
-                        ? BFD_RELOC_AARCH64_TLSDESC_LD32_LO12_NC
-                        : BFD_RELOC_AARCH64_TLSDESC_LD64_LO12);
+      if (fixP->tc_fix_data.c64)
+       fixP->fx_r_type = BFD_RELOC_MORELLO_TLSDESC_LD128_LO12;
+      else if (ilp32_p)
+       fixP->fx_r_type = BFD_RELOC_AARCH64_TLSDESC_LD32_LO12_NC;
+      else
+       fixP->fx_r_type = BFD_RELOC_AARCH64_TLSDESC_LD64_LO12;
       S_SET_THREAD_LOCAL (fixP->fx_addsy);
       /* Should always be exported to object file, see
         aarch64_force_relocation().  */
@@ -9659,10 +9666,12 @@ md_apply_fix (fixS * fixP, valueT * valP, segT seg)
       break;
 
     case BFD_RELOC_AARCH64_TLSDESC_ADD_LO12:
+    case BFD_RELOC_MORELLO_TLSDESC_ADR_PAGE20:
     case BFD_RELOC_AARCH64_TLSDESC_ADR_PAGE21:
     case BFD_RELOC_AARCH64_TLSDESC_ADR_PREL21:
     case BFD_RELOC_AARCH64_TLSDESC_LD32_LO12_NC:
     case BFD_RELOC_AARCH64_TLSDESC_LD64_LO12:
+    case BFD_RELOC_MORELLO_TLSDESC_LD128_LO12:
     case BFD_RELOC_AARCH64_TLSDESC_LD_PREL19:
     case BFD_RELOC_AARCH64_TLSGD_ADD_LO12_NC:
     case BFD_RELOC_AARCH64_TLSGD_ADR_PAGE21:
@@ -9757,6 +9766,7 @@ md_apply_fix (fixS * fixP, valueT * valP, segT seg)
 
     case BFD_RELOC_AARCH64_TLSDESC_ADD:
     case BFD_RELOC_AARCH64_TLSDESC_CALL:
+    case BFD_RELOC_MORELLO_TLSDESC_CALL:
     case BFD_RELOC_AARCH64_TLSDESC_LDR:
     case BFD_RELOC_MORELLO_CAPINIT:
       break;
diff --git a/gas/testsuite/gas/aarch64/morello-tlsdesc.d b/gas/testsuite/gas/aarch64/morello-tlsdesc.d
new file mode 100644 (file)
index 0000000..64364a0
--- /dev/null
@@ -0,0 +1,16 @@
+#source: morello-tlsdesc.s
+#as: -march=morello+c64
+#objdump: -dr
+
+.*:     file format .*
+
+
+Disassembly of section .text:
+
+.*<bar>:
+.*:    90800000        adrp    c0, 0 <foo>
+                       .*: R_MORELLO_TLSDESC_ADR_PAGE20        foo
+.*:    c2400001        ldr     c1, \[c0\]
+                       .*: R_MORELLO_TLSDESC_LD128_LO12        foo
+.*:    c2c23020        blr     c1
+                       .*: R_MORELLO_TLSDESC_CALL      foo
diff --git a/gas/testsuite/gas/aarch64/morello-tlsdesc.s b/gas/testsuite/gas/aarch64/morello-tlsdesc.s
new file mode 100644 (file)
index 0000000..c5b8fea
--- /dev/null
@@ -0,0 +1,5 @@
+bar:
+       adrp    c0, :tlsdesc:foo
+       ldr     c1, [c0, #:tlsdesc_lo12:foo]
+       .tlsdesccall foo
+       blr c1
index 4fa1f3c5329667452a734bbf955e1708395d8131..67f10a9f29010a542ba50b368ff6ca77e6b6091d 100644 (file)
@@ -1,3 +1,7 @@
+2020-10-20  Siddhesh Poyarekar  <siddesh.poyarekar@arm.com>
+
+       * elf/aarch64.h: New Morello TLSDESC relocations.
+
 2020-10-20  Siddhesh Poyarekar  <siddesh.poyarekar@arm.com>
 
        * elf/aarch64.h: New relocations R_MORELLO_TSTBR14,
index 4feac6711e222de33cba92d7f50d52cd9429f31e..4eb4691ed104b89b1154404f5866be37e7589afa 100644 (file)
@@ -472,6 +472,10 @@ RELOC_NUMBER (R_MORELLO_ADR_GOT_PAGE, 57351)
 
 RELOC_NUMBER (R_MORELLO_LD128_GOT_LO12_NC, 57352)
 
+RELOC_NUMBER (R_MORELLO_TLSDESC_ADR_PAGE20, 57600)
+RELOC_NUMBER (R_MORELLO_TLSDESC_LD128_LO12, 57601)
+RELOC_NUMBER (R_MORELLO_TLSDESC_CALL, 57602)
+
 /* Morello dynamic relocations.  */
 
 RELOC_NUMBER (R_MORELLO_CAPINIT, 59392)
@@ -479,6 +483,7 @@ RELOC_NUMBER (R_MORELLO_GLOB_DAT, 59393)
 RELOC_NUMBER (R_MORELLO_JUMP_SLOT, 59394)
 RELOC_NUMBER (R_MORELLO_RELATIVE, 59395)
 RELOC_NUMBER (R_MORELLO_IRELATIVE, 59396)
+RELOC_NUMBER (R_MORELLO_TLSDESC, 59397)
 
 END_RELOC_NUMBERS (R_AARCH64_end)
 
index d81c6939c495bd5c95df65cdf891d8c97ad003c7..72693ed03f02cf9c18aafb33fe8289788f38c1fa 100644 (file)
@@ -1,3 +1,11 @@
+2020-10-20  Siddhesh Poyarekar  <siddesh.poyarekar@arm.com>
+
+       * testsuite/ld-aarch64/morello-tlsdesc.s: New file.
+       * testsuite/ld-aarch64/morello-tlsdesc.d: New test.
+       * testsuite/ld-aarch64/morello-tlsdesc-static.d: New test.
+       * testsuite/ld-aarch64/morello-tlsdesc-staticpie.d: New test.
+       * testsuite/ld-aarch64/aarch64-elf.exp: Add them.
+
 2020-10-20  Siddhesh Poyarekar  <siddesh.poyarekar@arm.com>
 
        * emultempl/aarch64elf.em (elf64_c64_pad_section): New
index ee965d11faeaf7bd0125a530e9f4b1a1cc516f4b..df1b6dbc2e94213b9cfe0c5a7959fda1f39267ee 100644 (file)
@@ -249,6 +249,9 @@ run_dump_test_lp64 "morello-capinit"
 run_dump_test_lp64 "morello-stubs"
 run_dump_test_lp64 "morello-stubs-static"
 run_dump_test_lp64 "morello-sec-round"
+run_dump_test_lp64 "morello-tlsdesc"
+run_dump_test_lp64 "morello-tlsdesc-static"
+run_dump_test_lp64 "morello-tlsdesc-staticpie"
 
 run_dump_test "reloc-overflow-bad"
 
diff --git a/ld/testsuite/ld-aarch64/morello-tlsdesc-static.d b/ld/testsuite/ld-aarch64/morello-tlsdesc-static.d
new file mode 100644 (file)
index 0000000..372f369
--- /dev/null
@@ -0,0 +1,29 @@
+#source: morello-tlsdesc.s
+#as: -march=morello+c64 --defsym STATIC=1
+#ld:
+#objdump: -D -j .got.plt -j .text -j .plt
+
+
+.*:     file format .*
+
+
+Disassembly of section .text:
+
+.*<f2>:
+.*:    94000008        bl      .* <_start>
+.*:    c29bd042        mrs     c2, ctpidr_el0
+.*:    d2a00001        movz    x1, #0x0, lsl #16
+.*:    d2a00000        movz    x0, #0x0, lsl #16
+.*:    f2800200        movk    x0, #0x10
+.*:    f2800001        movk    x1, #0x0
+.*:    c2a06040        add     c0, c2, x0, uxtx
+.*:    c2c10000        scbnds  c0, c0, x1
+
+.*<_start>:
+.*:    c29bd042        mrs     c2, ctpidr_el0
+.*:    d2a00001        movz    x1, #0x0, lsl #16
+.*:    d2a00000        movz    x0, #0x0, lsl #16
+.*:    f2800280        movk    x0, #0x14
+.*:    f2800281        movk    x1, #0x14
+.*:    c2a06040        add     c0, c2, x0, uxtx
+.*:    c2c10000        scbnds  c0, c0, x1
diff --git a/ld/testsuite/ld-aarch64/morello-tlsdesc-staticpie.d b/ld/testsuite/ld-aarch64/morello-tlsdesc-staticpie.d
new file mode 100644 (file)
index 0000000..e391d86
--- /dev/null
@@ -0,0 +1,54 @@
+#source: morello-tlsdesc.s
+#as: -march=morello+c64 --defsym STATIC=1
+#ld: -pie
+#objdump: -DR -j .got.plt -j .text -j .plt
+
+.*:     file format .*
+
+
+Disassembly of section .plt:
+
+.*<.plt>:
+.*:    62bf7bf0        stp     c16, c30, \[csp, #-32\]!
+.*:    908...90        adrp    c16, .*
+.*:    c2....11        ldr     c17, \[c16, #[0-9]+\]
+.*:    02....10        add     c16, c16, #0x[0-9a-f]+
+.*:    c2c21220        br      c17
+.*:    d503201f        nop
+.*:    d503201f        nop
+.*:    d503201f        nop
+.*:    62bf8fe2        stp     c2, c3, \[csp, #-16\]!
+.*:    908...82        adrp    c2, .*
+.*:    908...83        adrp    c3, .*
+.*:    c2....42        ldr     c2, \[c2, #[0-9]+\]
+.*:    02....63        add     c3, c3, #0x[0-9a-f]+
+.*:    c2c21040        br      c2
+.*:    d503201f        nop
+.*:    d503201f        nop
+
+Disassembly of section .text:
+
+.*<f2>:
+.*:    94000008        bl      .* <_start>
+.*:    c29bd042        mrs     c2, ctpidr_el0
+.*:    d503201f        nop
+.*:    908...80        adrp    c0, .*
+.*:    c2....01        ldr     c1, \[c0, #[0-9]+\]
+.*:    02....00        add     c0, c0, #0x[0-9a-f]+
+.*:    c2c23020        blr     c1
+.*:    c2c10000        scbnds  c0, c0, x1
+
+.*<_start>:
+.*:    c29bd042        mrs     c2, ctpidr_el0
+.*:    d2a00001        movz    x1, #0x0, lsl #16
+.*:    d2a00000        movz    x0, #0x0, lsl #16
+.*:    f2800280        movk    x0, #0x14
+.*:    f2800281        movk    x1, #0x14
+.*:    c2....40        add     c0, c2, x0, uxtx
+.*:    c2c10000        scbnds  c0, c0, x1
+
+Disassembly of section .got.plt:
+
+.*:
+       ...
+                       .*: R_MORELLO_TLSDESC   \*ABS\*
diff --git a/ld/testsuite/ld-aarch64/morello-tlsdesc.d b/ld/testsuite/ld-aarch64/morello-tlsdesc.d
new file mode 100644 (file)
index 0000000..58336a7
--- /dev/null
@@ -0,0 +1,89 @@
+#source: morello-tlsdesc.s
+#as: -march=morello+c64
+#ld: -shared
+#objdump: -DR -j .got.plt -j .text -j .plt
+
+
+.*:     file format .*
+
+
+Disassembly of section .plt:
+
+.*<.plt>:
+.*:    62bf7bf0        stp     c16, c30, \[csp, #-32\]!
+.*:    908...90        adrp    c16, .*
+.*:    c2....11        ldr     c17, \[c16, #[0-9]+\]
+.*:    02....10        add     c16, c16, #0x[0-9a-f]+
+.*:    c2c21220        br      c17
+.*:    d503201f        nop
+.*:    d503201f        nop
+.*:    d503201f        nop
+
+.*<_start@plt>:
+.*:    908...90        adrp    c16, .*
+.*:    c2....11        ldr     c17, \[c16, #[0-9]+\]
+.*:    02....10        add     c16, c16, #0x[0-9a-f]+
+.*:    c2c21220        br      c17
+
+.*<extf@plt>:
+.*:    908...90        adrp    c16, .*
+.*:    c2....11        ldr     c17, \[c16, #[0-9]+\]
+.*:    02....10        add     c16, c16, #0x[0-9a-f]+
+.*:    c2c21220        br      c17
+
+.*<var1@plt>:
+.*:    62bf8fe2        stp     c2, c3, \[csp, #-16\]!
+.*:    908...82        adrp    c2, .*
+.*:    908...83        adrp    c3, .*
+.*:    c2....42        ldr     c2, \[c2, #[0-9]+\]
+
+.*<var2@plt>:
+.*:    02....63        add     c3, c3, #0x[0-9a-f]+
+.*:    c2c21040        br      c2
+.*:    d503201f        nop
+.*:    d503201f        nop
+
+Disassembly of section .text:
+
+.*<f1>:
+.*:    97fffff4        bl      .* <extf@plt>
+.*:    c29bd042        mrs     c2, ctpidr_el0
+.*:    d503201f        nop
+.*:    908...80        adrp    c0, .*
+.*:    c2....01        ldr     c1, \[c0, #[0-9]+\]
+.*:    02....00        add     c0, c0, #0x[0-9a-f]+
+.*:    c2c23020        blr     c1
+.*:    c2c10000        scbnds  c0, c0, x1
+
+.*<f2>:
+.*:    97ffffe8        bl      .* <_start@plt>
+.*:    c29bd042        mrs     c2, ctpidr_el0
+.*:    d503201f        nop
+.*:    908...80        adrp    c0, .*
+.*:    c2....01        ldr     c1, \[c0, #[0-9]+\]
+.*:    02....00        add     c0, c0, #0x[0-9a-f]+
+.*:    c2c23020        blr     c1
+.*:    c2c10000        scbnds  c0, c0, x1
+
+.*<_start>:
+.*:    c29bd042        mrs     c2, ctpidr_el0
+.*:    d503201f        nop
+.*:    908...80        adrp    c0, .*
+.*:    c2....01        ldr     c1, \[c0, #[0-9]+\]
+.*:    02....00        add     c0, c0, #0x[0-9a-f]+
+.*:    c2c23020        blr     c1
+.*:    c2c10000        scbnds  c0, c0, x1
+
+Disassembly of section .got.plt:
+
+.*:
+       ...
+.*:    [0-9a-f]+       .*
+                       .*: R_MORELLO_JUMP_SLOT _start
+       ...
+.*:    [0-9a-f]+       .*
+                       .*: R_MORELLO_JUMP_SLOT extf
+       ...
+                       .*: R_MORELLO_TLSDESC   \*ABS\*\+0x4
+                       .*: R_MORELLO_TLSDESC   var1
+                       .*: R_MORELLO_TLSDESC   var2
diff --git a/ld/testsuite/ld-aarch64/morello-tlsdesc.s b/ld/testsuite/ld-aarch64/morello-tlsdesc.s
new file mode 100644 (file)
index 0000000..5eab58a
--- /dev/null
@@ -0,0 +1,50 @@
+.section .tbss
+.globl var2
+var2:
+        .word   0
+        .size   var2, .-var2
+
+var3:
+        .word   0
+        .word   0
+        .word   0
+        .word   0
+        .word   0
+        .size   var3, .-var3
+
+.section .text
+.ifndef STATIC
+f1:
+       bl      extf
+       mrs     c2, CTPIDR_EL0
+       nop
+       adrp    c0, :tlsdesc:var1
+       ldr     c1, [c0, #:tlsdesc_lo12:var1]
+       add     c0, c0, #:tlsdesc_lo12:var1
+       .tlsdesccall var1
+       blr     c1
+       scbnds  c0, c0, x1
+.endif
+
+f2:
+       bl      _start
+       mrs     c2, CTPIDR_EL0
+       nop
+       adrp    c0, :tlsdesc:var2
+       ldr     c1, [c0, #:tlsdesc_lo12:var2]
+       add     c0, c0, #:tlsdesc_lo12:var2
+       .tlsdesccall var2
+       blr     c1
+       scbnds  c0, c0, x1
+
+.globl _start
+.type _start, STT_FUNC
+_start:
+       mrs     c2, CTPIDR_EL0
+       nop
+       adrp    c0, :tlsdesc:var3
+       ldr     c1, [c0, #:tlsdesc_lo12:var3]
+       add     c0, c0, #:tlsdesc_lo12:var3
+       .tlsdesccall var3
+       blr     c1
+       scbnds  c0, c0, x1