public inbox for binutils@sourceware.org
 help / color / mirror / Atom feed
* [PATCH 0/4] RISC-V: Implement TLS Descriptors.
@ 2023-08-17 18:08 Tatsuyuki Ishi
  2023-08-17 18:08 ` [PATCH 1/4] RISC-V: Add TLSDESC reloc definitions Tatsuyuki Ishi
                   ` (7 more replies)
  0 siblings, 8 replies; 49+ messages in thread
From: Tatsuyuki Ishi @ 2023-08-17 18:08 UTC (permalink / raw)
  To: binutils; +Cc: rui314, ruiu, Tatsuyuki Ishi

This patchset implements TLS Descriptors (TLSDESC) for RISC-V targets, per
the specification draft at [1].

This patchset is based on top of [2].

No regression in binutils and gcc tests for rv64gc, tested alongside the
gcc and glibc implementation (will be posted shortly).

This contribution is made on behalf of Blue Whale Systems, which has
copyright assignment on file with the FSF.

[1]: https://github.com/riscv-non-isa/riscv-elf-psabi-doc/pull/373
[2]: https://sourceware.org/pipermail/binutils/2023-August/129075.html

Tatsuyuki Ishi (4):
  RISC-V: Add TLSDESC reloc definitions.
  RISC-V: Add assembly support for TLSDESC.
  RISC-V: Define and use GOT entry size constants for TLS.
  RISC-V: Initial ld.bfd support for TLSDESC.

 bfd/bfd-in2.h                              |   4 +
 bfd/elfnn-riscv.c                          | 105 ++++++++++++++++++---
 bfd/elfxx-riscv.c                          |  75 ++++++++++++++-
 bfd/libbfd.h                               |   4 +
 bfd/reloc.c                                |   8 ++
 gas/config/tc-riscv.c                      |  18 +++-
 include/elf/riscv.h                        |   5 +
 ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp |   2 +
 opcodes/riscv-opc.c                        |   1 +
 9 files changed, 201 insertions(+), 21 deletions(-)

-- 
2.41.0


^ permalink raw reply	[flat|nested] 49+ messages in thread

* [PATCH 1/4] RISC-V: Add TLSDESC reloc definitions.
  2023-08-17 18:08 [PATCH 0/4] RISC-V: Implement TLS Descriptors Tatsuyuki Ishi
@ 2023-08-17 18:08 ` Tatsuyuki Ishi
  2023-08-17 18:08 ` [PATCH 2/4] RISC-V: Add assembly support for TLSDESC Tatsuyuki Ishi
                   ` (6 subsequent siblings)
  7 siblings, 0 replies; 49+ messages in thread
From: Tatsuyuki Ishi @ 2023-08-17 18:08 UTC (permalink / raw)
  To: binutils; +Cc: rui314, ruiu, Tatsuyuki Ishi

---
 bfd/bfd-in2.h       |  4 +++
 bfd/elfxx-riscv.c   | 75 ++++++++++++++++++++++++++++++++++++++++++++-
 bfd/libbfd.h        |  4 +++
 bfd/reloc.c         |  8 +++++
 include/elf/riscv.h |  5 +++
 5 files changed, 95 insertions(+), 1 deletion(-)

diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h
index e2deb107494..110207789c3 100644
--- a/bfd/bfd-in2.h
+++ b/bfd/bfd-in2.h
@@ -5404,6 +5404,10 @@ number for the SBIC, SBIS, SBI and CBI instructions  */
   BFD_RELOC_RISCV_GOT_HI20,
   BFD_RELOC_RISCV_TLS_GOT_HI20,
   BFD_RELOC_RISCV_TLS_GD_HI20,
+  BFD_RELOC_RISCV_TLSDESC_HI20,
+  BFD_RELOC_RISCV_TLSDESC_LOAD_LO12,
+  BFD_RELOC_RISCV_TLSDESC_ADD_LO12,
+  BFD_RELOC_RISCV_TLSDESC_CALL,
   BFD_RELOC_RISCV_JMP,
   BFD_RELOC_RISCV_TLS_DTPMOD32,
   BFD_RELOC_RISCV_TLS_DTPREL32,
diff --git a/bfd/elfxx-riscv.c b/bfd/elfxx-riscv.c
index e9852ef8fa1..43931a2be5d 100644
--- a/bfd/elfxx-riscv.c
+++ b/bfd/elfxx-riscv.c
@@ -218,8 +218,21 @@ static reloc_howto_type howto_table[] =
 	 MINUS_ONE,			/* dst_mask */
 	 false),			/* pcrel_offset */
 
+  HOWTO (R_RISCV_TLSDESC,		/* type */
+	 0,				/* rightshift */
+	 0,				/* size is handled by dynamic linker */
+	 0,				/* bitsize */
+	 false,				/* pc_relative */
+	 0,				/* bitpos */
+	 complain_overflow_dont,	/* complain_on_overflow */
+	 bfd_elf_generic_reloc,		/* special_function */
+	 "R_RISCV_TLSDESC",		/* name */
+	 false,				/* partial_inplace */
+	 0,				/* src_mask */
+	 MINUS_ONE,			/* dst_mask */
+	 false),			/* pcrel_offset */
+
   /* Reserved for future relocs that the dynamic linker must understand.  */
-  EMPTY_HOWTO (12),
   EMPTY_HOWTO (13),
   EMPTY_HOWTO (14),
   EMPTY_HOWTO (15),
@@ -879,6 +892,62 @@ static reloc_howto_type howto_table[] =
 	 0,				/* src_mask */
 	 0,				/* dst_mask */
 	 false),			/* pcrel_offset */
+
+  HOWTO (R_RISCV_TLSDESC_HI20,		/* type */
+	 0,				/* rightshift */
+	 4,				/* size */
+	 32,				/* bitsize */
+	 true,				/* pc_relative */
+	 0,				/* bitpos */
+	 complain_overflow_signed,	/* complain_on_overflow */
+	 bfd_elf_generic_reloc,		/* special_function */
+	 "R_RISCV_TLSDESC_HI20",	/* name */
+	 true,				/* partial_inplace */
+	 0,				/* src_mask */
+	 ENCODE_UTYPE_IMM (-1U),	/* dst_mask */
+	 false),			/* pcrel_offset */
+
+  HOWTO (R_RISCV_TLSDESC_LOAD_LO12,	/* type */
+	 0,				/* rightshift */
+	 4,				/* size */
+	 32,				/* bitsize */
+	 false,				/* pc_relative */
+	 0,				/* bitpos */
+	 complain_overflow_signed,	/* complain_on_overflow */
+	 bfd_elf_generic_reloc,		/* special_function */
+	 "R_RISCV_TLSDESC_LOAD_LO12",	/* name */
+	 false,				/* partial_inplace */
+	 0,				/* src_mask */
+	 ENCODE_ITYPE_IMM (-1U),	/* dst_mask */
+	 false),			/* pcrel_offset */
+
+  HOWTO (R_RISCV_TLSDESC_ADD_LO12,	/* type */
+	 0,				/* rightshift */
+	 4,				/* size */
+	 32,				/* bitsize */
+	 false,				/* pc_relative */
+	 0,				/* bitpos */
+	 complain_overflow_signed,	/* complain_on_overflow */
+	 bfd_elf_generic_reloc,		/* special_function */
+	 "R_RISCV_TLSDESC_ADD_LO12",	/* name */
+	 false,				/* partial_inplace */
+	 0,				/* src_mask */
+	 ENCODE_ITYPE_IMM (-1U),	/* dst_mask */
+	 false), 			/* pcrel_offset */
+
+  HOWTO (R_RISCV_TLSDESC_CALL,		/* type */
+	 0,				/* rightshift */
+	 0,				/* size */
+	 0,				/* bitsize */
+	 false,				/* pc_relative */
+	 0,				/* bitpos */
+	 complain_overflow_dont,	/* complain_on_overflow */
+	 bfd_elf_generic_reloc,		/* special_function */
+	 "R_RISCV_TLSDESC_CALL",	/* name */
+	 false,				/* partial_inplace */
+	 0,				/* src_mask */
+	 ENCODE_ITYPE_IMM (-1U),	/* dst_mask */
+	 false) 			/* pcrel_offset */
 };
 
 /* A mapping from BFD reloc types to RISC-V ELF reloc types.  */
@@ -925,6 +994,10 @@ static const struct elf_reloc_map riscv_reloc_map[] =
   { BFD_RELOC_RISCV_TPREL_LO12_I, R_RISCV_TPREL_LO12_I },
   { BFD_RELOC_RISCV_TLS_GOT_HI20, R_RISCV_TLS_GOT_HI20 },
   { BFD_RELOC_RISCV_TLS_GD_HI20, R_RISCV_TLS_GD_HI20 },
+  { BFD_RELOC_RISCV_TLSDESC_HI20, R_RISCV_TLSDESC_HI20 },
+  { BFD_RELOC_RISCV_TLSDESC_LOAD_LO12, R_RISCV_TLSDESC_LOAD_LO12 },
+  { BFD_RELOC_RISCV_TLSDESC_ADD_LO12, R_RISCV_TLSDESC_ADD_LO12 },
+  { BFD_RELOC_RISCV_TLSDESC_CALL, R_RISCV_TLSDESC_CALL },
   { BFD_RELOC_RISCV_ALIGN, R_RISCV_ALIGN },
   { BFD_RELOC_RISCV_RVC_BRANCH, R_RISCV_RVC_BRANCH },
   { BFD_RELOC_RISCV_RVC_JUMP, R_RISCV_RVC_JUMP },
diff --git a/bfd/libbfd.h b/bfd/libbfd.h
index a84febd8257..e04ab7d8d36 100644
--- a/bfd/libbfd.h
+++ b/bfd/libbfd.h
@@ -2401,6 +2401,10 @@ static const char *const bfd_reloc_code_real_names[] = { "@@uninitialized@@",
   "BFD_RELOC_RISCV_GOT_HI20",
   "BFD_RELOC_RISCV_TLS_GOT_HI20",
   "BFD_RELOC_RISCV_TLS_GD_HI20",
+  "BFD_RELOC_RISCV_TLSDESC_HI20",
+  "BFD_RELOC_RISCV_TLSDESC_LOAD_LO12",
+  "BFD_RELOC_RISCV_TLSDESC_ADD_LO12",
+  "BFD_RELOC_RISCV_TLSDESC_CALL",
   "BFD_RELOC_RISCV_JMP",
   "BFD_RELOC_RISCV_TLS_DTPMOD32",
   "BFD_RELOC_RISCV_TLS_DTPREL32",
diff --git a/bfd/reloc.c b/bfd/reloc.c
index 07d35e45c8b..38e1bdfc754 100644
--- a/bfd/reloc.c
+++ b/bfd/reloc.c
@@ -5016,6 +5016,14 @@ ENUMX
   BFD_RELOC_RISCV_TLS_TPREL32
 ENUMX
   BFD_RELOC_RISCV_TLS_TPREL64
+ENUMX
+  BFD_RELOC_RISCV_TLSDESC_HI20
+ENUMX
+  BFD_RELOC_RISCV_TLSDESC_LOAD_LO12
+ENUMX
+  BFD_RELOC_RISCV_TLSDESC_ADD_LO12
+ENUMX
+  BFD_RELOC_RISCV_TLSDESC_CALL
 ENUMX
   BFD_RELOC_RISCV_ALIGN
 ENUMX
diff --git a/include/elf/riscv.h b/include/elf/riscv.h
index 0aa8b3359c4..f32215f5d95 100644
--- a/include/elf/riscv.h
+++ b/include/elf/riscv.h
@@ -44,6 +44,7 @@ START_RELOC_NUMBERS (elf_riscv_reloc_type)
   RELOC_NUMBER (R_RISCV_TLS_DTPREL64, 9)
   RELOC_NUMBER (R_RISCV_TLS_TPREL32, 10)
   RELOC_NUMBER (R_RISCV_TLS_TPREL64, 11)
+  RELOC_NUMBER (R_RISCV_TLSDESC, 12)
 
   /* Relocation types not used by the dynamic linker.  */
   RELOC_NUMBER (R_RISCV_BRANCH, 16)
@@ -90,6 +91,10 @@ START_RELOC_NUMBERS (elf_riscv_reloc_type)
   /* Reserved 59 for R_RISCV_PLT32.  */
   RELOC_NUMBER (R_RISCV_SET_ULEB128, 60)
   RELOC_NUMBER (R_RISCV_SUB_ULEB128, 61)
+  RELOC_NUMBER (R_RISCV_TLSDESC_HI20, 62)
+  RELOC_NUMBER (R_RISCV_TLSDESC_LOAD_LO12, 63)
+  RELOC_NUMBER (R_RISCV_TLSDESC_ADD_LO12, 64)
+  RELOC_NUMBER (R_RISCV_TLSDESC_CALL, 65)
 END_RELOC_NUMBERS (R_RISCV_max)
 
 /* Processor specific flags for the ELF header e_flags field.  */
-- 
2.41.0


^ permalink raw reply	[flat|nested] 49+ messages in thread

* [PATCH 2/4] RISC-V: Add assembly support for TLSDESC.
  2023-08-17 18:08 [PATCH 0/4] RISC-V: Implement TLS Descriptors Tatsuyuki Ishi
  2023-08-17 18:08 ` [PATCH 1/4] RISC-V: Add TLSDESC reloc definitions Tatsuyuki Ishi
@ 2023-08-17 18:08 ` Tatsuyuki Ishi
  2023-08-17 18:08 ` [PATCH 3/4] RISC-V: Define and use GOT entry size constants for TLS Tatsuyuki Ishi
                   ` (5 subsequent siblings)
  7 siblings, 0 replies; 49+ messages in thread
From: Tatsuyuki Ishi @ 2023-08-17 18:08 UTC (permalink / raw)
  To: binutils; +Cc: rui314, ruiu, Tatsuyuki Ishi

---
 gas/config/tc-riscv.c | 18 +++++++++++++-----
 opcodes/riscv-opc.c   |  1 +
 2 files changed, 14 insertions(+), 5 deletions(-)

diff --git a/gas/config/tc-riscv.c b/gas/config/tc-riscv.c
index 959cbbc32a5..0a1fac9de9d 100644
--- a/gas/config/tc-riscv.c
+++ b/gas/config/tc-riscv.c
@@ -2195,6 +2195,7 @@ static const struct percent_op_match percent_op_utype[] =
   {"tprel_hi", BFD_RELOC_RISCV_TPREL_HI20},
   {"pcrel_hi", BFD_RELOC_RISCV_PCREL_HI20},
   {"got_pcrel_hi", BFD_RELOC_RISCV_GOT_HI20},
+  {"tlsdesc_hi", BFD_RELOC_RISCV_TLSDESC_HI20},
   {"tls_ie_pcrel_hi", BFD_RELOC_RISCV_TLS_GOT_HI20},
   {"tls_gd_pcrel_hi", BFD_RELOC_RISCV_TLS_GD_HI20},
   {"hi", BFD_RELOC_RISCV_HI20},
@@ -2206,6 +2207,8 @@ static const struct percent_op_match percent_op_itype[] =
   {"lo", BFD_RELOC_RISCV_LO12_I},
   {"tprel_lo", BFD_RELOC_RISCV_TPREL_LO12_I},
   {"pcrel_lo", BFD_RELOC_RISCV_PCREL_LO12_I},
+  {"tlsdesc_load_lo", BFD_RELOC_RISCV_TLSDESC_LOAD_LO12},
+  {"tlsdesc_add_lo", BFD_RELOC_RISCV_TLSDESC_ADD_LO12},
   {0, 0}
 };
 
@@ -2217,8 +2220,9 @@ static const struct percent_op_match percent_op_stype[] =
   {0, 0}
 };
 
-static const struct percent_op_match percent_op_rtype[] =
+static const struct percent_op_match percent_op_relax_only[] =
 {
+  {"tlsdesc_call", BFD_RELOC_RISCV_TLSDESC_CALL},
   {"tprel_add", BFD_RELOC_RISCV_TPREL_ADD},
   {0, 0}
 };
@@ -3326,10 +3330,10 @@ riscv_ip (char *str, struct riscv_cl_insn *ip, expressionS *imm_expr,
 	      *imm_reloc = BFD_RELOC_RISCV_LO12_I;
 	      goto load_store;
 	    case '1':
-	      /* This is used for TLS, where the fourth operand is
-		 %tprel_add, to get a relocation applied to an add
-		 instruction, for relaxation to use.  */
-	      p = percent_op_rtype;
+	      /* This is used for TLS relocations that acts as relaxation
+	         markers and do not change the instruction encoding,
+	         i.e. %tprel_add and %tlsdesc_call.  */
+	      p = percent_op_relax_only;
 	      goto alu_op;
 	    case '0': /* AMO displacement, which must be zero.  */
 	    load_store:
@@ -4082,6 +4086,7 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
     case BFD_RELOC_RISCV_TPREL_LO12_I:
     case BFD_RELOC_RISCV_TPREL_LO12_S:
     case BFD_RELOC_RISCV_TPREL_ADD:
+    case BFD_RELOC_RISCV_TLSDESC_HI20:
       relaxable = true;
       /* Fall through.  */
 
@@ -4255,6 +4260,9 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
 
     case BFD_RELOC_RISCV_CALL:
     case BFD_RELOC_RISCV_CALL_PLT:
+    case BFD_RELOC_RISCV_TLSDESC_LOAD_LO12:
+    case BFD_RELOC_RISCV_TLSDESC_ADD_LO12:
+    case BFD_RELOC_RISCV_TLSDESC_CALL:
       relaxable = true;
       break;
 
diff --git a/opcodes/riscv-opc.c b/opcodes/riscv-opc.c
index 067e9fdb611..467666b9805 100644
--- a/opcodes/riscv-opc.c
+++ b/opcodes/riscv-opc.c
@@ -370,6 +370,7 @@ const struct riscv_opcode riscv_opcodes[] =
 {"jalr",        0, INSN_CLASS_I, "s,j",       MATCH_JALR|(X_RA << OP_SH_RD), MASK_JALR|MASK_RD, match_opcode, INSN_ALIAS|INSN_JSR },
 {"jalr",        0, INSN_CLASS_I, "d,s",       MATCH_JALR, MASK_JALR|MASK_IMM, match_opcode, INSN_ALIAS|INSN_JSR },
 {"jalr",        0, INSN_CLASS_I, "d,o(s)",    MATCH_JALR, MASK_JALR, match_opcode, INSN_JSR },
+{"jalr",        0, INSN_CLASS_I, "d,s,1",     MATCH_JALR, MASK_JALR|MASK_IMM, match_opcode, INSN_JSR },
 {"jalr",        0, INSN_CLASS_I, "d,s,j",     MATCH_JALR, MASK_JALR, match_opcode, INSN_JSR },
 {"j",           0, INSN_CLASS_C, "Ca",        MATCH_C_J, MASK_C_J, match_opcode, INSN_ALIAS|INSN_BRANCH },
 {"j",           0, INSN_CLASS_I, "a",         MATCH_JAL, MASK_JAL|MASK_RD, match_opcode, INSN_ALIAS|INSN_BRANCH },
-- 
2.41.0


^ permalink raw reply	[flat|nested] 49+ messages in thread

* [PATCH 3/4] RISC-V: Define and use GOT entry size constants for TLS.
  2023-08-17 18:08 [PATCH 0/4] RISC-V: Implement TLS Descriptors Tatsuyuki Ishi
  2023-08-17 18:08 ` [PATCH 1/4] RISC-V: Add TLSDESC reloc definitions Tatsuyuki Ishi
  2023-08-17 18:08 ` [PATCH 2/4] RISC-V: Add assembly support for TLSDESC Tatsuyuki Ishi
@ 2023-08-17 18:08 ` Tatsuyuki Ishi
  2023-08-17 18:08 ` [PATCH 4/4] RISC-V: Initial ld.bfd support for TLSDESC Tatsuyuki Ishi
                   ` (4 subsequent siblings)
  7 siblings, 0 replies; 49+ messages in thread
From: Tatsuyuki Ishi @ 2023-08-17 18:08 UTC (permalink / raw)
  To: binutils; +Cc: rui314, ruiu, Tatsuyuki Ishi

As the size calculation is split by global and local symbols, using a
shared constant definition for its size improves clarity.
---
 bfd/elfnn-riscv.c | 16 +++++++++-------
 1 file changed, 9 insertions(+), 7 deletions(-)

diff --git a/bfd/elfnn-riscv.c b/bfd/elfnn-riscv.c
index 02b46835cc7..38883134828 100644
--- a/bfd/elfnn-riscv.c
+++ b/bfd/elfnn-riscv.c
@@ -301,6 +301,8 @@ riscv_is_insn_reloc (const reloc_howto_type *howto)
 #define PLT_HEADER_SIZE (PLT_HEADER_INSNS * 4)
 #define PLT_ENTRY_SIZE (PLT_ENTRY_INSNS * 4)
 #define GOT_ENTRY_SIZE RISCV_ELF_WORD_BYTES
+#define TLS_GD_GOT_ENTRY_SIZE (RISCV_ELF_WORD_BYTES * 2)
+#define TLS_IE_GOT_ENTRY_SIZE RISCV_ELF_WORD_BYTES
 /* Reserve two entries of GOTPLT for ld.so, one is used for PLT resolver,
    the other is used for link map.  Other targets also reserve one more
    entry used for runtime profile?  */
@@ -1323,7 +1325,7 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
 	  /* TLS_GD needs two dynamic relocs and two GOT slots.  */
 	  if (tls_type & GOT_TLS_GD)
 	    {
-	      s->size += 2 * RISCV_ELF_WORD_BYTES;
+	      s->size += TLS_GD_GOT_ENTRY_SIZE;
 	      if (need_reloc)
 		htab->elf.srelgot->size += 2 * sizeof (ElfNN_External_Rela);
 	    }
@@ -1331,14 +1333,14 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
 	  /* TLS_IE needs one dynamic reloc and one GOT slot.  */
 	  if (tls_type & GOT_TLS_IE)
 	    {
-	      s->size += RISCV_ELF_WORD_BYTES;
+	      s->size += TLS_IE_GOT_ENTRY_SIZE;
 	      if (need_reloc)
 		htab->elf.srelgot->size += sizeof (ElfNN_External_Rela);
 	    }
 	}
       else
 	{
-	  s->size += RISCV_ELF_WORD_BYTES;
+	  s->size += GOT_ENTRY_SIZE;
 	  if (WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, bfd_link_pic (info), h)
 	      && ! UNDEFWEAK_NO_DYNAMIC_RELOC (info, h))
 	    htab->elf.srelgot->size += sizeof (ElfNN_External_Rela);
@@ -1566,20 +1568,20 @@ riscv_elf_size_dynamic_sections (bfd *output_bfd, struct bfd_link_info *info)
 		{
 		  if (*local_tls_type & GOT_TLS_GD)
 		    {
-		      s->size += 2 * RISCV_ELF_WORD_BYTES;
+		      s->size += TLS_GD_GOT_ENTRY_SIZE;
 		      if (bfd_link_dll (info))
 			srel->size += sizeof (ElfNN_External_Rela);
 		    }
 		  if (*local_tls_type & GOT_TLS_IE)
 		    {
-		      s->size += RISCV_ELF_WORD_BYTES;
+		      s->size += TLS_IE_GOT_ENTRY_SIZE;
 		      if (bfd_link_dll (info))
 			srel->size += sizeof (ElfNN_External_Rela);
 		    }
 		}
 	      else
 		{
-		  s->size += RISCV_ELF_WORD_BYTES;
+		  s->size += GOT_ENTRY_SIZE;
 		  if (bfd_link_pic (info))
 		    srel->size += sizeof (ElfNN_External_Rela);
 		}
@@ -2905,7 +2907,7 @@ riscv_elf_relocate_section (bfd *output_bfd,
 	     reference's GOT slot follows the GD reference's slots.  */
 	  ie_off = 0;
 	  if ((tls_type & GOT_TLS_GD) && (tls_type & GOT_TLS_IE))
-	    ie_off = 2 * GOT_ENTRY_SIZE;
+	    ie_off = TLS_GD_GOT_ENTRY_SIZE;
 
 	  if ((off & 1) != 0)
 	    off &= ~1;
-- 
2.41.0


^ permalink raw reply	[flat|nested] 49+ messages in thread

* [PATCH 4/4] RISC-V: Initial ld.bfd support for TLSDESC.
  2023-08-17 18:08 [PATCH 0/4] RISC-V: Implement TLS Descriptors Tatsuyuki Ishi
                   ` (2 preceding siblings ...)
  2023-08-17 18:08 ` [PATCH 3/4] RISC-V: Define and use GOT entry size constants for TLS Tatsuyuki Ishi
@ 2023-08-17 18:08 ` Tatsuyuki Ishi
  2023-08-18  0:22 ` [PATCH 0/4] RISC-V: Implement TLS Descriptors Nelson Chu
                   ` (3 subsequent siblings)
  7 siblings, 0 replies; 49+ messages in thread
From: Tatsuyuki Ishi @ 2023-08-17 18:08 UTC (permalink / raw)
  To: binutils; +Cc: rui314, ruiu, Tatsuyuki Ishi

Only relocation handling for now; relaxation is not implemented yet.
---
 bfd/elfnn-riscv.c                          | 91 +++++++++++++++++++---
 ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp |  2 +
 2 files changed, 84 insertions(+), 9 deletions(-)

diff --git a/bfd/elfnn-riscv.c b/bfd/elfnn-riscv.c
index 38883134828..a55bee7af52 100644
--- a/bfd/elfnn-riscv.c
+++ b/bfd/elfnn-riscv.c
@@ -166,6 +166,7 @@ struct riscv_elf_link_hash_entry
 #define GOT_TLS_GD	2
 #define GOT_TLS_IE	4
 #define GOT_TLS_LE	8
+#define GOT_TLSDESC	16
   char tls_type;
 };
 
@@ -303,6 +304,7 @@ riscv_is_insn_reloc (const reloc_howto_type *howto)
 #define GOT_ENTRY_SIZE RISCV_ELF_WORD_BYTES
 #define TLS_GD_GOT_ENTRY_SIZE (RISCV_ELF_WORD_BYTES * 2)
 #define TLS_IE_GOT_ENTRY_SIZE RISCV_ELF_WORD_BYTES
+#define TLSDESC_GOT_ENTRY_SIZE (RISCV_ELF_WORD_BYTES * 2)
 /* Reserve two entries of GOTPLT for ld.so, one is used for PLT resolver,
    the other is used for link map.  Other targets also reserve one more
    entry used for runtime profile?  */
@@ -858,6 +860,12 @@ riscv_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
 	    return false;
 	  break;
 
+	  case R_RISCV_TLSDESC_HI20:
+	    if (!riscv_elf_record_got_reference (abfd, info, h, r_symndx)
+		|| !riscv_elf_record_tls_type (abfd, h, r_symndx, GOT_TLSDESC))
+	      return false;
+	  break;
+
 	case R_RISCV_CALL:
 	case R_RISCV_CALL_PLT:
 	  /* These symbol requires a procedure linkage table entry.
@@ -1316,7 +1324,7 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
       s = htab->elf.sgot;
       h->got.offset = s->size;
       dyn = htab->elf.dynamic_sections_created;
-      if (tls_type & (GOT_TLS_GD | GOT_TLS_IE))
+      if (tls_type & (GOT_TLS_GD | GOT_TLS_IE | GOT_TLSDESC))
 	{
 	  int indx = 0;
 	  bool need_reloc = false;
@@ -1337,6 +1345,14 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
 	      if (need_reloc)
 		htab->elf.srelgot->size += sizeof (ElfNN_External_Rela);
 	    }
+
+	  /* TLSDESC needs one dynamic reloc and four GOT slots.  */
+	  if (tls_type & GOT_TLSDESC)
+	    {
+	      s->size += TLSDESC_GOT_ENTRY_SIZE;
+	      /* TLSDESC always use dynamic relocs.  */
+	      htab->elf.srelgot->size += sizeof (ElfNN_External_Rela);
+	    }
 	}
       else
 	{
@@ -1564,7 +1580,7 @@ riscv_elf_size_dynamic_sections (bfd *output_bfd, struct bfd_link_info *info)
 	  if (*local_got > 0)
 	    {
 	      *local_got = s->size;
-	      if (*local_tls_type & (GOT_TLS_GD | GOT_TLS_IE))
+	      if (*local_tls_type & (GOT_TLS_GD | GOT_TLS_IE | GOT_TLSDESC))
 		{
 		  if (*local_tls_type & GOT_TLS_GD)
 		    {
@@ -1578,6 +1594,11 @@ riscv_elf_size_dynamic_sections (bfd *output_bfd, struct bfd_link_info *info)
 		      if (bfd_link_dll (info))
 			srel->size += sizeof (ElfNN_External_Rela);
 		    }
+		  if (*local_tls_type & GOT_TLSDESC)
+		    {
+		      s->size += TLSDESC_GOT_ENTRY_SIZE;
+		      srel->size += sizeof (ElfNN_External_Rela);
+		    }
 		}
 	      else
 		{
@@ -1728,6 +1749,17 @@ tpoff (struct bfd_link_info *info, bfd_vma address)
   return address - elf_hash_table (info)->tls_sec->vma - TP_OFFSET;
 }
 
+/* Return the relocation value for a static TLSDESC relocation.  */
+
+static bfd_vma
+tlsdescoff (struct bfd_link_info *info, bfd_vma address)
+{
+  /* If tls_sec is NULL, we should have signalled an error already.  */
+  if (elf_hash_table (info)->tls_sec == NULL)
+    return 0;
+  return address - elf_hash_table (info)->tls_sec->vma;
+}
+
 /* Return the global pointer's value, or 0 if it is not in use.  */
 
 static bfd_vma
@@ -1764,6 +1796,7 @@ perform_relocation (const reloc_howto_type *howto,
     case R_RISCV_GOT_HI20:
     case R_RISCV_TLS_GOT_HI20:
     case R_RISCV_TLS_GD_HI20:
+    case R_RISCV_TLSDESC_HI20:
       if (ARCH_SIZE > 32 && !VALID_UTYPE_IMM (RISCV_CONST_HIGH_PART (value)))
 	return bfd_reloc_overflow;
       value = ENCODE_UTYPE_IMM (RISCV_CONST_HIGH_PART (value));
@@ -1774,6 +1807,8 @@ perform_relocation (const reloc_howto_type *howto,
     case R_RISCV_TPREL_LO12_I:
     case R_RISCV_TPREL_I:
     case R_RISCV_PCREL_LO12_I:
+    case R_RISCV_TLSDESC_LOAD_LO12:
+    case R_RISCV_TLSDESC_ADD_LO12:
       value = ENCODE_ITYPE_IMM (value);
       break;
 
@@ -2195,8 +2230,8 @@ riscv_elf_relocate_section (bfd *output_bfd,
       bfd_vma relocation;
       bfd_reloc_status_type r = bfd_reloc_ok;
       const char *name = NULL;
-      bfd_vma off, ie_off;
-      bool unresolved_reloc, is_ie = false;
+      bfd_vma off, ie_off, desc_off;
+      bool unresolved_reloc, is_ie = false, is_desc = false;
       bfd_vma pc = sec_addr (input_section) + rel->r_offset;
       int r_type = ELFNN_R_TYPE (rel->r_info), tls_type;
       reloc_howto_type *howto = riscv_elf_rtype_to_howto (input_bfd, r_type);
@@ -2499,6 +2534,7 @@ riscv_elf_relocate_section (bfd *output_bfd,
 	case R_RISCV_NONE:
 	case R_RISCV_RELAX:
 	case R_RISCV_TPREL_ADD:
+	case R_RISCV_TLSDESC_CALL:
 	case R_RISCV_COPY:
 	case R_RISCV_JUMP_SLOT:
 	case R_RISCV_RELATIVE:
@@ -2820,6 +2856,15 @@ riscv_elf_relocate_section (bfd *output_bfd,
 	  relocation = dtpoff (info, relocation);
 	  break;
 
+	case R_RISCV_TLSDESC_LOAD_LO12:
+	case R_RISCV_TLSDESC_ADD_LO12:
+	  if (riscv_record_pcrel_lo_reloc (&pcrel_relocs, relocation, rel,
+					   input_section, info, howto,
+					   contents))
+	      continue;
+	  r = bfd_reloc_overflow;
+	  break;
+
 	case R_RISCV_32:
 	  /* Non ABS symbol should be blocked in check_relocs.  */
 	  if (ARCH_SIZE > 32)
@@ -2885,11 +2930,16 @@ riscv_elf_relocate_section (bfd *output_bfd,
 	    }
 	  break;
 
+	case R_RISCV_TLSDESC_HI20:
+	  is_desc = true;
+	  goto tls;
+
 	case R_RISCV_TLS_GOT_HI20:
 	  is_ie = true;
-	  /* Fall through.  */
+	  goto tls;
 
 	case R_RISCV_TLS_GD_HI20:
+	tls:
 	  if (h != NULL)
 	    {
 	      off = h->got.offset;
@@ -2902,12 +2952,16 @@ riscv_elf_relocate_section (bfd *output_bfd,
 	    }
 
 	  tls_type = _bfd_riscv_elf_tls_type (input_bfd, h, r_symndx);
-	  BFD_ASSERT (tls_type & (GOT_TLS_IE | GOT_TLS_GD));
+	  BFD_ASSERT (tls_type & (GOT_TLS_IE | GOT_TLS_GD | GOT_TLSDESC));
 	  /* If this symbol is referenced by both GD and IE TLS, the IE
 	     reference's GOT slot follows the GD reference's slots.  */
 	  ie_off = 0;
 	  if ((tls_type & GOT_TLS_GD) && (tls_type & GOT_TLS_IE))
-	    ie_off = TLS_GD_GOT_ENTRY_SIZE;
+	    ie_off += TLS_GD_GOT_ENTRY_SIZE;
+
+	  desc_off = ie_off;
+	  if (tls_type & GOT_TLS_IE)
+	    desc_off += TLS_IE_GOT_ENTRY_SIZE;
 
 	  if ((off & 1) != 0)
 	    off &= ~1;
@@ -2989,10 +3043,29 @@ riscv_elf_relocate_section (bfd *output_bfd,
 				  htab->elf.sgot->contents + off + ie_off);
 		    }
 		}
+
+	      if (tls_type & GOT_TLSDESC)
+		{
+		  /* TLSDESC is always handled by the dynamic linker and always need
+		   * a relocation.  */
+		  bfd_put_NN (output_bfd, 0,
+			      htab->elf.sgot->contents + off + desc_off);
+		  outrel.r_offset = sec_addr (htab->elf.sgot)
+				    + off + desc_off;
+		  outrel.r_addend = 0;
+		  if (indx == 0)
+		    outrel.r_addend = tlsdescoff (info, relocation);
+		  outrel.r_info = ELFNN_R_INFO (indx, R_RISCV_TLSDESC);
+		  riscv_elf_append_rela (output_bfd, htab->elf.srelgot, &outrel);
+		}
 	    }
 
 	  BFD_ASSERT (off < (bfd_vma) -2);
-	  relocation = sec_addr (htab->elf.sgot) + off + (is_ie ? ie_off : 0);
+	  relocation = sec_addr (htab->elf.sgot) + off;
+	  if (is_ie)
+	    relocation += ie_off;
+	  else if (is_desc)
+	    relocation += desc_off;
 	  if (!riscv_record_pcrel_hi_reloc (&pcrel_relocs, pc,
 					    relocation, r_type,
 					    false))
@@ -3212,7 +3285,7 @@ riscv_elf_finish_dynamic_symbol (bfd *output_bfd,
     }
 
   if (h->got.offset != (bfd_vma) -1
-      && !(riscv_elf_hash_entry (h)->tls_type & (GOT_TLS_GD | GOT_TLS_IE))
+      && !(riscv_elf_hash_entry (h)->tls_type & (GOT_TLS_GD | GOT_TLS_IE | GOT_TLSDESC))
       && !UNDEFWEAK_NO_DYNAMIC_RELOC (info, h))
     {
       asection *sgot;
diff --git a/ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp b/ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp
index 947a266ba72..e09c25486a5 100644
--- a/ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp
+++ b/ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp
@@ -317,4 +317,6 @@ if [istarget "riscv*-*-*"] {
     run_dump_test "pcrel-reloc-rel-pie"
     run_dump_test "pcrel-reloc-abs-nopie"
     run_dump_test "pcrel-reloc-abs-pie"
+
+    run_dump_test "tlsdesc"
 }
-- 
2.41.0


^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [PATCH 0/4] RISC-V: Implement TLS Descriptors.
  2023-08-17 18:08 [PATCH 0/4] RISC-V: Implement TLS Descriptors Tatsuyuki Ishi
                   ` (3 preceding siblings ...)
  2023-08-17 18:08 ` [PATCH 4/4] RISC-V: Initial ld.bfd support for TLSDESC Tatsuyuki Ishi
@ 2023-08-18  0:22 ` Nelson Chu
  2023-08-18  7:13   ` Fangrui Song
  2023-08-31 17:13 ` [PATCH v2 0/5] " Tatsuyuki Ishi
                   ` (2 subsequent siblings)
  7 siblings, 1 reply; 49+ messages in thread
From: Nelson Chu @ 2023-08-18  0:22 UTC (permalink / raw)
  To: Tatsuyuki Ishi; +Cc: binutils, rui314, ruiu

[-- Attachment #1: Type: text/plain, Size: 1993 bytes --]

Hi,

Before the reviewing, I think you still should have test cases for each
patch to make sure everything is correct in the binutils, and helps people
understand what the patches try to resolve what problem or support what
features.  In general, the regressions in binutils, gcc and glibc are
seperate.  Besides, each patch should at least have the ChangLogs in the
commit message.

Thanks
Nelson

On Fri, Aug 18, 2023 at 2:10 AM Tatsuyuki Ishi via Binutils <
binutils@sourceware.org> wrote:

> This patchset implements TLS Descriptors (TLSDESC) for RISC-V targets, per
> the specification draft at [1].
>
> This patchset is based on top of [2].
>
> No regression in binutils and gcc tests for rv64gc, tested alongside the
> gcc and glibc implementation (will be posted shortly).
>
> This contribution is made on behalf of Blue Whale Systems, which has
> copyright assignment on file with the FSF.
>
> [1]: https://github.com/riscv-non-isa/riscv-elf-psabi-doc/pull/373
> [2]: https://sourceware.org/pipermail/binutils/2023-August/129075.html
>
> Tatsuyuki Ishi (4):
>   RISC-V: Add TLSDESC reloc definitions.
>   RISC-V: Add assembly support for TLSDESC.
>   RISC-V: Define and use GOT entry size constants for TLS.
>   RISC-V: Initial ld.bfd support for TLSDESC.
>
>  bfd/bfd-in2.h                              |   4 +
>  bfd/elfnn-riscv.c                          | 105 ++++++++++++++++++---
>  bfd/elfxx-riscv.c                          |  75 ++++++++++++++-
>  bfd/libbfd.h                               |   4 +
>  bfd/reloc.c                                |   8 ++
>  gas/config/tc-riscv.c                      |  18 +++-
>  include/elf/riscv.h                        |   5 +
>


>  ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp |   2 +
>

This doesn't work, seems still not adding any test cases.


>  opcodes/riscv-opc.c                        |   1 +
>  9 files changed, 201 insertions(+), 21 deletions(-)
>
> --
> 2.41.0
>
>

^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [PATCH 0/4] RISC-V: Implement TLS Descriptors.
  2023-08-18  0:22 ` [PATCH 0/4] RISC-V: Implement TLS Descriptors Nelson Chu
@ 2023-08-18  7:13   ` Fangrui Song
  0 siblings, 0 replies; 49+ messages in thread
From: Fangrui Song @ 2023-08-18  7:13 UTC (permalink / raw)
  To: Tatsuyuki Ishi; +Cc: Nelson Chu, binutils, rui314, ruiu

On Thu, Aug 17, 2023 at 5:22 PM Nelson Chu <nelson@rivosinc.com> wrote:
>
> Hi,
>
> Before the reviewing, I think you still should have test cases for each
> patch to make sure everything is correct in the binutils, and helps people
> understand what the patches try to resolve what problem or support what
> features.  In general, the regressions in binutils, gcc and glibc are
> seperate.  Besides, each patch should at least have the ChangLogs in the
> commit message.
>
> Thanks
> Nelson

A relocatable object file can contain both TLSDESC and TLS GD
relocations (e.g. relocatable output).
The GOT use cases are different. It will be nice to have such a test.

We need tests for at least (a) -shared and (b) -no-pie or -pie (I
prefer just -no-pie).

Perhaps you have done this (as the glibc patch suggests), but I want
to make sure that the GOT entries are placed in .rela.dyn, not
.rela.plt
(https://sourceware.org/bugzilla/show_bug.cgi?id=28387  ld: Move
R_*_TLSDESC to .rela.dyn)
sysdeps/{aarch64,x86_64}/dl-machine.h unfortunately have to handle
TLSDESC in elf_machine_lazy_rel for compatibility.

> [PATCH 4/4] RISC-V: Initial ld.bfd support for TLSDESC.
> + /* TLSDESC needs one dynamic reloc and four GOT slots. *

Why is there 4? Other ports reserve 2 GOT slots for one symbol.

> On Fri, Aug 18, 2023 at 2:10 AM Tatsuyuki Ishi via Binutils <
> binutils@sourceware.org> wrote:
>
> > This patchset implements TLS Descriptors (TLSDESC) for RISC-V targets, per
> > the specification draft at [1].
> >
> > This patchset is based on top of [2].
> >
> > No regression in binutils and gcc tests for rv64gc, tested alongside the
> > gcc and glibc implementation (will be posted shortly).
> >
> > This contribution is made on behalf of Blue Whale Systems, which has
> > copyright assignment on file with the FSF.
> >
> > [1]: https://github.com/riscv-non-isa/riscv-elf-psabi-doc/pull/373
> > [2]: https://sourceware.org/pipermail/binutils/2023-August/129075.html
> >
> > Tatsuyuki Ishi (4):
> >   RISC-V: Add TLSDESC reloc definitions.
> >   RISC-V: Add assembly support for TLSDESC.
> >   RISC-V: Define and use GOT entry size constants for TLS.
> >   RISC-V: Initial ld.bfd support for TLSDESC.
> >
> >  bfd/bfd-in2.h                              |   4 +
> >  bfd/elfnn-riscv.c                          | 105 ++++++++++++++++++---
> >  bfd/elfxx-riscv.c                          |  75 ++++++++++++++-
> >  bfd/libbfd.h                               |   4 +
> >  bfd/reloc.c                                |   8 ++
> >  gas/config/tc-riscv.c                      |  18 +++-
> >  include/elf/riscv.h                        |   5 +
> >
>
>
> >  ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp |   2 +
> >
>
> This doesn't work, seems still not adding any test cases.
>
>
> >  opcodes/riscv-opc.c                        |   1 +
> >  9 files changed, 201 insertions(+), 21 deletions(-)
> >
> > --
> > 2.41.0
> >
> >

^ permalink raw reply	[flat|nested] 49+ messages in thread

* [PATCH v2 0/5] RISC-V: Implement TLS Descriptors.
  2023-08-17 18:08 [PATCH 0/4] RISC-V: Implement TLS Descriptors Tatsuyuki Ishi
                   ` (4 preceding siblings ...)
  2023-08-18  0:22 ` [PATCH 0/4] RISC-V: Implement TLS Descriptors Nelson Chu
@ 2023-08-31 17:13 ` Tatsuyuki Ishi
  2023-08-31 17:13   ` [PATCH v2 1/5] RISC-V: Fix local GOT and reloc size calculation for TLS Tatsuyuki Ishi
                     ` (4 more replies)
  2023-11-28  8:51 ` [PATCH v3 0/9] RISC-V: Implement TLS Descriptors Tatsuyuki Ishi
  2024-02-20 17:55 ` [PATCH v4 " Tatsuyuki Ishi
  7 siblings, 5 replies; 49+ messages in thread
From: Tatsuyuki Ishi @ 2023-08-31 17:13 UTC (permalink / raw)
  To: binutils; +Cc: rui314, ruiu, i, nelson, Tatsuyuki Ishi

This patchset implements TLS Descriptors (TLSDESC) for RISC-V targets, per
the specification draft at [1].

No regression (& passing new tests) in binutils, tested for rv64gc.

This contribution is made on behalf of Blue Whale Systems, which has
copyright assignment on file with the FSF.

[1]: https://github.com/riscv-non-isa/riscv-elf-psabi-doc/pull/373

v2: Add changelogs and tests. Minor fixes described in patch messages.

Tatsuyuki Ishi (5):
  RISC-V: Fix local GOT and reloc size calculation for TLS.
  RISC-V: Add TLSDESC reloc definitions.
  RISC-V: Add assembly support for TLSDESC.
  RISC-V: Define and use GOT entry size constants for TLS.
  RISC-V: Initial ld.bfd support for TLSDESC.

 bfd/bfd-in2.h                              |   4 +
 bfd/elfnn-riscv.c                          | 124 ++++++++++++++++++---
 bfd/elfxx-riscv.c                          |  75 ++++++++++++-
 bfd/libbfd.h                               |   4 +
 bfd/reloc.c                                |   8 ++
 gas/config/tc-riscv.c                      |  18 ++-
 gas/testsuite/gas/riscv/tlsdesc.d          |  22 ++++
 gas/testsuite/gas/riscv/tlsdesc.s          |  24 ++++
 include/elf/riscv.h                        |   5 +
 ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp |   8 ++
 ld/testsuite/ld-riscv-elf/tls.d            |  17 +++
 ld/testsuite/ld-riscv-elf/tls.s            |  42 +++++++
 ld/testsuite/ld-riscv-elf/tlsbin.d         |  12 ++
 ld/testsuite/ld-riscv-elf/tlslib.s         |   6 +
 opcodes/riscv-opc.c                        |   1 +
 15 files changed, 347 insertions(+), 23 deletions(-)
 create mode 100644 gas/testsuite/gas/riscv/tlsdesc.d
 create mode 100644 gas/testsuite/gas/riscv/tlsdesc.s
 create mode 100644 ld/testsuite/ld-riscv-elf/tls.d
 create mode 100644 ld/testsuite/ld-riscv-elf/tls.s
 create mode 100644 ld/testsuite/ld-riscv-elf/tlsbin.d
 create mode 100644 ld/testsuite/ld-riscv-elf/tlslib.s

-- 
2.42.0


^ permalink raw reply	[flat|nested] 49+ messages in thread

* [PATCH v2 1/5] RISC-V: Fix local GOT and reloc size calculation for TLS.
  2023-08-31 17:13 ` [PATCH v2 0/5] " Tatsuyuki Ishi
@ 2023-08-31 17:13   ` Tatsuyuki Ishi
  2024-02-21  0:49     ` Nelson Chu
  2023-08-31 17:13   ` [PATCH v2 2/5] RISC-V: Add TLSDESC reloc definitions Tatsuyuki Ishi
                     ` (3 subsequent siblings)
  4 siblings, 1 reply; 49+ messages in thread
From: Tatsuyuki Ishi @ 2023-08-31 17:13 UTC (permalink / raw)
  To: binutils; +Cc: rui314, ruiu, i, nelson, Tatsuyuki Ishi

The previous code did not account correctly for two cases:
* A TLS symbol can be referenced with multiple TLS types (although rare),
  in which case it only allocated the maximum slot size among the types,
  instead of the sum.
* TLS relocations are only needed for DLLs, unlike normal symbols which
  requires relocations for all PIE code.

Modify the logic to account for the two cases.

bfd/
    * elfnn-riscv.c (riscv_elf_size_dynamic_sections): Handle relocation
    sizing for TLS and non-TLS symbols differently, with the former
    requiring relocs on DLL while the latter requiring on PIE.
    Allocate GOT slots and relocation slots for each TLS type separately,
    accounting for the possibility of a TLS variable getting referenced by
    multiple symbols.
ld/
    * testsuite/ld-riscv-elf/ld-riscv-elf.exp: Updated.
    * testsuite/ld-riscv-elf/tls*: New testcase for TLS GD and IE, with
    symbols referred by both types and global and local symbols.
---
v2: Add tests for GD and IE, testing both global and local symbols.
    Both -shared and -no-pie are tested.

 bfd/elfnn-riscv.c                          | 27 ++++++++++++++++-----
 ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp |  8 +++++++
 ld/testsuite/ld-riscv-elf/tls.d            | 15 ++++++++++++
 ld/testsuite/ld-riscv-elf/tls.s            | 28 ++++++++++++++++++++++
 ld/testsuite/ld-riscv-elf/tlsbin.d         |  7 ++++++
 ld/testsuite/ld-riscv-elf/tlslib.s         |  6 +++++
 6 files changed, 85 insertions(+), 6 deletions(-)
 create mode 100644 ld/testsuite/ld-riscv-elf/tls.d
 create mode 100644 ld/testsuite/ld-riscv-elf/tls.s
 create mode 100644 ld/testsuite/ld-riscv-elf/tlsbin.d
 create mode 100644 ld/testsuite/ld-riscv-elf/tlslib.s

diff --git a/bfd/elfnn-riscv.c b/bfd/elfnn-riscv.c
index 09aa7be225e..02b46835cc7 100644
--- a/bfd/elfnn-riscv.c
+++ b/bfd/elfnn-riscv.c
@@ -1562,12 +1562,27 @@ riscv_elf_size_dynamic_sections (bfd *output_bfd, struct bfd_link_info *info)
 	  if (*local_got > 0)
 	    {
 	      *local_got = s->size;
-	      s->size += RISCV_ELF_WORD_BYTES;
-	      if (*local_tls_type & GOT_TLS_GD)
-		s->size += RISCV_ELF_WORD_BYTES;
-	      if (bfd_link_pic (info)
-		  || (*local_tls_type & (GOT_TLS_GD | GOT_TLS_IE)))
-		srel->size += sizeof (ElfNN_External_Rela);
+	      if (*local_tls_type & (GOT_TLS_GD | GOT_TLS_IE))
+		{
+		  if (*local_tls_type & GOT_TLS_GD)
+		    {
+		      s->size += 2 * RISCV_ELF_WORD_BYTES;
+		      if (bfd_link_dll (info))
+			srel->size += sizeof (ElfNN_External_Rela);
+		    }
+		  if (*local_tls_type & GOT_TLS_IE)
+		    {
+		      s->size += RISCV_ELF_WORD_BYTES;
+		      if (bfd_link_dll (info))
+			srel->size += sizeof (ElfNN_External_Rela);
+		    }
+		}
+	      else
+		{
+		  s->size += RISCV_ELF_WORD_BYTES;
+		  if (bfd_link_pic (info))
+		    srel->size += sizeof (ElfNN_External_Rela);
+		}
 	    }
 	  else
 	    *local_got = (bfd_vma) -1;
diff --git a/ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp b/ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp
index 947a266ba72..adb4ee75e4a 100644
--- a/ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp
+++ b/ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp
@@ -317,4 +317,12 @@ if [istarget "riscv*-*-*"] {
     run_dump_test "pcrel-reloc-rel-pie"
     run_dump_test "pcrel-reloc-abs-nopie"
     run_dump_test "pcrel-reloc-abs-pie"
+
+    run_ld_link_tests {
+       { "Build shared library for TLS runtime"
+	 "-shared" "" "" {tlslib.s}
+	 {} "tlslib.so" }
+    }
+    run_dump_test "tls"
+    run_dump_test "tlsbin"
 }
diff --git a/ld/testsuite/ld-riscv-elf/tls.d b/ld/testsuite/ld-riscv-elf/tls.d
new file mode 100644
index 00000000000..0e2ab5683ad
--- /dev/null
+++ b/ld/testsuite/ld-riscv-elf/tls.d
@@ -0,0 +1,15 @@
+#source: tls.s
+#ld: --shared tmpdir/tlslib.so
+#readelf: -Wr
+
+Relocation section '.rela.dyn' at offset 0x[0-9a-f]+ contains 5 entries:
+ +Offset +Info +Type +Symbol's Value +Symbol's Name \+ Addend
+[0-9a-f]+ +[0-9a-f]+ R_RISCV_TLS_DTPMOD64 +0
+[0-9a-f]+ +[0-9a-f]+ R_RISCV_TLS_TPREL64 +4
+[0-9a-f]+ +[0-9a-f]+ R_RISCV_TLS_DTPMOD64 +0+ sg1 \+ 0
+[0-9a-f]+ +[0-9a-f]+ R_RISCV_TLS_DTPREL64 +0+ sg1 \+ 0
+[0-9a-f]+ +[0-9a-f]+ R_RISCV_TLS_TPREL64 +0+ sg1 \+ 0
+
+Relocation section '.rela.plt' at offset 0x[0-9a-f]+ contains 1 entry:
+ +Offset +Info +Type +Symbol's Value +Symbol's Name \+ Addend
+[0-9a-f]+ +[0-9a-f]+ R_RISCV_JUMP_SLOT +0+ __tls_get_addr \+ 0
\ No newline at end of file
diff --git a/ld/testsuite/ld-riscv-elf/tls.s b/ld/testsuite/ld-riscv-elf/tls.s
new file mode 100644
index 00000000000..79e9bc20374
--- /dev/null
+++ b/ld/testsuite/ld-riscv-elf/tls.s
@@ -0,0 +1,28 @@
+	.section	.tbss,"awT",@nobits
+	.global sg1
+sg1:
+	.zero	4
+sl1:
+	.zero	4
+
+	.text
+	.globl	_start
+	.type	_start,@function
+_start:
+	/* GD, global var */
+	la.tls.gd	a0,sg1
+	call  __tls_get_addr
+
+	/* IE, global var */
+	la.tls.ie	a0,sg1
+	add	a0,a0,tp
+
+	/* GD, local var */
+	la.tls.gd	a0,sl1
+	call  __tls_get_addr
+
+	/* IE, local var */
+	la.tls.ie	a0,sl1
+	add	a0,a0,tp
+
+	ret
diff --git a/ld/testsuite/ld-riscv-elf/tlsbin.d b/ld/testsuite/ld-riscv-elf/tlsbin.d
new file mode 100644
index 00000000000..12a4d0ea703
--- /dev/null
+++ b/ld/testsuite/ld-riscv-elf/tlsbin.d
@@ -0,0 +1,7 @@
+#source: tls.s
+#ld: -no-pie tmpdir/tlslib.so
+#readelf: -Wr
+
+Relocation section '.rela.plt' at offset 0x[0-9a-f]+ contains 1 entry:
+ +Offset +Info +Type +Symbol's Value +Symbol's Name \+ Addend
+[0-9a-f]+ +[0-9a-f]+ R_RISCV_JUMP_SLOT +[0-9a-f]+ __tls_get_addr \+ 0
\ No newline at end of file
diff --git a/ld/testsuite/ld-riscv-elf/tlslib.s b/ld/testsuite/ld-riscv-elf/tlslib.s
new file mode 100644
index 00000000000..17c770786d0
--- /dev/null
+++ b/ld/testsuite/ld-riscv-elf/tlslib.s
@@ -0,0 +1,6 @@
+	.text
+	/* Dummy.  */
+	.globl	__tls_get_addr
+	.type	__tls_get_addr,@function
+__tls_get_addr:
+	ret
-- 
2.42.0


^ permalink raw reply	[flat|nested] 49+ messages in thread

* [PATCH v2 2/5] RISC-V: Add TLSDESC reloc definitions.
  2023-08-31 17:13 ` [PATCH v2 0/5] " Tatsuyuki Ishi
  2023-08-31 17:13   ` [PATCH v2 1/5] RISC-V: Fix local GOT and reloc size calculation for TLS Tatsuyuki Ishi
@ 2023-08-31 17:13   ` Tatsuyuki Ishi
  2023-08-31 17:13   ` [PATCH v2 3/5] RISC-V: Add assembly support for TLSDESC Tatsuyuki Ishi
                     ` (2 subsequent siblings)
  4 siblings, 0 replies; 49+ messages in thread
From: Tatsuyuki Ishi @ 2023-08-31 17:13 UTC (permalink / raw)
  To: binutils; +Cc: rui314, ruiu, i, nelson, Tatsuyuki Ishi

bfd/
    * elfxx-riscv.c: Add 5 TLSDESC reloc descriptions.
    * reloc.c: Likewise.
    * libbfd.h: Regenerate.
    * bfd-in2.h: Regenerate.
include/
    * elf/riscv.h: Add 5 TLSDESC reloc descriptions.
---
v2: Properly regenerate the headers instead of updating them by hand.

 bfd/bfd-in2.h       |  4 +++
 bfd/elfxx-riscv.c   | 75 ++++++++++++++++++++++++++++++++++++++++++++-
 bfd/libbfd.h        |  4 +++
 bfd/reloc.c         |  8 +++++
 include/elf/riscv.h |  5 +++
 5 files changed, 95 insertions(+), 1 deletion(-)

diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h
index e2deb107494..ce324383dee 100644
--- a/bfd/bfd-in2.h
+++ b/bfd/bfd-in2.h
@@ -5411,6 +5411,10 @@ number for the SBIC, SBIS, SBI and CBI instructions  */
   BFD_RELOC_RISCV_TLS_DTPREL64,
   BFD_RELOC_RISCV_TLS_TPREL32,
   BFD_RELOC_RISCV_TLS_TPREL64,
+  BFD_RELOC_RISCV_TLSDESC_HI20,
+  BFD_RELOC_RISCV_TLSDESC_LOAD_LO12,
+  BFD_RELOC_RISCV_TLSDESC_ADD_LO12,
+  BFD_RELOC_RISCV_TLSDESC_CALL,
   BFD_RELOC_RISCV_ALIGN,
   BFD_RELOC_RISCV_RVC_BRANCH,
   BFD_RELOC_RISCV_RVC_JUMP,
diff --git a/bfd/elfxx-riscv.c b/bfd/elfxx-riscv.c
index e9852ef8fa1..43931a2be5d 100644
--- a/bfd/elfxx-riscv.c
+++ b/bfd/elfxx-riscv.c
@@ -218,8 +218,21 @@ static reloc_howto_type howto_table[] =
 	 MINUS_ONE,			/* dst_mask */
 	 false),			/* pcrel_offset */
 
+  HOWTO (R_RISCV_TLSDESC,		/* type */
+	 0,				/* rightshift */
+	 0,				/* size is handled by dynamic linker */
+	 0,				/* bitsize */
+	 false,				/* pc_relative */
+	 0,				/* bitpos */
+	 complain_overflow_dont,	/* complain_on_overflow */
+	 bfd_elf_generic_reloc,		/* special_function */
+	 "R_RISCV_TLSDESC",		/* name */
+	 false,				/* partial_inplace */
+	 0,				/* src_mask */
+	 MINUS_ONE,			/* dst_mask */
+	 false),			/* pcrel_offset */
+
   /* Reserved for future relocs that the dynamic linker must understand.  */
-  EMPTY_HOWTO (12),
   EMPTY_HOWTO (13),
   EMPTY_HOWTO (14),
   EMPTY_HOWTO (15),
@@ -879,6 +892,62 @@ static reloc_howto_type howto_table[] =
 	 0,				/* src_mask */
 	 0,				/* dst_mask */
 	 false),			/* pcrel_offset */
+
+  HOWTO (R_RISCV_TLSDESC_HI20,		/* type */
+	 0,				/* rightshift */
+	 4,				/* size */
+	 32,				/* bitsize */
+	 true,				/* pc_relative */
+	 0,				/* bitpos */
+	 complain_overflow_signed,	/* complain_on_overflow */
+	 bfd_elf_generic_reloc,		/* special_function */
+	 "R_RISCV_TLSDESC_HI20",	/* name */
+	 true,				/* partial_inplace */
+	 0,				/* src_mask */
+	 ENCODE_UTYPE_IMM (-1U),	/* dst_mask */
+	 false),			/* pcrel_offset */
+
+  HOWTO (R_RISCV_TLSDESC_LOAD_LO12,	/* type */
+	 0,				/* rightshift */
+	 4,				/* size */
+	 32,				/* bitsize */
+	 false,				/* pc_relative */
+	 0,				/* bitpos */
+	 complain_overflow_signed,	/* complain_on_overflow */
+	 bfd_elf_generic_reloc,		/* special_function */
+	 "R_RISCV_TLSDESC_LOAD_LO12",	/* name */
+	 false,				/* partial_inplace */
+	 0,				/* src_mask */
+	 ENCODE_ITYPE_IMM (-1U),	/* dst_mask */
+	 false),			/* pcrel_offset */
+
+  HOWTO (R_RISCV_TLSDESC_ADD_LO12,	/* type */
+	 0,				/* rightshift */
+	 4,				/* size */
+	 32,				/* bitsize */
+	 false,				/* pc_relative */
+	 0,				/* bitpos */
+	 complain_overflow_signed,	/* complain_on_overflow */
+	 bfd_elf_generic_reloc,		/* special_function */
+	 "R_RISCV_TLSDESC_ADD_LO12",	/* name */
+	 false,				/* partial_inplace */
+	 0,				/* src_mask */
+	 ENCODE_ITYPE_IMM (-1U),	/* dst_mask */
+	 false), 			/* pcrel_offset */
+
+  HOWTO (R_RISCV_TLSDESC_CALL,		/* type */
+	 0,				/* rightshift */
+	 0,				/* size */
+	 0,				/* bitsize */
+	 false,				/* pc_relative */
+	 0,				/* bitpos */
+	 complain_overflow_dont,	/* complain_on_overflow */
+	 bfd_elf_generic_reloc,		/* special_function */
+	 "R_RISCV_TLSDESC_CALL",	/* name */
+	 false,				/* partial_inplace */
+	 0,				/* src_mask */
+	 ENCODE_ITYPE_IMM (-1U),	/* dst_mask */
+	 false) 			/* pcrel_offset */
 };
 
 /* A mapping from BFD reloc types to RISC-V ELF reloc types.  */
@@ -925,6 +994,10 @@ static const struct elf_reloc_map riscv_reloc_map[] =
   { BFD_RELOC_RISCV_TPREL_LO12_I, R_RISCV_TPREL_LO12_I },
   { BFD_RELOC_RISCV_TLS_GOT_HI20, R_RISCV_TLS_GOT_HI20 },
   { BFD_RELOC_RISCV_TLS_GD_HI20, R_RISCV_TLS_GD_HI20 },
+  { BFD_RELOC_RISCV_TLSDESC_HI20, R_RISCV_TLSDESC_HI20 },
+  { BFD_RELOC_RISCV_TLSDESC_LOAD_LO12, R_RISCV_TLSDESC_LOAD_LO12 },
+  { BFD_RELOC_RISCV_TLSDESC_ADD_LO12, R_RISCV_TLSDESC_ADD_LO12 },
+  { BFD_RELOC_RISCV_TLSDESC_CALL, R_RISCV_TLSDESC_CALL },
   { BFD_RELOC_RISCV_ALIGN, R_RISCV_ALIGN },
   { BFD_RELOC_RISCV_RVC_BRANCH, R_RISCV_RVC_BRANCH },
   { BFD_RELOC_RISCV_RVC_JUMP, R_RISCV_RVC_JUMP },
diff --git a/bfd/libbfd.h b/bfd/libbfd.h
index a84febd8257..62e0d43d2ab 100644
--- a/bfd/libbfd.h
+++ b/bfd/libbfd.h
@@ -2408,6 +2408,10 @@ static const char *const bfd_reloc_code_real_names[] = { "@@uninitialized@@",
   "BFD_RELOC_RISCV_TLS_DTPREL64",
   "BFD_RELOC_RISCV_TLS_TPREL32",
   "BFD_RELOC_RISCV_TLS_TPREL64",
+  "BFD_RELOC_RISCV_TLSDESC_HI20",
+  "BFD_RELOC_RISCV_TLSDESC_LOAD_LO12",
+  "BFD_RELOC_RISCV_TLSDESC_ADD_LO12",
+  "BFD_RELOC_RISCV_TLSDESC_CALL",
   "BFD_RELOC_RISCV_ALIGN",
   "BFD_RELOC_RISCV_RVC_BRANCH",
   "BFD_RELOC_RISCV_RVC_JUMP",
diff --git a/bfd/reloc.c b/bfd/reloc.c
index 07d35e45c8b..38e1bdfc754 100644
--- a/bfd/reloc.c
+++ b/bfd/reloc.c
@@ -5016,6 +5016,14 @@ ENUMX
   BFD_RELOC_RISCV_TLS_TPREL32
 ENUMX
   BFD_RELOC_RISCV_TLS_TPREL64
+ENUMX
+  BFD_RELOC_RISCV_TLSDESC_HI20
+ENUMX
+  BFD_RELOC_RISCV_TLSDESC_LOAD_LO12
+ENUMX
+  BFD_RELOC_RISCV_TLSDESC_ADD_LO12
+ENUMX
+  BFD_RELOC_RISCV_TLSDESC_CALL
 ENUMX
   BFD_RELOC_RISCV_ALIGN
 ENUMX
diff --git a/include/elf/riscv.h b/include/elf/riscv.h
index 0aa8b3359c4..f32215f5d95 100644
--- a/include/elf/riscv.h
+++ b/include/elf/riscv.h
@@ -44,6 +44,7 @@ START_RELOC_NUMBERS (elf_riscv_reloc_type)
   RELOC_NUMBER (R_RISCV_TLS_DTPREL64, 9)
   RELOC_NUMBER (R_RISCV_TLS_TPREL32, 10)
   RELOC_NUMBER (R_RISCV_TLS_TPREL64, 11)
+  RELOC_NUMBER (R_RISCV_TLSDESC, 12)
 
   /* Relocation types not used by the dynamic linker.  */
   RELOC_NUMBER (R_RISCV_BRANCH, 16)
@@ -90,6 +91,10 @@ START_RELOC_NUMBERS (elf_riscv_reloc_type)
   /* Reserved 59 for R_RISCV_PLT32.  */
   RELOC_NUMBER (R_RISCV_SET_ULEB128, 60)
   RELOC_NUMBER (R_RISCV_SUB_ULEB128, 61)
+  RELOC_NUMBER (R_RISCV_TLSDESC_HI20, 62)
+  RELOC_NUMBER (R_RISCV_TLSDESC_LOAD_LO12, 63)
+  RELOC_NUMBER (R_RISCV_TLSDESC_ADD_LO12, 64)
+  RELOC_NUMBER (R_RISCV_TLSDESC_CALL, 65)
 END_RELOC_NUMBERS (R_RISCV_max)
 
 /* Processor specific flags for the ELF header e_flags field.  */
-- 
2.42.0


^ permalink raw reply	[flat|nested] 49+ messages in thread

* [PATCH v2 3/5] RISC-V: Add assembly support for TLSDESC.
  2023-08-31 17:13 ` [PATCH v2 0/5] " Tatsuyuki Ishi
  2023-08-31 17:13   ` [PATCH v2 1/5] RISC-V: Fix local GOT and reloc size calculation for TLS Tatsuyuki Ishi
  2023-08-31 17:13   ` [PATCH v2 2/5] RISC-V: Add TLSDESC reloc definitions Tatsuyuki Ishi
@ 2023-08-31 17:13   ` Tatsuyuki Ishi
  2023-08-31 17:13   ` [PATCH v2 4/5] RISC-V: Define and use GOT entry size constants for TLS Tatsuyuki Ishi
  2023-08-31 17:13   ` [PATCH v2 5/5] RISC-V: Initial ld.bfd support for TLSDESC Tatsuyuki Ishi
  4 siblings, 0 replies; 49+ messages in thread
From: Tatsuyuki Ishi @ 2023-08-31 17:13 UTC (permalink / raw)
  To: binutils; +Cc: rui314, ruiu, i, nelson, Tatsuyuki Ishi

gas/
    * tc-riscv.c (percent_op_*): Add support for %tlsdesc_hi,
    %tlsdesc_load_lo, %tlsdesc_add_lo and %tlsdesc_call. percent_op_rtype
    renamed to percent_op_relax_only as this matcher is extended to handle
    jalr as well which is not R-type.
    (riscv_ip): Apply the percent_op_relax_only rename and update comment.
    (md_apply_fix): Add TLSDESC_* to relaxable list. Add TLSDESC_HI20 to
    TLS relocation check list.
    * testsuite/gas/riscv/tlsdesc.*: New test cases for TLSDESC relocation
    generation.
opcodes/
    * riscv-opc.c (riscv_opcodes): Add a new syntax for jalr with
    %tlsdesc_call annotations.
---
 gas/config/tc-riscv.c             | 18 +++++++++++++-----
 gas/testsuite/gas/riscv/tlsdesc.d | 22 ++++++++++++++++++++++
 gas/testsuite/gas/riscv/tlsdesc.s | 24 ++++++++++++++++++++++++
 opcodes/riscv-opc.c               |  1 +
 4 files changed, 60 insertions(+), 5 deletions(-)
 create mode 100644 gas/testsuite/gas/riscv/tlsdesc.d
 create mode 100644 gas/testsuite/gas/riscv/tlsdesc.s

diff --git a/gas/config/tc-riscv.c b/gas/config/tc-riscv.c
index 959cbbc32a5..0a1fac9de9d 100644
--- a/gas/config/tc-riscv.c
+++ b/gas/config/tc-riscv.c
@@ -2195,6 +2195,7 @@ static const struct percent_op_match percent_op_utype[] =
   {"tprel_hi", BFD_RELOC_RISCV_TPREL_HI20},
   {"pcrel_hi", BFD_RELOC_RISCV_PCREL_HI20},
   {"got_pcrel_hi", BFD_RELOC_RISCV_GOT_HI20},
+  {"tlsdesc_hi", BFD_RELOC_RISCV_TLSDESC_HI20},
   {"tls_ie_pcrel_hi", BFD_RELOC_RISCV_TLS_GOT_HI20},
   {"tls_gd_pcrel_hi", BFD_RELOC_RISCV_TLS_GD_HI20},
   {"hi", BFD_RELOC_RISCV_HI20},
@@ -2206,6 +2207,8 @@ static const struct percent_op_match percent_op_itype[] =
   {"lo", BFD_RELOC_RISCV_LO12_I},
   {"tprel_lo", BFD_RELOC_RISCV_TPREL_LO12_I},
   {"pcrel_lo", BFD_RELOC_RISCV_PCREL_LO12_I},
+  {"tlsdesc_load_lo", BFD_RELOC_RISCV_TLSDESC_LOAD_LO12},
+  {"tlsdesc_add_lo", BFD_RELOC_RISCV_TLSDESC_ADD_LO12},
   {0, 0}
 };
 
@@ -2217,8 +2220,9 @@ static const struct percent_op_match percent_op_stype[] =
   {0, 0}
 };
 
-static const struct percent_op_match percent_op_rtype[] =
+static const struct percent_op_match percent_op_relax_only[] =
 {
+  {"tlsdesc_call", BFD_RELOC_RISCV_TLSDESC_CALL},
   {"tprel_add", BFD_RELOC_RISCV_TPREL_ADD},
   {0, 0}
 };
@@ -3326,10 +3330,10 @@ riscv_ip (char *str, struct riscv_cl_insn *ip, expressionS *imm_expr,
 	      *imm_reloc = BFD_RELOC_RISCV_LO12_I;
 	      goto load_store;
 	    case '1':
-	      /* This is used for TLS, where the fourth operand is
-		 %tprel_add, to get a relocation applied to an add
-		 instruction, for relaxation to use.  */
-	      p = percent_op_rtype;
+	      /* This is used for TLS relocations that acts as relaxation
+	         markers and do not change the instruction encoding,
+	         i.e. %tprel_add and %tlsdesc_call.  */
+	      p = percent_op_relax_only;
 	      goto alu_op;
 	    case '0': /* AMO displacement, which must be zero.  */
 	    load_store:
@@ -4082,6 +4086,7 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
     case BFD_RELOC_RISCV_TPREL_LO12_I:
     case BFD_RELOC_RISCV_TPREL_LO12_S:
     case BFD_RELOC_RISCV_TPREL_ADD:
+    case BFD_RELOC_RISCV_TLSDESC_HI20:
       relaxable = true;
       /* Fall through.  */
 
@@ -4255,6 +4260,9 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
 
     case BFD_RELOC_RISCV_CALL:
     case BFD_RELOC_RISCV_CALL_PLT:
+    case BFD_RELOC_RISCV_TLSDESC_LOAD_LO12:
+    case BFD_RELOC_RISCV_TLSDESC_ADD_LO12:
+    case BFD_RELOC_RISCV_TLSDESC_CALL:
       relaxable = true;
       break;
 
diff --git a/gas/testsuite/gas/riscv/tlsdesc.d b/gas/testsuite/gas/riscv/tlsdesc.d
new file mode 100644
index 00000000000..8ba35826130
--- /dev/null
+++ b/gas/testsuite/gas/riscv/tlsdesc.d
@@ -0,0 +1,22 @@
+#as: -march=rv32ia
+#source: tlsdesc.s
+#readelf: -Wr
+
+Relocation section '.rela.text' at offset 0x[0-9a-f]+ contains 16 entries:
+ +Offset +Info +Type +Sym. Value +Symbol's Name \+ Addend
+0+ +0+a3e +R_RISCV_TLSDESC_HI20 +0+ +sg1 \+ 0
+0+ +0+33 +R_RISCV_RELAX + 0
+0+4 +0+63f +R_RISCV_TLSDESC_LOAD_LO12 0+ +\.desc1 \+ 0
+0+4 +0+33 +R_RISCV_RELAX + 0
+0+8 +0+640 +R_RISCV_TLSDESC_ADD_LO12 0+ +\.desc1 \+ 0
+0+8 +0+33 +R_RISCV_RELAX + 0
+0+c +0+641 +R_RISCV_TLSDESC_CALL +0+ +\.desc1 \+ 0
+0+c +0+33 +R_RISCV_RELAX + 0
+0+10 +0+53e +R_RISCV_TLSDESC_HI20 +0+4 +sl1 \+ 0
+0+10 +0+33 +R_RISCV_RELAX + 0
+0+14 +0+83f +R_RISCV_TLSDESC_LOAD_LO12 0+10 +\.desc2 \+ 0
+0+14 +0+33 +R_RISCV_RELAX + 0
+0+18 +0+840 +R_RISCV_TLSDESC_ADD_LO12 0+10 +\.desc2 \+ 0
+0+18 +0+33 +R_RISCV_RELAX +0
+0+1c +0+841 +R_RISCV_TLSDESC_CALL +0+10 +\.desc2 \+ 0
+0+1c +0+33 +R_RISCV_RELAX +0
\ No newline at end of file
diff --git a/gas/testsuite/gas/riscv/tlsdesc.s b/gas/testsuite/gas/riscv/tlsdesc.s
new file mode 100644
index 00000000000..15468d5f947
--- /dev/null
+++ b/gas/testsuite/gas/riscv/tlsdesc.s
@@ -0,0 +1,24 @@
+	.section	.tbss,"awT",@nobits
+	.global sg1
+sg1:
+	.zero	4
+sl1:
+	.zero	4
+
+	.text
+	.globl	_start
+	.type	_start,@function
+_start:
+.desc1:
+	auipc	a0, %tlsdesc_hi(sg1)
+	lw	t0, %tlsdesc_load_lo(.desc1)(a0)
+	addi	a0, a0, %tlsdesc_add_lo(.desc1)
+	jalr	t0, t0, %tlsdesc_call(.desc1)
+
+.desc2:
+	auipc	a0, %tlsdesc_hi(sl1)
+	lw	t0, %tlsdesc_load_lo(.desc2)(a0)
+	addi	a0, a0, %tlsdesc_add_lo(.desc2)
+	jalr	t0, t0, %tlsdesc_call(.desc2)
+
+	ret
diff --git a/opcodes/riscv-opc.c b/opcodes/riscv-opc.c
index 067e9fdb611..467666b9805 100644
--- a/opcodes/riscv-opc.c
+++ b/opcodes/riscv-opc.c
@@ -370,6 +370,7 @@ const struct riscv_opcode riscv_opcodes[] =
 {"jalr",        0, INSN_CLASS_I, "s,j",       MATCH_JALR|(X_RA << OP_SH_RD), MASK_JALR|MASK_RD, match_opcode, INSN_ALIAS|INSN_JSR },
 {"jalr",        0, INSN_CLASS_I, "d,s",       MATCH_JALR, MASK_JALR|MASK_IMM, match_opcode, INSN_ALIAS|INSN_JSR },
 {"jalr",        0, INSN_CLASS_I, "d,o(s)",    MATCH_JALR, MASK_JALR, match_opcode, INSN_JSR },
+{"jalr",        0, INSN_CLASS_I, "d,s,1",     MATCH_JALR, MASK_JALR|MASK_IMM, match_opcode, INSN_JSR },
 {"jalr",        0, INSN_CLASS_I, "d,s,j",     MATCH_JALR, MASK_JALR, match_opcode, INSN_JSR },
 {"j",           0, INSN_CLASS_C, "Ca",        MATCH_C_J, MASK_C_J, match_opcode, INSN_ALIAS|INSN_BRANCH },
 {"j",           0, INSN_CLASS_I, "a",         MATCH_JAL, MASK_JAL|MASK_RD, match_opcode, INSN_ALIAS|INSN_BRANCH },
-- 
2.42.0


^ permalink raw reply	[flat|nested] 49+ messages in thread

* [PATCH v2 4/5] RISC-V: Define and use GOT entry size constants for TLS.
  2023-08-31 17:13 ` [PATCH v2 0/5] " Tatsuyuki Ishi
                     ` (2 preceding siblings ...)
  2023-08-31 17:13   ` [PATCH v2 3/5] RISC-V: Add assembly support for TLSDESC Tatsuyuki Ishi
@ 2023-08-31 17:13   ` Tatsuyuki Ishi
  2023-08-31 17:13   ` [PATCH v2 5/5] RISC-V: Initial ld.bfd support for TLSDESC Tatsuyuki Ishi
  4 siblings, 0 replies; 49+ messages in thread
From: Tatsuyuki Ishi @ 2023-08-31 17:13 UTC (permalink / raw)
  To: binutils; +Cc: rui314, ruiu, i, nelson, Tatsuyuki Ishi

As the size calculation is split by global and local symbols, using a
shared constant definition for its size improves clarity.

bfd/
    * elfnn-riscv.c: Add macros for sizes of a normal GOT entry, TLS GD and
    TLS IE entry.
    (allocate_dynrelocs): Replace GOT size expressions with the new
    constants.
    (riscv_elf_size_dynamic_sections): Likewise.
    (riscv_elf_relocate_section): Likewise.
---
 bfd/elfnn-riscv.c | 16 +++++++++-------
 1 file changed, 9 insertions(+), 7 deletions(-)

diff --git a/bfd/elfnn-riscv.c b/bfd/elfnn-riscv.c
index 02b46835cc7..38883134828 100644
--- a/bfd/elfnn-riscv.c
+++ b/bfd/elfnn-riscv.c
@@ -301,6 +301,8 @@ riscv_is_insn_reloc (const reloc_howto_type *howto)
 #define PLT_HEADER_SIZE (PLT_HEADER_INSNS * 4)
 #define PLT_ENTRY_SIZE (PLT_ENTRY_INSNS * 4)
 #define GOT_ENTRY_SIZE RISCV_ELF_WORD_BYTES
+#define TLS_GD_GOT_ENTRY_SIZE (RISCV_ELF_WORD_BYTES * 2)
+#define TLS_IE_GOT_ENTRY_SIZE RISCV_ELF_WORD_BYTES
 /* Reserve two entries of GOTPLT for ld.so, one is used for PLT resolver,
    the other is used for link map.  Other targets also reserve one more
    entry used for runtime profile?  */
@@ -1323,7 +1325,7 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
 	  /* TLS_GD needs two dynamic relocs and two GOT slots.  */
 	  if (tls_type & GOT_TLS_GD)
 	    {
-	      s->size += 2 * RISCV_ELF_WORD_BYTES;
+	      s->size += TLS_GD_GOT_ENTRY_SIZE;
 	      if (need_reloc)
 		htab->elf.srelgot->size += 2 * sizeof (ElfNN_External_Rela);
 	    }
@@ -1331,14 +1333,14 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
 	  /* TLS_IE needs one dynamic reloc and one GOT slot.  */
 	  if (tls_type & GOT_TLS_IE)
 	    {
-	      s->size += RISCV_ELF_WORD_BYTES;
+	      s->size += TLS_IE_GOT_ENTRY_SIZE;
 	      if (need_reloc)
 		htab->elf.srelgot->size += sizeof (ElfNN_External_Rela);
 	    }
 	}
       else
 	{
-	  s->size += RISCV_ELF_WORD_BYTES;
+	  s->size += GOT_ENTRY_SIZE;
 	  if (WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, bfd_link_pic (info), h)
 	      && ! UNDEFWEAK_NO_DYNAMIC_RELOC (info, h))
 	    htab->elf.srelgot->size += sizeof (ElfNN_External_Rela);
@@ -1566,20 +1568,20 @@ riscv_elf_size_dynamic_sections (bfd *output_bfd, struct bfd_link_info *info)
 		{
 		  if (*local_tls_type & GOT_TLS_GD)
 		    {
-		      s->size += 2 * RISCV_ELF_WORD_BYTES;
+		      s->size += TLS_GD_GOT_ENTRY_SIZE;
 		      if (bfd_link_dll (info))
 			srel->size += sizeof (ElfNN_External_Rela);
 		    }
 		  if (*local_tls_type & GOT_TLS_IE)
 		    {
-		      s->size += RISCV_ELF_WORD_BYTES;
+		      s->size += TLS_IE_GOT_ENTRY_SIZE;
 		      if (bfd_link_dll (info))
 			srel->size += sizeof (ElfNN_External_Rela);
 		    }
 		}
 	      else
 		{
-		  s->size += RISCV_ELF_WORD_BYTES;
+		  s->size += GOT_ENTRY_SIZE;
 		  if (bfd_link_pic (info))
 		    srel->size += sizeof (ElfNN_External_Rela);
 		}
@@ -2905,7 +2907,7 @@ riscv_elf_relocate_section (bfd *output_bfd,
 	     reference's GOT slot follows the GD reference's slots.  */
 	  ie_off = 0;
 	  if ((tls_type & GOT_TLS_GD) && (tls_type & GOT_TLS_IE))
-	    ie_off = 2 * GOT_ENTRY_SIZE;
+	    ie_off = TLS_GD_GOT_ENTRY_SIZE;
 
 	  if ((off & 1) != 0)
 	    off &= ~1;
-- 
2.42.0


^ permalink raw reply	[flat|nested] 49+ messages in thread

* [PATCH v2 5/5] RISC-V: Initial ld.bfd support for TLSDESC.
  2023-08-31 17:13 ` [PATCH v2 0/5] " Tatsuyuki Ishi
                     ` (3 preceding siblings ...)
  2023-08-31 17:13   ` [PATCH v2 4/5] RISC-V: Define and use GOT entry size constants for TLS Tatsuyuki Ishi
@ 2023-08-31 17:13   ` Tatsuyuki Ishi
  4 siblings, 0 replies; 49+ messages in thread
From: Tatsuyuki Ishi @ 2023-08-31 17:13 UTC (permalink / raw)
  To: binutils; +Cc: rui314, ruiu, i, nelson, Tatsuyuki Ishi

Only relocation handling for now; relaxation is not implemented yet.

bfd/
    * elfnn-riscv.c (riscv_elf_check_relocs): Record GOT reference and
    paired relocation for TLSDESC_HI20.
    (riscv_elf_adjust_dynamic_symbol): Allocate GOT and reloc slots for
    TLSDESC symbols.
    (riscv_elf_size_dynamic_sections): Likewise but for local symbols.
    (tlsdescoff): New helper to determine static addend for R_TLSDESC.
    (riscv_elf_relocate_section): Ignore TLSDESC_CALL reloc for now (it is
    relaxation only).
    Handle TLSDESC_{LOAD,ADD}_LO12 as paired pcrel relocs.
    For TLS GOT slot generation, generalize the logic to handle any
    combination of (GD, IE, TLSDESC).
    Add TLSDESC Rela generation.
    * ld/testsuite/ld-riscv-elf/tls*: Add TLSDESC instruction sequences
    next to the existing GD and IE sequences. Update expectations.
---
v2: Fix one formatting issue, and an erroneous comment referring to the
    four-slot TLSDESC layout instead of the two-slot one.

 bfd/elfnn-riscv.c                  | 91 +++++++++++++++++++++++++++---
 ld/testsuite/ld-riscv-elf/tls.d    |  4 +-
 ld/testsuite/ld-riscv-elf/tls.s    | 14 +++++
 ld/testsuite/ld-riscv-elf/tlsbin.d |  5 ++
 4 files changed, 104 insertions(+), 10 deletions(-)

diff --git a/bfd/elfnn-riscv.c b/bfd/elfnn-riscv.c
index 38883134828..35011a25341 100644
--- a/bfd/elfnn-riscv.c
+++ b/bfd/elfnn-riscv.c
@@ -166,6 +166,7 @@ struct riscv_elf_link_hash_entry
 #define GOT_TLS_GD	2
 #define GOT_TLS_IE	4
 #define GOT_TLS_LE	8
+#define GOT_TLSDESC	16
   char tls_type;
 };
 
@@ -303,6 +304,7 @@ riscv_is_insn_reloc (const reloc_howto_type *howto)
 #define GOT_ENTRY_SIZE RISCV_ELF_WORD_BYTES
 #define TLS_GD_GOT_ENTRY_SIZE (RISCV_ELF_WORD_BYTES * 2)
 #define TLS_IE_GOT_ENTRY_SIZE RISCV_ELF_WORD_BYTES
+#define TLSDESC_GOT_ENTRY_SIZE (RISCV_ELF_WORD_BYTES * 2)
 /* Reserve two entries of GOTPLT for ld.so, one is used for PLT resolver,
    the other is used for link map.  Other targets also reserve one more
    entry used for runtime profile?  */
@@ -858,6 +860,12 @@ riscv_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
 	    return false;
 	  break;
 
+	case R_RISCV_TLSDESC_HI20:
+	  if (!riscv_elf_record_got_reference (abfd, info, h, r_symndx)
+	      || !riscv_elf_record_tls_type (abfd, h, r_symndx, GOT_TLSDESC))
+	    return false;
+	  break;
+
 	case R_RISCV_CALL:
 	case R_RISCV_CALL_PLT:
 	  /* These symbol requires a procedure linkage table entry.
@@ -1316,7 +1324,7 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
       s = htab->elf.sgot;
       h->got.offset = s->size;
       dyn = htab->elf.dynamic_sections_created;
-      if (tls_type & (GOT_TLS_GD | GOT_TLS_IE))
+      if (tls_type & (GOT_TLS_GD | GOT_TLS_IE | GOT_TLSDESC))
 	{
 	  int indx = 0;
 	  bool need_reloc = false;
@@ -1337,6 +1345,14 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
 	      if (need_reloc)
 		htab->elf.srelgot->size += sizeof (ElfNN_External_Rela);
 	    }
+
+	  /* TLSDESC needs one dynamic reloc and two GOT slots.  */
+	  if (tls_type & GOT_TLSDESC)
+	    {
+	      s->size += TLSDESC_GOT_ENTRY_SIZE;
+	      /* TLSDESC always use dynamic relocs.  */
+	      htab->elf.srelgot->size += sizeof (ElfNN_External_Rela);
+	    }
 	}
       else
 	{
@@ -1564,7 +1580,7 @@ riscv_elf_size_dynamic_sections (bfd *output_bfd, struct bfd_link_info *info)
 	  if (*local_got > 0)
 	    {
 	      *local_got = s->size;
-	      if (*local_tls_type & (GOT_TLS_GD | GOT_TLS_IE))
+	      if (*local_tls_type & (GOT_TLS_GD | GOT_TLS_IE | GOT_TLSDESC))
 		{
 		  if (*local_tls_type & GOT_TLS_GD)
 		    {
@@ -1578,6 +1594,11 @@ riscv_elf_size_dynamic_sections (bfd *output_bfd, struct bfd_link_info *info)
 		      if (bfd_link_dll (info))
 			srel->size += sizeof (ElfNN_External_Rela);
 		    }
+		  if (*local_tls_type & GOT_TLSDESC)
+		    {
+		      s->size += TLSDESC_GOT_ENTRY_SIZE;
+		      srel->size += sizeof (ElfNN_External_Rela);
+		    }
 		}
 	      else
 		{
@@ -1728,6 +1749,17 @@ tpoff (struct bfd_link_info *info, bfd_vma address)
   return address - elf_hash_table (info)->tls_sec->vma - TP_OFFSET;
 }
 
+/* Return the relocation value for a static TLSDESC relocation.  */
+
+static bfd_vma
+tlsdescoff (struct bfd_link_info *info, bfd_vma address)
+{
+  /* If tls_sec is NULL, we should have signalled an error already.  */
+  if (elf_hash_table (info)->tls_sec == NULL)
+    return 0;
+  return address - elf_hash_table (info)->tls_sec->vma;
+}
+
 /* Return the global pointer's value, or 0 if it is not in use.  */
 
 static bfd_vma
@@ -1764,6 +1796,7 @@ perform_relocation (const reloc_howto_type *howto,
     case R_RISCV_GOT_HI20:
     case R_RISCV_TLS_GOT_HI20:
     case R_RISCV_TLS_GD_HI20:
+    case R_RISCV_TLSDESC_HI20:
       if (ARCH_SIZE > 32 && !VALID_UTYPE_IMM (RISCV_CONST_HIGH_PART (value)))
 	return bfd_reloc_overflow;
       value = ENCODE_UTYPE_IMM (RISCV_CONST_HIGH_PART (value));
@@ -1774,6 +1807,8 @@ perform_relocation (const reloc_howto_type *howto,
     case R_RISCV_TPREL_LO12_I:
     case R_RISCV_TPREL_I:
     case R_RISCV_PCREL_LO12_I:
+    case R_RISCV_TLSDESC_LOAD_LO12:
+    case R_RISCV_TLSDESC_ADD_LO12:
       value = ENCODE_ITYPE_IMM (value);
       break;
 
@@ -2195,8 +2230,8 @@ riscv_elf_relocate_section (bfd *output_bfd,
       bfd_vma relocation;
       bfd_reloc_status_type r = bfd_reloc_ok;
       const char *name = NULL;
-      bfd_vma off, ie_off;
-      bool unresolved_reloc, is_ie = false;
+      bfd_vma off, ie_off, desc_off;
+      bool unresolved_reloc, is_ie = false, is_desc = false;
       bfd_vma pc = sec_addr (input_section) + rel->r_offset;
       int r_type = ELFNN_R_TYPE (rel->r_info), tls_type;
       reloc_howto_type *howto = riscv_elf_rtype_to_howto (input_bfd, r_type);
@@ -2499,6 +2534,7 @@ riscv_elf_relocate_section (bfd *output_bfd,
 	case R_RISCV_NONE:
 	case R_RISCV_RELAX:
 	case R_RISCV_TPREL_ADD:
+	case R_RISCV_TLSDESC_CALL:
 	case R_RISCV_COPY:
 	case R_RISCV_JUMP_SLOT:
 	case R_RISCV_RELATIVE:
@@ -2820,6 +2856,15 @@ riscv_elf_relocate_section (bfd *output_bfd,
 	  relocation = dtpoff (info, relocation);
 	  break;
 
+	case R_RISCV_TLSDESC_LOAD_LO12:
+	case R_RISCV_TLSDESC_ADD_LO12:
+	  if (riscv_record_pcrel_lo_reloc (&pcrel_relocs, relocation, rel,
+					   input_section, info, howto,
+					   contents))
+	      continue;
+	  r = bfd_reloc_overflow;
+	  break;
+
 	case R_RISCV_32:
 	  /* Non ABS symbol should be blocked in check_relocs.  */
 	  if (ARCH_SIZE > 32)
@@ -2885,11 +2930,16 @@ riscv_elf_relocate_section (bfd *output_bfd,
 	    }
 	  break;
 
+	case R_RISCV_TLSDESC_HI20:
+	  is_desc = true;
+	  goto tls;
+
 	case R_RISCV_TLS_GOT_HI20:
 	  is_ie = true;
-	  /* Fall through.  */
+	  goto tls;
 
 	case R_RISCV_TLS_GD_HI20:
+	tls:
 	  if (h != NULL)
 	    {
 	      off = h->got.offset;
@@ -2902,12 +2952,16 @@ riscv_elf_relocate_section (bfd *output_bfd,
 	    }
 
 	  tls_type = _bfd_riscv_elf_tls_type (input_bfd, h, r_symndx);
-	  BFD_ASSERT (tls_type & (GOT_TLS_IE | GOT_TLS_GD));
+	  BFD_ASSERT (tls_type & (GOT_TLS_IE | GOT_TLS_GD | GOT_TLSDESC));
 	  /* If this symbol is referenced by both GD and IE TLS, the IE
 	     reference's GOT slot follows the GD reference's slots.  */
 	  ie_off = 0;
 	  if ((tls_type & GOT_TLS_GD) && (tls_type & GOT_TLS_IE))
-	    ie_off = TLS_GD_GOT_ENTRY_SIZE;
+	    ie_off += TLS_GD_GOT_ENTRY_SIZE;
+
+	  desc_off = ie_off;
+	  if (tls_type & GOT_TLS_IE)
+	    desc_off += TLS_IE_GOT_ENTRY_SIZE;
 
 	  if ((off & 1) != 0)
 	    off &= ~1;
@@ -2989,10 +3043,29 @@ riscv_elf_relocate_section (bfd *output_bfd,
 				  htab->elf.sgot->contents + off + ie_off);
 		    }
 		}
+
+	      if (tls_type & GOT_TLSDESC)
+		{
+		  /* TLSDESC is always handled by the dynamic linker and always need
+		   * a relocation.  */
+		  bfd_put_NN (output_bfd, 0,
+			      htab->elf.sgot->contents + off + desc_off);
+		  outrel.r_offset = sec_addr (htab->elf.sgot)
+				    + off + desc_off;
+		  outrel.r_addend = 0;
+		  if (indx == 0)
+		    outrel.r_addend = tlsdescoff (info, relocation);
+		  outrel.r_info = ELFNN_R_INFO (indx, R_RISCV_TLSDESC);
+		  riscv_elf_append_rela (output_bfd, htab->elf.srelgot, &outrel);
+		}
 	    }
 
 	  BFD_ASSERT (off < (bfd_vma) -2);
-	  relocation = sec_addr (htab->elf.sgot) + off + (is_ie ? ie_off : 0);
+	  relocation = sec_addr (htab->elf.sgot) + off;
+	  if (is_ie)
+	    relocation += ie_off;
+	  else if (is_desc)
+	    relocation += desc_off;
 	  if (!riscv_record_pcrel_hi_reloc (&pcrel_relocs, pc,
 					    relocation, r_type,
 					    false))
@@ -3212,7 +3285,7 @@ riscv_elf_finish_dynamic_symbol (bfd *output_bfd,
     }
 
   if (h->got.offset != (bfd_vma) -1
-      && !(riscv_elf_hash_entry (h)->tls_type & (GOT_TLS_GD | GOT_TLS_IE))
+      && !(riscv_elf_hash_entry (h)->tls_type & (GOT_TLS_GD | GOT_TLS_IE | GOT_TLSDESC))
       && !UNDEFWEAK_NO_DYNAMIC_RELOC (info, h))
     {
       asection *sgot;
diff --git a/ld/testsuite/ld-riscv-elf/tls.d b/ld/testsuite/ld-riscv-elf/tls.d
index 0e2ab5683ad..5019383070c 100644
--- a/ld/testsuite/ld-riscv-elf/tls.d
+++ b/ld/testsuite/ld-riscv-elf/tls.d
@@ -2,13 +2,15 @@
 #ld: --shared tmpdir/tlslib.so
 #readelf: -Wr
 
-Relocation section '.rela.dyn' at offset 0x[0-9a-f]+ contains 5 entries:
+Relocation section '.rela.dyn' at offset 0x[0-9a-f]+ contains 7 entries:
  +Offset +Info +Type +Symbol's Value +Symbol's Name \+ Addend
 [0-9a-f]+ +[0-9a-f]+ R_RISCV_TLS_DTPMOD64 +0
 [0-9a-f]+ +[0-9a-f]+ R_RISCV_TLS_TPREL64 +4
+[0-9a-f]+ +[0-9a-f]+ R_RISCV_TLSDESC +4
 [0-9a-f]+ +[0-9a-f]+ R_RISCV_TLS_DTPMOD64 +0+ sg1 \+ 0
 [0-9a-f]+ +[0-9a-f]+ R_RISCV_TLS_DTPREL64 +0+ sg1 \+ 0
 [0-9a-f]+ +[0-9a-f]+ R_RISCV_TLS_TPREL64 +0+ sg1 \+ 0
+[0-9a-f]+ +[0-9a-f]+ R_RISCV_TLSDESC +0+ sg1 \+ 0
 
 Relocation section '.rela.plt' at offset 0x[0-9a-f]+ contains 1 entry:
  +Offset +Info +Type +Symbol's Value +Symbol's Name \+ Addend
diff --git a/ld/testsuite/ld-riscv-elf/tls.s b/ld/testsuite/ld-riscv-elf/tls.s
index 79e9bc20374..7cbf5ea6c72 100644
--- a/ld/testsuite/ld-riscv-elf/tls.s
+++ b/ld/testsuite/ld-riscv-elf/tls.s
@@ -17,6 +17,13 @@ _start:
 	la.tls.ie	a0,sg1
 	add	a0,a0,tp
 
+	/* GD (TLSDESC), global var */
+.desc1:
+	auipc	a0, %tlsdesc_hi(sg1)
+	lw	t0, %tlsdesc_load_lo(.desc1)(a0)
+	addi	a0, a0, %tlsdesc_add_lo(.desc1)
+	jalr	t0, t0, %tlsdesc_call(.desc1)
+
 	/* GD, local var */
 	la.tls.gd	a0,sl1
 	call  __tls_get_addr
@@ -25,4 +32,11 @@ _start:
 	la.tls.ie	a0,sl1
 	add	a0,a0,tp
 
+	/* GD (TLSDESC), local var */
+.desc2:
+	auipc	a0, %tlsdesc_hi(sl1)
+	lw	t0, %tlsdesc_load_lo(.desc2)(a0)
+	addi	a0, a0, %tlsdesc_add_lo(.desc2)
+	jalr	t0, t0, %tlsdesc_call(.desc2)
+
 	ret
diff --git a/ld/testsuite/ld-riscv-elf/tlsbin.d b/ld/testsuite/ld-riscv-elf/tlsbin.d
index 12a4d0ea703..16545a90639 100644
--- a/ld/testsuite/ld-riscv-elf/tlsbin.d
+++ b/ld/testsuite/ld-riscv-elf/tlsbin.d
@@ -2,6 +2,11 @@
 #ld: -no-pie tmpdir/tlslib.so
 #readelf: -Wr
 
+Relocation section '.rela.dyn' at offset 0x[0-9a-f]+ contains 2 entries:
+ +Offset +Info +Type +Symbol's Value +Symbol's Name \+ Addend
+[0-9a-f]+ +[0-9a-f]+ R_RISCV_TLSDESC +4
+[0-9a-f]+ +[0-9a-f]+ R_RISCV_TLSDESC +0
+
 Relocation section '.rela.plt' at offset 0x[0-9a-f]+ contains 1 entry:
  +Offset +Info +Type +Symbol's Value +Symbol's Name \+ Addend
 [0-9a-f]+ +[0-9a-f]+ R_RISCV_JUMP_SLOT +[0-9a-f]+ __tls_get_addr \+ 0
\ No newline at end of file
-- 
2.42.0


^ permalink raw reply	[flat|nested] 49+ messages in thread

* [PATCH v3 0/9] RISC-V: Implement TLS Descriptors.
  2023-08-17 18:08 [PATCH 0/4] RISC-V: Implement TLS Descriptors Tatsuyuki Ishi
                   ` (5 preceding siblings ...)
  2023-08-31 17:13 ` [PATCH v2 0/5] " Tatsuyuki Ishi
@ 2023-11-28  8:51 ` Tatsuyuki Ishi
  2023-11-28  8:51   ` [PATCH v3 1/9] RISC-V: Fix local GOT and reloc size calculation for TLS Tatsuyuki Ishi
                     ` (9 more replies)
  2024-02-20 17:55 ` [PATCH v4 " Tatsuyuki Ishi
  7 siblings, 10 replies; 49+ messages in thread
From: Tatsuyuki Ishi @ 2023-11-28  8:51 UTC (permalink / raw)
  To: binutils; +Cc: i, nelson, rui314, ruiu, Tatsuyuki Ishi

This patchset implements TLS Descriptors (TLSDESC) for RISC-V targets, per
the specification (merged) at [1].

Tested on rv64gc for:
- No regression (& passing new tests) in binutils
- No regression in gcc
- No regression in glibc for subdirs=elf
With both -mtls-dialect=desc and trad.

This contribution is made on behalf of Blue Whale Systems, which has
copyright assignment on file with the FSF.

[1]: https://github.com/riscv-non-isa/riscv-elf-psabi-doc/pull/373

v2: Add changelogs and tests. Minor fixes described in patch messages.
v3: Add relaxation support. This fixes tst-tls1-static in glibc.

Tatsuyuki Ishi (9):
  RISC-V: Fix local GOT and reloc size calculation for TLS.
  RISC-V: Add TLSDESC reloc definitions.
  RISC-V: Add assembly support for TLSDESC.
  RISC-V: Define and use GOT entry size constants for TLS.
  RISC-V: Initial ld.bfd support for TLSDESC.
  RISC-V: Move STATIC_TLS handling into record_tls_type.
  RISC-V: Unify TLS handling in check_relocs.
  RISC-V: Add elf_link_hash_entry to relax_func args.
  RISC-V: Introduce TLSDESC relaxation.

 bfd/bfd-in2.h                              |   4 +
 bfd/elfnn-riscv.c                          | 341 ++++++++++++++++++---
 bfd/elfxx-riscv.c                          | 130 +++++++-
 bfd/libbfd.h                               |   4 +
 bfd/reloc.c                                |   8 +
 gas/config/tc-riscv.c                      |  18 +-
 gas/testsuite/gas/riscv/tlsdesc.d          |  22 ++
 gas/testsuite/gas/riscv/tlsdesc.s          |  24 ++
 include/elf/riscv.h                        |  21 +-
 include/opcode/riscv.h                     |   1 +
 ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp |   8 +
 ld/testsuite/ld-riscv-elf/tls.d            |  17 +
 ld/testsuite/ld-riscv-elf/tls.s            |  42 +++
 ld/testsuite/ld-riscv-elf/tlsbin.d         |   7 +
 ld/testsuite/ld-riscv-elf/tlslib.s         |   6 +
 opcodes/riscv-opc.c                        |   1 +
 16 files changed, 601 insertions(+), 53 deletions(-)
 create mode 100644 gas/testsuite/gas/riscv/tlsdesc.d
 create mode 100644 gas/testsuite/gas/riscv/tlsdesc.s
 create mode 100644 ld/testsuite/ld-riscv-elf/tls.d
 create mode 100644 ld/testsuite/ld-riscv-elf/tls.s
 create mode 100644 ld/testsuite/ld-riscv-elf/tlsbin.d
 create mode 100644 ld/testsuite/ld-riscv-elf/tlslib.s

-- 
2.43.0


^ permalink raw reply	[flat|nested] 49+ messages in thread

* [PATCH v3 1/9] RISC-V: Fix local GOT and reloc size calculation for TLS.
  2023-11-28  8:51 ` [PATCH v3 0/9] RISC-V: Implement TLS Descriptors Tatsuyuki Ishi
@ 2023-11-28  8:51   ` Tatsuyuki Ishi
  2023-11-28  8:51   ` [PATCH v3 2/9] RISC-V: Add TLSDESC reloc definitions Tatsuyuki Ishi
                     ` (8 subsequent siblings)
  9 siblings, 0 replies; 49+ messages in thread
From: Tatsuyuki Ishi @ 2023-11-28  8:51 UTC (permalink / raw)
  To: binutils; +Cc: i, nelson, rui314, ruiu, Tatsuyuki Ishi

The previous code did not account correctly for two cases:
* A TLS symbol can be referenced with multiple TLS types (although rare),
  in which case it only allocated the maximum slot size among the types,
  instead of the sum.
* TLS relocations are only needed for DLLs, unlike normal symbols which
  requires relocations for all PIE code.

Modify the logic to account for the two cases.

bfd/
    * elfnn-riscv.c (riscv_elf_size_dynamic_sections): Handle relocation
    sizing for TLS and non-TLS symbols differently, with the former
    requiring relocs on DLL while the latter requiring on PIE.
    Allocate GOT slots and relocation slots for each TLS type separately,
    accounting for the possibility of a TLS variable getting referenced by
    multiple symbols.
ld/
    * testsuite/ld-riscv-elf/ld-riscv-elf.exp: Updated.
    * testsuite/ld-riscv-elf/tls*: New testcase for TLS GD and IE, with
    symbols referred by both types and global and local symbols.
---
 bfd/elfnn-riscv.c                          | 27 ++++++++++++++++-----
 ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp |  8 +++++++
 ld/testsuite/ld-riscv-elf/tls.d            | 15 ++++++++++++
 ld/testsuite/ld-riscv-elf/tls.s            | 28 ++++++++++++++++++++++
 ld/testsuite/ld-riscv-elf/tlsbin.d         |  7 ++++++
 ld/testsuite/ld-riscv-elf/tlslib.s         |  6 +++++
 6 files changed, 85 insertions(+), 6 deletions(-)
 create mode 100644 ld/testsuite/ld-riscv-elf/tls.d
 create mode 100644 ld/testsuite/ld-riscv-elf/tls.s
 create mode 100644 ld/testsuite/ld-riscv-elf/tlsbin.d
 create mode 100644 ld/testsuite/ld-riscv-elf/tlslib.s

diff --git a/bfd/elfnn-riscv.c b/bfd/elfnn-riscv.c
index 5c4bf4bc3cb..c0207765906 100644
--- a/bfd/elfnn-riscv.c
+++ b/bfd/elfnn-riscv.c
@@ -1559,12 +1559,27 @@ riscv_elf_size_dynamic_sections (bfd *output_bfd, struct bfd_link_info *info)
 	  if (*local_got > 0)
 	    {
 	      *local_got = s->size;
-	      s->size += RISCV_ELF_WORD_BYTES;
-	      if (*local_tls_type & GOT_TLS_GD)
-		s->size += RISCV_ELF_WORD_BYTES;
-	      if (bfd_link_pic (info)
-		  || (*local_tls_type & (GOT_TLS_GD | GOT_TLS_IE)))
-		srel->size += sizeof (ElfNN_External_Rela);
+	      if (*local_tls_type & (GOT_TLS_GD | GOT_TLS_IE))
+		{
+		  if (*local_tls_type & GOT_TLS_GD)
+		    {
+		      s->size += 2 * RISCV_ELF_WORD_BYTES;
+		      if (bfd_link_dll (info))
+			srel->size += sizeof (ElfNN_External_Rela);
+		    }
+		  if (*local_tls_type & GOT_TLS_IE)
+		    {
+		      s->size += RISCV_ELF_WORD_BYTES;
+		      if (bfd_link_dll (info))
+			srel->size += sizeof (ElfNN_External_Rela);
+		    }
+		}
+	      else
+		{
+		  s->size += RISCV_ELF_WORD_BYTES;
+		  if (bfd_link_pic (info))
+		    srel->size += sizeof (ElfNN_External_Rela);
+		}
 	    }
 	  else
 	    *local_got = (bfd_vma) -1;
diff --git a/ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp b/ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp
index 947a266ba72..adb4ee75e4a 100644
--- a/ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp
+++ b/ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp
@@ -317,4 +317,12 @@ if [istarget "riscv*-*-*"] {
     run_dump_test "pcrel-reloc-rel-pie"
     run_dump_test "pcrel-reloc-abs-nopie"
     run_dump_test "pcrel-reloc-abs-pie"
+
+    run_ld_link_tests {
+       { "Build shared library for TLS runtime"
+	 "-shared" "" "" {tlslib.s}
+	 {} "tlslib.so" }
+    }
+    run_dump_test "tls"
+    run_dump_test "tlsbin"
 }
diff --git a/ld/testsuite/ld-riscv-elf/tls.d b/ld/testsuite/ld-riscv-elf/tls.d
new file mode 100644
index 00000000000..e7f20309bf1
--- /dev/null
+++ b/ld/testsuite/ld-riscv-elf/tls.d
@@ -0,0 +1,15 @@
+#source: tls.s
+#ld: --shared tmpdir/tlslib.so
+#readelf: -Wr
+
+Relocation section '.rela.dyn' at offset 0x[0-9a-f]+ contains 5 entries:
+ +Offset +Info +Type +Symbol's Value +Symbol's Name \+ Addend
+[0-9a-f]+ +[0-9a-f]+ R_RISCV_TLS_DTPMOD64 +0
+[0-9a-f]+ +[0-9a-f]+ R_RISCV_TLS_TPREL64 +4
+[0-9a-f]+ +[0-9a-f]+ R_RISCV_TLS_DTPMOD64 +0+ sg1 \+ 0
+[0-9a-f]+ +[0-9a-f]+ R_RISCV_TLS_DTPREL64 +0+ sg1 \+ 0
+[0-9a-f]+ +[0-9a-f]+ R_RISCV_TLS_TPREL64 +0+ sg1 \+ 0
+
+Relocation section '.rela.plt' at offset 0x[0-9a-f]+ contains 1 entry:
+ +Offset +Info +Type +Symbol's Value +Symbol's Name \+ Addend
+[0-9a-f]+ +[0-9a-f]+ R_RISCV_JUMP_SLOT +0+ __tls_get_addr \+ 0
diff --git a/ld/testsuite/ld-riscv-elf/tls.s b/ld/testsuite/ld-riscv-elf/tls.s
new file mode 100644
index 00000000000..79e9bc20374
--- /dev/null
+++ b/ld/testsuite/ld-riscv-elf/tls.s
@@ -0,0 +1,28 @@
+	.section	.tbss,"awT",@nobits
+	.global sg1
+sg1:
+	.zero	4
+sl1:
+	.zero	4
+
+	.text
+	.globl	_start
+	.type	_start,@function
+_start:
+	/* GD, global var */
+	la.tls.gd	a0,sg1
+	call  __tls_get_addr
+
+	/* IE, global var */
+	la.tls.ie	a0,sg1
+	add	a0,a0,tp
+
+	/* GD, local var */
+	la.tls.gd	a0,sl1
+	call  __tls_get_addr
+
+	/* IE, local var */
+	la.tls.ie	a0,sl1
+	add	a0,a0,tp
+
+	ret
diff --git a/ld/testsuite/ld-riscv-elf/tlsbin.d b/ld/testsuite/ld-riscv-elf/tlsbin.d
new file mode 100644
index 00000000000..cdcd51a9199
--- /dev/null
+++ b/ld/testsuite/ld-riscv-elf/tlsbin.d
@@ -0,0 +1,7 @@
+#source: tls.s
+#ld: -no-pie tmpdir/tlslib.so
+#readelf: -Wr
+
+Relocation section '.rela.plt' at offset 0x[0-9a-f]+ contains 1 entry:
+ +Offset +Info +Type +Symbol's Value +Symbol's Name \+ Addend
+[0-9a-f]+ +[0-9a-f]+ R_RISCV_JUMP_SLOT +[0-9a-f]+ __tls_get_addr \+ 0
diff --git a/ld/testsuite/ld-riscv-elf/tlslib.s b/ld/testsuite/ld-riscv-elf/tlslib.s
new file mode 100644
index 00000000000..17c770786d0
--- /dev/null
+++ b/ld/testsuite/ld-riscv-elf/tlslib.s
@@ -0,0 +1,6 @@
+	.text
+	/* Dummy.  */
+	.globl	__tls_get_addr
+	.type	__tls_get_addr,@function
+__tls_get_addr:
+	ret
-- 
2.43.0


^ permalink raw reply	[flat|nested] 49+ messages in thread

* [PATCH v3 2/9] RISC-V: Add TLSDESC reloc definitions.
  2023-11-28  8:51 ` [PATCH v3 0/9] RISC-V: Implement TLS Descriptors Tatsuyuki Ishi
  2023-11-28  8:51   ` [PATCH v3 1/9] RISC-V: Fix local GOT and reloc size calculation for TLS Tatsuyuki Ishi
@ 2023-11-28  8:51   ` Tatsuyuki Ishi
  2024-02-19  0:49     ` Nelson Chu
  2023-11-28  8:51   ` [PATCH v3 3/9] RISC-V: Add assembly support for TLSDESC Tatsuyuki Ishi
                     ` (7 subsequent siblings)
  9 siblings, 1 reply; 49+ messages in thread
From: Tatsuyuki Ishi @ 2023-11-28  8:51 UTC (permalink / raw)
  To: binutils; +Cc: i, nelson, rui314, ruiu, Tatsuyuki Ishi

bfd/
    * elfxx-riscv.c: Add 5 TLSDESC reloc descriptions.
    * reloc.c: Likewise.
    * libbfd.h: Regenerate.
    * bfd-in2.h: Regenerate.
include/
    * elf/riscv.h: Add 5 TLSDESC reloc descriptions.
---
 bfd/bfd-in2.h       |  4 +++
 bfd/elfxx-riscv.c   | 75 ++++++++++++++++++++++++++++++++++++++++++++-
 bfd/libbfd.h        |  4 +++
 bfd/reloc.c         |  8 +++++
 include/elf/riscv.h |  5 +++
 5 files changed, 95 insertions(+), 1 deletion(-)

diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h
index 040d5560cdf..9bc6b9885ff 100644
--- a/bfd/bfd-in2.h
+++ b/bfd/bfd-in2.h
@@ -5407,6 +5407,10 @@ enum bfd_reloc_code_real
   BFD_RELOC_RISCV_TLS_DTPREL64,
   BFD_RELOC_RISCV_TLS_TPREL32,
   BFD_RELOC_RISCV_TLS_TPREL64,
+  BFD_RELOC_RISCV_TLSDESC_HI20,
+  BFD_RELOC_RISCV_TLSDESC_LOAD_LO12,
+  BFD_RELOC_RISCV_TLSDESC_ADD_LO12,
+  BFD_RELOC_RISCV_TLSDESC_CALL,
   BFD_RELOC_RISCV_ALIGN,
   BFD_RELOC_RISCV_RVC_BRANCH,
   BFD_RELOC_RISCV_RVC_JUMP,
diff --git a/bfd/elfxx-riscv.c b/bfd/elfxx-riscv.c
index 567631e7d96..65d676b06b1 100644
--- a/bfd/elfxx-riscv.c
+++ b/bfd/elfxx-riscv.c
@@ -218,7 +218,20 @@ static reloc_howto_type howto_table[] =
 	 MINUS_ONE,			/* dst_mask */
 	 false),			/* pcrel_offset */
 
-  EMPTY_HOWTO (12),
+  HOWTO (R_RISCV_TLSDESC,		/* type */
+	 0,				/* rightshift */
+	 0,				/* size is handled by dynamic linker */
+	 0,				/* bitsize */
+	 false,				/* pc_relative */
+	 0,				/* bitpos */
+	 complain_overflow_dont,	/* complain_on_overflow */
+	 bfd_elf_generic_reloc,		/* special_function */
+	 "R_RISCV_TLSDESC",		/* name */
+	 false,				/* partial_inplace */
+	 0,				/* src_mask */
+	 MINUS_ONE,			/* dst_mask */
+	 false),			/* pcrel_offset */
+
   EMPTY_HOWTO (13),
   EMPTY_HOWTO (14),
   EMPTY_HOWTO (15),
@@ -808,6 +821,62 @@ static reloc_howto_type howto_table[] =
 	 0,				/* src_mask */
 	 0,				/* dst_mask */
 	 false),			/* pcrel_offset */
+
+  HOWTO (R_RISCV_TLSDESC_HI20,		/* type */
+	 0,				/* rightshift */
+	 4,				/* size */
+	 32,				/* bitsize */
+	 true,				/* pc_relative */
+	 0,				/* bitpos */
+	 complain_overflow_signed,	/* complain_on_overflow */
+	 bfd_elf_generic_reloc,		/* special_function */
+	 "R_RISCV_TLSDESC_HI20",	/* name */
+	 true,				/* partial_inplace */
+	 0,				/* src_mask */
+	 ENCODE_UTYPE_IMM (-1U),	/* dst_mask */
+	 false),			/* pcrel_offset */
+
+  HOWTO (R_RISCV_TLSDESC_LOAD_LO12,	/* type */
+	 0,				/* rightshift */
+	 4,				/* size */
+	 32,				/* bitsize */
+	 false,				/* pc_relative */
+	 0,				/* bitpos */
+	 complain_overflow_signed,	/* complain_on_overflow */
+	 bfd_elf_generic_reloc,		/* special_function */
+	 "R_RISCV_TLSDESC_LOAD_LO12",	/* name */
+	 false,				/* partial_inplace */
+	 0,				/* src_mask */
+	 ENCODE_ITYPE_IMM (-1U),	/* dst_mask */
+	 false),			/* pcrel_offset */
+
+  HOWTO (R_RISCV_TLSDESC_ADD_LO12,	/* type */
+	 0,				/* rightshift */
+	 4,				/* size */
+	 32,				/* bitsize */
+	 false,				/* pc_relative */
+	 0,				/* bitpos */
+	 complain_overflow_signed,	/* complain_on_overflow */
+	 bfd_elf_generic_reloc,		/* special_function */
+	 "R_RISCV_TLSDESC_ADD_LO12",	/* name */
+	 false,				/* partial_inplace */
+	 0,				/* src_mask */
+	 ENCODE_ITYPE_IMM (-1U),	/* dst_mask */
+	 false), 			/* pcrel_offset */
+
+  HOWTO (R_RISCV_TLSDESC_CALL,		/* type */
+	 0,				/* rightshift */
+	 0,				/* size */
+	 0,				/* bitsize */
+	 false,				/* pc_relative */
+	 0,				/* bitpos */
+	 complain_overflow_dont,	/* complain_on_overflow */
+	 bfd_elf_generic_reloc,		/* special_function */
+	 "R_RISCV_TLSDESC_CALL",	/* name */
+	 false,				/* partial_inplace */
+	 0,				/* src_mask */
+	 ENCODE_ITYPE_IMM (-1U),	/* dst_mask */
+	 false) 			/* pcrel_offset */
 };
 
 static reloc_howto_type howto_table_internal[] =
@@ -935,6 +1004,10 @@ static const struct elf_reloc_map riscv_reloc_map[] =
   { BFD_RELOC_RISCV_TPREL_LO12_I, R_RISCV_TPREL_LO12_I },
   { BFD_RELOC_RISCV_TLS_GOT_HI20, R_RISCV_TLS_GOT_HI20 },
   { BFD_RELOC_RISCV_TLS_GD_HI20, R_RISCV_TLS_GD_HI20 },
+  { BFD_RELOC_RISCV_TLSDESC_HI20, R_RISCV_TLSDESC_HI20 },
+  { BFD_RELOC_RISCV_TLSDESC_LOAD_LO12, R_RISCV_TLSDESC_LOAD_LO12 },
+  { BFD_RELOC_RISCV_TLSDESC_ADD_LO12, R_RISCV_TLSDESC_ADD_LO12 },
+  { BFD_RELOC_RISCV_TLSDESC_CALL, R_RISCV_TLSDESC_CALL },
   { BFD_RELOC_RISCV_ALIGN, R_RISCV_ALIGN },
   { BFD_RELOC_RISCV_RVC_BRANCH, R_RISCV_RVC_BRANCH },
   { BFD_RELOC_RISCV_RVC_JUMP, R_RISCV_RVC_JUMP },
diff --git a/bfd/libbfd.h b/bfd/libbfd.h
index cc432677a81..919b63d51a1 100644
--- a/bfd/libbfd.h
+++ b/bfd/libbfd.h
@@ -2400,6 +2400,10 @@ static const char *const bfd_reloc_code_real_names[] = { "@@uninitialized@@",
   "BFD_RELOC_RISCV_TLS_DTPREL64",
   "BFD_RELOC_RISCV_TLS_TPREL32",
   "BFD_RELOC_RISCV_TLS_TPREL64",
+  "BFD_RELOC_RISCV_TLSDESC_HI20",
+  "BFD_RELOC_RISCV_TLSDESC_LOAD_LO12",
+  "BFD_RELOC_RISCV_TLSDESC_ADD_LO12",
+  "BFD_RELOC_RISCV_TLSDESC_CALL",
   "BFD_RELOC_RISCV_ALIGN",
   "BFD_RELOC_RISCV_RVC_BRANCH",
   "BFD_RELOC_RISCV_RVC_JUMP",
diff --git a/bfd/reloc.c b/bfd/reloc.c
index 93ebad879e0..345f444d17a 100644
--- a/bfd/reloc.c
+++ b/bfd/reloc.c
@@ -4984,6 +4984,14 @@ ENUMX
   BFD_RELOC_RISCV_TLS_TPREL32
 ENUMX
   BFD_RELOC_RISCV_TLS_TPREL64
+ENUMX
+  BFD_RELOC_RISCV_TLSDESC_HI20
+ENUMX
+  BFD_RELOC_RISCV_TLSDESC_LOAD_LO12
+ENUMX
+  BFD_RELOC_RISCV_TLSDESC_ADD_LO12
+ENUMX
+  BFD_RELOC_RISCV_TLSDESC_CALL
 ENUMX
   BFD_RELOC_RISCV_ALIGN
 ENUMX
diff --git a/include/elf/riscv.h b/include/elf/riscv.h
index 56d419c665b..7f5c0407ac8 100644
--- a/include/elf/riscv.h
+++ b/include/elf/riscv.h
@@ -44,6 +44,7 @@ START_RELOC_NUMBERS (elf_riscv_reloc_type)
   RELOC_NUMBER (R_RISCV_TLS_DTPREL64, 9)
   RELOC_NUMBER (R_RISCV_TLS_TPREL32, 10)
   RELOC_NUMBER (R_RISCV_TLS_TPREL64, 11)
+  RELOC_NUMBER (R_RISCV_TLSDESC, 12)
 
   /* Relocation types not used by the dynamic linker.  */
   RELOC_NUMBER (R_RISCV_BRANCH, 16)
@@ -90,6 +91,10 @@ START_RELOC_NUMBERS (elf_riscv_reloc_type)
   /* Reserved 59 for R_RISCV_PLT32.  */
   RELOC_NUMBER (R_RISCV_SET_ULEB128, 60)
   RELOC_NUMBER (R_RISCV_SUB_ULEB128, 61)
+  RELOC_NUMBER (R_RISCV_TLSDESC_HI20, 62)
+  RELOC_NUMBER (R_RISCV_TLSDESC_LOAD_LO12, 63)
+  RELOC_NUMBER (R_RISCV_TLSDESC_ADD_LO12, 64)
+  RELOC_NUMBER (R_RISCV_TLSDESC_CALL, 65)
 END_RELOC_NUMBERS (R_RISCV_max)
 
 /* Internal relocations used exclusively by the relaxation pass.  */
-- 
2.43.0


^ permalink raw reply	[flat|nested] 49+ messages in thread

* [PATCH v3 3/9] RISC-V: Add assembly support for TLSDESC.
  2023-11-28  8:51 ` [PATCH v3 0/9] RISC-V: Implement TLS Descriptors Tatsuyuki Ishi
  2023-11-28  8:51   ` [PATCH v3 1/9] RISC-V: Fix local GOT and reloc size calculation for TLS Tatsuyuki Ishi
  2023-11-28  8:51   ` [PATCH v3 2/9] RISC-V: Add TLSDESC reloc definitions Tatsuyuki Ishi
@ 2023-11-28  8:51   ` Tatsuyuki Ishi
  2024-02-19  1:44     ` Nelson Chu
  2023-11-28  8:51   ` [PATCH v3 4/9] RISC-V: Define and use GOT entry size constants for TLS Tatsuyuki Ishi
                     ` (6 subsequent siblings)
  9 siblings, 1 reply; 49+ messages in thread
From: Tatsuyuki Ishi @ 2023-11-28  8:51 UTC (permalink / raw)
  To: binutils; +Cc: i, nelson, rui314, ruiu, Tatsuyuki Ishi

gas/
    * tc-riscv.c (percent_op_*): Add support for %tlsdesc_hi,
    %tlsdesc_load_lo, %tlsdesc_add_lo and %tlsdesc_call. percent_op_rtype
    renamed to percent_op_relax_only as this matcher is extended to handle
    jalr as well which is not R-type.
    (riscv_ip): Apply the percent_op_relax_only rename and update comment.
    (md_apply_fix): Add TLSDESC_* to relaxable list. Add TLSDESC_HI20 to
    TLS relocation check list.
    * testsuite/gas/riscv/tlsdesc.*: New test cases for TLSDESC relocation
    generation.
opcodes/
    * riscv-opc.c (riscv_opcodes): Add a new syntax for jalr with
    %tlsdesc_call annotations.
---
 gas/config/tc-riscv.c             | 18 +++++++++++++-----
 gas/testsuite/gas/riscv/tlsdesc.d | 22 ++++++++++++++++++++++
 gas/testsuite/gas/riscv/tlsdesc.s | 24 ++++++++++++++++++++++++
 opcodes/riscv-opc.c               |  1 +
 4 files changed, 60 insertions(+), 5 deletions(-)
 create mode 100644 gas/testsuite/gas/riscv/tlsdesc.d
 create mode 100644 gas/testsuite/gas/riscv/tlsdesc.s

diff --git a/gas/config/tc-riscv.c b/gas/config/tc-riscv.c
index 04738d5e00c..376d2a34530 100644
--- a/gas/config/tc-riscv.c
+++ b/gas/config/tc-riscv.c
@@ -2113,6 +2113,7 @@ static const struct percent_op_match percent_op_utype[] =
   {"tprel_hi", BFD_RELOC_RISCV_TPREL_HI20},
   {"pcrel_hi", BFD_RELOC_RISCV_PCREL_HI20},
   {"got_pcrel_hi", BFD_RELOC_RISCV_GOT_HI20},
+  {"tlsdesc_hi", BFD_RELOC_RISCV_TLSDESC_HI20},
   {"tls_ie_pcrel_hi", BFD_RELOC_RISCV_TLS_GOT_HI20},
   {"tls_gd_pcrel_hi", BFD_RELOC_RISCV_TLS_GD_HI20},
   {"hi", BFD_RELOC_RISCV_HI20},
@@ -2124,6 +2125,8 @@ static const struct percent_op_match percent_op_itype[] =
   {"lo", BFD_RELOC_RISCV_LO12_I},
   {"tprel_lo", BFD_RELOC_RISCV_TPREL_LO12_I},
   {"pcrel_lo", BFD_RELOC_RISCV_PCREL_LO12_I},
+  {"tlsdesc_load_lo", BFD_RELOC_RISCV_TLSDESC_LOAD_LO12},
+  {"tlsdesc_add_lo", BFD_RELOC_RISCV_TLSDESC_ADD_LO12},
   {0, 0}
 };
 
@@ -2135,8 +2138,9 @@ static const struct percent_op_match percent_op_stype[] =
   {0, 0}
 };
 
-static const struct percent_op_match percent_op_rtype[] =
+static const struct percent_op_match percent_op_relax_only[] =
 {
+  {"tlsdesc_call", BFD_RELOC_RISCV_TLSDESC_CALL},
   {"tprel_add", BFD_RELOC_RISCV_TPREL_ADD},
   {0, 0}
 };
@@ -3244,10 +3248,10 @@ riscv_ip (char *str, struct riscv_cl_insn *ip, expressionS *imm_expr,
 	      *imm_reloc = BFD_RELOC_RISCV_LO12_I;
 	      goto load_store;
 	    case '1':
-	      /* This is used for TLS, where the fourth operand is
-		 %tprel_add, to get a relocation applied to an add
-		 instruction, for relaxation to use.  */
-	      p = percent_op_rtype;
+	      /* This is used for TLS relocations that acts as relaxation
+		 markers and do not change the instruction encoding,
+		 i.e. %tprel_add and %tlsdesc_call.  */
+	      p = percent_op_relax_only;
 	      goto alu_op;
 	    case '0': /* AMO displacement, which must be zero.  */
 	    load_store:
@@ -4036,6 +4040,7 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
     case BFD_RELOC_RISCV_TPREL_LO12_I:
     case BFD_RELOC_RISCV_TPREL_LO12_S:
     case BFD_RELOC_RISCV_TPREL_ADD:
+    case BFD_RELOC_RISCV_TLSDESC_HI20:
       relaxable = true;
       /* Fall through.  */
 
@@ -4209,6 +4214,9 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
 
     case BFD_RELOC_RISCV_CALL:
     case BFD_RELOC_RISCV_CALL_PLT:
+    case BFD_RELOC_RISCV_TLSDESC_LOAD_LO12:
+    case BFD_RELOC_RISCV_TLSDESC_ADD_LO12:
+    case BFD_RELOC_RISCV_TLSDESC_CALL:
       relaxable = true;
       break;
 
diff --git a/gas/testsuite/gas/riscv/tlsdesc.d b/gas/testsuite/gas/riscv/tlsdesc.d
new file mode 100644
index 00000000000..11872953d23
--- /dev/null
+++ b/gas/testsuite/gas/riscv/tlsdesc.d
@@ -0,0 +1,22 @@
+#as: -march=rv32ia
+#source: tlsdesc.s
+#readelf: -Wr
+
+Relocation section '.rela.text' at offset 0x[0-9a-f]+ contains 16 entries:
+ +Offset +Info +Type +Sym. Value +Symbol's Name \+ Addend
+0+ +0+a3e +R_RISCV_TLSDESC_HI20 +0+ +sg1 \+ 0
+0+ +0+33 +R_RISCV_RELAX + 0
+0+4 +0+63f +R_RISCV_TLSDESC_LOAD_LO12 0+ +\.desc1 \+ 0
+0+4 +0+33 +R_RISCV_RELAX + 0
+0+8 +0+640 +R_RISCV_TLSDESC_ADD_LO12 0+ +\.desc1 \+ 0
+0+8 +0+33 +R_RISCV_RELAX + 0
+0+c +0+641 +R_RISCV_TLSDESC_CALL +0+ +\.desc1 \+ 0
+0+c +0+33 +R_RISCV_RELAX + 0
+0+10 +0+53e +R_RISCV_TLSDESC_HI20 +0+4 +sl1 \+ 0
+0+10 +0+33 +R_RISCV_RELAX + 0
+0+14 +0+83f +R_RISCV_TLSDESC_LOAD_LO12 0+10 +\.desc2 \+ 0
+0+14 +0+33 +R_RISCV_RELAX + 0
+0+18 +0+840 +R_RISCV_TLSDESC_ADD_LO12 0+10 +\.desc2 \+ 0
+0+18 +0+33 +R_RISCV_RELAX +0
+0+1c +0+841 +R_RISCV_TLSDESC_CALL +0+10 +\.desc2 \+ 0
+0+1c +0+33 +R_RISCV_RELAX +0
diff --git a/gas/testsuite/gas/riscv/tlsdesc.s b/gas/testsuite/gas/riscv/tlsdesc.s
new file mode 100644
index 00000000000..15468d5f947
--- /dev/null
+++ b/gas/testsuite/gas/riscv/tlsdesc.s
@@ -0,0 +1,24 @@
+	.section	.tbss,"awT",@nobits
+	.global sg1
+sg1:
+	.zero	4
+sl1:
+	.zero	4
+
+	.text
+	.globl	_start
+	.type	_start,@function
+_start:
+.desc1:
+	auipc	a0, %tlsdesc_hi(sg1)
+	lw	t0, %tlsdesc_load_lo(.desc1)(a0)
+	addi	a0, a0, %tlsdesc_add_lo(.desc1)
+	jalr	t0, t0, %tlsdesc_call(.desc1)
+
+.desc2:
+	auipc	a0, %tlsdesc_hi(sl1)
+	lw	t0, %tlsdesc_load_lo(.desc2)(a0)
+	addi	a0, a0, %tlsdesc_add_lo(.desc2)
+	jalr	t0, t0, %tlsdesc_call(.desc2)
+
+	ret
diff --git a/opcodes/riscv-opc.c b/opcodes/riscv-opc.c
index bf19978e025..edaf4b0c8b5 100644
--- a/opcodes/riscv-opc.c
+++ b/opcodes/riscv-opc.c
@@ -372,6 +372,7 @@ const struct riscv_opcode riscv_opcodes[] =
 {"jalr",        0, INSN_CLASS_I, "s,j",       MATCH_JALR|(X_RA << OP_SH_RD), MASK_JALR|MASK_RD, match_opcode, INSN_ALIAS|INSN_JSR },
 {"jalr",        0, INSN_CLASS_I, "d,s",       MATCH_JALR, MASK_JALR|MASK_IMM, match_opcode, INSN_ALIAS|INSN_JSR },
 {"jalr",        0, INSN_CLASS_I, "d,o(s)",    MATCH_JALR, MASK_JALR, match_opcode, INSN_JSR },
+{"jalr",        0, INSN_CLASS_I, "d,s,1",     MATCH_JALR, MASK_JALR|MASK_IMM, match_opcode, INSN_JSR },
 {"jalr",        0, INSN_CLASS_I, "d,s,j",     MATCH_JALR, MASK_JALR, match_opcode, INSN_JSR },
 {"j",           0, INSN_CLASS_C, "Ca",        MATCH_C_J, MASK_C_J, match_opcode, INSN_ALIAS|INSN_BRANCH },
 {"j",           0, INSN_CLASS_I, "a",         MATCH_JAL, MASK_JAL|MASK_RD, match_opcode, INSN_ALIAS|INSN_BRANCH },
-- 
2.43.0


^ permalink raw reply	[flat|nested] 49+ messages in thread

* [PATCH v3 4/9] RISC-V: Define and use GOT entry size constants for TLS.
  2023-11-28  8:51 ` [PATCH v3 0/9] RISC-V: Implement TLS Descriptors Tatsuyuki Ishi
                     ` (2 preceding siblings ...)
  2023-11-28  8:51   ` [PATCH v3 3/9] RISC-V: Add assembly support for TLSDESC Tatsuyuki Ishi
@ 2023-11-28  8:51   ` Tatsuyuki Ishi
  2024-02-19  1:57     ` Nelson Chu
  2023-11-28  8:51   ` [PATCH v3 5/9] RISC-V: Initial ld.bfd support for TLSDESC Tatsuyuki Ishi
                     ` (5 subsequent siblings)
  9 siblings, 1 reply; 49+ messages in thread
From: Tatsuyuki Ishi @ 2023-11-28  8:51 UTC (permalink / raw)
  To: binutils; +Cc: i, nelson, rui314, ruiu, Tatsuyuki Ishi

As the size calculation is split by global and local symbols, using a
shared constant definition for its size improves clarity.

bfd/
    * elfnn-riscv.c: Add macros for sizes of a normal GOT entry, TLS GD and
    TLS IE entry.
    (allocate_dynrelocs): Replace GOT size expressions with the new
    constants.
    (riscv_elf_size_dynamic_sections): Likewise.
    (riscv_elf_relocate_section): Likewise.
---
 bfd/elfnn-riscv.c | 16 +++++++++-------
 1 file changed, 9 insertions(+), 7 deletions(-)

diff --git a/bfd/elfnn-riscv.c b/bfd/elfnn-riscv.c
index c0207765906..d5190538503 100644
--- a/bfd/elfnn-riscv.c
+++ b/bfd/elfnn-riscv.c
@@ -298,6 +298,8 @@ riscv_is_insn_reloc (const reloc_howto_type *howto)
 #define PLT_HEADER_SIZE (PLT_HEADER_INSNS * 4)
 #define PLT_ENTRY_SIZE (PLT_ENTRY_INSNS * 4)
 #define GOT_ENTRY_SIZE RISCV_ELF_WORD_BYTES
+#define TLS_GD_GOT_ENTRY_SIZE (RISCV_ELF_WORD_BYTES * 2)
+#define TLS_IE_GOT_ENTRY_SIZE RISCV_ELF_WORD_BYTES
 /* Reserve two entries of GOTPLT for ld.so, one is used for PLT resolver,
    the other is used for link map.  Other targets also reserve one more
    entry used for runtime profile?  */
@@ -1320,7 +1322,7 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
 	  /* TLS_GD needs two dynamic relocs and two GOT slots.  */
 	  if (tls_type & GOT_TLS_GD)
 	    {
-	      s->size += 2 * RISCV_ELF_WORD_BYTES;
+	      s->size += TLS_GD_GOT_ENTRY_SIZE;
 	      if (need_reloc)
 		htab->elf.srelgot->size += 2 * sizeof (ElfNN_External_Rela);
 	    }
@@ -1328,14 +1330,14 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
 	  /* TLS_IE needs one dynamic reloc and one GOT slot.  */
 	  if (tls_type & GOT_TLS_IE)
 	    {
-	      s->size += RISCV_ELF_WORD_BYTES;
+	      s->size += TLS_IE_GOT_ENTRY_SIZE;
 	      if (need_reloc)
 		htab->elf.srelgot->size += sizeof (ElfNN_External_Rela);
 	    }
 	}
       else
 	{
-	  s->size += RISCV_ELF_WORD_BYTES;
+	  s->size += GOT_ENTRY_SIZE;
 	  if (WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, bfd_link_pic (info), h)
 	      && ! UNDEFWEAK_NO_DYNAMIC_RELOC (info, h))
 	    htab->elf.srelgot->size += sizeof (ElfNN_External_Rela);
@@ -1563,20 +1565,20 @@ riscv_elf_size_dynamic_sections (bfd *output_bfd, struct bfd_link_info *info)
 		{
 		  if (*local_tls_type & GOT_TLS_GD)
 		    {
-		      s->size += 2 * RISCV_ELF_WORD_BYTES;
+		      s->size += TLS_GD_GOT_ENTRY_SIZE;
 		      if (bfd_link_dll (info))
 			srel->size += sizeof (ElfNN_External_Rela);
 		    }
 		  if (*local_tls_type & GOT_TLS_IE)
 		    {
-		      s->size += RISCV_ELF_WORD_BYTES;
+		      s->size += TLS_IE_GOT_ENTRY_SIZE;
 		      if (bfd_link_dll (info))
 			srel->size += sizeof (ElfNN_External_Rela);
 		    }
 		}
 	      else
 		{
-		  s->size += RISCV_ELF_WORD_BYTES;
+		  s->size += GOT_ENTRY_SIZE;
 		  if (bfd_link_pic (info))
 		    srel->size += sizeof (ElfNN_External_Rela);
 		}
@@ -2912,7 +2914,7 @@ riscv_elf_relocate_section (bfd *output_bfd,
 	     reference's GOT slot follows the GD reference's slots.  */
 	  ie_off = 0;
 	  if ((tls_type & GOT_TLS_GD) && (tls_type & GOT_TLS_IE))
-	    ie_off = 2 * GOT_ENTRY_SIZE;
+	    ie_off = TLS_GD_GOT_ENTRY_SIZE;
 
 	  if ((off & 1) != 0)
 	    off &= ~1;
-- 
2.43.0


^ permalink raw reply	[flat|nested] 49+ messages in thread

* [PATCH v3 5/9] RISC-V: Initial ld.bfd support for TLSDESC.
  2023-11-28  8:51 ` [PATCH v3 0/9] RISC-V: Implement TLS Descriptors Tatsuyuki Ishi
                     ` (3 preceding siblings ...)
  2023-11-28  8:51   ` [PATCH v3 4/9] RISC-V: Define and use GOT entry size constants for TLS Tatsuyuki Ishi
@ 2023-11-28  8:51   ` Tatsuyuki Ishi
  2024-02-19  4:33     ` Nelson Chu
  2023-11-28  8:51   ` [PATCH v3 6/9] RISC-V: Move STATIC_TLS handling into record_tls_type Tatsuyuki Ishi
                     ` (4 subsequent siblings)
  9 siblings, 1 reply; 49+ messages in thread
From: Tatsuyuki Ishi @ 2023-11-28  8:51 UTC (permalink / raw)
  To: binutils; +Cc: i, nelson, rui314, ruiu, Tatsuyuki Ishi

Only relocation handling for now; relaxation is not implemented yet.

bfd/
    * elfnn-riscv.c (riscv_elf_check_relocs): Record GOT reference and
    paired relocation for TLSDESC_HI20.
    (riscv_elf_adjust_dynamic_symbol): Allocate GOT and reloc slots for
    TLSDESC symbols.
    (riscv_elf_size_dynamic_sections): Likewise but for local symbols.
    (tlsdescoff): New helper to determine static addend for R_TLSDESC.
    (riscv_elf_relocate_section): Ignore TLSDESC_CALL reloc for now (it is
    relaxation only).
    Handle TLSDESC_{LOAD,ADD}_LO12 as paired pcrel relocs.
    For TLS GOT slot generation, generalize the logic to handle any
    combination of (GD, IE, TLSDESC).
    Add TLSDESC Rela generation.
    * ld/testsuite/ld-riscv-elf/tls*: Add TLSDESC instruction sequences
    next to the existing GD and IE sequences. Update expectations.
---
 bfd/elfnn-riscv.c                  | 91 +++++++++++++++++++++++++++---
 ld/testsuite/ld-riscv-elf/tls.d    |  4 +-
 ld/testsuite/ld-riscv-elf/tls.s    | 14 +++++
 ld/testsuite/ld-riscv-elf/tlsbin.d |  5 ++
 4 files changed, 104 insertions(+), 10 deletions(-)

diff --git a/bfd/elfnn-riscv.c b/bfd/elfnn-riscv.c
index d5190538503..8f63998aa5a 100644
--- a/bfd/elfnn-riscv.c
+++ b/bfd/elfnn-riscv.c
@@ -163,6 +163,7 @@ struct riscv_elf_link_hash_entry
 #define GOT_TLS_GD	2
 #define GOT_TLS_IE	4
 #define GOT_TLS_LE	8
+#define GOT_TLSDESC	16
   char tls_type;
 };
 
@@ -300,6 +301,7 @@ riscv_is_insn_reloc (const reloc_howto_type *howto)
 #define GOT_ENTRY_SIZE RISCV_ELF_WORD_BYTES
 #define TLS_GD_GOT_ENTRY_SIZE (RISCV_ELF_WORD_BYTES * 2)
 #define TLS_IE_GOT_ENTRY_SIZE RISCV_ELF_WORD_BYTES
+#define TLSDESC_GOT_ENTRY_SIZE (RISCV_ELF_WORD_BYTES * 2)
 /* Reserve two entries of GOTPLT for ld.so, one is used for PLT resolver,
    the other is used for link map.  Other targets also reserve one more
    entry used for runtime profile?  */
@@ -855,6 +857,12 @@ riscv_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
 	    return false;
 	  break;
 
+	case R_RISCV_TLSDESC_HI20:
+	  if (!riscv_elf_record_got_reference (abfd, info, h, r_symndx)
+	      || !riscv_elf_record_tls_type (abfd, h, r_symndx, GOT_TLSDESC))
+	    return false;
+	  break;
+
 	case R_RISCV_CALL:
 	case R_RISCV_CALL_PLT:
 	  /* These symbol requires a procedure linkage table entry.
@@ -1313,7 +1321,7 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
       s = htab->elf.sgot;
       h->got.offset = s->size;
       dyn = htab->elf.dynamic_sections_created;
-      if (tls_type & (GOT_TLS_GD | GOT_TLS_IE))
+      if (tls_type & (GOT_TLS_GD | GOT_TLS_IE | GOT_TLSDESC))
 	{
 	  int indx = 0;
 	  bool need_reloc = false;
@@ -1334,6 +1342,14 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
 	      if (need_reloc)
 		htab->elf.srelgot->size += sizeof (ElfNN_External_Rela);
 	    }
+
+	  /* TLSDESC needs one dynamic reloc and two GOT slots.  */
+	  if (tls_type & GOT_TLSDESC)
+	    {
+	      s->size += TLSDESC_GOT_ENTRY_SIZE;
+	      /* TLSDESC always use dynamic relocs.  */
+	      htab->elf.srelgot->size += sizeof (ElfNN_External_Rela);
+	    }
 	}
       else
 	{
@@ -1561,7 +1577,7 @@ riscv_elf_size_dynamic_sections (bfd *output_bfd, struct bfd_link_info *info)
 	  if (*local_got > 0)
 	    {
 	      *local_got = s->size;
-	      if (*local_tls_type & (GOT_TLS_GD | GOT_TLS_IE))
+	      if (*local_tls_type & (GOT_TLS_GD | GOT_TLS_IE | GOT_TLSDESC))
 		{
 		  if (*local_tls_type & GOT_TLS_GD)
 		    {
@@ -1575,6 +1591,11 @@ riscv_elf_size_dynamic_sections (bfd *output_bfd, struct bfd_link_info *info)
 		      if (bfd_link_dll (info))
 			srel->size += sizeof (ElfNN_External_Rela);
 		    }
+		  if (*local_tls_type & GOT_TLSDESC)
+		    {
+		      s->size += TLSDESC_GOT_ENTRY_SIZE;
+		      srel->size += sizeof (ElfNN_External_Rela);
+		    }
 		}
 	      else
 		{
@@ -1725,6 +1746,17 @@ tpoff (struct bfd_link_info *info, bfd_vma address)
   return address - elf_hash_table (info)->tls_sec->vma - TP_OFFSET;
 }
 
+/* Return the relocation value for a static TLSDESC relocation.  */
+
+static bfd_vma
+tlsdescoff (struct bfd_link_info *info, bfd_vma address)
+{
+  /* If tls_sec is NULL, we should have signalled an error already.  */
+  if (elf_hash_table (info)->tls_sec == NULL)
+    return 0;
+  return address - elf_hash_table (info)->tls_sec->vma;
+}
+
 /* Return the global pointer's value, or 0 if it is not in use.  */
 
 static bfd_vma
@@ -1774,6 +1806,7 @@ perform_relocation (const reloc_howto_type *howto,
     case R_RISCV_GOT_HI20:
     case R_RISCV_TLS_GOT_HI20:
     case R_RISCV_TLS_GD_HI20:
+    case R_RISCV_TLSDESC_HI20:
       if (ARCH_SIZE > 32 && !VALID_UTYPE_IMM (RISCV_CONST_HIGH_PART (value)))
 	return bfd_reloc_overflow;
       value = ENCODE_UTYPE_IMM (RISCV_CONST_HIGH_PART (value));
@@ -1784,6 +1817,8 @@ perform_relocation (const reloc_howto_type *howto,
     case R_RISCV_TPREL_LO12_I:
     case R_RISCV_TPREL_I:
     case R_RISCV_PCREL_LO12_I:
+    case R_RISCV_TLSDESC_LOAD_LO12:
+    case R_RISCV_TLSDESC_ADD_LO12:
       value = ENCODE_ITYPE_IMM (value);
       break;
 
@@ -2202,8 +2237,8 @@ riscv_elf_relocate_section (bfd *output_bfd,
       bfd_vma relocation;
       bfd_reloc_status_type r = bfd_reloc_ok;
       const char *name = NULL;
-      bfd_vma off, ie_off;
-      bool unresolved_reloc, is_ie = false;
+      bfd_vma off, ie_off, desc_off;
+      bool unresolved_reloc, is_ie = false, is_desc = false;
       bfd_vma pc = sec_addr (input_section) + rel->r_offset;
       int r_type = ELFNN_R_TYPE (rel->r_info), tls_type;
       reloc_howto_type *howto = riscv_elf_rtype_to_howto (input_bfd, r_type);
@@ -2506,6 +2541,7 @@ riscv_elf_relocate_section (bfd *output_bfd,
 	case R_RISCV_NONE:
 	case R_RISCV_RELAX:
 	case R_RISCV_TPREL_ADD:
+	case R_RISCV_TLSDESC_CALL:
 	case R_RISCV_COPY:
 	case R_RISCV_JUMP_SLOT:
 	case R_RISCV_RELATIVE:
@@ -2827,6 +2863,15 @@ riscv_elf_relocate_section (bfd *output_bfd,
 	  relocation = dtpoff (info, relocation);
 	  break;
 
+	case R_RISCV_TLSDESC_LOAD_LO12:
+	case R_RISCV_TLSDESC_ADD_LO12:
+	  if (riscv_record_pcrel_lo_reloc (&pcrel_relocs, relocation, rel,
+					   input_section, info, howto,
+					   contents))
+	      continue;
+	  r = bfd_reloc_overflow;
+	  break;
+
 	case R_RISCV_32:
 	  /* Non ABS symbol should be blocked in check_relocs.  */
 	  if (ARCH_SIZE > 32)
@@ -2892,11 +2937,16 @@ riscv_elf_relocate_section (bfd *output_bfd,
 	    }
 	  break;
 
+	case R_RISCV_TLSDESC_HI20:
+	  is_desc = true;
+	  goto tls;
+
 	case R_RISCV_TLS_GOT_HI20:
 	  is_ie = true;
-	  /* Fall through.  */
+	  goto tls;
 
 	case R_RISCV_TLS_GD_HI20:
+	tls:
 	  if (h != NULL)
 	    {
 	      off = h->got.offset;
@@ -2909,12 +2959,16 @@ riscv_elf_relocate_section (bfd *output_bfd,
 	    }
 
 	  tls_type = _bfd_riscv_elf_tls_type (input_bfd, h, r_symndx);
-	  BFD_ASSERT (tls_type & (GOT_TLS_IE | GOT_TLS_GD));
+	  BFD_ASSERT (tls_type & (GOT_TLS_IE | GOT_TLS_GD | GOT_TLSDESC));
 	  /* If this symbol is referenced by both GD and IE TLS, the IE
 	     reference's GOT slot follows the GD reference's slots.  */
 	  ie_off = 0;
 	  if ((tls_type & GOT_TLS_GD) && (tls_type & GOT_TLS_IE))
-	    ie_off = TLS_GD_GOT_ENTRY_SIZE;
+	    ie_off += TLS_GD_GOT_ENTRY_SIZE;
+
+	  desc_off = ie_off;
+	  if (tls_type & GOT_TLS_IE)
+	    desc_off += TLS_IE_GOT_ENTRY_SIZE;
 
 	  if ((off & 1) != 0)
 	    off &= ~1;
@@ -2996,10 +3050,29 @@ riscv_elf_relocate_section (bfd *output_bfd,
 				  htab->elf.sgot->contents + off + ie_off);
 		    }
 		}
+
+	      if (tls_type & GOT_TLSDESC)
+		{
+		  /* TLSDESC is always handled by the dynamic linker and always need
+		   * a relocation.  */
+		  bfd_put_NN (output_bfd, 0,
+			      htab->elf.sgot->contents + off + desc_off);
+		  outrel.r_offset = sec_addr (htab->elf.sgot)
+				    + off + desc_off;
+		  outrel.r_addend = 0;
+		  if (indx == 0)
+		    outrel.r_addend = tlsdescoff (info, relocation);
+		  outrel.r_info = ELFNN_R_INFO (indx, R_RISCV_TLSDESC);
+		  riscv_elf_append_rela (output_bfd, htab->elf.srelgot, &outrel);
+		}
 	    }
 
 	  BFD_ASSERT (off < (bfd_vma) -2);
-	  relocation = sec_addr (htab->elf.sgot) + off + (is_ie ? ie_off : 0);
+	  relocation = sec_addr (htab->elf.sgot) + off;
+	  if (is_ie)
+	    relocation += ie_off;
+	  else if (is_desc)
+	    relocation += desc_off;
 	  if (!riscv_record_pcrel_hi_reloc (&pcrel_relocs, pc,
 					    relocation, r_type,
 					    false))
@@ -3219,7 +3292,7 @@ riscv_elf_finish_dynamic_symbol (bfd *output_bfd,
     }
 
   if (h->got.offset != (bfd_vma) -1
-      && !(riscv_elf_hash_entry (h)->tls_type & (GOT_TLS_GD | GOT_TLS_IE))
+      && !(riscv_elf_hash_entry (h)->tls_type & (GOT_TLS_GD | GOT_TLS_IE | GOT_TLSDESC))
       && !UNDEFWEAK_NO_DYNAMIC_RELOC (info, h))
     {
       asection *sgot;
diff --git a/ld/testsuite/ld-riscv-elf/tls.d b/ld/testsuite/ld-riscv-elf/tls.d
index e7f20309bf1..6cf008ac7a0 100644
--- a/ld/testsuite/ld-riscv-elf/tls.d
+++ b/ld/testsuite/ld-riscv-elf/tls.d
@@ -2,13 +2,15 @@
 #ld: --shared tmpdir/tlslib.so
 #readelf: -Wr
 
-Relocation section '.rela.dyn' at offset 0x[0-9a-f]+ contains 5 entries:
+Relocation section '.rela.dyn' at offset 0x[0-9a-f]+ contains 7 entries:
  +Offset +Info +Type +Symbol's Value +Symbol's Name \+ Addend
 [0-9a-f]+ +[0-9a-f]+ R_RISCV_TLS_DTPMOD64 +0
 [0-9a-f]+ +[0-9a-f]+ R_RISCV_TLS_TPREL64 +4
+[0-9a-f]+ +[0-9a-f]+ R_RISCV_TLSDESC +4
 [0-9a-f]+ +[0-9a-f]+ R_RISCV_TLS_DTPMOD64 +0+ sg1 \+ 0
 [0-9a-f]+ +[0-9a-f]+ R_RISCV_TLS_DTPREL64 +0+ sg1 \+ 0
 [0-9a-f]+ +[0-9a-f]+ R_RISCV_TLS_TPREL64 +0+ sg1 \+ 0
+[0-9a-f]+ +[0-9a-f]+ R_RISCV_TLSDESC +0+ sg1 \+ 0
 
 Relocation section '.rela.plt' at offset 0x[0-9a-f]+ contains 1 entry:
  +Offset +Info +Type +Symbol's Value +Symbol's Name \+ Addend
diff --git a/ld/testsuite/ld-riscv-elf/tls.s b/ld/testsuite/ld-riscv-elf/tls.s
index 79e9bc20374..7cbf5ea6c72 100644
--- a/ld/testsuite/ld-riscv-elf/tls.s
+++ b/ld/testsuite/ld-riscv-elf/tls.s
@@ -17,6 +17,13 @@ _start:
 	la.tls.ie	a0,sg1
 	add	a0,a0,tp
 
+	/* GD (TLSDESC), global var */
+.desc1:
+	auipc	a0, %tlsdesc_hi(sg1)
+	lw	t0, %tlsdesc_load_lo(.desc1)(a0)
+	addi	a0, a0, %tlsdesc_add_lo(.desc1)
+	jalr	t0, t0, %tlsdesc_call(.desc1)
+
 	/* GD, local var */
 	la.tls.gd	a0,sl1
 	call  __tls_get_addr
@@ -25,4 +32,11 @@ _start:
 	la.tls.ie	a0,sl1
 	add	a0,a0,tp
 
+	/* GD (TLSDESC), local var */
+.desc2:
+	auipc	a0, %tlsdesc_hi(sl1)
+	lw	t0, %tlsdesc_load_lo(.desc2)(a0)
+	addi	a0, a0, %tlsdesc_add_lo(.desc2)
+	jalr	t0, t0, %tlsdesc_call(.desc2)
+
 	ret
diff --git a/ld/testsuite/ld-riscv-elf/tlsbin.d b/ld/testsuite/ld-riscv-elf/tlsbin.d
index cdcd51a9199..79b7ade405e 100644
--- a/ld/testsuite/ld-riscv-elf/tlsbin.d
+++ b/ld/testsuite/ld-riscv-elf/tlsbin.d
@@ -2,6 +2,11 @@
 #ld: -no-pie tmpdir/tlslib.so
 #readelf: -Wr
 
+Relocation section '.rela.dyn' at offset 0x[0-9a-f]+ contains 2 entries:
+ +Offset +Info +Type +Symbol's Value +Symbol's Name \+ Addend
+[0-9a-f]+ +[0-9a-f]+ R_RISCV_TLSDESC +4
+[0-9a-f]+ +[0-9a-f]+ R_RISCV_TLSDESC +0
+
 Relocation section '.rela.plt' at offset 0x[0-9a-f]+ contains 1 entry:
  +Offset +Info +Type +Symbol's Value +Symbol's Name \+ Addend
 [0-9a-f]+ +[0-9a-f]+ R_RISCV_JUMP_SLOT +[0-9a-f]+ __tls_get_addr \+ 0
-- 
2.43.0


^ permalink raw reply	[flat|nested] 49+ messages in thread

* [PATCH v3 6/9] RISC-V: Move STATIC_TLS handling into record_tls_type.
  2023-11-28  8:51 ` [PATCH v3 0/9] RISC-V: Implement TLS Descriptors Tatsuyuki Ishi
                     ` (4 preceding siblings ...)
  2023-11-28  8:51   ` [PATCH v3 5/9] RISC-V: Initial ld.bfd support for TLSDESC Tatsuyuki Ishi
@ 2023-11-28  8:51   ` Tatsuyuki Ishi
  2023-11-28  8:51   ` [PATCH v3 7/9] RISC-V: Unify TLS handling in check_relocs Tatsuyuki Ishi
                     ` (3 subsequent siblings)
  9 siblings, 0 replies; 49+ messages in thread
From: Tatsuyuki Ishi @ 2023-11-28  8:51 UTC (permalink / raw)
  To: binutils; +Cc: i, nelson, rui314, ruiu, Tatsuyuki Ishi

bfd/Changelog:
	* elfnn-riscv.c (riscv_elf_record_tls_type): Add bfd_link_info
	parameter and move code from below.
	(riscv_elf_check_relocs): Move STATIC_TLS handling into
	riscv_elf_record_tls_type.
	Add missing early return in the R_RISCV_TPREL_HI20 case.
---
 bfd/elfnn-riscv.c | 27 ++++++++++++++++++---------
 1 file changed, 18 insertions(+), 9 deletions(-)

diff --git a/bfd/elfnn-riscv.c b/bfd/elfnn-riscv.c
index 8f63998aa5a..4c722388aa0 100644
--- a/bfd/elfnn-riscv.c
+++ b/bfd/elfnn-riscv.c
@@ -663,12 +663,14 @@ riscv_elf_copy_indirect_symbol (struct bfd_link_info *info,
 }
 
 static bool
-riscv_elf_record_tls_type (bfd *abfd, struct elf_link_hash_entry *h,
+riscv_elf_record_tls_type (bfd *abfd, struct bfd_link_info *info,
+			   struct elf_link_hash_entry *h,
 			   unsigned long symndx, char tls_type)
 {
   char *new_tls_type = &_bfd_riscv_elf_tls_type (abfd, h, symndx);
 
   *new_tls_type |= tls_type;
+
   if ((*new_tls_type & GOT_NORMAL) && (*new_tls_type & ~GOT_NORMAL))
     {
       (*_bfd_error_handler)
@@ -676,6 +678,10 @@ riscv_elf_record_tls_type (bfd *abfd, struct elf_link_hash_entry *h,
 	 abfd, h ? h->root.root.string : "<local>");
       return false;
     }
+
+  if ((*new_tls_type & GOT_TLS_IE) && bfd_link_dll (info))
+    info->flags |= DF_STATIC_TLS;
+
   return true;
 }
 
@@ -839,27 +845,29 @@ riscv_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
 	{
 	case R_RISCV_TLS_GD_HI20:
 	  if (!riscv_elf_record_got_reference (abfd, info, h, r_symndx)
-	      || !riscv_elf_record_tls_type (abfd, h, r_symndx, GOT_TLS_GD))
+	      || !riscv_elf_record_tls_type (abfd, info, h, r_symndx,
+					     GOT_TLS_GD))
 	    return false;
 	  break;
 
 	case R_RISCV_TLS_GOT_HI20:
-	  if (bfd_link_dll (info))
-	    info->flags |= DF_STATIC_TLS;
 	  if (!riscv_elf_record_got_reference (abfd, info, h, r_symndx)
-	      || !riscv_elf_record_tls_type (abfd, h, r_symndx, GOT_TLS_IE))
+	      || !riscv_elf_record_tls_type (abfd, info, h, r_symndx,
+					     GOT_TLS_IE))
 	    return false;
 	  break;
 
 	case R_RISCV_GOT_HI20:
 	  if (!riscv_elf_record_got_reference (abfd, info, h, r_symndx)
-	      || !riscv_elf_record_tls_type (abfd, h, r_symndx, GOT_NORMAL))
+	      || !riscv_elf_record_tls_type (abfd, info, h, r_symndx,
+					     GOT_NORMAL))
 	    return false;
 	  break;
 
 	case R_RISCV_TLSDESC_HI20:
 	  if (!riscv_elf_record_got_reference (abfd, info, h, r_symndx)
-	      || !riscv_elf_record_tls_type (abfd, h, r_symndx, GOT_TLSDESC))
+	      || !riscv_elf_record_tls_type (abfd, info, h, r_symndx,
+					     GOT_TLSDESC))
 	    return false;
 	  break;
 
@@ -949,8 +957,9 @@ riscv_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
 	  /* This is not allowed in the pic, but okay in pie.  */
 	  if (!bfd_link_executable (info))
 	    return bad_static_reloc (abfd, r_type, h);
-	  if (h != NULL)
-	    riscv_elf_record_tls_type (abfd, h, r_symndx, GOT_TLS_LE);
+	  if (h != NULL
+	      && !riscv_elf_record_tls_type (abfd, info, h, r_symndx, GOT_TLS_LE))
+	    return false;
 	  break;
 
 	case R_RISCV_HI20:
-- 
2.43.0


^ permalink raw reply	[flat|nested] 49+ messages in thread

* [PATCH v3 7/9] RISC-V: Unify TLS handling in check_relocs.
  2023-11-28  8:51 ` [PATCH v3 0/9] RISC-V: Implement TLS Descriptors Tatsuyuki Ishi
                     ` (5 preceding siblings ...)
  2023-11-28  8:51   ` [PATCH v3 6/9] RISC-V: Move STATIC_TLS handling into record_tls_type Tatsuyuki Ishi
@ 2023-11-28  8:51   ` Tatsuyuki Ishi
  2023-11-28  8:51   ` [PATCH v3 8/9] RISC-V: Add elf_link_hash_entry to relax_func args Tatsuyuki Ishi
                     ` (2 subsequent siblings)
  9 siblings, 0 replies; 49+ messages in thread
From: Tatsuyuki Ishi @ 2023-11-28  8:51 UTC (permalink / raw)
  To: binutils; +Cc: i, nelson, rui314, ruiu, Tatsuyuki Ishi

With the introduction of transition, multiple relocation types may map to
GOT_TLS_IE or GOT_TLS_LE and it makes more sense to unify the code path to
perform checks common to them.

bfd/
	* elfnn-riscv.c (riscv_elf_check_relocs): Merge switch cases for
	TLS relocs.
---
 bfd/elfnn-riscv.c | 64 +++++++++++++++++++++++++++--------------------
 1 file changed, 37 insertions(+), 27 deletions(-)

diff --git a/bfd/elfnn-riscv.c b/bfd/elfnn-riscv.c
index 4c722388aa0..1d88ecd53b5 100644
--- a/bfd/elfnn-riscv.c
+++ b/bfd/elfnn-riscv.c
@@ -662,6 +662,24 @@ riscv_elf_copy_indirect_symbol (struct bfd_link_info *info,
   _bfd_elf_link_hash_copy_indirect (info, dir, ind);
 }
 
+static char
+riscv_elf_tls_type_from_hi_reloc (unsigned int r_type)
+{
+  switch (r_type)
+    {
+      case R_RISCV_TLS_GD_HI20:
+	return GOT_TLS_GD;
+      case R_RISCV_TLS_GOT_HI20:
+	return GOT_TLS_IE;
+      case R_RISCV_TLSDESC_HI20:
+	return GOT_TLSDESC;
+      case R_RISCV_TPREL_HI20:
+	return GOT_TLS_LE;
+      default:
+	abort ();
+    }
+}
+
 static bool
 riscv_elf_record_tls_type (bfd *abfd, struct bfd_link_info *info,
 			   struct elf_link_hash_entry *h,
@@ -843,19 +861,26 @@ riscv_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
 
       switch (r_type)
 	{
-	case R_RISCV_TLS_GD_HI20:
-	  if (!riscv_elf_record_got_reference (abfd, info, h, r_symndx)
-	      || !riscv_elf_record_tls_type (abfd, info, h, r_symndx,
-					     GOT_TLS_GD))
-	    return false;
-	  break;
+	  case R_RISCV_TLS_GD_HI20:
+	  case R_RISCV_TLS_GOT_HI20:
+	  case R_RISCV_TLSDESC_HI20:
+	  case R_RISCV_TPREL_HI20:
+	    {
+	      char tls_type = riscv_elf_tls_type_from_hi_reloc (r_type);
 
-	case R_RISCV_TLS_GOT_HI20:
-	  if (!riscv_elf_record_got_reference (abfd, info, h, r_symndx)
-	      || !riscv_elf_record_tls_type (abfd, info, h, r_symndx,
-					     GOT_TLS_IE))
-	    return false;
-	  break;
+	      /* Local exec is only allowed for executables.  */
+	      if (tls_type == GOT_TLS_LE && !bfd_link_executable (info))
+		return bad_static_reloc (abfd, r_type, h);
+
+	      if (tls_type != GOT_TLS_LE
+		  && !riscv_elf_record_got_reference (abfd, info, h, r_symndx))
+		return false;
+	      if ((tls_type != GOT_TLS_LE || h != NULL)
+		  && !riscv_elf_record_tls_type (abfd, info, h, r_symndx,
+						 tls_type))
+		return false;
+	      break;
+	    }
 
 	case R_RISCV_GOT_HI20:
 	  if (!riscv_elf_record_got_reference (abfd, info, h, r_symndx)
@@ -864,12 +889,6 @@ riscv_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
 	    return false;
 	  break;
 
-	case R_RISCV_TLSDESC_HI20:
-	  if (!riscv_elf_record_got_reference (abfd, info, h, r_symndx)
-	      || !riscv_elf_record_tls_type (abfd, info, h, r_symndx,
-					     GOT_TLSDESC))
-	    return false;
-	  break;
 
 	case R_RISCV_CALL:
 	case R_RISCV_CALL_PLT:
@@ -953,15 +972,6 @@ riscv_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
 	    break;
 	  goto static_reloc;
 
-	case R_RISCV_TPREL_HI20:
-	  /* This is not allowed in the pic, but okay in pie.  */
-	  if (!bfd_link_executable (info))
-	    return bad_static_reloc (abfd, r_type, h);
-	  if (h != NULL
-	      && !riscv_elf_record_tls_type (abfd, info, h, r_symndx, GOT_TLS_LE))
-	    return false;
-	  break;
-
 	case R_RISCV_HI20:
 	  if (bfd_link_pic (info))
 	    return bad_static_reloc (abfd, r_type, h);
-- 
2.43.0


^ permalink raw reply	[flat|nested] 49+ messages in thread

* [PATCH v3 8/9] RISC-V: Add elf_link_hash_entry to relax_func args.
  2023-11-28  8:51 ` [PATCH v3 0/9] RISC-V: Implement TLS Descriptors Tatsuyuki Ishi
                     ` (6 preceding siblings ...)
  2023-11-28  8:51   ` [PATCH v3 7/9] RISC-V: Unify TLS handling in check_relocs Tatsuyuki Ishi
@ 2023-11-28  8:51   ` Tatsuyuki Ishi
  2023-11-28  8:51   ` [PATCH v3 9/9] RISC-V: Introduce TLSDESC relaxation Tatsuyuki Ishi
  2023-12-05 16:44   ` [PATCH v3 0/9] RISC-V: Implement TLS Descriptors Tatsuyuki Ishi
  9 siblings, 0 replies; 49+ messages in thread
From: Tatsuyuki Ishi @ 2023-11-28  8:51 UTC (permalink / raw)
  To: binutils; +Cc: i, nelson, rui314, ruiu, Tatsuyuki Ishi

bfd/
	* elfnn-riscv.c (riscv_pcgp_hi_reloc): Add a field for hash_entry.
	(riscv_record_pcgp_hi_reloc): Add argument and record the
	hash_entry.
	(_bfd_riscv_relax_*): Add unused hash_entry argument.
	(_bfd_riscv_relax_pc): Also record the hash_entry, for consistency
	 (but it is not used by the LO reloc handling).
	(_bfd_riscv_relax_section): Move h to outer scope and pass into
	relax helpers.
---
 bfd/elfnn-riscv.c | 14 ++++++++++++--
 1 file changed, 12 insertions(+), 2 deletions(-)

diff --git a/bfd/elfnn-riscv.c b/bfd/elfnn-riscv.c
index 1d88ecd53b5..b98264319d8 100644
--- a/bfd/elfnn-riscv.c
+++ b/bfd/elfnn-riscv.c
@@ -4212,6 +4212,7 @@ struct riscv_pcgp_hi_reloc
   bfd_vma hi_addr;
   unsigned hi_sym;
   asection *sym_sec;
+  struct elf_link_hash_entry *h;
   bool undefined_weak;
   riscv_pcgp_hi_reloc *next;
 };
@@ -4272,6 +4273,7 @@ static bool
 riscv_record_pcgp_hi_reloc (riscv_pcgp_relocs *p, bfd_vma hi_sec_off,
 			    bfd_vma hi_addend, bfd_vma hi_addr,
 			    unsigned hi_sym, asection *sym_sec,
+			    struct elf_link_hash_entry *h,
 			    bool undefined_weak)
 {
   riscv_pcgp_hi_reloc *new = bfd_malloc (sizeof (*new));
@@ -4282,6 +4284,7 @@ riscv_record_pcgp_hi_reloc (riscv_pcgp_relocs *p, bfd_vma hi_sec_off,
   new->hi_addr = hi_addr;
   new->hi_sym = hi_sym;
   new->sym_sec = sym_sec;
+  new->h = h;
   new->undefined_weak = undefined_weak;
   new->next = p->hi;
   p->hi = new;
@@ -4584,6 +4587,7 @@ riscv_relax_resolve_delete_relocs (bfd *abfd,
 
 typedef bool (*relax_func_t) (bfd *, asection *, asection *,
 			      struct bfd_link_info *,
+			      struct elf_link_hash_entry *,
 			      Elf_Internal_Rela *,
 			      bfd_vma, bfd_vma, bfd_vma, bool *,
 			      riscv_pcgp_relocs *,
@@ -4594,6 +4598,7 @@ typedef bool (*relax_func_t) (bfd *, asection *, asection *,
 static bool
 _bfd_riscv_relax_call (bfd *abfd, asection *sec, asection *sym_sec,
 		       struct bfd_link_info *link_info,
+		       struct elf_link_hash_entry *_h ATTRIBUTE_UNUSED,
 		       Elf_Internal_Rela *rel,
 		       bfd_vma symval,
 		       bfd_vma max_alignment,
@@ -4700,6 +4705,7 @@ _bfd_riscv_relax_lui (bfd *abfd,
 		      asection *sec,
 		      asection *sym_sec,
 		      struct bfd_link_info *link_info,
+		      struct elf_link_hash_entry *_h ATTRIBUTE_UNUSED,
 		      Elf_Internal_Rela *rel,
 		      bfd_vma symval,
 		      bfd_vma max_alignment,
@@ -4813,6 +4819,7 @@ _bfd_riscv_relax_tls_le (bfd *abfd,
 			 asection *sec,
 			 asection *sym_sec ATTRIBUTE_UNUSED,
 			 struct bfd_link_info *link_info,
+			 struct elf_link_hash_entry *_h ATTRIBUTE_UNUSED,
 			 Elf_Internal_Rela *rel,
 			 bfd_vma symval,
 			 bfd_vma max_alignment ATTRIBUTE_UNUSED,
@@ -4855,6 +4862,7 @@ static bool
 _bfd_riscv_relax_align (bfd *abfd, asection *sec,
 			asection *sym_sec,
 			struct bfd_link_info *link_info,
+			struct elf_link_hash_entry *_h ATTRIBUTE_UNUSED,
 			Elf_Internal_Rela *rel,
 			bfd_vma symval,
 			bfd_vma max_alignment ATTRIBUTE_UNUSED,
@@ -4915,6 +4923,7 @@ _bfd_riscv_relax_pc (bfd *abfd ATTRIBUTE_UNUSED,
 		     asection *sec,
 		     asection *sym_sec,
 		     struct bfd_link_info *link_info,
+		     struct elf_link_hash_entry *_h,
 		     Elf_Internal_Rela *rel,
 		     bfd_vma symval,
 		     bfd_vma max_alignment,
@@ -5035,6 +5044,7 @@ _bfd_riscv_relax_pc (bfd *abfd ATTRIBUTE_UNUSED,
 				      symval,
 				      ELFNN_R_SYM(rel->r_info),
 				      sym_sec,
+				      _h,
 				      undefined_weak);
 	  /* Delete unnecessary AUIPC and reuse the reloc.  */
 	  *again = true;
@@ -5124,6 +5134,7 @@ _bfd_riscv_relax_section (bfd *abfd, asection *sec,
   /* Examine and consider relaxing each reloc.  */
   for (i = 0; i < sec->reloc_count; i++)
     {
+      struct elf_link_hash_entry *h = NULL;
       asection *sym_sec;
       Elf_Internal_Rela *rel = relocs + i;
       relax_func_t relax_func;
@@ -5226,7 +5237,6 @@ _bfd_riscv_relax_section (bfd *abfd, asection *sec,
       else
 	{
 	  unsigned long indx;
-	  struct elf_link_hash_entry *h;
 
 	  indx = ELFNN_R_SYM (rel->r_info) - symtab_hdr->sh_info;
 	  h = elf_sym_hashes (abfd)[indx];
@@ -5328,7 +5338,7 @@ _bfd_riscv_relax_section (bfd *abfd, asection *sec,
 
       symval += sec_addr (sym_sec);
 
-      if (!relax_func (abfd, sec, sym_sec, info, rel, symval,
+      if (!relax_func (abfd, sec, sym_sec, info, h, rel, symval,
 		       max_alignment, reserve_size, again,
 		       &pcgp_relocs, undefined_weak))
 	goto fail;
-- 
2.43.0


^ permalink raw reply	[flat|nested] 49+ messages in thread

* [PATCH v3 9/9] RISC-V: Introduce TLSDESC relaxation.
  2023-11-28  8:51 ` [PATCH v3 0/9] RISC-V: Implement TLS Descriptors Tatsuyuki Ishi
                     ` (7 preceding siblings ...)
  2023-11-28  8:51   ` [PATCH v3 8/9] RISC-V: Add elf_link_hash_entry to relax_func args Tatsuyuki Ishi
@ 2023-11-28  8:51   ` Tatsuyuki Ishi
  2023-12-05 16:44   ` [PATCH v3 0/9] RISC-V: Implement TLS Descriptors Tatsuyuki Ishi
  9 siblings, 0 replies; 49+ messages in thread
From: Tatsuyuki Ishi @ 2023-11-28  8:51 UTC (permalink / raw)
  To: binutils; +Cc: i, nelson, rui314, ruiu, Tatsuyuki Ishi

For now, only the 2 instruction (long) forms. This allows static binaries
to correctly execute when TLSDESC is used.

bfd/
	* elfnn-riscv.c (riscv_elf_tls_type_from_hi_reloc): Decide TLS type
	based on relaxation eligibility as well.
	(riscv_elf_check_relocs): Pass the required eligibility information to
	riscv_elf_tls_type_from_hi_reloc.
	(perform_relocation): Handle encoding for TLSDESC relaxation
	relocations.
	(riscv_elf_relocate_section): Emit relaxation instruction sequence.
	(_bfd_riscv_relax_tlsdesc): Added for handling of relaxable TLSDESC
	relocs.
	(_bfd_riscv_relax_section): Call _bfd_riscv_relax_tlsdesc when
	eligible.
	* elfxx-riscv.c (howto_table_internal): Add internal relocations
	for TLSDESC -> LE / IE relaxation.
include/
	elf/riscv.h: Add internal relocations, same as above.
	opcode/riscv.h: Add X_A0 for use in TLSDESC relaxation sequence.
ld/
	* testsuite/ld-riscv-elf/tlsbin.d: Remove TLSDESC relocs from
	expectation to now that we have relaxation.
---
 bfd/elfnn-riscv.c                  | 146 ++++++++++++++++++++++++++++-
 bfd/elfxx-riscv.c                  |  55 +++++++++++
 include/elf/riscv.h                |  16 ++--
 include/opcode/riscv.h             |   1 +
 ld/testsuite/ld-riscv-elf/tlsbin.d |   5 -
 5 files changed, 209 insertions(+), 14 deletions(-)

diff --git a/bfd/elfnn-riscv.c b/bfd/elfnn-riscv.c
index b98264319d8..61bfa763799 100644
--- a/bfd/elfnn-riscv.c
+++ b/bfd/elfnn-riscv.c
@@ -663,8 +663,12 @@ riscv_elf_copy_indirect_symbol (struct bfd_link_info *info,
 }
 
 static char
-riscv_elf_tls_type_from_hi_reloc (unsigned int r_type)
+riscv_elf_tls_type_from_hi_reloc (struct bfd_link_info *info,
+				  unsigned int r_type,
+				  struct elf_link_hash_entry *h,
+				  bool can_relax)
 {
+  bool local_exec = SYMBOL_REFERENCES_LOCAL (info, h);
   switch (r_type)
     {
       case R_RISCV_TLS_GD_HI20:
@@ -672,7 +676,10 @@ riscv_elf_tls_type_from_hi_reloc (unsigned int r_type)
       case R_RISCV_TLS_GOT_HI20:
 	return GOT_TLS_IE;
       case R_RISCV_TLSDESC_HI20:
-	return GOT_TLSDESC;
+	if (!can_relax || !bfd_link_executable (info))
+	  return GOT_TLSDESC;
+	else
+	  return local_exec ? GOT_TLS_LE : GOT_TLS_IE;
       case R_RISCV_TPREL_HI20:
 	return GOT_TLS_LE;
       default:
@@ -866,7 +873,10 @@ riscv_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
 	  case R_RISCV_TLSDESC_HI20:
 	  case R_RISCV_TPREL_HI20:
 	    {
-	      char tls_type = riscv_elf_tls_type_from_hi_reloc (r_type);
+	      bool can_relax = rel != relocs + sec->reloc_count - 1
+			       && ELFNN_R_TYPE ((rel + 1)->r_info) == R_RISCV_RELAX
+			       && rel->r_offset == (rel + 1)->r_offset;
+	      char tls_type = riscv_elf_tls_type_from_hi_reloc (info, r_type, h, can_relax);
 
 	      /* Local exec is only allowed for executables.  */
 	      if (tls_type == GOT_TLS_LE && !bfd_link_executable (info))
@@ -1826,6 +1836,8 @@ perform_relocation (const reloc_howto_type *howto,
     case R_RISCV_TLS_GOT_HI20:
     case R_RISCV_TLS_GD_HI20:
     case R_RISCV_TLSDESC_HI20:
+    case R_RISCV_TLSDESC_LE_HI:
+    case R_RISCV_TLSDESC_IE_HI:
       if (ARCH_SIZE > 32 && !VALID_UTYPE_IMM (RISCV_CONST_HIGH_PART (value)))
 	return bfd_reloc_overflow;
       value = ENCODE_UTYPE_IMM (RISCV_CONST_HIGH_PART (value));
@@ -1838,6 +1850,8 @@ perform_relocation (const reloc_howto_type *howto,
     case R_RISCV_PCREL_LO12_I:
     case R_RISCV_TLSDESC_LOAD_LO12:
     case R_RISCV_TLSDESC_ADD_LO12:
+    case R_RISCV_TLSDESC_LE_LO:
+    case R_RISCV_TLSDESC_IE_LO:
       value = ENCODE_ITYPE_IMM (value);
       break;
 
@@ -2818,6 +2832,35 @@ riscv_elf_relocate_section (bfd *output_bfd,
 	    r = bfd_reloc_overflow;
 	  break;
 
+	case R_RISCV_TLSDESC_IE_HI:
+	  {
+	    bfd_vma insn = MATCH_AUIPC | (X_A0 << OP_SH_RD);
+	    relocation = dtpoff (info, relocation);
+	    bfd_putl32 (insn, contents + rel->r_offset);
+	    break;
+	  }
+	case R_RISCV_TLSDESC_IE_LO:
+	  {
+	    bfd_vma insn = MATCH_LREG | (X_A0 << OP_SH_RD) | (X_A0 << OP_SH_RS1);
+	    relocation = dtpoff (info, relocation);
+	    bfd_putl32 (insn, contents + rel->r_offset);
+	    break;
+	  }
+	case R_RISCV_TLSDESC_LE_HI:
+	  {
+	    bfd_vma insn = MATCH_LUI | (X_A0 << OP_SH_RD);
+	    relocation = tpoff (info, relocation);
+	    bfd_putl32 (insn, contents + rel->r_offset);
+	    break;
+	  }
+	case R_RISCV_TLSDESC_LE_LO:
+	  {
+	    bfd_vma insn = MATCH_ADDI | (X_A0 << OP_SH_RD) | (X_A0 << OP_SH_RS1);
+	    relocation = tpoff (info, relocation);
+	    bfd_putl32 (insn, contents + rel->r_offset);
+	    break;
+	  }
+
 	case R_RISCV_GPREL_I:
 	case R_RISCV_GPREL_S:
 	  {
@@ -4855,6 +4898,97 @@ _bfd_riscv_relax_tls_le (bfd *abfd,
     }
 }
 
+/* Relax TLSDESC (global-dynamic) references to TLS IE or LE references. */
+
+static bool
+_bfd_riscv_relax_tlsdesc (bfd *abfd,
+			  asection *sec,
+			  asection *sym_sec,
+			  struct bfd_link_info *link_info,
+			  struct elf_link_hash_entry *h,
+			  Elf_Internal_Rela *rel,
+			  bfd_vma symval,
+			  bfd_vma max_alignment ATTRIBUTE_UNUSED,
+			  bfd_vma reserve_size ATTRIBUTE_UNUSED,
+			  bool *again,
+			  riscv_pcgp_relocs *pcgp_relocs,
+			  bool undefined_weak)
+{
+  BFD_ASSERT (rel->r_offset + 4 <= sec->size);
+  BFD_ASSERT (bfd_link_executable (link_info));
+  riscv_pcgp_hi_reloc *hi = NULL;
+  bool local_exec;
+  unsigned sym;
+
+  /* Chain the _LO relocs to their corresponding _HI reloc to compute the
+     actual target address.  */
+  switch (ELFNN_R_TYPE (rel->r_info)) {
+    case R_RISCV_TLSDESC_HI20: {
+      /* If the corresponding lo relocation has already been seen then it's not
+	 safe to relax this relocation.  */
+      if (riscv_find_pcgp_lo_reloc (pcgp_relocs, rel->r_offset))
+	return true;
+      riscv_record_pcgp_hi_reloc (pcgp_relocs,
+				  rel->r_offset,
+				  rel->r_addend,
+				  symval,
+				  ELFNN_R_SYM (rel->r_info),
+				  sym_sec,
+				  h,
+				  undefined_weak);
+      sym = ELFNN_R_SYM (rel->r_info);
+      break;
+    }
+
+    case R_RISCV_TLSDESC_LOAD_LO12:
+    case R_RISCV_TLSDESC_ADD_LO12:
+    case R_RISCV_TLSDESC_CALL: {
+      /* _LO addends are not allowed in the psABI, but handle them similarly to
+	 PC_LO for now.  */
+      bfd_vma hi_sec_off = symval - sec_addr (sym_sec) - rel->r_addend;
+      hi = riscv_find_pcgp_hi_reloc (pcgp_relocs, hi_sec_off);
+      if (hi == NULL) {
+	riscv_record_pcgp_lo_reloc (pcgp_relocs, hi_sec_off);
+	return true;
+      }
+      sym = hi->hi_sym;
+      symval = hi->hi_addr;
+      sym_sec = hi->sym_sec;
+      h = hi->h;
+      break;
+    }
+    default:
+      abort ();
+  }
+
+  local_exec = SYMBOL_REFERENCES_LOCAL (link_info, h);
+
+  switch (ELFNN_R_TYPE (rel->r_info)) {
+    case R_RISCV_TLSDESC_HI20:
+      *again = true;
+      riscv_relax_delete_bytes (abfd, sec, rel->r_offset, 4, link_info,
+				pcgp_relocs, rel);
+      break;
+    case R_RISCV_TLSDESC_LOAD_LO12:
+      riscv_relax_delete_bytes (abfd, sec, rel->r_offset, 4, link_info,
+				pcgp_relocs, rel);
+      break;
+    case R_RISCV_TLSDESC_ADD_LO12:
+      rel->r_info = ELFNN_R_INFO (sym, local_exec ? R_RISCV_TLSDESC_LE_HI : R_RISCV_TLSDESC_IE_HI);
+      rel->r_addend += hi->hi_addend;
+      break;
+    case R_RISCV_TLSDESC_CALL:
+      rel->r_info = ELFNN_R_INFO (sym, local_exec ? R_RISCV_TLSDESC_LE_LO : R_RISCV_TLSDESC_IE_LO);
+      rel->r_addend += hi->hi_addend;
+      break;
+    default:
+      abort ();
+  }
+
+  return true;
+}
+
+
 /* Implement R_RISCV_ALIGN by deleting excess alignment NOPs.
    Once we've handled an R_RISCV_ALIGN, we can't relax anything else.  */
 
@@ -5159,6 +5293,12 @@ _bfd_riscv_relax_section (bfd *abfd, asection *sec,
 		   || type == R_RISCV_TPREL_LO12_I
 		   || type == R_RISCV_TPREL_LO12_S)
 	    relax_func = _bfd_riscv_relax_tls_le;
+	  else if (bfd_link_executable (info)
+		   && (type == R_RISCV_TLSDESC_HI20
+		       || type == R_RISCV_TLSDESC_LOAD_LO12
+		       || type == R_RISCV_TLSDESC_ADD_LO12
+		       || type == R_RISCV_TLSDESC_CALL))
+	    relax_func = _bfd_riscv_relax_tlsdesc;
 	  else if (!bfd_link_pic (info)
 		   && (type == R_RISCV_PCREL_HI20
 		       || type == R_RISCV_PCREL_LO12_I
diff --git a/bfd/elfxx-riscv.c b/bfd/elfxx-riscv.c
index 65d676b06b1..dbca69a89d1 100644
--- a/bfd/elfxx-riscv.c
+++ b/bfd/elfxx-riscv.c
@@ -958,6 +958,61 @@ static reloc_howto_type howto_table_internal[] =
 	 0,				/* src_mask */
 	 ENCODE_STYPE_IMM (-1U),	/* dst_mask */
 	 false),			/* pcrel_offset */
+
+  /* TLSDESC relaxed to Initial Exec.  */
+  HOWTO (R_RISCV_TLSDESC_IE_HI,		/* type */
+	 0,				/* rightshift */
+	 4,				/* size */
+	 32,				/* bitsize */
+	 true,				/* pc_relative */
+	 0,				/* bitpos */
+	 complain_overflow_signed,	/* complain_on_overflow */
+	 bfd_elf_generic_reloc,		/* special_function */
+	 "R_RISCV_TLSDESC_IE_HI",	/* name */
+	 false,				/* partial_inplace */
+	 0,				/* src_mask */
+	 ENCODE_UTYPE_IMM (-1U),	/* dst_mask */
+	 false),			/* pcrel_offset */
+  HOWTO (R_RISCV_TLSDESC_IE_LO,		/* type */
+	 0,				/* rightshift */
+	 4,				/* size */
+	 32,				/* bitsize */
+	 true,				/* pc_relative */
+	 0,				/* bitpos */
+	 complain_overflow_signed,	/* complain_on_overflow */
+	 bfd_elf_generic_reloc,		/* special_function */
+	 "R_RISCV_TLSDESC_IE_LO",	/* name */
+	 false,				/* partial_inplace */
+	 0,				/* src_mask */
+	 ENCODE_ITYPE_IMM (-1U),	/* dst_mask */
+	 false),			/* pcrel_offset */
+  /* TLSDESC relaxed to Local Exec.  */
+  HOWTO (R_RISCV_TLSDESC_LE_HI,		/* type */
+	 0,				/* rightshift */
+	 4,				/* size */
+	 32,				/* bitsize */
+	 false,				/* pc_relative */
+	 0,				/* bitpos */
+	 complain_overflow_signed,	/* complain_on_overflow */
+	 bfd_elf_generic_reloc,		/* special_function */
+	 "R_RISCV_TLSDESC_LE_HI",	/* name */
+	 false,				/* partial_inplace */
+	 0,				/* src_mask */
+	 ENCODE_UTYPE_IMM (-1U),	/* dst_mask */
+	 false),			/* pcrel_offset */
+  HOWTO (R_RISCV_TLSDESC_LE_LO,		/* type */
+	 0,				/* rightshift */
+	 4,				/* size */
+	 32,				/* bitsize */
+	 false,				/* pc_relative */
+	 0,				/* bitpos */
+	 complain_overflow_signed,	/* complain_on_overflow */
+	 bfd_elf_generic_reloc,		/* special_function */
+	 "R_RISCV_TLSDESC_LE_LO",	/* name */
+	 false,				/* partial_inplace */
+	 0,				/* src_mask */
+	 ENCODE_ITYPE_IMM (-1U),	/* dst_mask */
+	 false),			/* pcrel_offset */
 };
 
 /* A mapping from BFD reloc types to RISC-V ELF reloc types.  */
diff --git a/include/elf/riscv.h b/include/elf/riscv.h
index 7f5c0407ac8..903c7645d68 100644
--- a/include/elf/riscv.h
+++ b/include/elf/riscv.h
@@ -98,12 +98,16 @@ START_RELOC_NUMBERS (elf_riscv_reloc_type)
 END_RELOC_NUMBERS (R_RISCV_max)
 
 /* Internal relocations used exclusively by the relaxation pass.  */
-#define R_RISCV_DELETE  (R_RISCV_max)
-#define R_RISCV_RVC_LUI (R_RISCV_max + 1)
-#define R_RISCV_GPREL_I (R_RISCV_max + 2)
-#define R_RISCV_GPREL_S (R_RISCV_max + 3)
-#define R_RISCV_TPREL_I (R_RISCV_max + 4)
-#define R_RISCV_TPREL_S (R_RISCV_max + 5)
+#define R_RISCV_DELETE		(R_RISCV_max)
+#define R_RISCV_RVC_LUI		(R_RISCV_max + 1)
+#define R_RISCV_GPREL_I		(R_RISCV_max + 2)
+#define R_RISCV_GPREL_S		(R_RISCV_max + 3)
+#define R_RISCV_TPREL_I		(R_RISCV_max + 4)
+#define R_RISCV_TPREL_S		(R_RISCV_max + 5)
+#define R_RISCV_TLSDESC_IE_HI	(R_RISCV_max + 6)
+#define R_RISCV_TLSDESC_IE_LO	(R_RISCV_max + 7)
+#define R_RISCV_TLSDESC_LE_HI	(R_RISCV_max + 8)
+#define R_RISCV_TLSDESC_LE_LO	(R_RISCV_max + 9)
 
 /* Processor specific flags for the ELF header e_flags field.  */
 
diff --git a/include/opcode/riscv.h b/include/opcode/riscv.h
index 25486869606..e60e1ba9502 100644
--- a/include/opcode/riscv.h
+++ b/include/opcode/riscv.h
@@ -340,6 +340,7 @@ static inline unsigned int riscv_insn_length (insn_t insn)
 #define X_T0 5
 #define X_T1 6
 #define X_T2 7
+#define X_A0 10
 #define X_T3 28
 
 #define NGPR 32
diff --git a/ld/testsuite/ld-riscv-elf/tlsbin.d b/ld/testsuite/ld-riscv-elf/tlsbin.d
index 79b7ade405e..cdcd51a9199 100644
--- a/ld/testsuite/ld-riscv-elf/tlsbin.d
+++ b/ld/testsuite/ld-riscv-elf/tlsbin.d
@@ -2,11 +2,6 @@
 #ld: -no-pie tmpdir/tlslib.so
 #readelf: -Wr
 
-Relocation section '.rela.dyn' at offset 0x[0-9a-f]+ contains 2 entries:
- +Offset +Info +Type +Symbol's Value +Symbol's Name \+ Addend
-[0-9a-f]+ +[0-9a-f]+ R_RISCV_TLSDESC +4
-[0-9a-f]+ +[0-9a-f]+ R_RISCV_TLSDESC +0
-
 Relocation section '.rela.plt' at offset 0x[0-9a-f]+ contains 1 entry:
  +Offset +Info +Type +Symbol's Value +Symbol's Name \+ Addend
 [0-9a-f]+ +[0-9a-f]+ R_RISCV_JUMP_SLOT +[0-9a-f]+ __tls_get_addr \+ 0
-- 
2.43.0


^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [PATCH v3 0/9] RISC-V: Implement TLS Descriptors.
  2023-11-28  8:51 ` [PATCH v3 0/9] RISC-V: Implement TLS Descriptors Tatsuyuki Ishi
                     ` (8 preceding siblings ...)
  2023-11-28  8:51   ` [PATCH v3 9/9] RISC-V: Introduce TLSDESC relaxation Tatsuyuki Ishi
@ 2023-12-05 16:44   ` Tatsuyuki Ishi
  2023-12-06  0:33     ` Nelson Chu
  9 siblings, 1 reply; 49+ messages in thread
From: Tatsuyuki Ishi @ 2023-12-05 16:44 UTC (permalink / raw)
  To: binutils; +Cc: i, nelson, Rui Ueyama, Rui Ueyama

> On Nov 28, 2023, at 17:51, Tatsuyuki Ishi <ishitatsuyuki@gmail.com> wrote:
> 
> This patchset implements TLS Descriptors (TLSDESC) for RISC-V targets, per
> the specification (merged) at [1].
> 
> Tested on rv64gc for:
> - No regression (& passing new tests) in binutils
> - No regression in gcc
> - No regression in glibc for subdirs=elf
> With both -mtls-dialect=desc and trad.
> 
> This contribution is made on behalf of Blue Whale Systems, which has
> copyright assignment on file with the FSF.
> 
> [1]: https://github.com/riscv-non-isa/riscv-elf-psabi-doc/pull/373
> 
> v2: Add changelogs and tests. Minor fixes described in patch messages.
> v3: Add relaxation support. This fixes tst-tls1-static in glibc.

Would anyone like to review this?  This is a prerequisite for the GCC-side
implementation to be useful (especially the gas part).

I can split up the series into bug fix / refactors and actual changes if
desired.

> Tatsuyuki Ishi (9):
>  RISC-V: Fix local GOT and reloc size calculation for TLS.
>  RISC-V: Add TLSDESC reloc definitions.
>  RISC-V: Add assembly support for TLSDESC.
>  RISC-V: Define and use GOT entry size constants for TLS.
>  RISC-V: Initial ld.bfd support for TLSDESC.
>  RISC-V: Move STATIC_TLS handling into record_tls_type.
>  RISC-V: Unify TLS handling in check_relocs.
>  RISC-V: Add elf_link_hash_entry to relax_func args.
>  RISC-V: Introduce TLSDESC relaxation.
> 
> bfd/bfd-in2.h                              |   4 +
> bfd/elfnn-riscv.c                          | 341 ++++++++++++++++++---
> bfd/elfxx-riscv.c                          | 130 +++++++-
> bfd/libbfd.h                               |   4 +
> bfd/reloc.c                                |   8 +
> gas/config/tc-riscv.c                      |  18 +-
> gas/testsuite/gas/riscv/tlsdesc.d          |  22 ++
> gas/testsuite/gas/riscv/tlsdesc.s          |  24 ++
> include/elf/riscv.h                        |  21 +-
> include/opcode/riscv.h                     |   1 +
> ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp |   8 +
> ld/testsuite/ld-riscv-elf/tls.d            |  17 +
> ld/testsuite/ld-riscv-elf/tls.s            |  42 +++
> ld/testsuite/ld-riscv-elf/tlsbin.d         |   7 +
> ld/testsuite/ld-riscv-elf/tlslib.s         |   6 +
> opcodes/riscv-opc.c                        |   1 +
> 16 files changed, 601 insertions(+), 53 deletions(-)
> create mode 100644 gas/testsuite/gas/riscv/tlsdesc.d
> create mode 100644 gas/testsuite/gas/riscv/tlsdesc.s
> create mode 100644 ld/testsuite/ld-riscv-elf/tls.d
> create mode 100644 ld/testsuite/ld-riscv-elf/tls.s
> create mode 100644 ld/testsuite/ld-riscv-elf/tlsbin.d
> create mode 100644 ld/testsuite/ld-riscv-elf/tlslib.s
> 
> -- 
> 2.43.0
> 


^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [PATCH v3 0/9] RISC-V: Implement TLS Descriptors.
  2023-12-05 16:44   ` [PATCH v3 0/9] RISC-V: Implement TLS Descriptors Tatsuyuki Ishi
@ 2023-12-06  0:33     ` Nelson Chu
  2023-12-07  3:35       ` Fangrui Song
  0 siblings, 1 reply; 49+ messages in thread
From: Nelson Chu @ 2023-12-06  0:33 UTC (permalink / raw)
  To: Tatsuyuki Ishi; +Cc: binutils, i, Rui Ueyama, Rui Ueyama

[-- Attachment #1: Type: text/plain, Size: 3512 bytes --]

Sorry that I don't familiar with the TLS stuff and TLS descriptor, so I
will need more time to figure these out if other maintainers are all busy.
Since there are other patches which are also being reviewed, if someone
thinks this is an urgent matter, please feel free to let us know, so we can
switch to see these first.

On Wed, Dec 6, 2023 at 12:44 AM Tatsuyuki Ishi <ishitatsuyuki@gmail.com>
wrote:

> > On Nov 28, 2023, at 17:51, Tatsuyuki Ishi <ishitatsuyuki@gmail.com>
> wrote:
> >
> > This patchset implements TLS Descriptors (TLSDESC) for RISC-V targets,
> per
> > the specification (merged) at [1].
> >
> > Tested on rv64gc for:
> > - No regression (& passing new tests) in binutils
> > - No regression in gcc
> > - No regression in glibc for subdirs=elf
> > With both -mtls-dialect=desc and trad.
> >
> > This contribution is made on behalf of Blue Whale Systems, which has
> > copyright assignment on file with the FSF.
> >
> > [1]: https://github.com/riscv-non-isa/riscv-elf-psabi-doc/pull/373
> >
> > v2: Add changelogs and tests. Minor fixes described in patch messages.
> > v3: Add relaxation support. This fixes tst-tls1-static in glibc.
>
> Would anyone like to review this?  This is a prerequisite for the GCC-side
> implementation to be useful (especially the gas part).
>

 For these huge features, gcc/binutils/glibc should be reviewed at the same
time, since all the stuff should be bound and tested together, so
"prerequisite" shouldn't apply here ;)

Thanks
Nelson


>
> I can split up the series into bug fix / refactors and actual changes if
> desired.
>
> > Tatsuyuki Ishi (9):
> >  RISC-V: Fix local GOT and reloc size calculation for TLS.
> >  RISC-V: Add TLSDESC reloc definitions.
> >  RISC-V: Add assembly support for TLSDESC.
> >  RISC-V: Define and use GOT entry size constants for TLS.
> >  RISC-V: Initial ld.bfd support for TLSDESC.
> >  RISC-V: Move STATIC_TLS handling into record_tls_type.
> >  RISC-V: Unify TLS handling in check_relocs.
> >  RISC-V: Add elf_link_hash_entry to relax_func args.
> >  RISC-V: Introduce TLSDESC relaxation.
> >
> > bfd/bfd-in2.h                              |   4 +
> > bfd/elfnn-riscv.c                          | 341 ++++++++++++++++++---
> > bfd/elfxx-riscv.c                          | 130 +++++++-
> > bfd/libbfd.h                               |   4 +
> > bfd/reloc.c                                |   8 +
> > gas/config/tc-riscv.c                      |  18 +-
> > gas/testsuite/gas/riscv/tlsdesc.d          |  22 ++
> > gas/testsuite/gas/riscv/tlsdesc.s          |  24 ++
> > include/elf/riscv.h                        |  21 +-
> > include/opcode/riscv.h                     |   1 +
> > ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp |   8 +
> > ld/testsuite/ld-riscv-elf/tls.d            |  17 +
> > ld/testsuite/ld-riscv-elf/tls.s            |  42 +++
> > ld/testsuite/ld-riscv-elf/tlsbin.d         |   7 +
> > ld/testsuite/ld-riscv-elf/tlslib.s         |   6 +
> > opcodes/riscv-opc.c                        |   1 +
> > 16 files changed, 601 insertions(+), 53 deletions(-)
> > create mode 100644 gas/testsuite/gas/riscv/tlsdesc.d
> > create mode 100644 gas/testsuite/gas/riscv/tlsdesc.s
> > create mode 100644 ld/testsuite/ld-riscv-elf/tls.d
> > create mode 100644 ld/testsuite/ld-riscv-elf/tls.s
> > create mode 100644 ld/testsuite/ld-riscv-elf/tlsbin.d
> > create mode 100644 ld/testsuite/ld-riscv-elf/tlslib.s
> >
> > --
> > 2.43.0
> >
>
>

^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [PATCH v3 0/9] RISC-V: Implement TLS Descriptors.
  2023-12-06  0:33     ` Nelson Chu
@ 2023-12-07  3:35       ` Fangrui Song
  2023-12-13  0:27         ` Palmer Dabbelt
  0 siblings, 1 reply; 49+ messages in thread
From: Fangrui Song @ 2023-12-07  3:35 UTC (permalink / raw)
  To: Nelson Chu, lazyparser; +Cc: Tatsuyuki Ishi, binutils, Rui Ueyama, Rui Ueyama

On Tue, Dec 5, 2023 at 4:33 PM Nelson Chu <nelson@rivosinc.com> wrote:
>
> Sorry that I don't familiar with the TLS stuff and TLS descriptor, so I will need more time to figure these out if other maintainers are all busy.  Since there are other patches which are also being reviewed, if someone thinks this is an urgent matter, please feel free to let us know, so we can switch to see these first.

I know that Android wants TLSDESC and having TLSDESC in gcc/binutils
helps check LLVM feature parity...
If we have TLSDESC earlier, an OS with a new RISC-V port can make
TLSDESC part of the baseline ABI...

> On Wed, Dec 6, 2023 at 12:44 AM Tatsuyuki Ishi <ishitatsuyuki@gmail.com> wrote:
>>
>> > On Nov 28, 2023, at 17:51, Tatsuyuki Ishi <ishitatsuyuki@gmail.com> wrote:
>> >
>> > This patchset implements TLS Descriptors (TLSDESC) for RISC-V targets, per
>> > the specification (merged) at [1].
>> >
>> > Tested on rv64gc for:
>> > - No regression (& passing new tests) in binutils
>> > - No regression in gcc
>> > - No regression in glibc for subdirs=elf
>> > With both -mtls-dialect=desc and trad.
>> >
>> > This contribution is made on behalf of Blue Whale Systems, which has
>> > copyright assignment on file with the FSF.
>> >
>> > [1]: https://github.com/riscv-non-isa/riscv-elf-psabi-doc/pull/373
>> >
>> > v2: Add changelogs and tests. Minor fixes described in patch messages.
>> > v3: Add relaxation support. This fixes tst-tls1-static in glibc.
>>
>> Would anyone like to review this?  This is a prerequisite for the GCC-side
>> implementation to be useful (especially the gas part).
>
>
>  For these huge features, gcc/binutils/glibc should be reviewed at the same time, since all the stuff should be bound and tested together, so "prerequisite" shouldn't apply here ;)
>
> Thanks
> Nelson

Agreed. I wonder whether Wei can find someone to test
gcc/binutils/glibc patches... and some packages using TLS (e.g.
https://codesearch.debian.net/search?q=__thread&literal=1).

>>
>>
>> I can split up the series into bug fix / refactors and actual changes if
>> desired.
>>
>> > Tatsuyuki Ishi (9):
>> >  RISC-V: Fix local GOT and reloc size calculation for TLS.
>> >  RISC-V: Add TLSDESC reloc definitions.
>> >  RISC-V: Add assembly support for TLSDESC.
>> >  RISC-V: Define and use GOT entry size constants for TLS.
>> >  RISC-V: Initial ld.bfd support for TLSDESC.
>> >  RISC-V: Move STATIC_TLS handling into record_tls_type.
>> >  RISC-V: Unify TLS handling in check_relocs.
>> >  RISC-V: Add elf_link_hash_entry to relax_func args.
>> >  RISC-V: Introduce TLSDESC relaxation.
>> >
>> > bfd/bfd-in2.h                              |   4 +
>> > bfd/elfnn-riscv.c                          | 341 ++++++++++++++++++---
>> > bfd/elfxx-riscv.c                          | 130 +++++++-
>> > bfd/libbfd.h                               |   4 +
>> > bfd/reloc.c                                |   8 +
>> > gas/config/tc-riscv.c                      |  18 +-
>> > gas/testsuite/gas/riscv/tlsdesc.d          |  22 ++
>> > gas/testsuite/gas/riscv/tlsdesc.s          |  24 ++
>> > include/elf/riscv.h                        |  21 +-
>> > include/opcode/riscv.h                     |   1 +
>> > ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp |   8 +
>> > ld/testsuite/ld-riscv-elf/tls.d            |  17 +
>> > ld/testsuite/ld-riscv-elf/tls.s            |  42 +++
>> > ld/testsuite/ld-riscv-elf/tlsbin.d         |   7 +
>> > ld/testsuite/ld-riscv-elf/tlslib.s         |   6 +
>> > opcodes/riscv-opc.c                        |   1 +
>> > 16 files changed, 601 insertions(+), 53 deletions(-)
>> > create mode 100644 gas/testsuite/gas/riscv/tlsdesc.d
>> > create mode 100644 gas/testsuite/gas/riscv/tlsdesc.s
>> > create mode 100644 ld/testsuite/ld-riscv-elf/tls.d
>> > create mode 100644 ld/testsuite/ld-riscv-elf/tls.s
>> > create mode 100644 ld/testsuite/ld-riscv-elf/tlsbin.d
>> > create mode 100644 ld/testsuite/ld-riscv-elf/tlslib.s
>> >
>> > --
>> > 2.43.0
>> >
>>

^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [PATCH v3 0/9] RISC-V: Implement TLS Descriptors.
  2023-12-07  3:35       ` Fangrui Song
@ 2023-12-13  0:27         ` Palmer Dabbelt
  2023-12-13  1:53           ` Tatsuyuki Ishi
  0 siblings, 1 reply; 49+ messages in thread
From: Palmer Dabbelt @ 2023-12-13  0:27 UTC (permalink / raw)
  To: i; +Cc: nelson, lazyparser, ishitatsuyuki, binutils, rui314, ruiu

On Wed, 06 Dec 2023 19:35:00 PST (-0800), i@maskray.me wrote:
> On Tue, Dec 5, 2023 at 4:33 PM Nelson Chu <nelson@rivosinc.com> wrote:
>>
>> Sorry that I don't familiar with the TLS stuff and TLS descriptor, so I will need more time to figure these out if other maintainers are all busy.  Since there are other patches which are also being reviewed, if someone thinks this is an urgent matter, please feel free to let us know, so we can switch to see these first.
>
> I know that Android wants TLSDESC and having TLSDESC in gcc/binutils
> helps check LLVM feature parity...
> If we have TLSDESC earlier, an OS with a new RISC-V port can make
> TLSDESC part of the baseline ABI...
>
>> On Wed, Dec 6, 2023 at 12:44 AM Tatsuyuki Ishi <ishitatsuyuki@gmail.com> wrote:
>>>
>>> > On Nov 28, 2023, at 17:51, Tatsuyuki Ishi <ishitatsuyuki@gmail.com> wrote:
>>> >
>>> > This patchset implements TLS Descriptors (TLSDESC) for RISC-V targets, per
>>> > the specification (merged) at [1].
>>> >
>>> > Tested on rv64gc for:
>>> > - No regression (& passing new tests) in binutils
>>> > - No regression in gcc
>>> > - No regression in glibc for subdirs=elf
>>> > With both -mtls-dialect=desc and trad.
>>> >
>>> > This contribution is made on behalf of Blue Whale Systems, which has
>>> > copyright assignment on file with the FSF.
>>> >
>>> > [1]: https://github.com/riscv-non-isa/riscv-elf-psabi-doc/pull/373
>>> >
>>> > v2: Add changelogs and tests. Minor fixes described in patch messages.
>>> > v3: Add relaxation support. This fixes tst-tls1-static in glibc.
>>>
>>> Would anyone like to review this?  This is a prerequisite for the GCC-side
>>> implementation to be useful (especially the gas part).
>>
>>
>>  For these huge features, gcc/binutils/glibc should be reviewed at the same time, since all the stuff should be bound and tested together, so "prerequisite" shouldn't apply here ;)

Ya, I agree.  It's super hard to review stuff like this without seeing 
all the code, doubly so now that the psABI has turned into a wasteland 
for discussions.

>>
>> Thanks
>> Nelson
>
> Agreed. I wonder whether Wei can find someone to test
> gcc/binutils/glibc patches... and some packages using TLS (e.g.
> https://codesearch.debian.net/search?q=__thread&literal=1).

Do you guys have a pointer to the glibc code?  I can't find it, but I'm 
happy to poke it (or maybe find someone else who to poke it...).

>
>>>
>>>
>>> I can split up the series into bug fix / refactors and actual changes if
>>> desired.
>>>
>>> > Tatsuyuki Ishi (9):
>>> >  RISC-V: Fix local GOT and reloc size calculation for TLS.
>>> >  RISC-V: Add TLSDESC reloc definitions.
>>> >  RISC-V: Add assembly support for TLSDESC.
>>> >  RISC-V: Define and use GOT entry size constants for TLS.
>>> >  RISC-V: Initial ld.bfd support for TLSDESC.
>>> >  RISC-V: Move STATIC_TLS handling into record_tls_type.
>>> >  RISC-V: Unify TLS handling in check_relocs.
>>> >  RISC-V: Add elf_link_hash_entry to relax_func args.
>>> >  RISC-V: Introduce TLSDESC relaxation.
>>> >
>>> > bfd/bfd-in2.h                              |   4 +
>>> > bfd/elfnn-riscv.c                          | 341 ++++++++++++++++++---
>>> > bfd/elfxx-riscv.c                          | 130 +++++++-
>>> > bfd/libbfd.h                               |   4 +
>>> > bfd/reloc.c                                |   8 +
>>> > gas/config/tc-riscv.c                      |  18 +-
>>> > gas/testsuite/gas/riscv/tlsdesc.d          |  22 ++
>>> > gas/testsuite/gas/riscv/tlsdesc.s          |  24 ++
>>> > include/elf/riscv.h                        |  21 +-
>>> > include/opcode/riscv.h                     |   1 +
>>> > ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp |   8 +
>>> > ld/testsuite/ld-riscv-elf/tls.d            |  17 +
>>> > ld/testsuite/ld-riscv-elf/tls.s            |  42 +++
>>> > ld/testsuite/ld-riscv-elf/tlsbin.d         |   7 +
>>> > ld/testsuite/ld-riscv-elf/tlslib.s         |   6 +
>>> > opcodes/riscv-opc.c                        |   1 +
>>> > 16 files changed, 601 insertions(+), 53 deletions(-)
>>> > create mode 100644 gas/testsuite/gas/riscv/tlsdesc.d
>>> > create mode 100644 gas/testsuite/gas/riscv/tlsdesc.s
>>> > create mode 100644 ld/testsuite/ld-riscv-elf/tls.d
>>> > create mode 100644 ld/testsuite/ld-riscv-elf/tls.s
>>> > create mode 100644 ld/testsuite/ld-riscv-elf/tlsbin.d
>>> > create mode 100644 ld/testsuite/ld-riscv-elf/tlslib.s
>>> >
>>> > --
>>> > 2.43.0
>>> >
>>>

^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [PATCH v3 0/9] RISC-V: Implement TLS Descriptors.
  2023-12-13  0:27         ` Palmer Dabbelt
@ 2023-12-13  1:53           ` Tatsuyuki Ishi
  2024-01-27  0:57             ` Fangrui Song
  0 siblings, 1 reply; 49+ messages in thread
From: Tatsuyuki Ishi @ 2023-12-13  1:53 UTC (permalink / raw)
  To: Palmer Dabbelt; +Cc: i, nelson, lazyparser, binutils, Rui Ueyama, ruiu

[-- Attachment #1: Type: text/plain, Size: 5104 bytes --]

> On Dec 13, 2023, at 9:27, Palmer Dabbelt <palmer@dabbelt.com> wrote:
> 
> On Wed, 06 Dec 2023 19:35:00 PST (-0800), i@maskray.me wrote:
>> On Tue, Dec 5, 2023 at 4:33 PM Nelson Chu <nelson@rivosinc.com> wrote:
>>> 
>>> Sorry that I don't familiar with the TLS stuff and TLS descriptor, so I will need more time to figure these out if other maintainers are all busy.  Since there are other patches which are also being reviewed, if someone thinks this is an urgent matter, please feel free to let us know, so we can switch to see these first.
>> 
>> I know that Android wants TLSDESC and having TLSDESC in gcc/binutils
>> helps check LLVM feature parity...
>> If we have TLSDESC earlier, an OS with a new RISC-V port can make
>> TLSDESC part of the baseline ABI...
>> 
>>> On Wed, Dec 6, 2023 at 12:44 AM Tatsuyuki Ishi <ishitatsuyuki@gmail.com> wrote:
>>>> 
>>>> > On Nov 28, 2023, at 17:51, Tatsuyuki Ishi <ishitatsuyuki@gmail.com> wrote:
>>>> >
>>>> > This patchset implements TLS Descriptors (TLSDESC) for RISC-V targets, per
>>>> > the specification (merged) at [1].
>>>> >
>>>> > Tested on rv64gc for:
>>>> > - No regression (& passing new tests) in binutils
>>>> > - No regression in gcc
>>>> > - No regression in glibc for subdirs=elf
>>>> > With both -mtls-dialect=desc and trad.
>>>> >
>>>> > This contribution is made on behalf of Blue Whale Systems, which has
>>>> > copyright assignment on file with the FSF.
>>>> >
>>>> > [1]: https://github.com/riscv-non-isa/riscv-elf-psabi-doc/pull/373
>>>> >
>>>> > v2: Add changelogs and tests. Minor fixes described in patch messages.
>>>> > v3: Add relaxation support. This fixes tst-tls1-static in glibc.
>>>> 
>>>> Would anyone like to review this?  This is a prerequisite for the GCC-side
>>>> implementation to be useful (especially the gas part).
>>> 
>>> 
>>> For these huge features, gcc/binutils/glibc should be reviewed at the same time, since all the stuff should be bound and tested together, so "prerequisite" shouldn't apply here ;)
> 
> Ya, I agree.  It's super hard to review stuff like this without seeing all the code, doubly so now that the psABI has turned into a wasteland for discussions.
> 
>>> 
>>> Thanks
>>> Nelson
>> 
>> Agreed. I wonder whether Wei can find someone to test
>> gcc/binutils/glibc patches... and some packages using TLS (e.g.
>> https://codesearch.debian.net/search?q=__thread&literal=1).
> 
> Do you guys have a pointer to the glibc code?  I can't find it, but I'm happy to poke it (or maybe find someone else who to poke it...).

Hi,
The glibc and gcc patches are available at [1] and [2] respectively.
For glibc, I still need to implement save/restore stubs for vector ABI, but apart from that it should be functional.

[1]: https://inbox.sourceware.org/libc-alpha/20230914084033.222120-1-ishitatsuyuki@gmail.com/
[2]: https://inbox.sourceware.org/gcc-patches/20231205070152.38360-1-ishitatsuyuki@gmail.com/

Tatsuyuki.

>> 
>>>> 
>>>> 
>>>> I can split up the series into bug fix / refactors and actual changes if
>>>> desired.
>>>> 
>>>> > Tatsuyuki Ishi (9):
>>>> >  RISC-V: Fix local GOT and reloc size calculation for TLS.
>>>> >  RISC-V: Add TLSDESC reloc definitions.
>>>> >  RISC-V: Add assembly support for TLSDESC.
>>>> >  RISC-V: Define and use GOT entry size constants for TLS.
>>>> >  RISC-V: Initial ld.bfd support for TLSDESC.
>>>> >  RISC-V: Move STATIC_TLS handling into record_tls_type.
>>>> >  RISC-V: Unify TLS handling in check_relocs.
>>>> >  RISC-V: Add elf_link_hash_entry to relax_func args.
>>>> >  RISC-V: Introduce TLSDESC relaxation.
>>>> >
>>>> > bfd/bfd-in2.h                              |   4 +
>>>> > bfd/elfnn-riscv.c                          | 341 ++++++++++++++++++---
>>>> > bfd/elfxx-riscv.c                          | 130 +++++++-
>>>> > bfd/libbfd.h                               |   4 +
>>>> > bfd/reloc.c                                |   8 +
>>>> > gas/config/tc-riscv.c                      |  18 +-
>>>> > gas/testsuite/gas/riscv/tlsdesc.d          |  22 ++
>>>> > gas/testsuite/gas/riscv/tlsdesc.s          |  24 ++
>>>> > include/elf/riscv.h                        |  21 +-
>>>> > include/opcode/riscv.h                     |   1 +
>>>> > ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp |   8 +
>>>> > ld/testsuite/ld-riscv-elf/tls.d            |  17 +
>>>> > ld/testsuite/ld-riscv-elf/tls.s            |  42 +++
>>>> > ld/testsuite/ld-riscv-elf/tlsbin.d         |   7 +
>>>> > ld/testsuite/ld-riscv-elf/tlslib.s         |   6 +
>>>> > opcodes/riscv-opc.c                        |   1 +
>>>> > 16 files changed, 601 insertions(+), 53 deletions(-)
>>>> > create mode 100644 gas/testsuite/gas/riscv/tlsdesc.d
>>>> > create mode 100644 gas/testsuite/gas/riscv/tlsdesc.s
>>>> > create mode 100644 ld/testsuite/ld-riscv-elf/tls.d
>>>> > create mode 100644 ld/testsuite/ld-riscv-elf/tls.s
>>>> > create mode 100644 ld/testsuite/ld-riscv-elf/tlsbin.d
>>>> > create mode 100644 ld/testsuite/ld-riscv-elf/tlslib.s
>>>> >
>>>> > --
>>>> > 2.43.0
>>>> >
>>>> 


^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [PATCH v3 0/9] RISC-V: Implement TLS Descriptors.
  2023-12-13  1:53           ` Tatsuyuki Ishi
@ 2024-01-27  0:57             ` Fangrui Song
  0 siblings, 0 replies; 49+ messages in thread
From: Fangrui Song @ 2024-01-27  0:57 UTC (permalink / raw)
  To: Tatsuyuki Ishi
  Cc: Palmer Dabbelt, nelson, binutils, Rui Ueyama, ruiu, lazyparser

On Tue, Dec 12, 2023 at 5:53 PM Tatsuyuki Ishi <ishitatsuyuki@gmail.com> wrote:
>
> On Dec 13, 2023, at 9:27, Palmer Dabbelt <palmer@dabbelt.com> wrote:
>
> On Wed, 06 Dec 2023 19:35:00 PST (-0800), i@maskray.me wrote:
>
> On Tue, Dec 5, 2023 at 4:33 PM Nelson Chu <nelson@rivosinc.com> wrote:
>
>
> Sorry that I don't familiar with the TLS stuff and TLS descriptor, so I will need more time to figure these out if other maintainers are all busy.  Since there are other patches which are also being reviewed, if someone thinks this is an urgent matter, please feel free to let us know, so we can switch to see these first.
>
>
> I know that Android wants TLSDESC and having TLSDESC in gcc/binutils
> helps check LLVM feature parity...
> If we have TLSDESC earlier, an OS with a new RISC-V port can make
> TLSDESC part of the baseline ABI...
>
> On Wed, Dec 6, 2023 at 12:44 AM Tatsuyuki Ishi <ishitatsuyuki@gmail.com> wrote:
>
>
> > On Nov 28, 2023, at 17:51, Tatsuyuki Ishi <ishitatsuyuki@gmail.com> wrote:
> >
> > This patchset implements TLS Descriptors (TLSDESC) for RISC-V targets, per
> > the specification (merged) at [1].
> >
> > Tested on rv64gc for:
> > - No regression (& passing new tests) in binutils
> > - No regression in gcc
> > - No regression in glibc for subdirs=elf
> > With both -mtls-dialect=desc and trad.
> >
> > This contribution is made on behalf of Blue Whale Systems, which has
> > copyright assignment on file with the FSF.
> >
> > [1]: https://github.com/riscv-non-isa/riscv-elf-psabi-doc/pull/373
> >
> > v2: Add changelogs and tests. Minor fixes described in patch messages.
> > v3: Add relaxation support. This fixes tst-tls1-static in glibc.
>
> Would anyone like to review this?  This is a prerequisite for the GCC-side
> implementation to be useful (especially the gas part).
>
>
>
> For these huge features, gcc/binutils/glibc should be reviewed at the same time, since all the stuff should be bound and tested together, so "prerequisite" shouldn't apply here ;)
>
>
> Ya, I agree.  It's super hard to review stuff like this without seeing all the code, doubly so now that the psABI has turned into a wasteland for discussions.
>
>
> Thanks
> Nelson
>
>
> Agreed. I wonder whether Wei can find someone to test
> gcc/binutils/glibc patches... and some packages using TLS (e.g.
> https://codesearch.debian.net/search?q=__thread&literal=1).
>
>
> Do you guys have a pointer to the glibc code?  I can't find it, but I'm happy to poke it (or maybe find someone else who to poke it...).
>
>
> Hi,
> The glibc and gcc patches are available at [1] and [2] respectively.
> For glibc, I still need to implement save/restore stubs for vector ABI, but apart from that it should be functional.
>
> [1]: https://inbox.sourceware.org/libc-alpha/20230914084033.222120-1-ishitatsuyuki@gmail.com/
> [2]: https://inbox.sourceware.org/gcc-patches/20231205070152.38360-1-ishitatsuyuki@gmail.com/
>
> Tatsuyuki.
>
>
>
>
> I can split up the series into bug fix / refactors and actual changes if
> desired.

On the LLVM side, the RISC-V TLSDESC work (LLVM, Clang, lld) has been
completed today.
(I will frequently update
https://maskray.me/blog/2024-01-23-riscv-tlsdesc-works to track the
status.)
I filed cherry-pick requests into the upcoming 18.1 release.

We postponed the LLVM change to add R_RISCV_RELAX when relaxation is
in effect. That one will not go to the 18.x releases for safety.

If the gas patch is to add one R_RISCV_RELAX to each of the 4 instructions.
Perhaps it can be adjusted to add just one per
https://github.com/riscv-non-isa/riscv-elf-psabi-doc/pull/421 ?

I haven't checked, but for the ld patch, you probably want to consider
TLSDESC to LE/IE optimization regardless of R_RISCV_RELAX.
TLSDESC to LE optimization is essential if a libc doesn't implement
R_RISCV_TLSDESC in its resolocation resolver for a statically linkeded
executable.

It seems that musl will merge the RISC-V TLSDESC patch soon
(https://www.openwall.com/lists/musl/2024/01/27/1 , CCed Tatsuyuki
there).
So even if glibc will take some time to be ready, we will still have a
testable libc :)

^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [PATCH v3 2/9] RISC-V: Add TLSDESC reloc definitions.
  2023-11-28  8:51   ` [PATCH v3 2/9] RISC-V: Add TLSDESC reloc definitions Tatsuyuki Ishi
@ 2024-02-19  0:49     ` Nelson Chu
  2024-02-20 17:28       ` Tatsuyuki Ishi
  0 siblings, 1 reply; 49+ messages in thread
From: Nelson Chu @ 2024-02-19  0:49 UTC (permalink / raw)
  To: Tatsuyuki Ishi; +Cc: binutils, i, rui314, ruiu

[-- Attachment #1: Type: text/plain, Size: 8648 bytes --]

On Tue, Nov 28, 2023 at 4:51 PM Tatsuyuki Ishi <ishitatsuyuki@gmail.com>
wrote:

> bfd/
>     * elfxx-riscv.c: Add 5 TLSDESC reloc descriptions.
>     * reloc.c: Likewise.
>     * libbfd.h: Regenerate.
>     * bfd-in2.h: Regenerate.
> include/
>     * elf/riscv.h: Add 5 TLSDESC reloc descriptions.
> ---
>  bfd/bfd-in2.h       |  4 +++
>  bfd/elfxx-riscv.c   | 75 ++++++++++++++++++++++++++++++++++++++++++++-
>  bfd/libbfd.h        |  4 +++
>  bfd/reloc.c         |  8 +++++
>  include/elf/riscv.h |  5 +++
>  5 files changed, 95 insertions(+), 1 deletion(-)
>
> diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h
> index 040d5560cdf..9bc6b9885ff 100644
> --- a/bfd/bfd-in2.h
> +++ b/bfd/bfd-in2.h
> @@ -5407,6 +5407,10 @@ enum bfd_reloc_code_real
>    BFD_RELOC_RISCV_TLS_DTPREL64,
>    BFD_RELOC_RISCV_TLS_TPREL32,
>    BFD_RELOC_RISCV_TLS_TPREL64,
> +  BFD_RELOC_RISCV_TLSDESC_HI20,
> +  BFD_RELOC_RISCV_TLSDESC_LOAD_LO12,
> +  BFD_RELOC_RISCV_TLSDESC_ADD_LO12,
> +  BFD_RELOC_RISCV_TLSDESC_CALL,
>    BFD_RELOC_RISCV_ALIGN,
>    BFD_RELOC_RISCV_RVC_BRANCH,
>    BFD_RELOC_RISCV_RVC_JUMP,
> diff --git a/bfd/elfxx-riscv.c b/bfd/elfxx-riscv.c
> index 567631e7d96..65d676b06b1 100644
> --- a/bfd/elfxx-riscv.c
> +++ b/bfd/elfxx-riscv.c
> @@ -218,7 +218,20 @@ static reloc_howto_type howto_table[] =
>          MINUS_ONE,                     /* dst_mask */
>          false),                        /* pcrel_offset */
>
> -  EMPTY_HOWTO (12),
> +  HOWTO (R_RISCV_TLSDESC,              /* type */
> +        0,                             /* rightshift */
> +        0,                             /* size is handled by dynamic
> linker */
> +        0,                             /* bitsize */
> +        false,                         /* pc_relative */
> +        0,                             /* bitpos */
> +        complain_overflow_dont,        /* complain_on_overflow */
> +        bfd_elf_generic_reloc,         /* special_function */
> +        "R_RISCV_TLSDESC",             /* name */
> +        false,                         /* partial_inplace */
> +        0,                             /* src_mask */
> +        MINUS_ONE,                     /* dst_mask */
> +        false),                        /* pcrel_offset */
> +
>    EMPTY_HOWTO (13),
>    EMPTY_HOWTO (14),
>    EMPTY_HOWTO (15),
> @@ -808,6 +821,62 @@ static reloc_howto_type howto_table[] =
>          0,                             /* src_mask */
>          0,                             /* dst_mask */
>          false),                        /* pcrel_offset */
> +
> +  HOWTO (R_RISCV_TLSDESC_HI20,         /* type */
> +        0,                             /* rightshift */
> +        4,                             /* size */
> +        32,                            /* bitsize */
> +        true,                          /* pc_relative */
> +        0,                             /* bitpos */
> +        complain_overflow_signed,      /* complain_on_overflow */
> +        bfd_elf_generic_reloc,         /* special_function */
> +        "R_RISCV_TLSDESC_HI20",        /* name */
> +        true,                          /* partial_inplace */
> +        0,                             /* src_mask */
> +        ENCODE_UTYPE_IMM (-1U),        /* dst_mask */
> +        false),                        /* pcrel_offset */
>

complain_overflow_dont?


> +  HOWTO (R_RISCV_TLSDESC_LOAD_LO12,    /* type */
> +        0,                             /* rightshift */
> +        4,                             /* size */
> +        32,                            /* bitsize */
> +        false,                         /* pc_relative */
> +        0,                             /* bitpos */
> +        complain_overflow_signed,      /* complain_on_overflow */
> +        bfd_elf_generic_reloc,         /* special_function */
> +        "R_RISCV_TLSDESC_LOAD_LO12",   /* name */
> +        false,                         /* partial_inplace */
> +        0,                             /* src_mask */
> +        ENCODE_ITYPE_IMM (-1U),        /* dst_mask */
> +        false),                        /* pcrel_offset */
>

Likewise.


> +  HOWTO (R_RISCV_TLSDESC_ADD_LO12,     /* type */
> +        0,                             /* rightshift */
> +        4,                             /* size */
> +        32,                            /* bitsize */
> +        false,                         /* pc_relative */
> +        0,                             /* bitpos */
> +        complain_overflow_signed,      /* complain_on_overflow */
> +        bfd_elf_generic_reloc,         /* special_function */
> +        "R_RISCV_TLSDESC_ADD_LO12",    /* name */
> +        false,                         /* partial_inplace */
> +        0,                             /* src_mask */
> +        ENCODE_ITYPE_IMM (-1U),        /* dst_mask */
> +        false),                        /* pcrel_offset */
>

Likewise.


> +  HOWTO (R_RISCV_TLSDESC_CALL,         /* type */
> +        0,                             /* rightshift */
> +        0,                             /* size */
> +        0,                             /* bitsize */
> +        false,                         /* pc_relative */
> +        0,                             /* bitpos */
> +        complain_overflow_dont,        /* complain_on_overflow */
> +        bfd_elf_generic_reloc,         /* special_function */
> +        "R_RISCV_TLSDESC_CALL",        /* name */
> +        false,                         /* partial_inplace */
> +        0,                             /* src_mask */
> +        ENCODE_ITYPE_IMM (-1U),        /* dst_mask */
> +        false)                         /* pcrel_offset */
>  };
>
>  static reloc_howto_type howto_table_internal[] =
> @@ -935,6 +1004,10 @@ static const struct elf_reloc_map riscv_reloc_map[] =
>    { BFD_RELOC_RISCV_TPREL_LO12_I, R_RISCV_TPREL_LO12_I },
>    { BFD_RELOC_RISCV_TLS_GOT_HI20, R_RISCV_TLS_GOT_HI20 },
>    { BFD_RELOC_RISCV_TLS_GD_HI20, R_RISCV_TLS_GD_HI20 },
> +  { BFD_RELOC_RISCV_TLSDESC_HI20, R_RISCV_TLSDESC_HI20 },
> +  { BFD_RELOC_RISCV_TLSDESC_LOAD_LO12, R_RISCV_TLSDESC_LOAD_LO12 },
> +  { BFD_RELOC_RISCV_TLSDESC_ADD_LO12, R_RISCV_TLSDESC_ADD_LO12 },
> +  { BFD_RELOC_RISCV_TLSDESC_CALL, R_RISCV_TLSDESC_CALL },
>    { BFD_RELOC_RISCV_ALIGN, R_RISCV_ALIGN },
>    { BFD_RELOC_RISCV_RVC_BRANCH, R_RISCV_RVC_BRANCH },
>    { BFD_RELOC_RISCV_RVC_JUMP, R_RISCV_RVC_JUMP },
> diff --git a/bfd/libbfd.h b/bfd/libbfd.h
> index cc432677a81..919b63d51a1 100644
> --- a/bfd/libbfd.h
> +++ b/bfd/libbfd.h
> @@ -2400,6 +2400,10 @@ static const char *const
> bfd_reloc_code_real_names[] = { "@@uninitialized@@",
>    "BFD_RELOC_RISCV_TLS_DTPREL64",
>    "BFD_RELOC_RISCV_TLS_TPREL32",
>    "BFD_RELOC_RISCV_TLS_TPREL64",
> +  "BFD_RELOC_RISCV_TLSDESC_HI20",
> +  "BFD_RELOC_RISCV_TLSDESC_LOAD_LO12",
> +  "BFD_RELOC_RISCV_TLSDESC_ADD_LO12",
> +  "BFD_RELOC_RISCV_TLSDESC_CALL",
>    "BFD_RELOC_RISCV_ALIGN",
>    "BFD_RELOC_RISCV_RVC_BRANCH",
>    "BFD_RELOC_RISCV_RVC_JUMP",
> diff --git a/bfd/reloc.c b/bfd/reloc.c
> index 93ebad879e0..345f444d17a 100644
> --- a/bfd/reloc.c
> +++ b/bfd/reloc.c
> @@ -4984,6 +4984,14 @@ ENUMX
>    BFD_RELOC_RISCV_TLS_TPREL32
>  ENUMX
>    BFD_RELOC_RISCV_TLS_TPREL64
> +ENUMX
> +  BFD_RELOC_RISCV_TLSDESC_HI20
> +ENUMX
> +  BFD_RELOC_RISCV_TLSDESC_LOAD_LO12
> +ENUMX
> +  BFD_RELOC_RISCV_TLSDESC_ADD_LO12
> +ENUMX
> +  BFD_RELOC_RISCV_TLSDESC_CALL
>  ENUMX
>    BFD_RELOC_RISCV_ALIGN
>  ENUMX
> diff --git a/include/elf/riscv.h b/include/elf/riscv.h
> index 56d419c665b..7f5c0407ac8 100644
> --- a/include/elf/riscv.h
> +++ b/include/elf/riscv.h
> @@ -44,6 +44,7 @@ START_RELOC_NUMBERS (elf_riscv_reloc_type)
>    RELOC_NUMBER (R_RISCV_TLS_DTPREL64, 9)
>    RELOC_NUMBER (R_RISCV_TLS_TPREL32, 10)
>    RELOC_NUMBER (R_RISCV_TLS_TPREL64, 11)
> +  RELOC_NUMBER (R_RISCV_TLSDESC, 12)
>
>    /* Relocation types not used by the dynamic linker.  */
>    RELOC_NUMBER (R_RISCV_BRANCH, 16)
> @@ -90,6 +91,10 @@ START_RELOC_NUMBERS (elf_riscv_reloc_type)
>    /* Reserved 59 for R_RISCV_PLT32.  */
>    RELOC_NUMBER (R_RISCV_SET_ULEB128, 60)
>    RELOC_NUMBER (R_RISCV_SUB_ULEB128, 61)
> +  RELOC_NUMBER (R_RISCV_TLSDESC_HI20, 62)
> +  RELOC_NUMBER (R_RISCV_TLSDESC_LOAD_LO12, 63)
> +  RELOC_NUMBER (R_RISCV_TLSDESC_ADD_LO12, 64)
> +  RELOC_NUMBER (R_RISCV_TLSDESC_CALL, 65)
>  END_RELOC_NUMBERS (R_RISCV_max)
>
>  /* Internal relocations used exclusively by the relaxation pass.  */
> --
> 2.43.0
>
>

^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [PATCH v3 3/9] RISC-V: Add assembly support for TLSDESC.
  2023-11-28  8:51   ` [PATCH v3 3/9] RISC-V: Add assembly support for TLSDESC Tatsuyuki Ishi
@ 2024-02-19  1:44     ` Nelson Chu
  2024-02-20 17:29       ` Tatsuyuki Ishi
  0 siblings, 1 reply; 49+ messages in thread
From: Nelson Chu @ 2024-02-19  1:44 UTC (permalink / raw)
  To: Tatsuyuki Ishi; +Cc: binutils, i, rui314, ruiu

[-- Attachment #1: Type: text/plain, Size: 7455 bytes --]

On Tue, Nov 28, 2023 at 4:51 PM Tatsuyuki Ishi <ishitatsuyuki@gmail.com>
wrote:

> gas/
>     * tc-riscv.c (percent_op_*): Add support for %tlsdesc_hi,
>     %tlsdesc_load_lo, %tlsdesc_add_lo and %tlsdesc_call. percent_op_rtype
>     renamed to percent_op_relax_only as this matcher is extended to handle
>     jalr as well which is not R-type.
>     (riscv_ip): Apply the percent_op_relax_only rename and update comment.
>     (md_apply_fix): Add TLSDESC_* to relaxable list. Add TLSDESC_HI20 to
>     TLS relocation check list.
>     * testsuite/gas/riscv/tlsdesc.*: New test cases for TLSDESC relocation
>     generation.
> opcodes/
>     * riscv-opc.c (riscv_opcodes): Add a new syntax for jalr with
>     %tlsdesc_call annotations.
> ---
>  gas/config/tc-riscv.c             | 18 +++++++++++++-----
>  gas/testsuite/gas/riscv/tlsdesc.d | 22 ++++++++++++++++++++++
>  gas/testsuite/gas/riscv/tlsdesc.s | 24 ++++++++++++++++++++++++
>  opcodes/riscv-opc.c               |  1 +
>  4 files changed, 60 insertions(+), 5 deletions(-)
>  create mode 100644 gas/testsuite/gas/riscv/tlsdesc.d
>  create mode 100644 gas/testsuite/gas/riscv/tlsdesc.s
>
> diff --git a/gas/config/tc-riscv.c b/gas/config/tc-riscv.c
> index 04738d5e00c..376d2a34530 100644
> --- a/gas/config/tc-riscv.c
> +++ b/gas/config/tc-riscv.c
> @@ -2113,6 +2113,7 @@ static const struct percent_op_match
> percent_op_utype[] =
>    {"tprel_hi", BFD_RELOC_RISCV_TPREL_HI20},
>    {"pcrel_hi", BFD_RELOC_RISCV_PCREL_HI20},
>    {"got_pcrel_hi", BFD_RELOC_RISCV_GOT_HI20},
> +  {"tlsdesc_hi", BFD_RELOC_RISCV_TLSDESC_HI20},
>    {"tls_ie_pcrel_hi", BFD_RELOC_RISCV_TLS_GOT_HI20},
>    {"tls_gd_pcrel_hi", BFD_RELOC_RISCV_TLS_GD_HI20},
>    {"hi", BFD_RELOC_RISCV_HI20},
> @@ -2124,6 +2125,8 @@ static const struct percent_op_match
> percent_op_itype[] =
>    {"lo", BFD_RELOC_RISCV_LO12_I},
>    {"tprel_lo", BFD_RELOC_RISCV_TPREL_LO12_I},
>    {"pcrel_lo", BFD_RELOC_RISCV_PCREL_LO12_I},
> +  {"tlsdesc_load_lo", BFD_RELOC_RISCV_TLSDESC_LOAD_LO12},
> +  {"tlsdesc_add_lo", BFD_RELOC_RISCV_TLSDESC_ADD_LO12},
>    {0, 0}
>  };
>
> @@ -2135,8 +2138,9 @@ static const struct percent_op_match
> percent_op_stype[] =
>    {0, 0}
>  };
>
> -static const struct percent_op_match percent_op_rtype[] =
> +static const struct percent_op_match percent_op_relax_only[] =
>  {
> +  {"tlsdesc_call", BFD_RELOC_RISCV_TLSDESC_CALL},
>    {"tprel_add", BFD_RELOC_RISCV_TPREL_ADD},
>    {0, 0}
>  };
> @@ -3244,10 +3248,10 @@ riscv_ip (char *str, struct riscv_cl_insn *ip,
> expressionS *imm_expr,
>               *imm_reloc = BFD_RELOC_RISCV_LO12_I;
>               goto load_store;
>             case '1':
> -             /* This is used for TLS, where the fourth operand is
> -                %tprel_add, to get a relocation applied to an add
> -                instruction, for relaxation to use.  */
> -             p = percent_op_rtype;
> +             /* This is used for TLS relocations that acts as relaxation
> +                markers and do not change the instruction encoding,
> +                i.e. %tprel_add and %tlsdesc_call.  */
> +             p = percent_op_relax_only;
>

Okay, looks good.


>               goto alu_op;
>             case '0': /* AMO displacement, which must be zero.  */
>             load_store:
> @@ -4036,6 +4040,7 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg
> ATTRIBUTE_UNUSED)
>      case BFD_RELOC_RISCV_TPREL_LO12_I:
>      case BFD_RELOC_RISCV_TPREL_LO12_S:
>      case BFD_RELOC_RISCV_TPREL_ADD:
> +    case BFD_RELOC_RISCV_TLSDESC_HI20:
>        relaxable = true;
>        /* Fall through.  */
>
> @@ -4209,6 +4214,9 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg
> ATTRIBUTE_UNUSED)
>
>      case BFD_RELOC_RISCV_CALL:
>      case BFD_RELOC_RISCV_CALL_PLT:
> +    case BFD_RELOC_RISCV_TLSDESC_LOAD_LO12:
> +    case BFD_RELOC_RISCV_TLSDESC_ADD_LO12:
> +    case BFD_RELOC_RISCV_TLSDESC_CALL:
>        relaxable = true;
>        break;
>
> diff --git a/gas/testsuite/gas/riscv/tlsdesc.d
> b/gas/testsuite/gas/riscv/tlsdesc.d
> new file mode 100644
> index 00000000000..11872953d23
> --- /dev/null
> +++ b/gas/testsuite/gas/riscv/tlsdesc.d
> @@ -0,0 +1,22 @@
> +#as: -march=rv32ia
>

Probably can remove the architecture setting, so that we can test more
situations.


> +#source: tlsdesc.s
> +#readelf: -Wr
>

#objdump: -dr maye be better.


> +
> +Relocation section '.rela.text' at offset 0x[0-9a-f]+ contains 16 entries:
> + +Offset +Info +Type +Sym. Value +Symbol's Name \+ Addend
> +0+ +0+a3e +R_RISCV_TLSDESC_HI20 +0+ +sg1 \+ 0
> +0+ +0+33 +R_RISCV_RELAX + 0
> +0+4 +0+63f +R_RISCV_TLSDESC_LOAD_LO12 0+ +\.desc1 \+ 0
> +0+4 +0+33 +R_RISCV_RELAX + 0
> +0+8 +0+640 +R_RISCV_TLSDESC_ADD_LO12 0+ +\.desc1 \+ 0
> +0+8 +0+33 +R_RISCV_RELAX + 0
> +0+c +0+641 +R_RISCV_TLSDESC_CALL +0+ +\.desc1 \+ 0
> +0+c +0+33 +R_RISCV_RELAX + 0
> +0+10 +0+53e +R_RISCV_TLSDESC_HI20 +0+4 +sl1 \+ 0
> +0+10 +0+33 +R_RISCV_RELAX + 0
> +0+14 +0+83f +R_RISCV_TLSDESC_LOAD_LO12 0+10 +\.desc2 \+ 0
> +0+14 +0+33 +R_RISCV_RELAX + 0
> +0+18 +0+840 +R_RISCV_TLSDESC_ADD_LO12 0+10 +\.desc2 \+ 0
> +0+18 +0+33 +R_RISCV_RELAX +0
> +0+1c +0+841 +R_RISCV_TLSDESC_CALL +0+10 +\.desc2 \+ 0
> +0+1c +0+33 +R_RISCV_RELAX +0


[ ] means [space+tab]

0+000 <_start>:
[ ]+0:[ ]+[0-9a-f]+[ ]+auipc[ ]+a0,0x0
[ ]+0:[ ]+R_RISCV_TLSDESC_HI20[ ]+sg1
[ ]+0:[ ]+R_RISCV_RELAX[ ]+0
...




> diff --git a/gas/testsuite/gas/riscv/tlsdesc.s
> b/gas/testsuite/gas/riscv/tlsdesc.s
> new file mode 100644
> index 00000000000..15468d5f947
> --- /dev/null
> +++ b/gas/testsuite/gas/riscv/tlsdesc.s
> @@ -0,0 +1,24 @@
> +       .section        .tbss,"awT",@nobits
> +       .global sg1
> +sg1:
> +       .zero   4
> +sl1:
> +       .zero   4
> +
> +       .text
> +       .globl  _start
> +       .type   _start,@function
> +_start:
> +.desc1:
> +       auipc   a0, %tlsdesc_hi(sg1)
> +       lw      t0, %tlsdesc_load_lo(.desc1)(a0)
> +       addi    a0, a0, %tlsdesc_add_lo(.desc1)
> +       jalr    t0, t0, %tlsdesc_call(.desc1)
> +
> +.desc2:
> +       auipc   a0, %tlsdesc_hi(sl1)
> +       lw      t0, %tlsdesc_load_lo(.desc2)(a0)
> +       addi    a0, a0, %tlsdesc_add_lo(.desc2)
> +       jalr    t0, t0, %tlsdesc_call(.desc2)
> +
> +       ret
> diff --git a/opcodes/riscv-opc.c b/opcodes/riscv-opc.c
> index bf19978e025..edaf4b0c8b5 100644
> --- a/opcodes/riscv-opc.c
> +++ b/opcodes/riscv-opc.c
> @@ -372,6 +372,7 @@ const struct riscv_opcode riscv_opcodes[] =
>  {"jalr",        0, INSN_CLASS_I, "s,j",       MATCH_JALR|(X_RA <<
> OP_SH_RD), MASK_JALR|MASK_RD, match_opcode, INSN_ALIAS|INSN_JSR },
>  {"jalr",        0, INSN_CLASS_I, "d,s",       MATCH_JALR,
> MASK_JALR|MASK_IMM, match_opcode, INSN_ALIAS|INSN_JSR },
>  {"jalr",        0, INSN_CLASS_I, "d,o(s)",    MATCH_JALR, MASK_JALR,
> match_opcode, INSN_JSR },
> +{"jalr",        0, INSN_CLASS_I, "d,s,1",     MATCH_JALR,
> MASK_JALR|MASK_IMM, match_opcode, INSN_JSR },
>  {"jalr",        0, INSN_CLASS_I, "d,s,j",     MATCH_JALR, MASK_JALR,
> match_opcode, INSN_JSR },
>  {"j",           0, INSN_CLASS_C, "Ca",        MATCH_C_J, MASK_C_J,
> match_opcode, INSN_ALIAS|INSN_BRANCH },
>  {"j",           0, INSN_CLASS_I, "a",         MATCH_JAL,
> MASK_JAL|MASK_RD, match_opcode, INSN_ALIAS|INSN_BRANCH },
> --
> 2.43.0
>
>

^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [PATCH v3 4/9] RISC-V: Define and use GOT entry size constants for TLS.
  2023-11-28  8:51   ` [PATCH v3 4/9] RISC-V: Define and use GOT entry size constants for TLS Tatsuyuki Ishi
@ 2024-02-19  1:57     ` Nelson Chu
  2024-02-20 17:32       ` Tatsuyuki Ishi
  0 siblings, 1 reply; 49+ messages in thread
From: Nelson Chu @ 2024-02-19  1:57 UTC (permalink / raw)
  To: Tatsuyuki Ishi; +Cc: binutils, i, rui314, ruiu

[-- Attachment #1: Type: text/plain, Size: 4213 bytes --]

Okay, but probably need to update the code since commit 20ef84ed2abb.
Otherwise this patch looks good to me.

Thanks
Nelson

On Tue, Nov 28, 2023 at 4:51 PM Tatsuyuki Ishi <ishitatsuyuki@gmail.com>
wrote:

> As the size calculation is split by global and local symbols, using a
> shared constant definition for its size improves clarity.
>
> bfd/
>     * elfnn-riscv.c: Add macros for sizes of a normal GOT entry, TLS GD and
>     TLS IE entry.
>     (allocate_dynrelocs): Replace GOT size expressions with the new
>     constants.
>     (riscv_elf_size_dynamic_sections): Likewise.
>     (riscv_elf_relocate_section): Likewise.
> ---
>  bfd/elfnn-riscv.c | 16 +++++++++-------
>  1 file changed, 9 insertions(+), 7 deletions(-)
>
> diff --git a/bfd/elfnn-riscv.c b/bfd/elfnn-riscv.c
> index c0207765906..d5190538503 100644
> --- a/bfd/elfnn-riscv.c
> +++ b/bfd/elfnn-riscv.c
> @@ -298,6 +298,8 @@ riscv_is_insn_reloc (const reloc_howto_type *howto)
>  #define PLT_HEADER_SIZE (PLT_HEADER_INSNS * 4)
>  #define PLT_ENTRY_SIZE (PLT_ENTRY_INSNS * 4)
>  #define GOT_ENTRY_SIZE RISCV_ELF_WORD_BYTES
> +#define TLS_GD_GOT_ENTRY_SIZE (RISCV_ELF_WORD_BYTES * 2)
> +#define TLS_IE_GOT_ENTRY_SIZE RISCV_ELF_WORD_BYTES
>  /* Reserve two entries of GOTPLT for ld.so, one is used for PLT resolver,
>     the other is used for link map.  Other targets also reserve one more
>     entry used for runtime profile?  */
> @@ -1320,7 +1322,7 @@ allocate_dynrelocs (struct elf_link_hash_entry *h,
> void *inf)
>           /* TLS_GD needs two dynamic relocs and two GOT slots.  */
>           if (tls_type & GOT_TLS_GD)
>             {
> -             s->size += 2 * RISCV_ELF_WORD_BYTES;
> +             s->size += TLS_GD_GOT_ENTRY_SIZE;
>               if (need_reloc)
>                 htab->elf.srelgot->size += 2 * sizeof
> (ElfNN_External_Rela);
>             }
> @@ -1328,14 +1330,14 @@ allocate_dynrelocs (struct elf_link_hash_entry *h,
> void *inf)
>           /* TLS_IE needs one dynamic reloc and one GOT slot.  */
>           if (tls_type & GOT_TLS_IE)
>             {
> -             s->size += RISCV_ELF_WORD_BYTES;
> +             s->size += TLS_IE_GOT_ENTRY_SIZE;
>               if (need_reloc)
>                 htab->elf.srelgot->size += sizeof (ElfNN_External_Rela);
>             }
>         }
>        else
>         {
> -         s->size += RISCV_ELF_WORD_BYTES;
> +         s->size += GOT_ENTRY_SIZE;
>           if (WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, bfd_link_pic (info), h)
>               && ! UNDEFWEAK_NO_DYNAMIC_RELOC (info, h))
>             htab->elf.srelgot->size += sizeof (ElfNN_External_Rela);
> @@ -1563,20 +1565,20 @@ riscv_elf_size_dynamic_sections (bfd *output_bfd,
> struct bfd_link_info *info)
>                 {
>                   if (*local_tls_type & GOT_TLS_GD)
>                     {
> -                     s->size += 2 * RISCV_ELF_WORD_BYTES;
> +                     s->size += TLS_GD_GOT_ENTRY_SIZE;
>                       if (bfd_link_dll (info))
>                         srel->size += sizeof (ElfNN_External_Rela);
>                     }
>                   if (*local_tls_type & GOT_TLS_IE)
>                     {
> -                     s->size += RISCV_ELF_WORD_BYTES;
> +                     s->size += TLS_IE_GOT_ENTRY_SIZE;
>                       if (bfd_link_dll (info))
>                         srel->size += sizeof (ElfNN_External_Rela);
>                     }
>                 }
>               else
>                 {
> -                 s->size += RISCV_ELF_WORD_BYTES;
> +                 s->size += GOT_ENTRY_SIZE;
>                   if (bfd_link_pic (info))
>                     srel->size += sizeof (ElfNN_External_Rela);
>                 }
> @@ -2912,7 +2914,7 @@ riscv_elf_relocate_section (bfd *output_bfd,
>              reference's GOT slot follows the GD reference's slots.  */
>           ie_off = 0;
>           if ((tls_type & GOT_TLS_GD) && (tls_type & GOT_TLS_IE))
> -           ie_off = 2 * GOT_ENTRY_SIZE;
> +           ie_off = TLS_GD_GOT_ENTRY_SIZE;
>
>           if ((off & 1) != 0)
>             off &= ~1;
> --
> 2.43.0
>
>

^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [PATCH v3 5/9] RISC-V: Initial ld.bfd support for TLSDESC.
  2023-11-28  8:51   ` [PATCH v3 5/9] RISC-V: Initial ld.bfd support for TLSDESC Tatsuyuki Ishi
@ 2024-02-19  4:33     ` Nelson Chu
  2024-02-20 17:36       ` Tatsuyuki Ishi
  0 siblings, 1 reply; 49+ messages in thread
From: Nelson Chu @ 2024-02-19  4:33 UTC (permalink / raw)
  To: Tatsuyuki Ishi; +Cc: binutils, i, rui314, ruiu

[-- Attachment #1: Type: text/plain, Size: 13863 bytes --]

On Tue, Nov 28, 2023 at 4:51 PM Tatsuyuki Ishi <ishitatsuyuki@gmail.com>
wrote:

> Only relocation handling for now; relaxation is not implemented yet.
>
> bfd/
>     * elfnn-riscv.c (riscv_elf_check_relocs): Record GOT reference and
>     paired relocation for TLSDESC_HI20.
>     (riscv_elf_adjust_dynamic_symbol): Allocate GOT and reloc slots for
>     TLSDESC symbols.
>     (riscv_elf_size_dynamic_sections): Likewise but for local symbols.
>     (tlsdescoff): New helper to determine static addend for R_TLSDESC.
>     (riscv_elf_relocate_section): Ignore TLSDESC_CALL reloc for now (it is
>     relaxation only).
>     Handle TLSDESC_{LOAD,ADD}_LO12 as paired pcrel relocs.
>     For TLS GOT slot generation, generalize the logic to handle any
>     combination of (GD, IE, TLSDESC).
>     Add TLSDESC Rela generation.
>     * ld/testsuite/ld-riscv-elf/tls*: Add TLSDESC instruction sequences
>     next to the existing GD and IE sequences. Update expectations.
> ---
>  bfd/elfnn-riscv.c                  | 91 +++++++++++++++++++++++++++---
>  ld/testsuite/ld-riscv-elf/tls.d    |  4 +-
>  ld/testsuite/ld-riscv-elf/tls.s    | 14 +++++
>  ld/testsuite/ld-riscv-elf/tlsbin.d |  5 ++
>  4 files changed, 104 insertions(+), 10 deletions(-)
>
> diff --git a/bfd/elfnn-riscv.c b/bfd/elfnn-riscv.c
> index d5190538503..8f63998aa5a 100644
> --- a/bfd/elfnn-riscv.c
> +++ b/bfd/elfnn-riscv.c
> @@ -163,6 +163,7 @@ struct riscv_elf_link_hash_entry
>  #define GOT_TLS_GD     2
>  #define GOT_TLS_IE     4
>  #define GOT_TLS_LE     8
> +#define GOT_TLSDESC    16
>    char tls_type;
>  };
>
> @@ -300,6 +301,7 @@ riscv_is_insn_reloc (const reloc_howto_type *howto)
>  #define GOT_ENTRY_SIZE RISCV_ELF_WORD_BYTES
>  #define TLS_GD_GOT_ENTRY_SIZE (RISCV_ELF_WORD_BYTES * 2)
>  #define TLS_IE_GOT_ENTRY_SIZE RISCV_ELF_WORD_BYTES
> +#define TLSDESC_GOT_ENTRY_SIZE (RISCV_ELF_WORD_BYTES * 2)
>  /* Reserve two entries of GOTPLT for ld.so, one is used for PLT resolver,
>     the other is used for link map.  Other targets also reserve one more
>     entry used for runtime profile?  */
> @@ -855,6 +857,12 @@ riscv_elf_check_relocs (bfd *abfd, struct
> bfd_link_info *info,
>             return false;
>           break;
>
> +       case R_RISCV_TLSDESC_HI20:
> +         if (!riscv_elf_record_got_reference (abfd, info, h, r_symndx)
> +             || !riscv_elf_record_tls_type (abfd, h, r_symndx,
> GOT_TLSDESC))
> +           return false;
> +         break;
> +
>         case R_RISCV_CALL:
>         case R_RISCV_CALL_PLT:
>           /* These symbol requires a procedure linkage table entry.
> @@ -1313,7 +1321,7 @@ allocate_dynrelocs (struct elf_link_hash_entry *h,
> void *inf)
>        s = htab->elf.sgot;
>        h->got.offset = s->size;
>        dyn = htab->elf.dynamic_sections_created;
> -      if (tls_type & (GOT_TLS_GD | GOT_TLS_IE))
> +      if (tls_type & (GOT_TLS_GD | GOT_TLS_IE | GOT_TLSDESC))
>         {
>           int indx = 0;
>           bool need_reloc = false;
> @@ -1334,6 +1342,14 @@ allocate_dynrelocs (struct elf_link_hash_entry *h,
> void *inf)
>               if (need_reloc)
>                 htab->elf.srelgot->size += sizeof (ElfNN_External_Rela);
>             }
> +
> +         /* TLSDESC needs one dynamic reloc and two GOT slots.  */
> +         if (tls_type & GOT_TLSDESC)
> +           {
> +             s->size += TLSDESC_GOT_ENTRY_SIZE;
> +             /* TLSDESC always use dynamic relocs.  */
> +             htab->elf.srelgot->size += sizeof (ElfNN_External_Rela);
> +           }

        }
>        else
>         {
> @@ -1561,7 +1577,7 @@ riscv_elf_size_dynamic_sections (bfd *output_bfd,
> struct bfd_link_info *info)
>           if (*local_got > 0)
>             {
>               *local_got = s->size;
> -             if (*local_tls_type & (GOT_TLS_GD | GOT_TLS_IE))
> +             if (*local_tls_type & (GOT_TLS_GD | GOT_TLS_IE |
> GOT_TLSDESC))
>                 {
>                   if (*local_tls_type & GOT_TLS_GD)
>                     {
> @@ -1575,6 +1591,11 @@ riscv_elf_size_dynamic_sections (bfd *output_bfd,
> struct bfd_link_info *info)
>                       if (bfd_link_dll (info))
>                         srel->size += sizeof (ElfNN_External_Rela);
>                     }
> +                 if (*local_tls_type & GOT_TLSDESC)
> +                   {
> +                     s->size += TLSDESC_GOT_ENTRY_SIZE;
> +                     srel->size += sizeof (ElfNN_External_Rela);
> +                   }
>

The code base seems different from the upstream code.


>                 }
>               else
>                 {
> @@ -1725,6 +1746,17 @@ tpoff (struct bfd_link_info *info, bfd_vma address)
>    return address - elf_hash_table (info)->tls_sec->vma - TP_OFFSET;
>  }
>
> +/* Return the relocation value for a static TLSDESC relocation.  */
> +
> +static bfd_vma
> +tlsdescoff (struct bfd_link_info *info, bfd_vma address)
> +{
> +  /* If tls_sec is NULL, we should have signalled an error already.  */
> +  if (elf_hash_table (info)->tls_sec == NULL)
> +    return 0;
> +  return address - elf_hash_table (info)->tls_sec->vma;
> +}
> +
>  /* Return the global pointer's value, or 0 if it is not in use.  */
>
>  static bfd_vma
> @@ -1774,6 +1806,7 @@ perform_relocation (const reloc_howto_type *howto,
>      case R_RISCV_GOT_HI20:
>      case R_RISCV_TLS_GOT_HI20:
>      case R_RISCV_TLS_GD_HI20:
> +    case R_RISCV_TLSDESC_HI20:
>        if (ARCH_SIZE > 32 && !VALID_UTYPE_IMM (RISCV_CONST_HIGH_PART
> (value)))
>         return bfd_reloc_overflow;
>        value = ENCODE_UTYPE_IMM (RISCV_CONST_HIGH_PART (value));
> @@ -1784,6 +1817,8 @@ perform_relocation (const reloc_howto_type *howto,
>      case R_RISCV_TPREL_LO12_I:
>      case R_RISCV_TPREL_I:
>      case R_RISCV_PCREL_LO12_I:
> +    case R_RISCV_TLSDESC_LOAD_LO12:
> +    case R_RISCV_TLSDESC_ADD_LO12:
>        value = ENCODE_ITYPE_IMM (value);
>        break;
>
> @@ -2202,8 +2237,8 @@ riscv_elf_relocate_section (bfd *output_bfd,
>        bfd_vma relocation;
>        bfd_reloc_status_type r = bfd_reloc_ok;
>        const char *name = NULL;
> -      bfd_vma off, ie_off;
> -      bool unresolved_reloc, is_ie = false;
> +      bfd_vma off, ie_off, desc_off;
> +      bool unresolved_reloc, is_ie = false, is_desc = false;
>        bfd_vma pc = sec_addr (input_section) + rel->r_offset;
>        int r_type = ELFNN_R_TYPE (rel->r_info), tls_type;
>        reloc_howto_type *howto = riscv_elf_rtype_to_howto (input_bfd,
> r_type);
> @@ -2506,6 +2541,7 @@ riscv_elf_relocate_section (bfd *output_bfd,
>         case R_RISCV_NONE:
>         case R_RISCV_RELAX:
>         case R_RISCV_TPREL_ADD:
> +       case R_RISCV_TLSDESC_CALL:
>         case R_RISCV_COPY:
>         case R_RISCV_JUMP_SLOT:
>         case R_RISCV_RELATIVE:
> @@ -2827,6 +2863,15 @@ riscv_elf_relocate_section (bfd *output_bfd,
>           relocation = dtpoff (info, relocation);
>           break;
>
> +       case R_RISCV_TLSDESC_LOAD_LO12:
> +       case R_RISCV_TLSDESC_ADD_LO12:
> +         if (riscv_record_pcrel_lo_reloc (&pcrel_relocs, relocation, rel,
> +                                          input_section, info, howto,
> +                                          contents))
> +             continue;
> +         r = bfd_reloc_overflow;
> +         break;
> +
>

According to the spec, we probably can add a check here to make sure the
addend must be zero, otherwise report dangerous relocation, just similar to
what pcrel_lo did.


>         case R_RISCV_32:
>           /* Non ABS symbol should be blocked in check_relocs.  */
>           if (ARCH_SIZE > 32)
> @@ -2892,11 +2937,16 @@ riscv_elf_relocate_section (bfd *output_bfd,
>             }
>           break;
>
> +       case R_RISCV_TLSDESC_HI20:
> +         is_desc = true;
> +         goto tls;
> +
>         case R_RISCV_TLS_GOT_HI20:
>           is_ie = true;
> -         /* Fall through.  */
> +         goto tls;
>
>         case R_RISCV_TLS_GD_HI20:
> +       tls:
>           if (h != NULL)
>             {
>               off = h->got.offset;
> @@ -2909,12 +2959,16 @@ riscv_elf_relocate_section (bfd *output_bfd,
>             }
>
>           tls_type = _bfd_riscv_elf_tls_type (input_bfd, h, r_symndx);
> -         BFD_ASSERT (tls_type & (GOT_TLS_IE | GOT_TLS_GD));
> +         BFD_ASSERT (tls_type & (GOT_TLS_IE | GOT_TLS_GD | GOT_TLSDESC));
>           /* If this symbol is referenced by both GD and IE TLS, the IE
>              reference's GOT slot follows the GD reference's slots.  */
>           ie_off = 0;
>           if ((tls_type & GOT_TLS_GD) && (tls_type & GOT_TLS_IE))
> -           ie_off = TLS_GD_GOT_ENTRY_SIZE;
> +           ie_off += TLS_GD_GOT_ENTRY_SIZE;
> +
> +         desc_off = ie_off;
> +         if (tls_type & GOT_TLS_IE)
> +           desc_off += TLS_IE_GOT_ENTRY_SIZE;


Is it possible that we only link GD and DESC, but without IE?


>           if ((off & 1) != 0)
>             off &= ~1;
> @@ -2996,10 +3050,29 @@ riscv_elf_relocate_section (bfd *output_bfd,
>                                   htab->elf.sgot->contents + off + ie_off);
>                     }
>                 }
> +
> +             if (tls_type & GOT_TLSDESC)
> +               {
> +                 /* TLSDESC is always handled by the dynamic linker and
> always need
> +                  * a relocation.  */
> +                 bfd_put_NN (output_bfd, 0,
> +                             htab->elf.sgot->contents + off + desc_off);
> +                 outrel.r_offset = sec_addr (htab->elf.sgot)
> +                                   + off + desc_off;
> +                 outrel.r_addend = 0;
> +                 if (indx == 0)
> +                   outrel.r_addend = tlsdescoff (info, relocation);
> +                 outrel.r_info = ELFNN_R_INFO (indx, R_RISCV_TLSDESC);
> +                 riscv_elf_append_rela (output_bfd, htab->elf.srelgot,
> &outrel);
> +               }
>             }
>
>           BFD_ASSERT (off < (bfd_vma) -2);
> -         relocation = sec_addr (htab->elf.sgot) + off + (is_ie ? ie_off :
> 0);
> +         relocation = sec_addr (htab->elf.sgot) + off;
> +         if (is_ie)
> +           relocation += ie_off;
> +         else if (is_desc)
> +           relocation += desc_off;
>           if (!riscv_record_pcrel_hi_reloc (&pcrel_relocs, pc,
>                                             relocation, r_type,
>                                             false))
> @@ -3219,7 +3292,7 @@ riscv_elf_finish_dynamic_symbol (bfd *output_bfd,
>      }
>
>    if (h->got.offset != (bfd_vma) -1
> -      && !(riscv_elf_hash_entry (h)->tls_type & (GOT_TLS_GD | GOT_TLS_IE))
> +      && !(riscv_elf_hash_entry (h)->tls_type & (GOT_TLS_GD | GOT_TLS_IE
> | GOT_TLSDESC))
>        && !UNDEFWEAK_NO_DYNAMIC_RELOC (info, h))
>      {
>        asection *sgot;
> diff --git a/ld/testsuite/ld-riscv-elf/tls.d
> b/ld/testsuite/ld-riscv-elf/tls.d
> index e7f20309bf1..6cf008ac7a0 100644
> --- a/ld/testsuite/ld-riscv-elf/tls.d
> +++ b/ld/testsuite/ld-riscv-elf/tls.d
> @@ -2,13 +2,15 @@
>  #ld: --shared tmpdir/tlslib.so
>  #readelf: -Wr
>
> -Relocation section '.rela.dyn' at offset 0x[0-9a-f]+ contains 5 entries:
> +Relocation section '.rela.dyn' at offset 0x[0-9a-f]+ contains 7 entries:
>   +Offset +Info +Type +Symbol's Value +Symbol's Name \+ Addend
>  [0-9a-f]+ +[0-9a-f]+ R_RISCV_TLS_DTPMOD64 +0
>  [0-9a-f]+ +[0-9a-f]+ R_RISCV_TLS_TPREL64 +4
> +[0-9a-f]+ +[0-9a-f]+ R_RISCV_TLSDESC +4
>  [0-9a-f]+ +[0-9a-f]+ R_RISCV_TLS_DTPMOD64 +0+ sg1 \+ 0
>  [0-9a-f]+ +[0-9a-f]+ R_RISCV_TLS_DTPREL64 +0+ sg1 \+ 0
>  [0-9a-f]+ +[0-9a-f]+ R_RISCV_TLS_TPREL64 +0+ sg1 \+ 0
> +[0-9a-f]+ +[0-9a-f]+ R_RISCV_TLSDESC +0+ sg1 \+ 0
>
>  Relocation section '.rela.plt' at offset 0x[0-9a-f]+ contains 1 entry:
>   +Offset +Info +Type +Symbol's Value +Symbol's Name \+ Addend
> diff --git a/ld/testsuite/ld-riscv-elf/tls.s
> b/ld/testsuite/ld-riscv-elf/tls.s
> index 79e9bc20374..7cbf5ea6c72 100644
> --- a/ld/testsuite/ld-riscv-elf/tls.s
> +++ b/ld/testsuite/ld-riscv-elf/tls.s
> @@ -17,6 +17,13 @@ _start:
>         la.tls.ie       a0,sg1
>         add     a0,a0,tp
>
> +       /* GD (TLSDESC), global var */
> +.desc1:
> +       auipc   a0, %tlsdesc_hi(sg1)
> +       lw      t0, %tlsdesc_load_lo(.desc1)(a0)
> +       addi    a0, a0, %tlsdesc_add_lo(.desc1)
> +       jalr    t0, t0, %tlsdesc_call(.desc1)
> +
>         /* GD, local var */
>         la.tls.gd       a0,sl1
>         call  __tls_get_addr
> @@ -25,4 +32,11 @@ _start:
>         la.tls.ie       a0,sl1
>         add     a0,a0,tp
>
> +       /* GD (TLSDESC), local var */
> +.desc2:
> +       auipc   a0, %tlsdesc_hi(sl1)
> +       lw      t0, %tlsdesc_load_lo(.desc2)(a0)
> +       addi    a0, a0, %tlsdesc_add_lo(.desc2)
> +       jalr    t0, t0, %tlsdesc_call(.desc2)
> +
>         ret
> diff --git a/ld/testsuite/ld-riscv-elf/tlsbin.d
> b/ld/testsuite/ld-riscv-elf/tlsbin.d
> index cdcd51a9199..79b7ade405e 100644
> --- a/ld/testsuite/ld-riscv-elf/tlsbin.d
> +++ b/ld/testsuite/ld-riscv-elf/tlsbin.d
> @@ -2,6 +2,11 @@
>  #ld: -no-pie tmpdir/tlslib.so
>  #readelf: -Wr
>
> +Relocation section '.rela.dyn' at offset 0x[0-9a-f]+ contains 2 entries:
> + +Offset +Info +Type +Symbol's Value +Symbol's Name \+ Addend
> +[0-9a-f]+ +[0-9a-f]+ R_RISCV_TLSDESC +4
> +[0-9a-f]+ +[0-9a-f]+ R_RISCV_TLSDESC +0
> +
>  Relocation section '.rela.plt' at offset 0x[0-9a-f]+ contains 1 entry:
>   +Offset +Info +Type +Symbol's Value +Symbol's Name \+ Addend
>  [0-9a-f]+ +[0-9a-f]+ R_RISCV_JUMP_SLOT +[0-9a-f]+ __tls_get_addr \+ 0
> --
> 2.43.0
>
>

^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [PATCH v3 2/9] RISC-V: Add TLSDESC reloc definitions.
  2024-02-19  0:49     ` Nelson Chu
@ 2024-02-20 17:28       ` Tatsuyuki Ishi
  0 siblings, 0 replies; 49+ messages in thread
From: Tatsuyuki Ishi @ 2024-02-20 17:28 UTC (permalink / raw)
  To: Nelson Chu; +Cc: binutils, Fangrui Song, Rui Ueyama, Rui Ueyama

[-- Attachment #1: Type: text/plain, Size: 0 bytes --]



^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [PATCH v3 3/9] RISC-V: Add assembly support for TLSDESC.
  2024-02-19  1:44     ` Nelson Chu
@ 2024-02-20 17:29       ` Tatsuyuki Ishi
  0 siblings, 0 replies; 49+ messages in thread
From: Tatsuyuki Ishi @ 2024-02-20 17:29 UTC (permalink / raw)
  To: Nelson Chu; +Cc: binutils, i, rui314, ruiu

[-- Attachment #1: Type: text/plain, Size: 0 bytes --]



^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [PATCH v3 4/9] RISC-V: Define and use GOT entry size constants for TLS.
  2024-02-19  1:57     ` Nelson Chu
@ 2024-02-20 17:32       ` Tatsuyuki Ishi
  0 siblings, 0 replies; 49+ messages in thread
From: Tatsuyuki Ishi @ 2024-02-20 17:32 UTC (permalink / raw)
  To: Nelson Chu; +Cc: binutils, Fangrui Song, Rui Ueyama, ruiu

[-- Attachment #1: Type: text/plain, Size: 0 bytes --]



^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [PATCH v3 5/9] RISC-V: Initial ld.bfd support for TLSDESC.
  2024-02-19  4:33     ` Nelson Chu
@ 2024-02-20 17:36       ` Tatsuyuki Ishi
  0 siblings, 0 replies; 49+ messages in thread
From: Tatsuyuki Ishi @ 2024-02-20 17:36 UTC (permalink / raw)
  To: Nelson Chu; +Cc: binutils, i, rui314, ruiu

[-- Attachment #1: Type: text/plain, Size: 0 bytes --]



^ permalink raw reply	[flat|nested] 49+ messages in thread

* [PATCH v4 0/9] RISC-V: Implement TLS Descriptors.
  2023-08-17 18:08 [PATCH 0/4] RISC-V: Implement TLS Descriptors Tatsuyuki Ishi
                   ` (6 preceding siblings ...)
  2023-11-28  8:51 ` [PATCH v3 0/9] RISC-V: Implement TLS Descriptors Tatsuyuki Ishi
@ 2024-02-20 17:55 ` Tatsuyuki Ishi
  2024-02-20 17:55   ` [PATCH v4 1/9] RISC-V: Fix local GOT and reloc size calculation for TLS Tatsuyuki Ishi
                     ` (8 more replies)
  7 siblings, 9 replies; 49+ messages in thread
From: Tatsuyuki Ishi @ 2024-02-20 17:55 UTC (permalink / raw)
  To: binutils; +Cc: i, nelson, rui314, ruiu, Tatsuyuki Ishi

This patchset implements TLS Descriptors (TLSDESC) for RISC-V targets, per
the specification (merged) at [1].

Tested on rv32gc & rv64gc for:
- No regression (& passing new tests) in binutils
- No regression in gcc
- No regression in glibc for subdirs=elf
With both -mtls-dialect=desc and trad.

This contribution is made on behalf of Blue Whale Systems, which has
copyright assignment on file with the FSF.

[1]: https://github.com/riscv-non-isa/riscv-elf-psabi-doc/pull/373

v2: Add changelogs and tests. Minor fixes described in patch messages.
v3: Add relaxation support. This fixes tst-tls1-static in glibc.
v4: Fix issues pointed out in review (thanks Nelson).

Tatsuyuki Ishi (9):
  RISC-V: Fix local GOT and reloc size calculation for TLS.
  RISC-V: Add TLSDESC reloc definitions.
  RISC-V: Add assembly support for TLSDESC.
  RISC-V: Define and use GOT entry size constants for TLS.
  RISC-V: Initial ld.bfd support for TLSDESC.
  RISC-V: Move STATIC_TLS handling into record_tls_type.
  RISC-V: Unify TLS handling in check_relocs.
  RISC-V: Add elf_link_hash_entry to relax_func args.
  RISC-V: Introduce TLSDESC relaxation.

 bfd/bfd-in2.h                              |   4 +
 bfd/elfnn-riscv.c                          | 352 ++++++++++++++++++---
 bfd/elfxx-riscv.c                          | 130 +++++++-
 bfd/libbfd.h                               |   4 +
 bfd/reloc.c                                |   8 +
 gas/config/tc-riscv.c                      |  18 +-
 gas/testsuite/gas/riscv/tlsdesc.d          |  36 +++
 gas/testsuite/gas/riscv/tlsdesc.s          |  24 ++
 include/elf/riscv.h                        |  21 +-
 include/opcode/riscv.h                     |   1 +
 ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp |   8 +
 ld/testsuite/ld-riscv-elf/tls.d            |  17 +
 ld/testsuite/ld-riscv-elf/tls.s            |  42 +++
 ld/testsuite/ld-riscv-elf/tlsbin.d         |   7 +
 ld/testsuite/ld-riscv-elf/tlslib.s         |   6 +
 opcodes/riscv-opc.c                        |   1 +
 16 files changed, 623 insertions(+), 56 deletions(-)
 create mode 100644 gas/testsuite/gas/riscv/tlsdesc.d
 create mode 100644 gas/testsuite/gas/riscv/tlsdesc.s
 create mode 100644 ld/testsuite/ld-riscv-elf/tls.d
 create mode 100644 ld/testsuite/ld-riscv-elf/tls.s
 create mode 100644 ld/testsuite/ld-riscv-elf/tlsbin.d
 create mode 100644 ld/testsuite/ld-riscv-elf/tlslib.s

-- 
2.43.2


^ permalink raw reply	[flat|nested] 49+ messages in thread

* [PATCH v4 1/9] RISC-V: Fix local GOT and reloc size calculation for TLS.
  2024-02-20 17:55 ` [PATCH v4 " Tatsuyuki Ishi
@ 2024-02-20 17:55   ` Tatsuyuki Ishi
  2024-02-20 17:55   ` [PATCH v4 2/9] RISC-V: Add TLSDESC reloc definitions Tatsuyuki Ishi
                     ` (7 subsequent siblings)
  8 siblings, 0 replies; 49+ messages in thread
From: Tatsuyuki Ishi @ 2024-02-20 17:55 UTC (permalink / raw)
  To: binutils; +Cc: i, nelson, rui314, ruiu, Tatsuyuki Ishi

The previous code did not account correctly for two cases:
* A TLS symbol can be referenced with multiple TLS types (although rare),
  in which case it only allocated the maximum slot size among the types,
  instead of the sum.
* TLS relocations are only needed for DLLs, unlike normal symbols which
  requires relocations for all PIE code.

Modify the logic to account for the two cases.

bfd/
    * elfnn-riscv.c (riscv_elf_size_dynamic_sections): Handle relocation
    sizing for TLS and non-TLS symbols differently, with the former
    requiring relocs on DLL while the latter requiring on PIE.
    Allocate GOT slots and relocation slots for each TLS type separately,
    accounting for the possibility of a TLS variable getting referenced by
    multiple symbols.
ld/
    * testsuite/ld-riscv-elf/ld-riscv-elf.exp: Updated.
    * testsuite/ld-riscv-elf/tls*: New testcase for TLS GD and IE, with
    symbols referred by both types and global and local symbols.
---
 bfd/elfnn-riscv.c                          | 27 ++++++++++++++++-----
 ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp |  8 +++++++
 ld/testsuite/ld-riscv-elf/tls.d            | 15 ++++++++++++
 ld/testsuite/ld-riscv-elf/tls.s            | 28 ++++++++++++++++++++++
 ld/testsuite/ld-riscv-elf/tlsbin.d         |  7 ++++++
 ld/testsuite/ld-riscv-elf/tlslib.s         |  6 +++++
 6 files changed, 85 insertions(+), 6 deletions(-)
 create mode 100644 ld/testsuite/ld-riscv-elf/tls.d
 create mode 100644 ld/testsuite/ld-riscv-elf/tls.s
 create mode 100644 ld/testsuite/ld-riscv-elf/tlsbin.d
 create mode 100644 ld/testsuite/ld-riscv-elf/tlslib.s

diff --git a/bfd/elfnn-riscv.c b/bfd/elfnn-riscv.c
index 951b19a911d..e5cecd79cf3 100644
--- a/bfd/elfnn-riscv.c
+++ b/bfd/elfnn-riscv.c
@@ -1559,12 +1559,27 @@ riscv_elf_size_dynamic_sections (bfd *output_bfd, struct bfd_link_info *info)
 	  if (*local_got > 0)
 	    {
 	      *local_got = s->size;
-	      s->size += RISCV_ELF_WORD_BYTES;
-	      if (*local_tls_type & GOT_TLS_GD)
-		s->size += RISCV_ELF_WORD_BYTES;
-	      if (bfd_link_pic (info)
-		  || (*local_tls_type & (GOT_TLS_GD | GOT_TLS_IE)))
-		srel->size += sizeof (ElfNN_External_Rela);
+	      if (*local_tls_type & (GOT_TLS_GD | GOT_TLS_IE))
+		{
+		  if (*local_tls_type & GOT_TLS_GD)
+		    {
+		      s->size += 2 * RISCV_ELF_WORD_BYTES;
+		      if (bfd_link_dll (info))
+			srel->size += sizeof (ElfNN_External_Rela);
+		    }
+		  if (*local_tls_type & GOT_TLS_IE)
+		    {
+		      s->size += RISCV_ELF_WORD_BYTES;
+		      if (bfd_link_dll (info))
+			srel->size += sizeof (ElfNN_External_Rela);
+		    }
+		}
+	      else
+		{
+		  s->size += RISCV_ELF_WORD_BYTES;
+		  if (bfd_link_pic (info))
+		    srel->size += sizeof (ElfNN_External_Rela);
+		}
 	    }
 	  else
 	    *local_got = (bfd_vma) -1;
diff --git a/ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp b/ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp
index 7e1281d826b..a1dd0e5e37e 100644
--- a/ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp
+++ b/ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp
@@ -319,4 +319,12 @@ if [istarget "riscv*-*-*"] {
     run_dump_test "pcrel-reloc-rel-pie"
     run_dump_test "pcrel-reloc-abs-nopie"
     run_dump_test "pcrel-reloc-abs-pie"
+
+    run_ld_link_tests {
+       { "Build shared library for TLS runtime"
+	 "-shared" "" "" {tlslib.s}
+	 {} "tlslib.so" }
+    }
+    run_dump_test "tls"
+    run_dump_test "tlsbin"
 }
diff --git a/ld/testsuite/ld-riscv-elf/tls.d b/ld/testsuite/ld-riscv-elf/tls.d
new file mode 100644
index 00000000000..e7f20309bf1
--- /dev/null
+++ b/ld/testsuite/ld-riscv-elf/tls.d
@@ -0,0 +1,15 @@
+#source: tls.s
+#ld: --shared tmpdir/tlslib.so
+#readelf: -Wr
+
+Relocation section '.rela.dyn' at offset 0x[0-9a-f]+ contains 5 entries:
+ +Offset +Info +Type +Symbol's Value +Symbol's Name \+ Addend
+[0-9a-f]+ +[0-9a-f]+ R_RISCV_TLS_DTPMOD64 +0
+[0-9a-f]+ +[0-9a-f]+ R_RISCV_TLS_TPREL64 +4
+[0-9a-f]+ +[0-9a-f]+ R_RISCV_TLS_DTPMOD64 +0+ sg1 \+ 0
+[0-9a-f]+ +[0-9a-f]+ R_RISCV_TLS_DTPREL64 +0+ sg1 \+ 0
+[0-9a-f]+ +[0-9a-f]+ R_RISCV_TLS_TPREL64 +0+ sg1 \+ 0
+
+Relocation section '.rela.plt' at offset 0x[0-9a-f]+ contains 1 entry:
+ +Offset +Info +Type +Symbol's Value +Symbol's Name \+ Addend
+[0-9a-f]+ +[0-9a-f]+ R_RISCV_JUMP_SLOT +0+ __tls_get_addr \+ 0
diff --git a/ld/testsuite/ld-riscv-elf/tls.s b/ld/testsuite/ld-riscv-elf/tls.s
new file mode 100644
index 00000000000..79e9bc20374
--- /dev/null
+++ b/ld/testsuite/ld-riscv-elf/tls.s
@@ -0,0 +1,28 @@
+	.section	.tbss,"awT",@nobits
+	.global sg1
+sg1:
+	.zero	4
+sl1:
+	.zero	4
+
+	.text
+	.globl	_start
+	.type	_start,@function
+_start:
+	/* GD, global var */
+	la.tls.gd	a0,sg1
+	call  __tls_get_addr
+
+	/* IE, global var */
+	la.tls.ie	a0,sg1
+	add	a0,a0,tp
+
+	/* GD, local var */
+	la.tls.gd	a0,sl1
+	call  __tls_get_addr
+
+	/* IE, local var */
+	la.tls.ie	a0,sl1
+	add	a0,a0,tp
+
+	ret
diff --git a/ld/testsuite/ld-riscv-elf/tlsbin.d b/ld/testsuite/ld-riscv-elf/tlsbin.d
new file mode 100644
index 00000000000..cdcd51a9199
--- /dev/null
+++ b/ld/testsuite/ld-riscv-elf/tlsbin.d
@@ -0,0 +1,7 @@
+#source: tls.s
+#ld: -no-pie tmpdir/tlslib.so
+#readelf: -Wr
+
+Relocation section '.rela.plt' at offset 0x[0-9a-f]+ contains 1 entry:
+ +Offset +Info +Type +Symbol's Value +Symbol's Name \+ Addend
+[0-9a-f]+ +[0-9a-f]+ R_RISCV_JUMP_SLOT +[0-9a-f]+ __tls_get_addr \+ 0
diff --git a/ld/testsuite/ld-riscv-elf/tlslib.s b/ld/testsuite/ld-riscv-elf/tlslib.s
new file mode 100644
index 00000000000..17c770786d0
--- /dev/null
+++ b/ld/testsuite/ld-riscv-elf/tlslib.s
@@ -0,0 +1,6 @@
+	.text
+	/* Dummy.  */
+	.globl	__tls_get_addr
+	.type	__tls_get_addr,@function
+__tls_get_addr:
+	ret
-- 
2.43.2


^ permalink raw reply	[flat|nested] 49+ messages in thread

* [PATCH v4 2/9] RISC-V: Add TLSDESC reloc definitions.
  2024-02-20 17:55 ` [PATCH v4 " Tatsuyuki Ishi
  2024-02-20 17:55   ` [PATCH v4 1/9] RISC-V: Fix local GOT and reloc size calculation for TLS Tatsuyuki Ishi
@ 2024-02-20 17:55   ` Tatsuyuki Ishi
  2024-02-20 17:55   ` [PATCH v4 3/9] RISC-V: Add assembly support for TLSDESC Tatsuyuki Ishi
                     ` (6 subsequent siblings)
  8 siblings, 0 replies; 49+ messages in thread
From: Tatsuyuki Ishi @ 2024-02-20 17:55 UTC (permalink / raw)
  To: binutils; +Cc: i, nelson, rui314, ruiu, Tatsuyuki Ishi

bfd/
    * elfxx-riscv.c: Add 5 TLSDESC reloc descriptions.
    * reloc.c: Likewise.
    * libbfd.h: Regenerate.
    * bfd-in2.h: Regenerate.
include/
    * elf/riscv.h: Add 5 TLSDESC reloc descriptions.
---
v4: Fix complain_on_overflow and use complain_overflow_dont.

 bfd/bfd-in2.h       |  4 +++
 bfd/elfxx-riscv.c   | 75 ++++++++++++++++++++++++++++++++++++++++++++-
 bfd/libbfd.h        |  4 +++
 bfd/reloc.c         |  8 +++++
 include/elf/riscv.h |  5 +++
 5 files changed, 95 insertions(+), 1 deletion(-)

diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h
index 37917845cf5..a335df522d2 100644
--- a/bfd/bfd-in2.h
+++ b/bfd/bfd-in2.h
@@ -5420,6 +5420,10 @@ enum bfd_reloc_code_real
   BFD_RELOC_RISCV_TLS_DTPREL64,
   BFD_RELOC_RISCV_TLS_TPREL32,
   BFD_RELOC_RISCV_TLS_TPREL64,
+  BFD_RELOC_RISCV_TLSDESC_HI20,
+  BFD_RELOC_RISCV_TLSDESC_LOAD_LO12,
+  BFD_RELOC_RISCV_TLSDESC_ADD_LO12,
+  BFD_RELOC_RISCV_TLSDESC_CALL,
   BFD_RELOC_RISCV_ALIGN,
   BFD_RELOC_RISCV_RVC_BRANCH,
   BFD_RELOC_RISCV_RVC_JUMP,
diff --git a/bfd/elfxx-riscv.c b/bfd/elfxx-riscv.c
index 9a121b47121..a4aa71fd809 100644
--- a/bfd/elfxx-riscv.c
+++ b/bfd/elfxx-riscv.c
@@ -218,7 +218,20 @@ static reloc_howto_type howto_table[] =
 	 MINUS_ONE,			/* dst_mask */
 	 false),			/* pcrel_offset */
 
-  EMPTY_HOWTO (12),
+  HOWTO (R_RISCV_TLSDESC,		/* type */
+	 0,				/* rightshift */
+	 0,				/* size is handled by dynamic linker */
+	 0,				/* bitsize */
+	 false,				/* pc_relative */
+	 0,				/* bitpos */
+	 complain_overflow_dont,	/* complain_on_overflow */
+	 bfd_elf_generic_reloc,		/* special_function */
+	 "R_RISCV_TLSDESC",		/* name */
+	 false,				/* partial_inplace */
+	 0,				/* src_mask */
+	 MINUS_ONE,			/* dst_mask */
+	 false),			/* pcrel_offset */
+
   EMPTY_HOWTO (13),
   EMPTY_HOWTO (14),
   EMPTY_HOWTO (15),
@@ -808,6 +821,62 @@ static reloc_howto_type howto_table[] =
 	 0,				/* src_mask */
 	 0,				/* dst_mask */
 	 false),			/* pcrel_offset */
+
+  HOWTO (R_RISCV_TLSDESC_HI20,		/* type */
+	 0,				/* rightshift */
+	 4,				/* size */
+	 32,				/* bitsize */
+	 true,				/* pc_relative */
+	 0,				/* bitpos */
+	 complain_overflow_dont,	/* complain_on_overflow */
+	 bfd_elf_generic_reloc,		/* special_function */
+	 "R_RISCV_TLSDESC_HI20",	/* name */
+	 true,				/* partial_inplace */
+	 0,				/* src_mask */
+	 ENCODE_UTYPE_IMM (-1U),	/* dst_mask */
+	 false),			/* pcrel_offset */
+
+  HOWTO (R_RISCV_TLSDESC_LOAD_LO12,	/* type */
+	 0,				/* rightshift */
+	 4,				/* size */
+	 32,				/* bitsize */
+	 false,				/* pc_relative */
+	 0,				/* bitpos */
+	 complain_overflow_dont,	/* complain_on_overflow */
+	 bfd_elf_generic_reloc,		/* special_function */
+	 "R_RISCV_TLSDESC_LOAD_LO12",	/* name */
+	 false,				/* partial_inplace */
+	 0,				/* src_mask */
+	 ENCODE_ITYPE_IMM (-1U),	/* dst_mask */
+	 false),			/* pcrel_offset */
+
+  HOWTO (R_RISCV_TLSDESC_ADD_LO12,	/* type */
+	 0,				/* rightshift */
+	 4,				/* size */
+	 32,				/* bitsize */
+	 false,				/* pc_relative */
+	 0,				/* bitpos */
+	 complain_overflow_dont,	/* complain_on_overflow */
+	 bfd_elf_generic_reloc,		/* special_function */
+	 "R_RISCV_TLSDESC_ADD_LO12",	/* name */
+	 false,				/* partial_inplace */
+	 0,				/* src_mask */
+	 ENCODE_ITYPE_IMM (-1U),	/* dst_mask */
+	 false), 			/* pcrel_offset */
+
+  HOWTO (R_RISCV_TLSDESC_CALL,		/* type */
+	 0,				/* rightshift */
+	 0,				/* size */
+	 0,				/* bitsize */
+	 false,				/* pc_relative */
+	 0,				/* bitpos */
+	 complain_overflow_dont,	/* complain_on_overflow */
+	 bfd_elf_generic_reloc,		/* special_function */
+	 "R_RISCV_TLSDESC_CALL",	/* name */
+	 false,				/* partial_inplace */
+	 0,				/* src_mask */
+	 ENCODE_ITYPE_IMM (-1U),	/* dst_mask */
+	 false) 			/* pcrel_offset */
 };
 
 static reloc_howto_type howto_table_internal[] =
@@ -935,6 +1004,10 @@ static const struct elf_reloc_map riscv_reloc_map[] =
   { BFD_RELOC_RISCV_TPREL_LO12_I, R_RISCV_TPREL_LO12_I },
   { BFD_RELOC_RISCV_TLS_GOT_HI20, R_RISCV_TLS_GOT_HI20 },
   { BFD_RELOC_RISCV_TLS_GD_HI20, R_RISCV_TLS_GD_HI20 },
+  { BFD_RELOC_RISCV_TLSDESC_HI20, R_RISCV_TLSDESC_HI20 },
+  { BFD_RELOC_RISCV_TLSDESC_LOAD_LO12, R_RISCV_TLSDESC_LOAD_LO12 },
+  { BFD_RELOC_RISCV_TLSDESC_ADD_LO12, R_RISCV_TLSDESC_ADD_LO12 },
+  { BFD_RELOC_RISCV_TLSDESC_CALL, R_RISCV_TLSDESC_CALL },
   { BFD_RELOC_RISCV_ALIGN, R_RISCV_ALIGN },
   { BFD_RELOC_RISCV_RVC_BRANCH, R_RISCV_RVC_BRANCH },
   { BFD_RELOC_RISCV_RVC_JUMP, R_RISCV_RVC_JUMP },
diff --git a/bfd/libbfd.h b/bfd/libbfd.h
index 40bbe6a3886..49f63a0b8e5 100644
--- a/bfd/libbfd.h
+++ b/bfd/libbfd.h
@@ -2409,6 +2409,10 @@ static const char *const bfd_reloc_code_real_names[] = { "@@uninitialized@@",
   "BFD_RELOC_RISCV_TLS_DTPREL64",
   "BFD_RELOC_RISCV_TLS_TPREL32",
   "BFD_RELOC_RISCV_TLS_TPREL64",
+  "BFD_RELOC_RISCV_TLSDESC_HI20",
+  "BFD_RELOC_RISCV_TLSDESC_LOAD_LO12",
+  "BFD_RELOC_RISCV_TLSDESC_ADD_LO12",
+  "BFD_RELOC_RISCV_TLSDESC_CALL",
   "BFD_RELOC_RISCV_ALIGN",
   "BFD_RELOC_RISCV_RVC_BRANCH",
   "BFD_RELOC_RISCV_RVC_JUMP",
diff --git a/bfd/reloc.c b/bfd/reloc.c
index 7583b7fd552..a187afe9b56 100644
--- a/bfd/reloc.c
+++ b/bfd/reloc.c
@@ -5002,6 +5002,14 @@ ENUMX
   BFD_RELOC_RISCV_TLS_TPREL32
 ENUMX
   BFD_RELOC_RISCV_TLS_TPREL64
+ENUMX
+  BFD_RELOC_RISCV_TLSDESC_HI20
+ENUMX
+  BFD_RELOC_RISCV_TLSDESC_LOAD_LO12
+ENUMX
+  BFD_RELOC_RISCV_TLSDESC_ADD_LO12
+ENUMX
+  BFD_RELOC_RISCV_TLSDESC_CALL
 ENUMX
   BFD_RELOC_RISCV_ALIGN
 ENUMX
diff --git a/include/elf/riscv.h b/include/elf/riscv.h
index 2000cf21b9d..c1e73f7f5c0 100644
--- a/include/elf/riscv.h
+++ b/include/elf/riscv.h
@@ -44,6 +44,7 @@ START_RELOC_NUMBERS (elf_riscv_reloc_type)
   RELOC_NUMBER (R_RISCV_TLS_DTPREL64, 9)
   RELOC_NUMBER (R_RISCV_TLS_TPREL32, 10)
   RELOC_NUMBER (R_RISCV_TLS_TPREL64, 11)
+  RELOC_NUMBER (R_RISCV_TLSDESC, 12)
 
   /* Relocation types not used by the dynamic linker.  */
   RELOC_NUMBER (R_RISCV_BRANCH, 16)
@@ -90,6 +91,10 @@ START_RELOC_NUMBERS (elf_riscv_reloc_type)
   /* Reserved 59 for R_RISCV_PLT32.  */
   RELOC_NUMBER (R_RISCV_SET_ULEB128, 60)
   RELOC_NUMBER (R_RISCV_SUB_ULEB128, 61)
+  RELOC_NUMBER (R_RISCV_TLSDESC_HI20, 62)
+  RELOC_NUMBER (R_RISCV_TLSDESC_LOAD_LO12, 63)
+  RELOC_NUMBER (R_RISCV_TLSDESC_ADD_LO12, 64)
+  RELOC_NUMBER (R_RISCV_TLSDESC_CALL, 65)
 END_RELOC_NUMBERS (R_RISCV_max)
 
 /* Internal relocations used exclusively by the relaxation pass.  */
-- 
2.43.2


^ permalink raw reply	[flat|nested] 49+ messages in thread

* [PATCH v4 3/9] RISC-V: Add assembly support for TLSDESC.
  2024-02-20 17:55 ` [PATCH v4 " Tatsuyuki Ishi
  2024-02-20 17:55   ` [PATCH v4 1/9] RISC-V: Fix local GOT and reloc size calculation for TLS Tatsuyuki Ishi
  2024-02-20 17:55   ` [PATCH v4 2/9] RISC-V: Add TLSDESC reloc definitions Tatsuyuki Ishi
@ 2024-02-20 17:55   ` Tatsuyuki Ishi
  2024-02-20 17:55   ` [PATCH v4 4/9] RISC-V: Define and use GOT entry size constants for TLS Tatsuyuki Ishi
                     ` (5 subsequent siblings)
  8 siblings, 0 replies; 49+ messages in thread
From: Tatsuyuki Ishi @ 2024-02-20 17:55 UTC (permalink / raw)
  To: binutils; +Cc: i, nelson, rui314, ruiu, Tatsuyuki Ishi

gas/
    * tc-riscv.c (percent_op_*): Add support for %tlsdesc_hi,
    %tlsdesc_load_lo, %tlsdesc_add_lo and %tlsdesc_call. percent_op_rtype
    renamed to percent_op_relax_only as this matcher is extended to handle
    jalr as well which is not R-type.
    (riscv_ip): Apply the percent_op_relax_only rename and update comment.
    (md_apply_fix): Add TLSDESC_* to relaxable list. Add TLSDESC_HI20 to
    TLS relocation check list.
    * testsuite/gas/riscv/tlsdesc.*: New test cases for TLSDESC relocation
    generation.
opcodes/
    * riscv-opc.c (riscv_opcodes): Add a new syntax for jalr with
    %tlsdesc_call annotations.
---
v4: Change test case to use objdump: -dr, and remove the rv32 arch
    restriction.

 gas/config/tc-riscv.c             | 18 +++++++++++-----
 gas/testsuite/gas/riscv/tlsdesc.d | 36 +++++++++++++++++++++++++++++++
 gas/testsuite/gas/riscv/tlsdesc.s | 24 +++++++++++++++++++++
 opcodes/riscv-opc.c               |  1 +
 4 files changed, 74 insertions(+), 5 deletions(-)
 create mode 100644 gas/testsuite/gas/riscv/tlsdesc.d
 create mode 100644 gas/testsuite/gas/riscv/tlsdesc.s

diff --git a/gas/config/tc-riscv.c b/gas/config/tc-riscv.c
index a4161420128..55c527520d5 100644
--- a/gas/config/tc-riscv.c
+++ b/gas/config/tc-riscv.c
@@ -2202,6 +2202,7 @@ static const struct percent_op_match percent_op_utype[] =
   {"tprel_hi", BFD_RELOC_RISCV_TPREL_HI20},
   {"pcrel_hi", BFD_RELOC_RISCV_PCREL_HI20},
   {"got_pcrel_hi", BFD_RELOC_RISCV_GOT_HI20},
+  {"tlsdesc_hi", BFD_RELOC_RISCV_TLSDESC_HI20},
   {"tls_ie_pcrel_hi", BFD_RELOC_RISCV_TLS_GOT_HI20},
   {"tls_gd_pcrel_hi", BFD_RELOC_RISCV_TLS_GD_HI20},
   {"hi", BFD_RELOC_RISCV_HI20},
@@ -2213,6 +2214,8 @@ static const struct percent_op_match percent_op_itype[] =
   {"lo", BFD_RELOC_RISCV_LO12_I},
   {"tprel_lo", BFD_RELOC_RISCV_TPREL_LO12_I},
   {"pcrel_lo", BFD_RELOC_RISCV_PCREL_LO12_I},
+  {"tlsdesc_load_lo", BFD_RELOC_RISCV_TLSDESC_LOAD_LO12},
+  {"tlsdesc_add_lo", BFD_RELOC_RISCV_TLSDESC_ADD_LO12},
   {0, 0}
 };
 
@@ -2224,8 +2227,9 @@ static const struct percent_op_match percent_op_stype[] =
   {0, 0}
 };
 
-static const struct percent_op_match percent_op_rtype[] =
+static const struct percent_op_match percent_op_relax_only[] =
 {
+  {"tlsdesc_call", BFD_RELOC_RISCV_TLSDESC_CALL},
   {"tprel_add", BFD_RELOC_RISCV_TPREL_ADD},
   {0, 0}
 };
@@ -3386,10 +3390,10 @@ riscv_ip (char *str, struct riscv_cl_insn *ip, expressionS *imm_expr,
 	      *imm_reloc = BFD_RELOC_RISCV_LO12_I;
 	      goto load_store;
 	    case '1':
-	      /* This is used for TLS, where the fourth operand is
-		 %tprel_add, to get a relocation applied to an add
-		 instruction, for relaxation to use.  */
-	      p = percent_op_rtype;
+	      /* This is used for TLS relocations that acts as relaxation
+		 markers and do not change the instruction encoding,
+		 i.e. %tprel_add and %tlsdesc_call.  */
+	      p = percent_op_relax_only;
 	      goto alu_op;
 	    case '0': /* AMO displacement, which must be zero.  */
 	    load_store:
@@ -4252,6 +4256,7 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
     case BFD_RELOC_RISCV_TPREL_LO12_I:
     case BFD_RELOC_RISCV_TPREL_LO12_S:
     case BFD_RELOC_RISCV_TPREL_ADD:
+    case BFD_RELOC_RISCV_TLSDESC_HI20:
       relaxable = true;
       /* Fall through.  */
 
@@ -4425,6 +4430,9 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
 
     case BFD_RELOC_RISCV_CALL:
     case BFD_RELOC_RISCV_CALL_PLT:
+    case BFD_RELOC_RISCV_TLSDESC_LOAD_LO12:
+    case BFD_RELOC_RISCV_TLSDESC_ADD_LO12:
+    case BFD_RELOC_RISCV_TLSDESC_CALL:
       relaxable = true;
       break;
 
diff --git a/gas/testsuite/gas/riscv/tlsdesc.d b/gas/testsuite/gas/riscv/tlsdesc.d
new file mode 100644
index 00000000000..5cd26ac3280
--- /dev/null
+++ b/gas/testsuite/gas/riscv/tlsdesc.d
@@ -0,0 +1,36 @@
+#source: tlsdesc.s
+#objdump: -dr
+
+.*:[ 	]+file format .*
+
+
+Disassembly of section .text:
+
+0+00 <_start>:
+[ 	]+0:[ 	]+00000517[ 	]+auipc[ 	]+a0,0x0
+[ 	]+0:[ 	]+R_RISCV_TLSDESC_HI20[ 	]+sg1
+[ 	]+0:[ 	]+R_RISCV_RELAX[ 	]+\*ABS\*
+[ 	]+4:[ 	]+00052283[ 	]+lw[ 	]+t0,0\(a0\) # 0( <.*>)?
+[ 	]+4:[ 	]+R_RISCV_TLSDESC_LOAD_LO12[ 	]+\.desc1
+[ 	]+4:[ 	]+R_RISCV_RELAX[ 	]+\*ABS\*
+[ 	]+8:[ 	]+00050513[ 	]+mv[ 	]+a0,a0
+[ 	]+8:[ 	]+R_RISCV_TLSDESC_ADD_LO12[ 	]+\.desc1
+[ 	]+8:[ 	]+R_RISCV_RELAX[ 	]+\*ABS\*
+[ 	]+c:[ 	]+000282e7[ 	]+jalr[ 	]+t0,t0
+[ 	]+c:[ 	]+R_RISCV_TLSDESC_CALL[ 	]+\.desc1
+[ 	]+c:[ 	]+R_RISCV_RELAX[ 	]+\*ABS\*
+
+0+10 <\.desc2>:
+[ 	]+10:[ 	]+00000517[ 	]+auipc[ 	]+a0,0x0
+[ 	]+10:[ 	]+R_RISCV_TLSDESC_HI20[ 	]+sl1
+[ 	]+10:[ 	]+R_RISCV_RELAX[ 	]+\*ABS\*
+[ 	]+14:[ 	]+00052283[ 	]+lw[ 	]+t0,0\(a0\) # 10( <.*>)?
+[ 	]+14:[ 	]+R_RISCV_TLSDESC_LOAD_LO12[ 	]+\.desc2
+[ 	]+14:[ 	]+R_RISCV_RELAX[ 	]+\*ABS\*
+[ 	]+18:[ 	]+00050513[ 	]+mv[ 	]+a0,a0
+[ 	]+18:[ 	]+R_RISCV_TLSDESC_ADD_LO12[ 	]+\.desc2
+[ 	]+18:[ 	]+R_RISCV_RELAX[ 	]+\*ABS\*
+[ 	]+1c:[ 	]+000282e7[ 	]+jalr[ 	]+t0,t0
+[ 	]+1c:[ 	]+R_RISCV_TLSDESC_CALL[ 	]+\.desc2
+[ 	]+1c:[ 	]+R_RISCV_RELAX[ 	]+\*ABS\*
+[ 	]+20:[ 	]+00008067[ 	]+ret
diff --git a/gas/testsuite/gas/riscv/tlsdesc.s b/gas/testsuite/gas/riscv/tlsdesc.s
new file mode 100644
index 00000000000..15468d5f947
--- /dev/null
+++ b/gas/testsuite/gas/riscv/tlsdesc.s
@@ -0,0 +1,24 @@
+	.section	.tbss,"awT",@nobits
+	.global sg1
+sg1:
+	.zero	4
+sl1:
+	.zero	4
+
+	.text
+	.globl	_start
+	.type	_start,@function
+_start:
+.desc1:
+	auipc	a0, %tlsdesc_hi(sg1)
+	lw	t0, %tlsdesc_load_lo(.desc1)(a0)
+	addi	a0, a0, %tlsdesc_add_lo(.desc1)
+	jalr	t0, t0, %tlsdesc_call(.desc1)
+
+.desc2:
+	auipc	a0, %tlsdesc_hi(sl1)
+	lw	t0, %tlsdesc_load_lo(.desc2)(a0)
+	addi	a0, a0, %tlsdesc_add_lo(.desc2)
+	jalr	t0, t0, %tlsdesc_call(.desc2)
+
+	ret
diff --git a/opcodes/riscv-opc.c b/opcodes/riscv-opc.c
index fdd05ac75dc..dcc592e1fc2 100644
--- a/opcodes/riscv-opc.c
+++ b/opcodes/riscv-opc.c
@@ -384,6 +384,7 @@ const struct riscv_opcode riscv_opcodes[] =
 {"jalr",        0, INSN_CLASS_I, "s,j",       MATCH_JALR|(X_RA << OP_SH_RD), MASK_JALR|MASK_RD, match_opcode, INSN_ALIAS|INSN_JSR },
 {"jalr",        0, INSN_CLASS_I, "d,s",       MATCH_JALR, MASK_JALR|MASK_IMM, match_opcode, INSN_ALIAS|INSN_JSR },
 {"jalr",        0, INSN_CLASS_I, "d,o(s)",    MATCH_JALR, MASK_JALR, match_opcode, INSN_JSR },
+{"jalr",        0, INSN_CLASS_I, "d,s,1",     MATCH_JALR, MASK_JALR|MASK_IMM, match_opcode, INSN_JSR },
 {"jalr",        0, INSN_CLASS_I, "d,s,j",     MATCH_JALR, MASK_JALR, match_opcode, INSN_JSR },
 {"j",           0, INSN_CLASS_C, "Ca",        MATCH_C_J, MASK_C_J, match_opcode, INSN_ALIAS|INSN_BRANCH },
 {"j",           0, INSN_CLASS_I, "a",         MATCH_JAL, MASK_JAL|MASK_RD, match_opcode, INSN_ALIAS|INSN_BRANCH },
-- 
2.43.2


^ permalink raw reply	[flat|nested] 49+ messages in thread

* [PATCH v4 4/9] RISC-V: Define and use GOT entry size constants for TLS.
  2024-02-20 17:55 ` [PATCH v4 " Tatsuyuki Ishi
                     ` (2 preceding siblings ...)
  2024-02-20 17:55   ` [PATCH v4 3/9] RISC-V: Add assembly support for TLSDESC Tatsuyuki Ishi
@ 2024-02-20 17:55   ` Tatsuyuki Ishi
  2024-02-20 17:55   ` [PATCH v4 5/9] RISC-V: Initial ld.bfd support for TLSDESC Tatsuyuki Ishi
                     ` (4 subsequent siblings)
  8 siblings, 0 replies; 49+ messages in thread
From: Tatsuyuki Ishi @ 2024-02-20 17:55 UTC (permalink / raw)
  To: binutils; +Cc: i, nelson, rui314, ruiu, Tatsuyuki Ishi

As the size calculation is split by global and local symbols, using a
shared constant definition for its size improves clarity.

bfd/
    * elfnn-riscv.c: Add macros for sizes of a normal GOT entry, TLS GD and
    TLS IE entry.
    (allocate_dynrelocs): Replace GOT size expressions with the new
    constants.
    (riscv_elf_size_dynamic_sections): Likewise.
    (riscv_elf_relocate_section): Likewise.
---
 bfd/elfnn-riscv.c | 16 +++++++++-------
 1 file changed, 9 insertions(+), 7 deletions(-)

diff --git a/bfd/elfnn-riscv.c b/bfd/elfnn-riscv.c
index e5cecd79cf3..17d44979d7e 100644
--- a/bfd/elfnn-riscv.c
+++ b/bfd/elfnn-riscv.c
@@ -298,6 +298,8 @@ riscv_is_insn_reloc (const reloc_howto_type *howto)
 #define PLT_HEADER_SIZE (PLT_HEADER_INSNS * 4)
 #define PLT_ENTRY_SIZE (PLT_ENTRY_INSNS * 4)
 #define GOT_ENTRY_SIZE RISCV_ELF_WORD_BYTES
+#define TLS_GD_GOT_ENTRY_SIZE (RISCV_ELF_WORD_BYTES * 2)
+#define TLS_IE_GOT_ENTRY_SIZE RISCV_ELF_WORD_BYTES
 /* Reserve two entries of GOTPLT for ld.so, one is used for PLT resolver,
    the other is used for link map.  Other targets also reserve one more
    entry used for runtime profile?  */
@@ -1320,7 +1322,7 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
 	  /* TLS_GD needs two dynamic relocs and two GOT slots.  */
 	  if (tls_type & GOT_TLS_GD)
 	    {
-	      s->size += 2 * RISCV_ELF_WORD_BYTES;
+	      s->size += TLS_GD_GOT_ENTRY_SIZE;
 	      if (need_reloc)
 		htab->elf.srelgot->size += 2 * sizeof (ElfNN_External_Rela);
 	    }
@@ -1328,14 +1330,14 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
 	  /* TLS_IE needs one dynamic reloc and one GOT slot.  */
 	  if (tls_type & GOT_TLS_IE)
 	    {
-	      s->size += RISCV_ELF_WORD_BYTES;
+	      s->size += TLS_IE_GOT_ENTRY_SIZE;
 	      if (need_reloc)
 		htab->elf.srelgot->size += sizeof (ElfNN_External_Rela);
 	    }
 	}
       else
 	{
-	  s->size += RISCV_ELF_WORD_BYTES;
+	  s->size += GOT_ENTRY_SIZE;
 	  if (WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, bfd_link_pic (info), h)
 	      && ! UNDEFWEAK_NO_DYNAMIC_RELOC (info, h))
 	    htab->elf.srelgot->size += sizeof (ElfNN_External_Rela);
@@ -1563,20 +1565,20 @@ riscv_elf_size_dynamic_sections (bfd *output_bfd, struct bfd_link_info *info)
 		{
 		  if (*local_tls_type & GOT_TLS_GD)
 		    {
-		      s->size += 2 * RISCV_ELF_WORD_BYTES;
+		      s->size += TLS_GD_GOT_ENTRY_SIZE;
 		      if (bfd_link_dll (info))
 			srel->size += sizeof (ElfNN_External_Rela);
 		    }
 		  if (*local_tls_type & GOT_TLS_IE)
 		    {
-		      s->size += RISCV_ELF_WORD_BYTES;
+		      s->size += TLS_IE_GOT_ENTRY_SIZE;
 		      if (bfd_link_dll (info))
 			srel->size += sizeof (ElfNN_External_Rela);
 		    }
 		}
 	      else
 		{
-		  s->size += RISCV_ELF_WORD_BYTES;
+		  s->size += GOT_ENTRY_SIZE;
 		  if (bfd_link_pic (info))
 		    srel->size += sizeof (ElfNN_External_Rela);
 		}
@@ -2928,7 +2930,7 @@ riscv_elf_relocate_section (bfd *output_bfd,
 	     reference's GOT slot follows the GD reference's slots.  */
 	  ie_off = 0;
 	  if ((tls_type & GOT_TLS_GD) && (tls_type & GOT_TLS_IE))
-	    ie_off = 2 * GOT_ENTRY_SIZE;
+	    ie_off = TLS_GD_GOT_ENTRY_SIZE;
 
 	  if ((off & 1) != 0)
 	    off &= ~1;
-- 
2.43.2


^ permalink raw reply	[flat|nested] 49+ messages in thread

* [PATCH v4 5/9] RISC-V: Initial ld.bfd support for TLSDESC.
  2024-02-20 17:55 ` [PATCH v4 " Tatsuyuki Ishi
                     ` (3 preceding siblings ...)
  2024-02-20 17:55   ` [PATCH v4 4/9] RISC-V: Define and use GOT entry size constants for TLS Tatsuyuki Ishi
@ 2024-02-20 17:55   ` Tatsuyuki Ishi
  2024-02-20 17:55   ` [PATCH v4 6/9] RISC-V: Move STATIC_TLS handling into record_tls_type Tatsuyuki Ishi
                     ` (3 subsequent siblings)
  8 siblings, 0 replies; 49+ messages in thread
From: Tatsuyuki Ishi @ 2024-02-20 17:55 UTC (permalink / raw)
  To: binutils; +Cc: i, nelson, rui314, ruiu, Tatsuyuki Ishi

Only relocation handling for now; relaxation is not implemented yet.

bfd/
    * elfnn-riscv.c (riscv_elf_check_relocs): Record GOT reference and
    paired relocation for TLSDESC_HI20.
    (riscv_elf_adjust_dynamic_symbol): Allocate GOT and reloc slots for
    TLSDESC symbols.
    (riscv_elf_size_dynamic_sections): Likewise but for local symbols.
    (tlsdescoff): New helper to determine static addend for R_TLSDESC.
    (riscv_elf_relocate_section): Ignore TLSDESC_CALL reloc for now (it is
    relaxation only).
    Handle TLSDESC_{LOAD,ADD}_LO12 as paired pcrel relocs.
    For TLS GOT slot generation, generalize the logic to handle any
    combination of (GD, IE, TLSDESC).
    Add TLSDESC Rela generation.
    * ld/testsuite/ld-riscv-elf/tls*: Add TLSDESC instruction sequences
    next to the existing GD and IE sequences. Update expectations.
---
v4: Reject non-zero addend for LO12.
    Calculate offset correctly when DESC and GD is present but not IE.

 bfd/elfnn-riscv.c                  | 104 +++++++++++++++++++++++++----
 ld/testsuite/ld-riscv-elf/tls.d    |   4 +-
 ld/testsuite/ld-riscv-elf/tls.s    |  14 ++++
 ld/testsuite/ld-riscv-elf/tlsbin.d |   5 ++
 4 files changed, 114 insertions(+), 13 deletions(-)

diff --git a/bfd/elfnn-riscv.c b/bfd/elfnn-riscv.c
index 17d44979d7e..16394110c6a 100644
--- a/bfd/elfnn-riscv.c
+++ b/bfd/elfnn-riscv.c
@@ -163,6 +163,7 @@ struct riscv_elf_link_hash_entry
 #define GOT_TLS_GD	2
 #define GOT_TLS_IE	4
 #define GOT_TLS_LE	8
+#define GOT_TLSDESC	16
   char tls_type;
 };
 
@@ -300,6 +301,7 @@ riscv_is_insn_reloc (const reloc_howto_type *howto)
 #define GOT_ENTRY_SIZE RISCV_ELF_WORD_BYTES
 #define TLS_GD_GOT_ENTRY_SIZE (RISCV_ELF_WORD_BYTES * 2)
 #define TLS_IE_GOT_ENTRY_SIZE RISCV_ELF_WORD_BYTES
+#define TLSDESC_GOT_ENTRY_SIZE (RISCV_ELF_WORD_BYTES * 2)
 /* Reserve two entries of GOTPLT for ld.so, one is used for PLT resolver,
    the other is used for link map.  Other targets also reserve one more
    entry used for runtime profile?  */
@@ -855,6 +857,12 @@ riscv_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
 	    return false;
 	  break;
 
+	case R_RISCV_TLSDESC_HI20:
+	  if (!riscv_elf_record_got_reference (abfd, info, h, r_symndx)
+	      || !riscv_elf_record_tls_type (abfd, h, r_symndx, GOT_TLSDESC))
+	    return false;
+	  break;
+
 	case R_RISCV_CALL:
 	case R_RISCV_CALL_PLT:
 	  /* These symbol requires a procedure linkage table entry.
@@ -1313,7 +1321,7 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
       s = htab->elf.sgot;
       h->got.offset = s->size;
       dyn = htab->elf.dynamic_sections_created;
-      if (tls_type & (GOT_TLS_GD | GOT_TLS_IE))
+      if (tls_type & (GOT_TLS_GD | GOT_TLS_IE | GOT_TLSDESC))
 	{
 	  int indx = 0;
 	  bool need_reloc = false;
@@ -1334,6 +1342,14 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
 	      if (need_reloc)
 		htab->elf.srelgot->size += sizeof (ElfNN_External_Rela);
 	    }
+
+	  /* TLSDESC needs one dynamic reloc and two GOT slots.  */
+	  if (tls_type & GOT_TLSDESC)
+	    {
+	      s->size += TLSDESC_GOT_ENTRY_SIZE;
+	      /* TLSDESC always use dynamic relocs.  */
+	      htab->elf.srelgot->size += sizeof (ElfNN_External_Rela);
+	    }
 	}
       else
 	{
@@ -1561,7 +1577,7 @@ riscv_elf_size_dynamic_sections (bfd *output_bfd, struct bfd_link_info *info)
 	  if (*local_got > 0)
 	    {
 	      *local_got = s->size;
-	      if (*local_tls_type & (GOT_TLS_GD | GOT_TLS_IE))
+	      if (*local_tls_type & (GOT_TLS_GD | GOT_TLS_IE | GOT_TLSDESC))
 		{
 		  if (*local_tls_type & GOT_TLS_GD)
 		    {
@@ -1575,6 +1591,11 @@ riscv_elf_size_dynamic_sections (bfd *output_bfd, struct bfd_link_info *info)
 		      if (bfd_link_dll (info))
 			srel->size += sizeof (ElfNN_External_Rela);
 		    }
+		  if (*local_tls_type & GOT_TLSDESC)
+		    {
+		      s->size += TLSDESC_GOT_ENTRY_SIZE;
+		      srel->size += sizeof (ElfNN_External_Rela);
+		    }
 		}
 	      else
 		{
@@ -1725,6 +1746,17 @@ tpoff (struct bfd_link_info *info, bfd_vma address)
   return address - elf_hash_table (info)->tls_sec->vma - TP_OFFSET;
 }
 
+/* Return the relocation value for a static TLSDESC relocation.  */
+
+static bfd_vma
+tlsdescoff (struct bfd_link_info *info, bfd_vma address)
+{
+  /* If tls_sec is NULL, we should have signalled an error already.  */
+  if (elf_hash_table (info)->tls_sec == NULL)
+    return 0;
+  return address - elf_hash_table (info)->tls_sec->vma;
+}
+
 /* Return the global pointer's value, or 0 if it is not in use.  */
 
 static bfd_vma
@@ -1764,6 +1796,7 @@ perform_relocation (const reloc_howto_type *howto,
     case R_RISCV_GOT_HI20:
     case R_RISCV_TLS_GOT_HI20:
     case R_RISCV_TLS_GD_HI20:
+    case R_RISCV_TLSDESC_HI20:
       if (ARCH_SIZE > 32 && !VALID_UTYPE_IMM (RISCV_CONST_HIGH_PART (value)))
 	return bfd_reloc_overflow;
       value = ENCODE_UTYPE_IMM (RISCV_CONST_HIGH_PART (value));
@@ -1774,6 +1807,8 @@ perform_relocation (const reloc_howto_type *howto,
     case R_RISCV_TPREL_LO12_I:
     case R_RISCV_TPREL_I:
     case R_RISCV_PCREL_LO12_I:
+    case R_RISCV_TLSDESC_LOAD_LO12:
+    case R_RISCV_TLSDESC_ADD_LO12:
       value = ENCODE_ITYPE_IMM (value);
       break;
 
@@ -2192,8 +2227,8 @@ riscv_elf_relocate_section (bfd *output_bfd,
       bfd_vma relocation;
       bfd_reloc_status_type r = bfd_reloc_ok;
       const char *name = NULL;
-      bfd_vma off, ie_off;
-      bool unresolved_reloc, is_ie = false;
+      bfd_vma off, ie_off, desc_off;
+      bool unresolved_reloc, is_ie = false, is_desc = false;
       bfd_vma pc = sec_addr (input_section) + rel->r_offset;
       int r_type = ELFNN_R_TYPE (rel->r_info), tls_type;
       reloc_howto_type *howto = riscv_elf_rtype_to_howto (input_bfd, r_type);
@@ -2496,6 +2531,7 @@ riscv_elf_relocate_section (bfd *output_bfd,
 	case R_RISCV_NONE:
 	case R_RISCV_RELAX:
 	case R_RISCV_TPREL_ADD:
+	case R_RISCV_TLSDESC_CALL:
 	case R_RISCV_COPY:
 	case R_RISCV_JUMP_SLOT:
 	case R_RISCV_RELATIVE:
@@ -2843,6 +2879,22 @@ riscv_elf_relocate_section (bfd *output_bfd,
 	  relocation = dtpoff (info, relocation);
 	  break;
 
+	case R_RISCV_TLSDESC_LOAD_LO12:
+	case R_RISCV_TLSDESC_ADD_LO12:
+	  if (rel->r_addend)
+	    {
+	      msg = _("%tlsdesc_lo with addend");
+	      r = bfd_reloc_dangerous;
+	      break;
+	    }
+
+	  if (riscv_record_pcrel_lo_reloc (&pcrel_relocs, relocation, rel,
+					   input_section, info, howto,
+					   contents))
+	      continue;
+	  r = bfd_reloc_overflow;
+	  break;
+
 	case R_RISCV_32:
 	  /* Non ABS symbol should be blocked in check_relocs.  */
 	  if (ARCH_SIZE > 32)
@@ -2908,11 +2960,16 @@ riscv_elf_relocate_section (bfd *output_bfd,
 	    }
 	  break;
 
+	case R_RISCV_TLSDESC_HI20:
+	  is_desc = true;
+	  goto tls;
+
 	case R_RISCV_TLS_GOT_HI20:
 	  is_ie = true;
-	  /* Fall through.  */
+	  goto tls;
 
 	case R_RISCV_TLS_GD_HI20:
+	tls:
 	  if (h != NULL)
 	    {
 	      off = h->got.offset;
@@ -2925,12 +2982,16 @@ riscv_elf_relocate_section (bfd *output_bfd,
 	    }
 
 	  tls_type = _bfd_riscv_elf_tls_type (input_bfd, h, r_symndx);
-	  BFD_ASSERT (tls_type & (GOT_TLS_IE | GOT_TLS_GD));
-	  /* If this symbol is referenced by both GD and IE TLS, the IE
-	     reference's GOT slot follows the GD reference's slots.  */
+	  BFD_ASSERT (tls_type & (GOT_TLS_IE | GOT_TLS_GD | GOT_TLSDESC));
+	  /* When more than one TLS type is used, the GD slot comes first,
+	     then IE, then finally TLSDESC.  */
 	  ie_off = 0;
-	  if ((tls_type & GOT_TLS_GD) && (tls_type & GOT_TLS_IE))
-	    ie_off = TLS_GD_GOT_ENTRY_SIZE;
+	  if (tls_type & GOT_TLS_GD)
+	    ie_off += TLS_GD_GOT_ENTRY_SIZE;
+
+	  desc_off = ie_off;
+	  if (tls_type & GOT_TLS_IE)
+	    desc_off += TLS_IE_GOT_ENTRY_SIZE;
 
 	  if ((off & 1) != 0)
 	    off &= ~1;
@@ -3012,10 +3073,29 @@ riscv_elf_relocate_section (bfd *output_bfd,
 				  htab->elf.sgot->contents + off + ie_off);
 		    }
 		}
+
+	      if (tls_type & GOT_TLSDESC)
+		{
+		  /* TLSDESC is always handled by the dynamic linker and always need
+		   * a relocation.  */
+		  bfd_put_NN (output_bfd, 0,
+			      htab->elf.sgot->contents + off + desc_off);
+		  outrel.r_offset = sec_addr (htab->elf.sgot)
+				    + off + desc_off;
+		  outrel.r_addend = 0;
+		  if (indx == 0)
+		    outrel.r_addend = tlsdescoff (info, relocation);
+		  outrel.r_info = ELFNN_R_INFO (indx, R_RISCV_TLSDESC);
+		  riscv_elf_append_rela (output_bfd, htab->elf.srelgot, &outrel);
+		}
 	    }
 
 	  BFD_ASSERT (off < (bfd_vma) -2);
-	  relocation = sec_addr (htab->elf.sgot) + off + (is_ie ? ie_off : 0);
+	  relocation = sec_addr (htab->elf.sgot) + off;
+	  if (is_ie)
+	    relocation += ie_off;
+	  else if (is_desc)
+	    relocation += desc_off;
 	  if (!riscv_record_pcrel_hi_reloc (&pcrel_relocs, pc,
 					    relocation, r_type,
 					    false))
@@ -3235,7 +3315,7 @@ riscv_elf_finish_dynamic_symbol (bfd *output_bfd,
     }
 
   if (h->got.offset != (bfd_vma) -1
-      && !(riscv_elf_hash_entry (h)->tls_type & (GOT_TLS_GD | GOT_TLS_IE))
+      && !(riscv_elf_hash_entry (h)->tls_type & (GOT_TLS_GD | GOT_TLS_IE | GOT_TLSDESC))
       && !UNDEFWEAK_NO_DYNAMIC_RELOC (info, h))
     {
       asection *sgot;
diff --git a/ld/testsuite/ld-riscv-elf/tls.d b/ld/testsuite/ld-riscv-elf/tls.d
index e7f20309bf1..6cf008ac7a0 100644
--- a/ld/testsuite/ld-riscv-elf/tls.d
+++ b/ld/testsuite/ld-riscv-elf/tls.d
@@ -2,13 +2,15 @@
 #ld: --shared tmpdir/tlslib.so
 #readelf: -Wr
 
-Relocation section '.rela.dyn' at offset 0x[0-9a-f]+ contains 5 entries:
+Relocation section '.rela.dyn' at offset 0x[0-9a-f]+ contains 7 entries:
  +Offset +Info +Type +Symbol's Value +Symbol's Name \+ Addend
 [0-9a-f]+ +[0-9a-f]+ R_RISCV_TLS_DTPMOD64 +0
 [0-9a-f]+ +[0-9a-f]+ R_RISCV_TLS_TPREL64 +4
+[0-9a-f]+ +[0-9a-f]+ R_RISCV_TLSDESC +4
 [0-9a-f]+ +[0-9a-f]+ R_RISCV_TLS_DTPMOD64 +0+ sg1 \+ 0
 [0-9a-f]+ +[0-9a-f]+ R_RISCV_TLS_DTPREL64 +0+ sg1 \+ 0
 [0-9a-f]+ +[0-9a-f]+ R_RISCV_TLS_TPREL64 +0+ sg1 \+ 0
+[0-9a-f]+ +[0-9a-f]+ R_RISCV_TLSDESC +0+ sg1 \+ 0
 
 Relocation section '.rela.plt' at offset 0x[0-9a-f]+ contains 1 entry:
  +Offset +Info +Type +Symbol's Value +Symbol's Name \+ Addend
diff --git a/ld/testsuite/ld-riscv-elf/tls.s b/ld/testsuite/ld-riscv-elf/tls.s
index 79e9bc20374..7cbf5ea6c72 100644
--- a/ld/testsuite/ld-riscv-elf/tls.s
+++ b/ld/testsuite/ld-riscv-elf/tls.s
@@ -17,6 +17,13 @@ _start:
 	la.tls.ie	a0,sg1
 	add	a0,a0,tp
 
+	/* GD (TLSDESC), global var */
+.desc1:
+	auipc	a0, %tlsdesc_hi(sg1)
+	lw	t0, %tlsdesc_load_lo(.desc1)(a0)
+	addi	a0, a0, %tlsdesc_add_lo(.desc1)
+	jalr	t0, t0, %tlsdesc_call(.desc1)
+
 	/* GD, local var */
 	la.tls.gd	a0,sl1
 	call  __tls_get_addr
@@ -25,4 +32,11 @@ _start:
 	la.tls.ie	a0,sl1
 	add	a0,a0,tp
 
+	/* GD (TLSDESC), local var */
+.desc2:
+	auipc	a0, %tlsdesc_hi(sl1)
+	lw	t0, %tlsdesc_load_lo(.desc2)(a0)
+	addi	a0, a0, %tlsdesc_add_lo(.desc2)
+	jalr	t0, t0, %tlsdesc_call(.desc2)
+
 	ret
diff --git a/ld/testsuite/ld-riscv-elf/tlsbin.d b/ld/testsuite/ld-riscv-elf/tlsbin.d
index cdcd51a9199..79b7ade405e 100644
--- a/ld/testsuite/ld-riscv-elf/tlsbin.d
+++ b/ld/testsuite/ld-riscv-elf/tlsbin.d
@@ -2,6 +2,11 @@
 #ld: -no-pie tmpdir/tlslib.so
 #readelf: -Wr
 
+Relocation section '.rela.dyn' at offset 0x[0-9a-f]+ contains 2 entries:
+ +Offset +Info +Type +Symbol's Value +Symbol's Name \+ Addend
+[0-9a-f]+ +[0-9a-f]+ R_RISCV_TLSDESC +4
+[0-9a-f]+ +[0-9a-f]+ R_RISCV_TLSDESC +0
+
 Relocation section '.rela.plt' at offset 0x[0-9a-f]+ contains 1 entry:
  +Offset +Info +Type +Symbol's Value +Symbol's Name \+ Addend
 [0-9a-f]+ +[0-9a-f]+ R_RISCV_JUMP_SLOT +[0-9a-f]+ __tls_get_addr \+ 0
-- 
2.43.2


^ permalink raw reply	[flat|nested] 49+ messages in thread

* [PATCH v4 6/9] RISC-V: Move STATIC_TLS handling into record_tls_type.
  2024-02-20 17:55 ` [PATCH v4 " Tatsuyuki Ishi
                     ` (4 preceding siblings ...)
  2024-02-20 17:55   ` [PATCH v4 5/9] RISC-V: Initial ld.bfd support for TLSDESC Tatsuyuki Ishi
@ 2024-02-20 17:55   ` Tatsuyuki Ishi
  2024-02-20 17:55   ` [PATCH v4 7/9] RISC-V: Unify TLS handling in check_relocs Tatsuyuki Ishi
                     ` (2 subsequent siblings)
  8 siblings, 0 replies; 49+ messages in thread
From: Tatsuyuki Ishi @ 2024-02-20 17:55 UTC (permalink / raw)
  To: binutils; +Cc: i, nelson, rui314, ruiu, Tatsuyuki Ishi

bfd/Changelog:
	* elfnn-riscv.c (riscv_elf_record_tls_type): Add bfd_link_info
	parameter and move code from below.
	(riscv_elf_check_relocs): Move STATIC_TLS handling into
	riscv_elf_record_tls_type.
	Add missing early return in the R_RISCV_TPREL_HI20 case.
---
 bfd/elfnn-riscv.c | 27 ++++++++++++++++++---------
 1 file changed, 18 insertions(+), 9 deletions(-)

diff --git a/bfd/elfnn-riscv.c b/bfd/elfnn-riscv.c
index 16394110c6a..1594856ccef 100644
--- a/bfd/elfnn-riscv.c
+++ b/bfd/elfnn-riscv.c
@@ -663,12 +663,14 @@ riscv_elf_copy_indirect_symbol (struct bfd_link_info *info,
 }
 
 static bool
-riscv_elf_record_tls_type (bfd *abfd, struct elf_link_hash_entry *h,
+riscv_elf_record_tls_type (bfd *abfd, struct bfd_link_info *info,
+			   struct elf_link_hash_entry *h,
 			   unsigned long symndx, char tls_type)
 {
   char *new_tls_type = &_bfd_riscv_elf_tls_type (abfd, h, symndx);
 
   *new_tls_type |= tls_type;
+
   if ((*new_tls_type & GOT_NORMAL) && (*new_tls_type & ~GOT_NORMAL))
     {
       (*_bfd_error_handler)
@@ -676,6 +678,10 @@ riscv_elf_record_tls_type (bfd *abfd, struct elf_link_hash_entry *h,
 	 abfd, h ? h->root.root.string : "<local>");
       return false;
     }
+
+  if ((*new_tls_type & GOT_TLS_IE) && bfd_link_dll (info))
+    info->flags |= DF_STATIC_TLS;
+
   return true;
 }
 
@@ -839,27 +845,29 @@ riscv_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
 	{
 	case R_RISCV_TLS_GD_HI20:
 	  if (!riscv_elf_record_got_reference (abfd, info, h, r_symndx)
-	      || !riscv_elf_record_tls_type (abfd, h, r_symndx, GOT_TLS_GD))
+	      || !riscv_elf_record_tls_type (abfd, info, h, r_symndx,
+					     GOT_TLS_GD))
 	    return false;
 	  break;
 
 	case R_RISCV_TLS_GOT_HI20:
-	  if (bfd_link_dll (info))
-	    info->flags |= DF_STATIC_TLS;
 	  if (!riscv_elf_record_got_reference (abfd, info, h, r_symndx)
-	      || !riscv_elf_record_tls_type (abfd, h, r_symndx, GOT_TLS_IE))
+	      || !riscv_elf_record_tls_type (abfd, info, h, r_symndx,
+					     GOT_TLS_IE))
 	    return false;
 	  break;
 
 	case R_RISCV_GOT_HI20:
 	  if (!riscv_elf_record_got_reference (abfd, info, h, r_symndx)
-	      || !riscv_elf_record_tls_type (abfd, h, r_symndx, GOT_NORMAL))
+	      || !riscv_elf_record_tls_type (abfd, info, h, r_symndx,
+					     GOT_NORMAL))
 	    return false;
 	  break;
 
 	case R_RISCV_TLSDESC_HI20:
 	  if (!riscv_elf_record_got_reference (abfd, info, h, r_symndx)
-	      || !riscv_elf_record_tls_type (abfd, h, r_symndx, GOT_TLSDESC))
+	      || !riscv_elf_record_tls_type (abfd, info, h, r_symndx,
+					     GOT_TLSDESC))
 	    return false;
 	  break;
 
@@ -949,8 +957,9 @@ riscv_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
 	  /* This is not allowed in the pic, but okay in pie.  */
 	  if (!bfd_link_executable (info))
 	    return bad_static_reloc (abfd, r_type, h);
-	  if (h != NULL)
-	    riscv_elf_record_tls_type (abfd, h, r_symndx, GOT_TLS_LE);
+	  if (h != NULL
+	      && !riscv_elf_record_tls_type (abfd, info, h, r_symndx, GOT_TLS_LE))
+	    return false;
 	  break;
 
 	case R_RISCV_HI20:
-- 
2.43.2


^ permalink raw reply	[flat|nested] 49+ messages in thread

* [PATCH v4 7/9] RISC-V: Unify TLS handling in check_relocs.
  2024-02-20 17:55 ` [PATCH v4 " Tatsuyuki Ishi
                     ` (5 preceding siblings ...)
  2024-02-20 17:55   ` [PATCH v4 6/9] RISC-V: Move STATIC_TLS handling into record_tls_type Tatsuyuki Ishi
@ 2024-02-20 17:55   ` Tatsuyuki Ishi
  2024-02-20 17:55   ` [PATCH v4 8/9] RISC-V: Add elf_link_hash_entry to relax_func args Tatsuyuki Ishi
  2024-02-20 17:55   ` [PATCH v4 9/9] RISC-V: Introduce TLSDESC relaxation Tatsuyuki Ishi
  8 siblings, 0 replies; 49+ messages in thread
From: Tatsuyuki Ishi @ 2024-02-20 17:55 UTC (permalink / raw)
  To: binutils; +Cc: i, nelson, rui314, ruiu, Tatsuyuki Ishi

With the introduction of transition, multiple relocation types may map to
GOT_TLS_IE or GOT_TLS_LE and it makes more sense to unify the code path to
perform checks common to them.

bfd/
	* elfnn-riscv.c (riscv_elf_check_relocs): Merge switch cases for
	TLS relocs.
---
 bfd/elfnn-riscv.c | 64 +++++++++++++++++++++++++++--------------------
 1 file changed, 37 insertions(+), 27 deletions(-)

diff --git a/bfd/elfnn-riscv.c b/bfd/elfnn-riscv.c
index 1594856ccef..1fbb0698ce1 100644
--- a/bfd/elfnn-riscv.c
+++ b/bfd/elfnn-riscv.c
@@ -662,6 +662,24 @@ riscv_elf_copy_indirect_symbol (struct bfd_link_info *info,
   _bfd_elf_link_hash_copy_indirect (info, dir, ind);
 }
 
+static char
+riscv_elf_tls_type_from_hi_reloc (unsigned int r_type)
+{
+  switch (r_type)
+    {
+      case R_RISCV_TLS_GD_HI20:
+	return GOT_TLS_GD;
+      case R_RISCV_TLS_GOT_HI20:
+	return GOT_TLS_IE;
+      case R_RISCV_TLSDESC_HI20:
+	return GOT_TLSDESC;
+      case R_RISCV_TPREL_HI20:
+	return GOT_TLS_LE;
+      default:
+	abort ();
+    }
+}
+
 static bool
 riscv_elf_record_tls_type (bfd *abfd, struct bfd_link_info *info,
 			   struct elf_link_hash_entry *h,
@@ -843,19 +861,26 @@ riscv_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
 
       switch (r_type)
 	{
-	case R_RISCV_TLS_GD_HI20:
-	  if (!riscv_elf_record_got_reference (abfd, info, h, r_symndx)
-	      || !riscv_elf_record_tls_type (abfd, info, h, r_symndx,
-					     GOT_TLS_GD))
-	    return false;
-	  break;
+	  case R_RISCV_TLS_GD_HI20:
+	  case R_RISCV_TLS_GOT_HI20:
+	  case R_RISCV_TLSDESC_HI20:
+	  case R_RISCV_TPREL_HI20:
+	    {
+	      char tls_type = riscv_elf_tls_type_from_hi_reloc (r_type);
 
-	case R_RISCV_TLS_GOT_HI20:
-	  if (!riscv_elf_record_got_reference (abfd, info, h, r_symndx)
-	      || !riscv_elf_record_tls_type (abfd, info, h, r_symndx,
-					     GOT_TLS_IE))
-	    return false;
-	  break;
+	      /* Local exec is only allowed for executables.  */
+	      if (tls_type == GOT_TLS_LE && !bfd_link_executable (info))
+		return bad_static_reloc (abfd, r_type, h);
+
+	      if (tls_type != GOT_TLS_LE
+		  && !riscv_elf_record_got_reference (abfd, info, h, r_symndx))
+		return false;
+	      if ((tls_type != GOT_TLS_LE || h != NULL)
+		  && !riscv_elf_record_tls_type (abfd, info, h, r_symndx,
+						 tls_type))
+		return false;
+	      break;
+	    }
 
 	case R_RISCV_GOT_HI20:
 	  if (!riscv_elf_record_got_reference (abfd, info, h, r_symndx)
@@ -864,12 +889,6 @@ riscv_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
 	    return false;
 	  break;
 
-	case R_RISCV_TLSDESC_HI20:
-	  if (!riscv_elf_record_got_reference (abfd, info, h, r_symndx)
-	      || !riscv_elf_record_tls_type (abfd, info, h, r_symndx,
-					     GOT_TLSDESC))
-	    return false;
-	  break;
 
 	case R_RISCV_CALL:
 	case R_RISCV_CALL_PLT:
@@ -953,15 +972,6 @@ riscv_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
 	    break;
 	  goto static_reloc;
 
-	case R_RISCV_TPREL_HI20:
-	  /* This is not allowed in the pic, but okay in pie.  */
-	  if (!bfd_link_executable (info))
-	    return bad_static_reloc (abfd, r_type, h);
-	  if (h != NULL
-	      && !riscv_elf_record_tls_type (abfd, info, h, r_symndx, GOT_TLS_LE))
-	    return false;
-	  break;
-
 	case R_RISCV_HI20:
 	  if (bfd_link_pic (info))
 	    return bad_static_reloc (abfd, r_type, h);
-- 
2.43.2


^ permalink raw reply	[flat|nested] 49+ messages in thread

* [PATCH v4 8/9] RISC-V: Add elf_link_hash_entry to relax_func args.
  2024-02-20 17:55 ` [PATCH v4 " Tatsuyuki Ishi
                     ` (6 preceding siblings ...)
  2024-02-20 17:55   ` [PATCH v4 7/9] RISC-V: Unify TLS handling in check_relocs Tatsuyuki Ishi
@ 2024-02-20 17:55   ` Tatsuyuki Ishi
  2024-02-20 17:55   ` [PATCH v4 9/9] RISC-V: Introduce TLSDESC relaxation Tatsuyuki Ishi
  8 siblings, 0 replies; 49+ messages in thread
From: Tatsuyuki Ishi @ 2024-02-20 17:55 UTC (permalink / raw)
  To: binutils; +Cc: i, nelson, rui314, ruiu, Tatsuyuki Ishi

bfd/
	* elfnn-riscv.c (riscv_pcgp_hi_reloc): Add a field for hash_entry.
	(riscv_record_pcgp_hi_reloc): Add argument and record the
	hash_entry.
	(_bfd_riscv_relax_*): Add unused hash_entry argument.
	(_bfd_riscv_relax_pc): Also record the hash_entry, for consistency
	 (but it is not used by the LO reloc handling).
	(_bfd_riscv_relax_section): Move h to outer scope and pass into
	relax helpers.
---
 bfd/elfnn-riscv.c | 14 ++++++++++++--
 1 file changed, 12 insertions(+), 2 deletions(-)

diff --git a/bfd/elfnn-riscv.c b/bfd/elfnn-riscv.c
index 1fbb0698ce1..acc45ebb549 100644
--- a/bfd/elfnn-riscv.c
+++ b/bfd/elfnn-riscv.c
@@ -4235,6 +4235,7 @@ struct riscv_pcgp_hi_reloc
   bfd_vma hi_addr;
   unsigned hi_sym;
   asection *sym_sec;
+  struct elf_link_hash_entry *h;
   bool undefined_weak;
   riscv_pcgp_hi_reloc *next;
 };
@@ -4295,6 +4296,7 @@ static bool
 riscv_record_pcgp_hi_reloc (riscv_pcgp_relocs *p, bfd_vma hi_sec_off,
 			    bfd_vma hi_addend, bfd_vma hi_addr,
 			    unsigned hi_sym, asection *sym_sec,
+			    struct elf_link_hash_entry *h,
 			    bool undefined_weak)
 {
   riscv_pcgp_hi_reloc *new = bfd_malloc (sizeof (*new));
@@ -4305,6 +4307,7 @@ riscv_record_pcgp_hi_reloc (riscv_pcgp_relocs *p, bfd_vma hi_sec_off,
   new->hi_addr = hi_addr;
   new->hi_sym = hi_sym;
   new->sym_sec = sym_sec;
+  new->h = h;
   new->undefined_weak = undefined_weak;
   new->next = p->hi;
   p->hi = new;
@@ -4607,6 +4610,7 @@ riscv_relax_resolve_delete_relocs (bfd *abfd,
 
 typedef bool (*relax_func_t) (bfd *, asection *, asection *,
 			      struct bfd_link_info *,
+			      struct elf_link_hash_entry *,
 			      Elf_Internal_Rela *,
 			      bfd_vma, bfd_vma, bfd_vma, bool *,
 			      riscv_pcgp_relocs *,
@@ -4617,6 +4621,7 @@ typedef bool (*relax_func_t) (bfd *, asection *, asection *,
 static bool
 _bfd_riscv_relax_call (bfd *abfd, asection *sec, asection *sym_sec,
 		       struct bfd_link_info *link_info,
+		       struct elf_link_hash_entry *_h ATTRIBUTE_UNUSED,
 		       Elf_Internal_Rela *rel,
 		       bfd_vma symval,
 		       bfd_vma max_alignment,
@@ -4723,6 +4728,7 @@ _bfd_riscv_relax_lui (bfd *abfd,
 		      asection *sec,
 		      asection *sym_sec,
 		      struct bfd_link_info *link_info,
+		      struct elf_link_hash_entry *_h ATTRIBUTE_UNUSED,
 		      Elf_Internal_Rela *rel,
 		      bfd_vma symval,
 		      bfd_vma max_alignment,
@@ -4836,6 +4842,7 @@ _bfd_riscv_relax_tls_le (bfd *abfd,
 			 asection *sec,
 			 asection *sym_sec ATTRIBUTE_UNUSED,
 			 struct bfd_link_info *link_info,
+			 struct elf_link_hash_entry *_h ATTRIBUTE_UNUSED,
 			 Elf_Internal_Rela *rel,
 			 bfd_vma symval,
 			 bfd_vma max_alignment ATTRIBUTE_UNUSED,
@@ -4878,6 +4885,7 @@ static bool
 _bfd_riscv_relax_align (bfd *abfd, asection *sec,
 			asection *sym_sec,
 			struct bfd_link_info *link_info,
+			struct elf_link_hash_entry *_h ATTRIBUTE_UNUSED,
 			Elf_Internal_Rela *rel,
 			bfd_vma symval,
 			bfd_vma max_alignment ATTRIBUTE_UNUSED,
@@ -4938,6 +4946,7 @@ _bfd_riscv_relax_pc (bfd *abfd ATTRIBUTE_UNUSED,
 		     asection *sec,
 		     asection *sym_sec,
 		     struct bfd_link_info *link_info,
+		     struct elf_link_hash_entry *_h,
 		     Elf_Internal_Rela *rel,
 		     bfd_vma symval,
 		     bfd_vma max_alignment,
@@ -5058,6 +5067,7 @@ _bfd_riscv_relax_pc (bfd *abfd ATTRIBUTE_UNUSED,
 				      symval,
 				      ELFNN_R_SYM(rel->r_info),
 				      sym_sec,
+				      _h,
 				      undefined_weak);
 	  /* Delete unnecessary AUIPC and reuse the reloc.  */
 	  *again = true;
@@ -5147,6 +5157,7 @@ _bfd_riscv_relax_section (bfd *abfd, asection *sec,
   /* Examine and consider relaxing each reloc.  */
   for (i = 0; i < sec->reloc_count; i++)
     {
+      struct elf_link_hash_entry *h = NULL;
       asection *sym_sec;
       Elf_Internal_Rela *rel = relocs + i;
       relax_func_t relax_func;
@@ -5249,7 +5260,6 @@ _bfd_riscv_relax_section (bfd *abfd, asection *sec,
       else
 	{
 	  unsigned long indx;
-	  struct elf_link_hash_entry *h;
 
 	  indx = ELFNN_R_SYM (rel->r_info) - symtab_hdr->sh_info;
 	  h = elf_sym_hashes (abfd)[indx];
@@ -5351,7 +5361,7 @@ _bfd_riscv_relax_section (bfd *abfd, asection *sec,
 
       symval += sec_addr (sym_sec);
 
-      if (!relax_func (abfd, sec, sym_sec, info, rel, symval,
+      if (!relax_func (abfd, sec, sym_sec, info, h, rel, symval,
 		       max_alignment, reserve_size, again,
 		       &pcgp_relocs, undefined_weak))
 	goto fail;
-- 
2.43.2


^ permalink raw reply	[flat|nested] 49+ messages in thread

* [PATCH v4 9/9] RISC-V: Introduce TLSDESC relaxation.
  2024-02-20 17:55 ` [PATCH v4 " Tatsuyuki Ishi
                     ` (7 preceding siblings ...)
  2024-02-20 17:55   ` [PATCH v4 8/9] RISC-V: Add elf_link_hash_entry to relax_func args Tatsuyuki Ishi
@ 2024-02-20 17:55   ` Tatsuyuki Ishi
  8 siblings, 0 replies; 49+ messages in thread
From: Tatsuyuki Ishi @ 2024-02-20 17:55 UTC (permalink / raw)
  To: binutils; +Cc: i, nelson, rui314, ruiu, Tatsuyuki Ishi

For now, only the 2 instruction (long) forms. This allows static binaries
to correctly execute when TLSDESC is used.

bfd/
	* elfnn-riscv.c (riscv_elf_tls_type_from_hi_reloc): Decide TLS type
	based on relaxation eligibility as well.
	(riscv_elf_check_relocs): Pass the required eligibility information to
	riscv_elf_tls_type_from_hi_reloc.
	(perform_relocation): Handle encoding for TLSDESC relaxation
	relocations.
	(riscv_elf_relocate_section): Emit relaxation instruction sequence.
	(_bfd_riscv_relax_tlsdesc): Added for handling of relaxable TLSDESC
	relocs.
	(_bfd_riscv_relax_section): Call _bfd_riscv_relax_tlsdesc when
	eligible.
	* elfxx-riscv.c (howto_table_internal): Add internal relocations
	for TLSDESC -> LE / IE relaxation.
include/
	elf/riscv.h: Add internal relocations, same as above.
	opcode/riscv.h: Add X_A0 for use in TLSDESC relaxation sequence.
ld/
	* testsuite/ld-riscv-elf/tlsbin.d: Remove TLSDESC relocs from
	expectation to now that we have relaxation.
---
v4: Remove addend from lo-hi calculation since it's required to be 0.

 bfd/elfnn-riscv.c                  | 144 ++++++++++++++++++++++++++++-
 bfd/elfxx-riscv.c                  |  55 +++++++++++
 include/elf/riscv.h                |  16 ++--
 include/opcode/riscv.h             |   1 +
 ld/testsuite/ld-riscv-elf/tlsbin.d |   5 -
 5 files changed, 207 insertions(+), 14 deletions(-)

diff --git a/bfd/elfnn-riscv.c b/bfd/elfnn-riscv.c
index acc45ebb549..43db8f1b5c0 100644
--- a/bfd/elfnn-riscv.c
+++ b/bfd/elfnn-riscv.c
@@ -663,8 +663,12 @@ riscv_elf_copy_indirect_symbol (struct bfd_link_info *info,
 }
 
 static char
-riscv_elf_tls_type_from_hi_reloc (unsigned int r_type)
+riscv_elf_tls_type_from_hi_reloc (struct bfd_link_info *info,
+				  unsigned int r_type,
+				  struct elf_link_hash_entry *h,
+				  bool can_relax)
 {
+  bool local_exec = SYMBOL_REFERENCES_LOCAL (info, h);
   switch (r_type)
     {
       case R_RISCV_TLS_GD_HI20:
@@ -672,7 +676,10 @@ riscv_elf_tls_type_from_hi_reloc (unsigned int r_type)
       case R_RISCV_TLS_GOT_HI20:
 	return GOT_TLS_IE;
       case R_RISCV_TLSDESC_HI20:
-	return GOT_TLSDESC;
+	if (!can_relax || !bfd_link_executable (info))
+	  return GOT_TLSDESC;
+	else
+	  return local_exec ? GOT_TLS_LE : GOT_TLS_IE;
       case R_RISCV_TPREL_HI20:
 	return GOT_TLS_LE;
       default:
@@ -866,7 +873,10 @@ riscv_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
 	  case R_RISCV_TLSDESC_HI20:
 	  case R_RISCV_TPREL_HI20:
 	    {
-	      char tls_type = riscv_elf_tls_type_from_hi_reloc (r_type);
+	      bool can_relax = rel != relocs + sec->reloc_count - 1
+			       && ELFNN_R_TYPE ((rel + 1)->r_info) == R_RISCV_RELAX
+			       && rel->r_offset == (rel + 1)->r_offset;
+	      char tls_type = riscv_elf_tls_type_from_hi_reloc (info, r_type, h, can_relax);
 
 	      /* Local exec is only allowed for executables.  */
 	      if (tls_type == GOT_TLS_LE && !bfd_link_executable (info))
@@ -1816,6 +1826,8 @@ perform_relocation (const reloc_howto_type *howto,
     case R_RISCV_TLS_GOT_HI20:
     case R_RISCV_TLS_GD_HI20:
     case R_RISCV_TLSDESC_HI20:
+    case R_RISCV_TLSDESC_LE_HI:
+    case R_RISCV_TLSDESC_IE_HI:
       if (ARCH_SIZE > 32 && !VALID_UTYPE_IMM (RISCV_CONST_HIGH_PART (value)))
 	return bfd_reloc_overflow;
       value = ENCODE_UTYPE_IMM (RISCV_CONST_HIGH_PART (value));
@@ -1828,6 +1840,8 @@ perform_relocation (const reloc_howto_type *howto,
     case R_RISCV_PCREL_LO12_I:
     case R_RISCV_TLSDESC_LOAD_LO12:
     case R_RISCV_TLSDESC_ADD_LO12:
+    case R_RISCV_TLSDESC_LE_LO:
+    case R_RISCV_TLSDESC_IE_LO:
       value = ENCODE_ITYPE_IMM (value);
       break;
 
@@ -2834,6 +2848,35 @@ riscv_elf_relocate_section (bfd *output_bfd,
 	    r = bfd_reloc_overflow;
 	  break;
 
+	case R_RISCV_TLSDESC_IE_HI:
+	  {
+	    bfd_vma insn = MATCH_AUIPC | (X_A0 << OP_SH_RD);
+	    relocation = dtpoff (info, relocation);
+	    bfd_putl32 (insn, contents + rel->r_offset);
+	    break;
+	  }
+	case R_RISCV_TLSDESC_IE_LO:
+	  {
+	    bfd_vma insn = MATCH_LREG | (X_A0 << OP_SH_RD) | (X_A0 << OP_SH_RS1);
+	    relocation = dtpoff (info, relocation);
+	    bfd_putl32 (insn, contents + rel->r_offset);
+	    break;
+	  }
+	case R_RISCV_TLSDESC_LE_HI:
+	  {
+	    bfd_vma insn = MATCH_LUI | (X_A0 << OP_SH_RD);
+	    relocation = tpoff (info, relocation);
+	    bfd_putl32 (insn, contents + rel->r_offset);
+	    break;
+	  }
+	case R_RISCV_TLSDESC_LE_LO:
+	  {
+	    bfd_vma insn = MATCH_ADDI | (X_A0 << OP_SH_RD) | (X_A0 << OP_SH_RS1);
+	    relocation = tpoff (info, relocation);
+	    bfd_putl32 (insn, contents + rel->r_offset);
+	    break;
+	  }
+
 	case R_RISCV_GPREL_I:
 	case R_RISCV_GPREL_S:
 	  {
@@ -4878,6 +4921,95 @@ _bfd_riscv_relax_tls_le (bfd *abfd,
     }
 }
 
+/* Relax TLSDESC (global-dynamic) references to TLS IE or LE references. */
+
+static bool
+_bfd_riscv_relax_tlsdesc (bfd *abfd,
+			  asection *sec,
+			  asection *sym_sec,
+			  struct bfd_link_info *link_info,
+			  struct elf_link_hash_entry *h,
+			  Elf_Internal_Rela *rel,
+			  bfd_vma symval,
+			  bfd_vma max_alignment ATTRIBUTE_UNUSED,
+			  bfd_vma reserve_size ATTRIBUTE_UNUSED,
+			  bool *again,
+			  riscv_pcgp_relocs *pcgp_relocs,
+			  bool undefined_weak)
+{
+  BFD_ASSERT (rel->r_offset + 4 <= sec->size);
+  BFD_ASSERT (bfd_link_executable (link_info));
+  riscv_pcgp_hi_reloc *hi = NULL;
+  bool local_exec;
+  unsigned sym;
+
+  /* Chain the _LO relocs to their corresponding _HI reloc to compute the
+     actual target address.  */
+  switch (ELFNN_R_TYPE (rel->r_info)) {
+    case R_RISCV_TLSDESC_HI20: {
+      /* If the corresponding lo relocation has already been seen then it's not
+	 safe to relax this relocation.  */
+      if (riscv_find_pcgp_lo_reloc (pcgp_relocs, rel->r_offset))
+	return true;
+      riscv_record_pcgp_hi_reloc (pcgp_relocs,
+				  rel->r_offset,
+				  rel->r_addend,
+				  symval,
+				  ELFNN_R_SYM (rel->r_info),
+				  sym_sec,
+				  h,
+				  undefined_weak);
+      sym = ELFNN_R_SYM (rel->r_info);
+      break;
+    }
+
+    case R_RISCV_TLSDESC_LOAD_LO12:
+    case R_RISCV_TLSDESC_ADD_LO12:
+    case R_RISCV_TLSDESC_CALL: {
+      bfd_vma hi_sec_off = symval - sec_addr (sym_sec);
+      hi = riscv_find_pcgp_hi_reloc (pcgp_relocs, hi_sec_off);
+      if (hi == NULL) {
+	riscv_record_pcgp_lo_reloc (pcgp_relocs, hi_sec_off);
+	return true;
+      }
+      sym = hi->hi_sym;
+      symval = hi->hi_addr;
+      sym_sec = hi->sym_sec;
+      h = hi->h;
+      break;
+    }
+    default:
+      abort ();
+  }
+
+  local_exec = SYMBOL_REFERENCES_LOCAL (link_info, h);
+
+  switch (ELFNN_R_TYPE (rel->r_info)) {
+    case R_RISCV_TLSDESC_HI20:
+      *again = true;
+      riscv_relax_delete_bytes (abfd, sec, rel->r_offset, 4, link_info,
+				pcgp_relocs, rel);
+      break;
+    case R_RISCV_TLSDESC_LOAD_LO12:
+      riscv_relax_delete_bytes (abfd, sec, rel->r_offset, 4, link_info,
+				pcgp_relocs, rel);
+      break;
+    case R_RISCV_TLSDESC_ADD_LO12:
+      rel->r_info = ELFNN_R_INFO (sym, local_exec ? R_RISCV_TLSDESC_LE_HI : R_RISCV_TLSDESC_IE_HI);
+      rel->r_addend += hi->hi_addend;
+      break;
+    case R_RISCV_TLSDESC_CALL:
+      rel->r_info = ELFNN_R_INFO (sym, local_exec ? R_RISCV_TLSDESC_LE_LO : R_RISCV_TLSDESC_IE_LO);
+      rel->r_addend += hi->hi_addend;
+      break;
+    default:
+      abort ();
+  }
+
+  return true;
+}
+
+
 /* Implement R_RISCV_ALIGN by deleting excess alignment NOPs.
    Once we've handled an R_RISCV_ALIGN, we can't relax anything else.  */
 
@@ -5182,6 +5314,12 @@ _bfd_riscv_relax_section (bfd *abfd, asection *sec,
 		   || type == R_RISCV_TPREL_LO12_I
 		   || type == R_RISCV_TPREL_LO12_S)
 	    relax_func = _bfd_riscv_relax_tls_le;
+	  else if (bfd_link_executable (info)
+		   && (type == R_RISCV_TLSDESC_HI20
+		       || type == R_RISCV_TLSDESC_LOAD_LO12
+		       || type == R_RISCV_TLSDESC_ADD_LO12
+		       || type == R_RISCV_TLSDESC_CALL))
+	    relax_func = _bfd_riscv_relax_tlsdesc;
 	  else if (!bfd_link_pic (info)
 		   && (type == R_RISCV_PCREL_HI20
 		       || type == R_RISCV_PCREL_LO12_I
diff --git a/bfd/elfxx-riscv.c b/bfd/elfxx-riscv.c
index a4aa71fd809..86f1538f69a 100644
--- a/bfd/elfxx-riscv.c
+++ b/bfd/elfxx-riscv.c
@@ -958,6 +958,61 @@ static reloc_howto_type howto_table_internal[] =
 	 0,				/* src_mask */
 	 ENCODE_STYPE_IMM (-1U),	/* dst_mask */
 	 false),			/* pcrel_offset */
+
+  /* TLSDESC relaxed to Initial Exec.  */
+  HOWTO (R_RISCV_TLSDESC_IE_HI,		/* type */
+	 0,				/* rightshift */
+	 4,				/* size */
+	 32,				/* bitsize */
+	 true,				/* pc_relative */
+	 0,				/* bitpos */
+	 complain_overflow_signed,	/* complain_on_overflow */
+	 bfd_elf_generic_reloc,		/* special_function */
+	 "R_RISCV_TLSDESC_IE_HI",	/* name */
+	 false,				/* partial_inplace */
+	 0,				/* src_mask */
+	 ENCODE_UTYPE_IMM (-1U),	/* dst_mask */
+	 false),			/* pcrel_offset */
+  HOWTO (R_RISCV_TLSDESC_IE_LO,		/* type */
+	 0,				/* rightshift */
+	 4,				/* size */
+	 32,				/* bitsize */
+	 true,				/* pc_relative */
+	 0,				/* bitpos */
+	 complain_overflow_signed,	/* complain_on_overflow */
+	 bfd_elf_generic_reloc,		/* special_function */
+	 "R_RISCV_TLSDESC_IE_LO",	/* name */
+	 false,				/* partial_inplace */
+	 0,				/* src_mask */
+	 ENCODE_ITYPE_IMM (-1U),	/* dst_mask */
+	 false),			/* pcrel_offset */
+  /* TLSDESC relaxed to Local Exec.  */
+  HOWTO (R_RISCV_TLSDESC_LE_HI,		/* type */
+	 0,				/* rightshift */
+	 4,				/* size */
+	 32,				/* bitsize */
+	 false,				/* pc_relative */
+	 0,				/* bitpos */
+	 complain_overflow_signed,	/* complain_on_overflow */
+	 bfd_elf_generic_reloc,		/* special_function */
+	 "R_RISCV_TLSDESC_LE_HI",	/* name */
+	 false,				/* partial_inplace */
+	 0,				/* src_mask */
+	 ENCODE_UTYPE_IMM (-1U),	/* dst_mask */
+	 false),			/* pcrel_offset */
+  HOWTO (R_RISCV_TLSDESC_LE_LO,		/* type */
+	 0,				/* rightshift */
+	 4,				/* size */
+	 32,				/* bitsize */
+	 false,				/* pc_relative */
+	 0,				/* bitpos */
+	 complain_overflow_signed,	/* complain_on_overflow */
+	 bfd_elf_generic_reloc,		/* special_function */
+	 "R_RISCV_TLSDESC_LE_LO",	/* name */
+	 false,				/* partial_inplace */
+	 0,				/* src_mask */
+	 ENCODE_ITYPE_IMM (-1U),	/* dst_mask */
+	 false),			/* pcrel_offset */
 };
 
 /* A mapping from BFD reloc types to RISC-V ELF reloc types.  */
diff --git a/include/elf/riscv.h b/include/elf/riscv.h
index c1e73f7f5c0..a99038d42d5 100644
--- a/include/elf/riscv.h
+++ b/include/elf/riscv.h
@@ -98,12 +98,16 @@ START_RELOC_NUMBERS (elf_riscv_reloc_type)
 END_RELOC_NUMBERS (R_RISCV_max)
 
 /* Internal relocations used exclusively by the relaxation pass.  */
-#define R_RISCV_DELETE  (R_RISCV_max)
-#define R_RISCV_RVC_LUI (R_RISCV_max + 1)
-#define R_RISCV_GPREL_I (R_RISCV_max + 2)
-#define R_RISCV_GPREL_S (R_RISCV_max + 3)
-#define R_RISCV_TPREL_I (R_RISCV_max + 4)
-#define R_RISCV_TPREL_S (R_RISCV_max + 5)
+#define R_RISCV_DELETE		(R_RISCV_max)
+#define R_RISCV_RVC_LUI		(R_RISCV_max + 1)
+#define R_RISCV_GPREL_I		(R_RISCV_max + 2)
+#define R_RISCV_GPREL_S		(R_RISCV_max + 3)
+#define R_RISCV_TPREL_I		(R_RISCV_max + 4)
+#define R_RISCV_TPREL_S		(R_RISCV_max + 5)
+#define R_RISCV_TLSDESC_IE_HI	(R_RISCV_max + 6)
+#define R_RISCV_TLSDESC_IE_LO	(R_RISCV_max + 7)
+#define R_RISCV_TLSDESC_LE_HI	(R_RISCV_max + 8)
+#define R_RISCV_TLSDESC_LE_LO	(R_RISCV_max + 9)
 
 /* Processor specific flags for the ELF header e_flags field.  */
 
diff --git a/include/opcode/riscv.h b/include/opcode/riscv.h
index adea7dbc794..6e359d11388 100644
--- a/include/opcode/riscv.h
+++ b/include/opcode/riscv.h
@@ -355,6 +355,7 @@ static inline unsigned int riscv_insn_length (insn_t insn)
 #define X_T0 5
 #define X_T1 6
 #define X_T2 7
+#define X_A0 10
 #define X_T3 28
 
 #define NGPR 32
diff --git a/ld/testsuite/ld-riscv-elf/tlsbin.d b/ld/testsuite/ld-riscv-elf/tlsbin.d
index 79b7ade405e..cdcd51a9199 100644
--- a/ld/testsuite/ld-riscv-elf/tlsbin.d
+++ b/ld/testsuite/ld-riscv-elf/tlsbin.d
@@ -2,11 +2,6 @@
 #ld: -no-pie tmpdir/tlslib.so
 #readelf: -Wr
 
-Relocation section '.rela.dyn' at offset 0x[0-9a-f]+ contains 2 entries:
- +Offset +Info +Type +Symbol's Value +Symbol's Name \+ Addend
-[0-9a-f]+ +[0-9a-f]+ R_RISCV_TLSDESC +4
-[0-9a-f]+ +[0-9a-f]+ R_RISCV_TLSDESC +0
-
 Relocation section '.rela.plt' at offset 0x[0-9a-f]+ contains 1 entry:
  +Offset +Info +Type +Symbol's Value +Symbol's Name \+ Addend
 [0-9a-f]+ +[0-9a-f]+ R_RISCV_JUMP_SLOT +[0-9a-f]+ __tls_get_addr \+ 0
-- 
2.43.2


^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [PATCH v2 1/5] RISC-V: Fix local GOT and reloc size calculation for TLS.
  2023-08-31 17:13   ` [PATCH v2 1/5] RISC-V: Fix local GOT and reloc size calculation for TLS Tatsuyuki Ishi
@ 2024-02-21  0:49     ` Nelson Chu
  2024-02-21  7:04       ` Nelson Chu
  0 siblings, 1 reply; 49+ messages in thread
From: Nelson Chu @ 2024-02-21  0:49 UTC (permalink / raw)
  To: Tatsuyuki Ishi; +Cc: binutils, rui314, ruiu, i

[-- Attachment #1: Type: text/plain, Size: 7384 bytes --]

Oops I lost this one.  This seems to fix the redundant dynamic R_RISCV_NONE
in .rela.dyn if using --no-pie for tls gd and ie, so looks good to me.

Btw, I just noticed that I also reviewed four of the TLS patches since my
mail box looks weird and only shows the old patches, so I lost this one and
others...  I will see the remaining stuff.

Thanks
Nelson

On Fri, Sep 1, 2023 at 1:13 AM Tatsuyuki Ishi <ishitatsuyuki@gmail.com>
wrote:

> The previous code did not account correctly for two cases:
> * A TLS symbol can be referenced with multiple TLS types (although rare),
>   in which case it only allocated the maximum slot size among the types,
>   instead of the sum.
> * TLS relocations are only needed for DLLs, unlike normal symbols which
>   requires relocations for all PIE code.
>
> Modify the logic to account for the two cases.
>
> bfd/
>     * elfnn-riscv.c (riscv_elf_size_dynamic_sections): Handle relocation
>     sizing for TLS and non-TLS symbols differently, with the former
>     requiring relocs on DLL while the latter requiring on PIE.
>     Allocate GOT slots and relocation slots for each TLS type separately,
>     accounting for the possibility of a TLS variable getting referenced by
>     multiple symbols.
> ld/
>     * testsuite/ld-riscv-elf/ld-riscv-elf.exp: Updated.
>     * testsuite/ld-riscv-elf/tls*: New testcase for TLS GD and IE, with
>     symbols referred by both types and global and local symbols.
> ---
> v2: Add tests for GD and IE, testing both global and local symbols.
>     Both -shared and -no-pie are tested.
>
>  bfd/elfnn-riscv.c                          | 27 ++++++++++++++++-----
>  ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp |  8 +++++++
>  ld/testsuite/ld-riscv-elf/tls.d            | 15 ++++++++++++
>  ld/testsuite/ld-riscv-elf/tls.s            | 28 ++++++++++++++++++++++
>  ld/testsuite/ld-riscv-elf/tlsbin.d         |  7 ++++++
>  ld/testsuite/ld-riscv-elf/tlslib.s         |  6 +++++
>  6 files changed, 85 insertions(+), 6 deletions(-)
>  create mode 100644 ld/testsuite/ld-riscv-elf/tls.d
>  create mode 100644 ld/testsuite/ld-riscv-elf/tls.s
>  create mode 100644 ld/testsuite/ld-riscv-elf/tlsbin.d
>  create mode 100644 ld/testsuite/ld-riscv-elf/tlslib.s
>
> diff --git a/bfd/elfnn-riscv.c b/bfd/elfnn-riscv.c
> index 09aa7be225e..02b46835cc7 100644
> --- a/bfd/elfnn-riscv.c
> +++ b/bfd/elfnn-riscv.c
> @@ -1562,12 +1562,27 @@ riscv_elf_size_dynamic_sections (bfd *output_bfd,
> struct bfd_link_info *info)
>           if (*local_got > 0)
>             {
>               *local_got = s->size;
> -             s->size += RISCV_ELF_WORD_BYTES;
> -             if (*local_tls_type & GOT_TLS_GD)
> -               s->size += RISCV_ELF_WORD_BYTES;
> -             if (bfd_link_pic (info)
> -                 || (*local_tls_type & (GOT_TLS_GD | GOT_TLS_IE)))
> -               srel->size += sizeof (ElfNN_External_Rela);
> +             if (*local_tls_type & (GOT_TLS_GD | GOT_TLS_IE))
> +               {
> +                 if (*local_tls_type & GOT_TLS_GD)
> +                   {
> +                     s->size += 2 * RISCV_ELF_WORD_BYTES;
> +                     if (bfd_link_dll (info))
> +                       srel->size += sizeof (ElfNN_External_Rela);
> +                   }
> +                 if (*local_tls_type & GOT_TLS_IE)
> +                   {
> +                     s->size += RISCV_ELF_WORD_BYTES;
> +                     if (bfd_link_dll (info))
> +                       srel->size += sizeof (ElfNN_External_Rela);
> +                   }
> +               }
> +             else
> +               {
> +                 s->size += RISCV_ELF_WORD_BYTES;
> +                 if (bfd_link_pic (info))
> +                   srel->size += sizeof (ElfNN_External_Rela);
> +               }
>             }
>           else
>             *local_got = (bfd_vma) -1;
> diff --git a/ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp
> b/ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp
> index 947a266ba72..adb4ee75e4a 100644
> --- a/ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp
> +++ b/ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp
> @@ -317,4 +317,12 @@ if [istarget "riscv*-*-*"] {
>      run_dump_test "pcrel-reloc-rel-pie"
>      run_dump_test "pcrel-reloc-abs-nopie"
>      run_dump_test "pcrel-reloc-abs-pie"
> +
> +    run_ld_link_tests {
> +       { "Build shared library for TLS runtime"
> +        "-shared" "" "" {tlslib.s}
> +        {} "tlslib.so" }
> +    }
> +    run_dump_test "tls"
> +    run_dump_test "tlsbin"
>  }
> diff --git a/ld/testsuite/ld-riscv-elf/tls.d
> b/ld/testsuite/ld-riscv-elf/tls.d
> new file mode 100644
> index 00000000000..0e2ab5683ad
> --- /dev/null
> +++ b/ld/testsuite/ld-riscv-elf/tls.d
> @@ -0,0 +1,15 @@
> +#source: tls.s
> +#ld: --shared tmpdir/tlslib.so
> +#readelf: -Wr
> +
> +Relocation section '.rela.dyn' at offset 0x[0-9a-f]+ contains 5 entries:
> + +Offset +Info +Type +Symbol's Value +Symbol's Name \+ Addend
> +[0-9a-f]+ +[0-9a-f]+ R_RISCV_TLS_DTPMOD64 +0
> +[0-9a-f]+ +[0-9a-f]+ R_RISCV_TLS_TPREL64 +4
> +[0-9a-f]+ +[0-9a-f]+ R_RISCV_TLS_DTPMOD64 +0+ sg1 \+ 0
> +[0-9a-f]+ +[0-9a-f]+ R_RISCV_TLS_DTPREL64 +0+ sg1 \+ 0
> +[0-9a-f]+ +[0-9a-f]+ R_RISCV_TLS_TPREL64 +0+ sg1 \+ 0
> +
> +Relocation section '.rela.plt' at offset 0x[0-9a-f]+ contains 1 entry:
> + +Offset +Info +Type +Symbol's Value +Symbol's Name \+ Addend
> +[0-9a-f]+ +[0-9a-f]+ R_RISCV_JUMP_SLOT +0+ __tls_get_addr \+ 0
> \ No newline at end of file
> diff --git a/ld/testsuite/ld-riscv-elf/tls.s
> b/ld/testsuite/ld-riscv-elf/tls.s
> new file mode 100644
> index 00000000000..79e9bc20374
> --- /dev/null
> +++ b/ld/testsuite/ld-riscv-elf/tls.s
> @@ -0,0 +1,28 @@
> +       .section        .tbss,"awT",@nobits
> +       .global sg1
> +sg1:
> +       .zero   4
> +sl1:
> +       .zero   4
> +
> +       .text
> +       .globl  _start
> +       .type   _start,@function
> +_start:
> +       /* GD, global var */
> +       la.tls.gd       a0,sg1
> +       call  __tls_get_addr
> +
> +       /* IE, global var */
> +       la.tls.ie       a0,sg1
> +       add     a0,a0,tp
> +
> +       /* GD, local var */
> +       la.tls.gd       a0,sl1
> +       call  __tls_get_addr
> +
> +       /* IE, local var */
> +       la.tls.ie       a0,sl1
> +       add     a0,a0,tp
> +
> +       ret
> diff --git a/ld/testsuite/ld-riscv-elf/tlsbin.d
> b/ld/testsuite/ld-riscv-elf/tlsbin.d
> new file mode 100644
> index 00000000000..12a4d0ea703
> --- /dev/null
> +++ b/ld/testsuite/ld-riscv-elf/tlsbin.d
> @@ -0,0 +1,7 @@
> +#source: tls.s
> +#ld: -no-pie tmpdir/tlslib.so
> +#readelf: -Wr
> +
> +Relocation section '.rela.plt' at offset 0x[0-9a-f]+ contains 1 entry:
> + +Offset +Info +Type +Symbol's Value +Symbol's Name \+ Addend
> +[0-9a-f]+ +[0-9a-f]+ R_RISCV_JUMP_SLOT +[0-9a-f]+ __tls_get_addr \+ 0
> \ No newline at end of file
> diff --git a/ld/testsuite/ld-riscv-elf/tlslib.s
> b/ld/testsuite/ld-riscv-elf/tlslib.s
> new file mode 100644
> index 00000000000..17c770786d0
> --- /dev/null
> +++ b/ld/testsuite/ld-riscv-elf/tlslib.s
> @@ -0,0 +1,6 @@
> +       .text
> +       /* Dummy.  */
> +       .globl  __tls_get_addr
> +       .type   __tls_get_addr,@function
> +__tls_get_addr:
> +       ret
> --
> 2.42.0
>
>

^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [PATCH v2 1/5] RISC-V: Fix local GOT and reloc size calculation for TLS.
  2024-02-21  0:49     ` Nelson Chu
@ 2024-02-21  7:04       ` Nelson Chu
  0 siblings, 0 replies; 49+ messages in thread
From: Nelson Chu @ 2024-02-21  7:04 UTC (permalink / raw)
  To: Tatsuyuki Ishi; +Cc: binutils, rui314, ruiu, i

[-- Attachment #1: Type: text/plain, Size: 7775 bytes --]

Committed this one first after passing the gcc/binutils regressions of
riscv-gnu-toolchain.

Nelson

On Wed, Feb 21, 2024 at 8:49 AM Nelson Chu <nelson@rivosinc.com> wrote:

> Oops I lost this one.  This seems to fix the redundant dynamic
> R_RISCV_NONE in .rela.dyn if using --no-pie for tls gd and ie, so looks
> good to me.
>
> Btw, I just noticed that I also reviewed four of the TLS patches since my
> mail box looks weird and only shows the old patches, so I lost this one and
> others...  I will see the remaining stuff.
>
> Thanks
> Nelson
>
> On Fri, Sep 1, 2023 at 1:13 AM Tatsuyuki Ishi <ishitatsuyuki@gmail.com>
> wrote:
>
>> The previous code did not account correctly for two cases:
>> * A TLS symbol can be referenced with multiple TLS types (although rare),
>>   in which case it only allocated the maximum slot size among the types,
>>   instead of the sum.
>> * TLS relocations are only needed for DLLs, unlike normal symbols which
>>   requires relocations for all PIE code.
>>
>> Modify the logic to account for the two cases.
>>
>> bfd/
>>     * elfnn-riscv.c (riscv_elf_size_dynamic_sections): Handle relocation
>>     sizing for TLS and non-TLS symbols differently, with the former
>>     requiring relocs on DLL while the latter requiring on PIE.
>>     Allocate GOT slots and relocation slots for each TLS type separately,
>>     accounting for the possibility of a TLS variable getting referenced by
>>     multiple symbols.
>> ld/
>>     * testsuite/ld-riscv-elf/ld-riscv-elf.exp: Updated.
>>     * testsuite/ld-riscv-elf/tls*: New testcase for TLS GD and IE, with
>>     symbols referred by both types and global and local symbols.
>> ---
>> v2: Add tests for GD and IE, testing both global and local symbols.
>>     Both -shared and -no-pie are tested.
>>
>>  bfd/elfnn-riscv.c                          | 27 ++++++++++++++++-----
>>  ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp |  8 +++++++
>>  ld/testsuite/ld-riscv-elf/tls.d            | 15 ++++++++++++
>>  ld/testsuite/ld-riscv-elf/tls.s            | 28 ++++++++++++++++++++++
>>  ld/testsuite/ld-riscv-elf/tlsbin.d         |  7 ++++++
>>  ld/testsuite/ld-riscv-elf/tlslib.s         |  6 +++++
>>  6 files changed, 85 insertions(+), 6 deletions(-)
>>  create mode 100644 ld/testsuite/ld-riscv-elf/tls.d
>>  create mode 100644 ld/testsuite/ld-riscv-elf/tls.s
>>  create mode 100644 ld/testsuite/ld-riscv-elf/tlsbin.d
>>  create mode 100644 ld/testsuite/ld-riscv-elf/tlslib.s
>>
>> diff --git a/bfd/elfnn-riscv.c b/bfd/elfnn-riscv.c
>> index 09aa7be225e..02b46835cc7 100644
>> --- a/bfd/elfnn-riscv.c
>> +++ b/bfd/elfnn-riscv.c
>> @@ -1562,12 +1562,27 @@ riscv_elf_size_dynamic_sections (bfd *output_bfd,
>> struct bfd_link_info *info)
>>           if (*local_got > 0)
>>             {
>>               *local_got = s->size;
>> -             s->size += RISCV_ELF_WORD_BYTES;
>> -             if (*local_tls_type & GOT_TLS_GD)
>> -               s->size += RISCV_ELF_WORD_BYTES;
>> -             if (bfd_link_pic (info)
>> -                 || (*local_tls_type & (GOT_TLS_GD | GOT_TLS_IE)))
>> -               srel->size += sizeof (ElfNN_External_Rela);
>> +             if (*local_tls_type & (GOT_TLS_GD | GOT_TLS_IE))
>> +               {
>> +                 if (*local_tls_type & GOT_TLS_GD)
>> +                   {
>> +                     s->size += 2 * RISCV_ELF_WORD_BYTES;
>> +                     if (bfd_link_dll (info))
>> +                       srel->size += sizeof (ElfNN_External_Rela);
>> +                   }
>> +                 if (*local_tls_type & GOT_TLS_IE)
>> +                   {
>> +                     s->size += RISCV_ELF_WORD_BYTES;
>> +                     if (bfd_link_dll (info))
>> +                       srel->size += sizeof (ElfNN_External_Rela);
>> +                   }
>> +               }
>> +             else
>> +               {
>> +                 s->size += RISCV_ELF_WORD_BYTES;
>> +                 if (bfd_link_pic (info))
>> +                   srel->size += sizeof (ElfNN_External_Rela);
>> +               }
>>             }
>>           else
>>             *local_got = (bfd_vma) -1;
>> diff --git a/ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp
>> b/ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp
>> index 947a266ba72..adb4ee75e4a 100644
>> --- a/ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp
>> +++ b/ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp
>> @@ -317,4 +317,12 @@ if [istarget "riscv*-*-*"] {
>>      run_dump_test "pcrel-reloc-rel-pie"
>>      run_dump_test "pcrel-reloc-abs-nopie"
>>      run_dump_test "pcrel-reloc-abs-pie"
>> +
>> +    run_ld_link_tests {
>> +       { "Build shared library for TLS runtime"
>> +        "-shared" "" "" {tlslib.s}
>> +        {} "tlslib.so" }
>> +    }
>> +    run_dump_test "tls"
>> +    run_dump_test "tlsbin"
>>  }
>> diff --git a/ld/testsuite/ld-riscv-elf/tls.d
>> b/ld/testsuite/ld-riscv-elf/tls.d
>> new file mode 100644
>> index 00000000000..0e2ab5683ad
>> --- /dev/null
>> +++ b/ld/testsuite/ld-riscv-elf/tls.d
>> @@ -0,0 +1,15 @@
>> +#source: tls.s
>> +#ld: --shared tmpdir/tlslib.so
>> +#readelf: -Wr
>> +
>> +Relocation section '.rela.dyn' at offset 0x[0-9a-f]+ contains 5 entries:
>> + +Offset +Info +Type +Symbol's Value +Symbol's Name \+ Addend
>> +[0-9a-f]+ +[0-9a-f]+ R_RISCV_TLS_DTPMOD64 +0
>> +[0-9a-f]+ +[0-9a-f]+ R_RISCV_TLS_TPREL64 +4
>> +[0-9a-f]+ +[0-9a-f]+ R_RISCV_TLS_DTPMOD64 +0+ sg1 \+ 0
>> +[0-9a-f]+ +[0-9a-f]+ R_RISCV_TLS_DTPREL64 +0+ sg1 \+ 0
>> +[0-9a-f]+ +[0-9a-f]+ R_RISCV_TLS_TPREL64 +0+ sg1 \+ 0
>> +
>> +Relocation section '.rela.plt' at offset 0x[0-9a-f]+ contains 1 entry:
>> + +Offset +Info +Type +Symbol's Value +Symbol's Name \+ Addend
>> +[0-9a-f]+ +[0-9a-f]+ R_RISCV_JUMP_SLOT +0+ __tls_get_addr \+ 0
>> \ No newline at end of file
>> diff --git a/ld/testsuite/ld-riscv-elf/tls.s
>> b/ld/testsuite/ld-riscv-elf/tls.s
>> new file mode 100644
>> index 00000000000..79e9bc20374
>> --- /dev/null
>> +++ b/ld/testsuite/ld-riscv-elf/tls.s
>> @@ -0,0 +1,28 @@
>> +       .section        .tbss,"awT",@nobits
>> +       .global sg1
>> +sg1:
>> +       .zero   4
>> +sl1:
>> +       .zero   4
>> +
>> +       .text
>> +       .globl  _start
>> +       .type   _start,@function
>> +_start:
>> +       /* GD, global var */
>> +       la.tls.gd       a0,sg1
>> +       call  __tls_get_addr
>> +
>> +       /* IE, global var */
>> +       la.tls.ie       a0,sg1
>> +       add     a0,a0,tp
>> +
>> +       /* GD, local var */
>> +       la.tls.gd       a0,sl1
>> +       call  __tls_get_addr
>> +
>> +       /* IE, local var */
>> +       la.tls.ie       a0,sl1
>> +       add     a0,a0,tp
>> +
>> +       ret
>> diff --git a/ld/testsuite/ld-riscv-elf/tlsbin.d
>> b/ld/testsuite/ld-riscv-elf/tlsbin.d
>> new file mode 100644
>> index 00000000000..12a4d0ea703
>> --- /dev/null
>> +++ b/ld/testsuite/ld-riscv-elf/tlsbin.d
>> @@ -0,0 +1,7 @@
>> +#source: tls.s
>> +#ld: -no-pie tmpdir/tlslib.so
>> +#readelf: -Wr
>> +
>> +Relocation section '.rela.plt' at offset 0x[0-9a-f]+ contains 1 entry:
>> + +Offset +Info +Type +Symbol's Value +Symbol's Name \+ Addend
>> +[0-9a-f]+ +[0-9a-f]+ R_RISCV_JUMP_SLOT +[0-9a-f]+ __tls_get_addr \+ 0
>> \ No newline at end of file
>> diff --git a/ld/testsuite/ld-riscv-elf/tlslib.s
>> b/ld/testsuite/ld-riscv-elf/tlslib.s
>> new file mode 100644
>> index 00000000000..17c770786d0
>> --- /dev/null
>> +++ b/ld/testsuite/ld-riscv-elf/tlslib.s
>> @@ -0,0 +1,6 @@
>> +       .text
>> +       /* Dummy.  */
>> +       .globl  __tls_get_addr
>> +       .type   __tls_get_addr,@function
>> +__tls_get_addr:
>> +       ret
>> --
>> 2.42.0
>>
>>

^ permalink raw reply	[flat|nested] 49+ messages in thread

end of thread, other threads:[~2024-02-21  7:04 UTC | newest]

Thread overview: 49+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-08-17 18:08 [PATCH 0/4] RISC-V: Implement TLS Descriptors Tatsuyuki Ishi
2023-08-17 18:08 ` [PATCH 1/4] RISC-V: Add TLSDESC reloc definitions Tatsuyuki Ishi
2023-08-17 18:08 ` [PATCH 2/4] RISC-V: Add assembly support for TLSDESC Tatsuyuki Ishi
2023-08-17 18:08 ` [PATCH 3/4] RISC-V: Define and use GOT entry size constants for TLS Tatsuyuki Ishi
2023-08-17 18:08 ` [PATCH 4/4] RISC-V: Initial ld.bfd support for TLSDESC Tatsuyuki Ishi
2023-08-18  0:22 ` [PATCH 0/4] RISC-V: Implement TLS Descriptors Nelson Chu
2023-08-18  7:13   ` Fangrui Song
2023-08-31 17:13 ` [PATCH v2 0/5] " Tatsuyuki Ishi
2023-08-31 17:13   ` [PATCH v2 1/5] RISC-V: Fix local GOT and reloc size calculation for TLS Tatsuyuki Ishi
2024-02-21  0:49     ` Nelson Chu
2024-02-21  7:04       ` Nelson Chu
2023-08-31 17:13   ` [PATCH v2 2/5] RISC-V: Add TLSDESC reloc definitions Tatsuyuki Ishi
2023-08-31 17:13   ` [PATCH v2 3/5] RISC-V: Add assembly support for TLSDESC Tatsuyuki Ishi
2023-08-31 17:13   ` [PATCH v2 4/5] RISC-V: Define and use GOT entry size constants for TLS Tatsuyuki Ishi
2023-08-31 17:13   ` [PATCH v2 5/5] RISC-V: Initial ld.bfd support for TLSDESC Tatsuyuki Ishi
2023-11-28  8:51 ` [PATCH v3 0/9] RISC-V: Implement TLS Descriptors Tatsuyuki Ishi
2023-11-28  8:51   ` [PATCH v3 1/9] RISC-V: Fix local GOT and reloc size calculation for TLS Tatsuyuki Ishi
2023-11-28  8:51   ` [PATCH v3 2/9] RISC-V: Add TLSDESC reloc definitions Tatsuyuki Ishi
2024-02-19  0:49     ` Nelson Chu
2024-02-20 17:28       ` Tatsuyuki Ishi
2023-11-28  8:51   ` [PATCH v3 3/9] RISC-V: Add assembly support for TLSDESC Tatsuyuki Ishi
2024-02-19  1:44     ` Nelson Chu
2024-02-20 17:29       ` Tatsuyuki Ishi
2023-11-28  8:51   ` [PATCH v3 4/9] RISC-V: Define and use GOT entry size constants for TLS Tatsuyuki Ishi
2024-02-19  1:57     ` Nelson Chu
2024-02-20 17:32       ` Tatsuyuki Ishi
2023-11-28  8:51   ` [PATCH v3 5/9] RISC-V: Initial ld.bfd support for TLSDESC Tatsuyuki Ishi
2024-02-19  4:33     ` Nelson Chu
2024-02-20 17:36       ` Tatsuyuki Ishi
2023-11-28  8:51   ` [PATCH v3 6/9] RISC-V: Move STATIC_TLS handling into record_tls_type Tatsuyuki Ishi
2023-11-28  8:51   ` [PATCH v3 7/9] RISC-V: Unify TLS handling in check_relocs Tatsuyuki Ishi
2023-11-28  8:51   ` [PATCH v3 8/9] RISC-V: Add elf_link_hash_entry to relax_func args Tatsuyuki Ishi
2023-11-28  8:51   ` [PATCH v3 9/9] RISC-V: Introduce TLSDESC relaxation Tatsuyuki Ishi
2023-12-05 16:44   ` [PATCH v3 0/9] RISC-V: Implement TLS Descriptors Tatsuyuki Ishi
2023-12-06  0:33     ` Nelson Chu
2023-12-07  3:35       ` Fangrui Song
2023-12-13  0:27         ` Palmer Dabbelt
2023-12-13  1:53           ` Tatsuyuki Ishi
2024-01-27  0:57             ` Fangrui Song
2024-02-20 17:55 ` [PATCH v4 " Tatsuyuki Ishi
2024-02-20 17:55   ` [PATCH v4 1/9] RISC-V: Fix local GOT and reloc size calculation for TLS Tatsuyuki Ishi
2024-02-20 17:55   ` [PATCH v4 2/9] RISC-V: Add TLSDESC reloc definitions Tatsuyuki Ishi
2024-02-20 17:55   ` [PATCH v4 3/9] RISC-V: Add assembly support for TLSDESC Tatsuyuki Ishi
2024-02-20 17:55   ` [PATCH v4 4/9] RISC-V: Define and use GOT entry size constants for TLS Tatsuyuki Ishi
2024-02-20 17:55   ` [PATCH v4 5/9] RISC-V: Initial ld.bfd support for TLSDESC Tatsuyuki Ishi
2024-02-20 17:55   ` [PATCH v4 6/9] RISC-V: Move STATIC_TLS handling into record_tls_type Tatsuyuki Ishi
2024-02-20 17:55   ` [PATCH v4 7/9] RISC-V: Unify TLS handling in check_relocs Tatsuyuki Ishi
2024-02-20 17:55   ` [PATCH v4 8/9] RISC-V: Add elf_link_hash_entry to relax_func args Tatsuyuki Ishi
2024-02-20 17:55   ` [PATCH v4 9/9] RISC-V: Introduce TLSDESC relaxation Tatsuyuki Ishi

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).