public inbox for binutils@sourceware.org
 help / color / mirror / Atom feed
* [PATCH v1 0/4] LoongArch: Add support for TLS Descriptors (TLSDESC)
@ 2023-12-01  9:04 Lulu Cai
  2023-12-01  9:04 ` [PATCH v1 1/4] LoongArch: Add new relocs and macro for TLSDESC Lulu Cai
                   ` (5 more replies)
  0 siblings, 6 replies; 11+ messages in thread
From: Lulu Cai @ 2023-12-01  9:04 UTC (permalink / raw)
  To: binutils
  Cc: xuchenghua, chenglulu, liuzhensong, mengqinggang, xry111,
	i.swmail, maskray, luweining, wanglei, hejinyang, Lulu Cai

The LoongArch TLS Descriptors implementation contains several points:

1. The instruction sequences is:
   pcalau12i  $a0,%desc_pc_hi20(var)		#R_LARCH_TLS_DESC_PC_HI20
   ld.d       $a1,$a0,%desc_ld_pc_lo12(var)	#R_LARCH_TLS_DESC_LD_PC_LO12
   addi.d     $a0,$a0,%desc_add_pc_lo12(var)	#R_LARCH_TLS_DESC_ADD_PC_LO12
   jirl       $ra,$a1,%desc_call(var)		#R_LARCH_TLS_DESC_CALL

   The linker for each DESC generates a R_LARCH_TLS_DESC64 dynamic relocation,
   which relocation is placed at .rela.dyn.
   TLSDESC always allocates two GOT slots and one dynamic relocation space to TLSDESC.

2. When using multiple ways to access the same TLS variable, a maximum of 5 GOT
   slots are used. For example, using GD, TLSDESC, and IE to access the same TLS
   variable,GD always uses the first two of the five GOT, TLSDESC uses the third
   and fourth, and IE uses the last.

3. TLSDESC always requires dynamic relocation because of LoongArch does not yet have
   a tls type transition. Howerer statically linked programs cannot resolve TLSDESC's
   dynamic relocation, so we did a type transition for this case.
   DESC -> LE:
   pcalau12i  $a0,%desc_pc_hi20(var)	      =>  lu12i.w $a0,%le_hi20(var)
   ld.d       $a1,$a0,%desc_ld_pc_lo12(var)   =>  ori $a0,$a0,%le_lo12(var)
   addi.d     $a0,$a0,%desc_add_pc_lo12(var)  =>  NOP	
   jirl       $ra,$a1,%desc_call(var)	      =>  NOP

4. The current code passes the tests of gas ld and glibc.

Lulu Cai (4):
  LoongArch: Add new relocs and macro for TLSDESC.
  LoongArch: Add support for TLSDESC in ld.
  LoongArch: Add transition support for DESC to LE.
  LoongArch: Add testsuits for TLSDESC in gas and ld.

 bfd/bfd-in2.h                                 |  12 +
 bfd/elfnn-loongarch.c                         | 276 ++++++++++++++++--
 bfd/elfxx-loongarch.c                         | 209 ++++++++++++-
 bfd/libbfd.h                                  |  12 +
 bfd/reloc.c                                   |  29 ++
 gas/config/tc-loongarch.c                     |  14 +-
 gas/testsuite/gas/loongarch/tlsdesc_32.d      |  26 ++
 gas/testsuite/gas/loongarch/tlsdesc_32.s      |  12 +
 gas/testsuite/gas/loongarch/tlsdesc_64.d      |  26 ++
 gas/testsuite/gas/loongarch/tlsdesc_64.s      |  12 +
 .../gas/loongarch/tlsdesc_large_abs.d         |  21 ++
 .../gas/loongarch/tlsdesc_large_abs.s         |   9 +
 .../gas/loongarch/tlsdesc_large_pc.d          |  34 +++
 .../gas/loongarch/tlsdesc_large_pc.s          |  16 +
 include/elf/loongarch.h                       |  22 +-
 include/opcode/loongarch.h                    |   3 +
 .../ld-loongarch-elf/ld-loongarch-elf.exp     |  16 +
 ld/testsuite/ld-loongarch-elf/tls-desc.dd     |  74 +++++
 ld/testsuite/ld-loongarch-elf/tls-desc.rd     |  79 +++++
 ld/testsuite/ld-loongarch-elf/tls-desc.s      | 102 +++++++
 .../ld-loongarch-elf/tls-relax-desc-le.d      |  15 +
 .../ld-loongarch-elf/tls-relax-desc-le.s      |   8 +
 opcodes/loongarch-opc.c                       |  54 ++++
 23 files changed, 1054 insertions(+), 27 deletions(-)
 create mode 100644 gas/testsuite/gas/loongarch/tlsdesc_32.d
 create mode 100644 gas/testsuite/gas/loongarch/tlsdesc_32.s
 create mode 100644 gas/testsuite/gas/loongarch/tlsdesc_64.d
 create mode 100644 gas/testsuite/gas/loongarch/tlsdesc_64.s
 create mode 100644 gas/testsuite/gas/loongarch/tlsdesc_large_abs.d
 create mode 100644 gas/testsuite/gas/loongarch/tlsdesc_large_abs.s
 create mode 100644 gas/testsuite/gas/loongarch/tlsdesc_large_pc.d
 create mode 100644 gas/testsuite/gas/loongarch/tlsdesc_large_pc.s
 create mode 100644 ld/testsuite/ld-loongarch-elf/tls-desc.dd
 create mode 100644 ld/testsuite/ld-loongarch-elf/tls-desc.rd
 create mode 100644 ld/testsuite/ld-loongarch-elf/tls-desc.s
 create mode 100644 ld/testsuite/ld-loongarch-elf/tls-relax-desc-le.d
 create mode 100644 ld/testsuite/ld-loongarch-elf/tls-relax-desc-le.s

-- 
2.36.0


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

* [PATCH v1 1/4] LoongArch: Add new relocs and macro for TLSDESC.
  2023-12-01  9:04 [PATCH v1 0/4] LoongArch: Add support for TLS Descriptors (TLSDESC) Lulu Cai
@ 2023-12-01  9:04 ` Lulu Cai
  2023-12-01  9:04 ` [PATCH v1 2/4] LoongArch: Add support for TLSDESC in ld Lulu Cai
                   ` (4 subsequent siblings)
  5 siblings, 0 replies; 11+ messages in thread
From: Lulu Cai @ 2023-12-01  9:04 UTC (permalink / raw)
  To: binutils
  Cc: xuchenghua, chenglulu, liuzhensong, mengqinggang, xry111,
	i.swmail, maskray, luweining, wanglei, hejinyang, Lulu Cai

---
 bfd/bfd-in2.h             |  12 +++
 bfd/elfxx-loongarch.c     | 209 +++++++++++++++++++++++++++++++++++++-
 bfd/libbfd.h              |  12 +++
 bfd/reloc.c               |  29 ++++++
 gas/config/tc-loongarch.c |  14 ++-
 include/elf/loongarch.h   |  22 +++-
 opcodes/loongarch-opc.c   |  54 ++++++++++
 7 files changed, 348 insertions(+), 4 deletions(-)

diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h
index 040d5560cdf..dfc9e8aceaa 100644
--- a/bfd/bfd-in2.h
+++ b/bfd/bfd-in2.h
@@ -7377,6 +7377,8 @@ enum bfd_reloc_code_real
   BFD_RELOC_LARCH_TLS_DTPREL64,
   BFD_RELOC_LARCH_TLS_TPREL32,
   BFD_RELOC_LARCH_TLS_TPREL64,
+  BFD_RELOC_LARCH_TLS_DESC32,
+  BFD_RELOC_LARCH_TLS_DESC64,
   BFD_RELOC_LARCH_MARK_LA,
   BFD_RELOC_LARCH_MARK_PCREL,
   BFD_RELOC_LARCH_SOP_PUSH_PCREL,
@@ -7460,6 +7462,16 @@ enum bfd_reloc_code_real
   BFD_RELOC_LARCH_ADD_ULEB128,
   BFD_RELOC_LARCH_SUB_ULEB128,
   BFD_RELOC_LARCH_64_PCREL,
+  BFD_RELOC_LARCH_TLS_DESC_PC_HI20,
+  BFD_RELOC_LARCH_TLS_DESC_LD_PC_LO12,
+  BFD_RELOC_LARCH_TLS_DESC_ADD_PC_LO12,
+  BFD_RELOC_LARCH_TLS_DESC64_PC_LO20,
+  BFD_RELOC_LARCH_TLS_DESC64_PC_HI12,
+  BFD_RELOC_LARCH_TLS_DESC_HI20,
+  BFD_RELOC_LARCH_TLS_DESC_LO12,
+  BFD_RELOC_LARCH_TLS_DESC64_LO20,
+  BFD_RELOC_LARCH_TLS_DESC64_HI12,
+  BFD_RELOC_LARCH_TLS_DESC_CALL,
   BFD_RELOC_UNUSED
 };
 typedef enum bfd_reloc_code_real bfd_reloc_code_real_type;
diff --git a/bfd/elfxx-loongarch.c b/bfd/elfxx-loongarch.c
index 7f298c08fd3..c2df8f05562 100644
--- a/bfd/elfxx-loongarch.c
+++ b/bfd/elfxx-loongarch.c
@@ -293,8 +293,40 @@ static loongarch_reloc_howto_type loongarch_howto_table[] =
 	 NULL,				  /* adjust_reloc_bits */
 	 NULL),				  /* larch_reloc_type_name */
 
-  LOONGARCH_EMPTY_HOWTO (13),
-  LOONGARCH_EMPTY_HOWTO (14),
+  LOONGARCH_HOWTO (R_LARCH_TLS_DESC32,	  /* type (13).  */
+	 0,				  /* rightshift.  */
+	 4,				  /* size.  */
+	 32,				  /* bitsize.  */
+	 false,				  /* pc_relative.  */
+	 0,				  /* bitpos.  */
+	 complain_overflow_dont,	  /* complain_on_overflow.  */
+	 bfd_elf_generic_reloc,		  /* special_function.  */
+	 "R_LARCH_TLS_DESC32",		  /* name.  */
+	 false,				  /* partial_inplace.  */
+	 0,				  /* src_mask.  */
+	 ALL_ONES,		  	  /* dst_mask.  */
+	 false,				  /* pcrel_offset.  */
+	 BFD_RELOC_LARCH_TLS_DESC32,	  /* bfd_reloc_code_real_type.  */
+	 NULL,				  /* adjust_reloc_bits.  */
+	 NULL),				  /* larch_reloc_type_name.  */
+
+  LOONGARCH_HOWTO (R_LARCH_TLS_DESC64,	  /* type (14).  */
+	 0,				  /* rightshift.  */
+	 4,				  /* size.  */
+	 64,				  /* bitsize.  */
+	 false,				  /* pc_relative.  */
+	 0,				  /* bitpos.  */
+	 complain_overflow_dont,	  /* complain_on_overflow.  */
+	 bfd_elf_generic_reloc,		  /* special_function.  */
+	 "R_LARCH_TLS_DESC64",		  /* name.  */
+	 false,				  /* partial_inplace.  */
+	 0,				  /* src_mask.  */
+	 ALL_ONES,			  /* dst_mask.  */
+	 false,				  /* pcrel_offset.  */
+	 BFD_RELOC_LARCH_TLS_DESC64,	  /* bfd_reloc_code_real_type.  */
+	 NULL,				  /* adjust_reloc_bits.  */
+	 NULL),				  /* larch_reloc_type_name.  */
+
   LOONGARCH_EMPTY_HOWTO (15),
   LOONGARCH_EMPTY_HOWTO (16),
   LOONGARCH_EMPTY_HOWTO (17),
@@ -1547,6 +1579,179 @@ static loongarch_reloc_howto_type loongarch_howto_table[] =
 	 NULL,					/* adjust_reloc_bits */
 	 NULL),					/* larch_reloc_type_name */
 
+  /* TLS_DESC PCREL.  */
+  LOONGARCH_HOWTO (R_LARCH_TLS_DESC_PC_HI20,	/* type (110).  */
+	 12,					/* rightshift.  */
+	 4,					/* size.  */
+	 20,					/* bitsize.  */
+	 true,					/* pc_relative.  */
+	 5,					/* bitpos.  */
+	 complain_overflow_signed,		/* complain_on_overflow.  */
+	 bfd_elf_generic_reloc,			/* special_function.  */
+	 "R_LARCH_TLS_DESC_PC_HI20",		/* name.  */
+	 false,					/* partial_inplace.  */
+	 0,					/* src_mask.  */
+	 0x1ffffe0,				/* dst_mask.  */
+	 false,					/* pcrel_offset.  */
+	 BFD_RELOC_LARCH_TLS_DESC_PC_HI20,	/* bfd_reloc_code_real_type.  */
+	 reloc_bits,				/* adjust_reloc_bits.  */
+	 "desc_pc_hi20"),			/* larch_reloc_type_name.  */
+
+  LOONGARCH_HOWTO (R_LARCH_TLS_DESC_LD_PC_LO12,	/* type (111).  */
+	 0,					/* rightshift.  */
+	 4,					/* size.  */
+	 12,					/* bitsize.  */
+	 true,					/* pc_relative.  */
+	 10,					/* bitpos.  */
+	 complain_overflow_signed,		/* complain_on_overflow.  */
+	 bfd_elf_generic_reloc,			/* special_function.  */
+	 "R_LARCH_TLS_DESC_LD_PC_LO12",		/* name.  */
+	 false,					/* partial_inplace.  */
+	 0,					/* src_mask.  */
+	 0x3ffc00,				/* dst_mask.  */
+	 false,					/* pcrel_offset.  */
+	 BFD_RELOC_LARCH_TLS_DESC_LD_PC_LO12,	/* bfd_reloc_code_real_type.  */
+	 reloc_bits,				/* adjust_reloc_bits.  */
+	 "desc_ld_pc_lo12"),			/* larch_reloc_type_name.  */
+
+  LOONGARCH_HOWTO (R_LARCH_TLS_DESC_ADD_PC_LO12,/* type (112).  */
+	 0,					/* rightshift.  */
+	 4,					/* size.  */
+	 12,					/* bitsize.  */
+	 true,					/* pc_relative.  */
+	 10,					/* bitpos.  */
+	 complain_overflow_signed,		/* complain_on_overflow.  */
+	 bfd_elf_generic_reloc,			/* special_function.  */
+	 "R_LARCH_TLS_DESC_ADD_PC_LO12",	/* name.  */
+	 false,					/* partial_inplace.  */
+	 0,					/* src_mask.  */
+	 0x3ffc00,				/* dst_mask.  */
+	 false,					/* pcrel_offset.  */
+	 BFD_RELOC_LARCH_TLS_DESC_ADD_PC_LO12,	/* bfd_reloc_code_real_type.  */
+	 reloc_bits,				/* adjust_reloc_bits.  */
+	 "desc_add_pc_lo12"),			/* larch_reloc_type_name.  */
+
+  /* TLS_DESC64 LARGE PCREL.  */
+  LOONGARCH_HOWTO (R_LARCH_TLS_DESC64_PC_LO20, /* type (113).  */
+	32,				       /* rightshift.  */
+	4,				       /* size.  */
+	20,				       /* bitsize.  */
+	true,				       /* pc_relative.  */
+	5,				       /* bitpos.  */
+	complain_overflow_signed,	       /* complain_on_overflow.  */
+	bfd_elf_generic_reloc,		       /* special_function.  */
+	"R_LARCH_TLS_DESC64_PC_LO20",	       /* name.  */
+	false,				       /* partial_inplace.  */
+	0,				       /* src_mask.  */
+	0x1ffffe0,			       /* dst_mask.  */
+	false,				       /* pcrel_offset.  */
+	BFD_RELOC_LARCH_TLS_DESC64_PC_LO20,    /* bfd_reloc_code_real_type.  */
+	reloc_bits,			       /* adjust_reloc_bits.  */
+	"desc64_pc_lo20"),		       /* larch_reloc_type_name.  */
+
+  LOONGARCH_HOWTO (R_LARCH_TLS_DESC64_PC_HI12, /* type (114).  */
+	52,				       /* rightshift.  */
+	4,				       /* size.  */
+	12,				       /* bitsize.  */
+	true,				       /* pc_relative.  */
+	10,				       /* bitpos.  */
+	complain_overflow_signed,	       /* complain_on_overflow.  */
+	bfd_elf_generic_reloc,		       /* special_function.  */
+	"R_LARCH_TLS_DESC64_PC_HI12",	       /* name.  */
+	false,				       /* partial_inplace.  */
+	0,				       /* src_mask.  */
+	0x3ffc00,			       /* dst_mask.  */
+	false,				       /* pcrel_offset.  */
+	BFD_RELOC_LARCH_TLS_DESC64_PC_HI12,    /* bfd_reloc_code_real_type.  */
+	reloc_bits,			       /* adjust_reloc_bits.  */
+	"desc64_pc_hi12"),		       /* larch_reloc_type_name.  */
+
+  /* TLS_DESC ABS.  */
+  LOONGARCH_HOWTO (R_LARCH_TLS_DESC_HI20,	/* type (115).  */
+	 12,					/* rightshift.  */
+	 4,					/* size.  */
+	 20,					/* bitsize.  */
+	 false,					/* pc_relative.  */
+	 5,					/* bitpos.  */
+	 complain_overflow_signed,		/* complain_on_overflow.  */
+	 bfd_elf_generic_reloc,			/* special_function.  */
+	 "R_LARCH_TLS_DESC_HI20",		/* name.  */
+	 false,					/* partial_inplace.  */
+	 0,					/* src_mask.  */
+	 0x1ffffe0,				/* dst_mask.  */
+	 false,					/* pcrel_offset.  */
+	 BFD_RELOC_LARCH_TLS_DESC_HI20,		/* bfd_reloc_code_real_type.  */
+	 reloc_bits,				/* adjust_reloc_bits.  */
+	 "desc_hi20"),				/* larch_reloc_type_name.  */
+
+  LOONGARCH_HOWTO (R_LARCH_TLS_DESC_LO12,	/* type (116).  */
+	 0,					/* rightshift.  */
+	 4,					/* size.  */
+	 12,					/* bitsize.  */
+	 false,					/* pc_relative.  */
+	 10,					/* bitpos.  */
+	 complain_overflow_signed,		/* complain_on_overflow.  */
+	 bfd_elf_generic_reloc,			/* special_function.  */
+	 "R_LARCH_TLS_DESC_LO12",		/* name.  */
+	 false,					/* partial_inplace.  */
+	 0,					/* src_mask.  */
+	 0x3ffc00,				/* dst_mask.  */
+	 false,					/* pcrel_offset.  */
+	 BFD_RELOC_LARCH_TLS_DESC_LO12,		/* bfd_reloc_code_real_type.  */
+	 reloc_bits,				/* adjust_reloc_bits.  */
+	 "desc_lo12"),				/* larch_reloc_type_name.  */
+
+  /* TLS_DESC64 LARGE ABS.  */
+  LOONGARCH_HOWTO (R_LARCH_TLS_DESC64_LO20,    /* type (117).  */
+	32,				       /* rightshift.  */
+	4,				       /* size.  */
+	20,				       /* bitsize.  */
+	false,				       /* pc_relative.  */
+	5,				       /* bitpos.  */
+	complain_overflow_signed,	       /* complain_on_overflow.  */
+	bfd_elf_generic_reloc,		       /* special_function.  */
+	"R_LARCH_TLS_DESC64_LO20",	       /* name.  */
+	false,				       /* partial_inplace.  */
+	0,				       /* src_mask.  */
+	0x1ffffe0,			       /* dst_mask.  */
+	false,				       /* pcrel_offset.  */
+	BFD_RELOC_LARCH_TLS_DESC64_LO20,       /* bfd_reloc_code_real_type.  */
+	reloc_bits,			       /* adjust_reloc_bits.  */
+	"desc64_lo20"),			       /* larch_reloc_type_name.  */
+
+  LOONGARCH_HOWTO (R_LARCH_TLS_DESC64_HI12,    /* type (118).  */
+	52,				       /* rightshift.  */
+	4,				       /* size.  */
+	12,				       /* bitsize.  */
+	false,				       /* pc_relative.  */
+	10,				       /* bitpos.  */
+	complain_overflow_signed,	       /* complain_on_overflow.  */
+	bfd_elf_generic_reloc,		       /* special_function.  */
+	"R_LARCH_TLS_DESC64_HI12",	       /* name.  */
+	false,				       /* partial_inplace.  */
+	0,				       /* src_mask.  */
+	0x3ffc00,			       /* dst_mask.  */
+	false,				       /* pcrel_offset.  */
+	BFD_RELOC_LARCH_TLS_DESC64_HI12,       /* bfd_reloc_code_real_type.  */
+	reloc_bits,			       /* adjust_reloc_bits.  */
+	"desc64_hi12"),			       /* larch_reloc_type_name.  */
+
+  LOONGARCH_HOWTO (R_LARCH_TLS_DESC_CALL,	/* type (119).  */
+	 0,					/* rightshift.  */
+	 4,					/* size.  */
+	 0,					/* bitsize.  */
+	 false,					/* pc_relative.  */
+	 0,					/* bitpos.  */
+	 complain_overflow_dont,		/* complain_on_overflow.  */
+	 bfd_elf_generic_reloc,			/* special_function.  */
+	 "R_LARCH_TLS_DESC_CALL",		/* name.  */
+	 false,					/* partial_inplace.  */
+	 0,					/* src_mask.  */
+	 0,					/* dst_mask.  */
+	 false,					/* pcrel_offset.  */
+	 BFD_RELOC_LARCH_TLS_DESC_CALL,		/* bfd_reloc_code_real_type.  */
+	 NULL,					/* adjust_reloc_bits.  */
+	 "desc_call"),				/* larch_reloc_type_name.  */
 };
 
 reloc_howto_type *
diff --git a/bfd/libbfd.h b/bfd/libbfd.h
index cc432677a81..65ede521601 100644
--- a/bfd/libbfd.h
+++ b/bfd/libbfd.h
@@ -3516,6 +3516,8 @@ static const char *const bfd_reloc_code_real_names[] = { "@@uninitialized@@",
   "BFD_RELOC_LARCH_TLS_DTPREL64",
   "BFD_RELOC_LARCH_TLS_TPREL32",
   "BFD_RELOC_LARCH_TLS_TPREL64",
+  "BFD_RELOC_LARCH_TLS_DESC32",
+  "BFD_RELOC_LARCH_TLS_DESC64",
   "BFD_RELOC_LARCH_MARK_LA",
   "BFD_RELOC_LARCH_MARK_PCREL",
   "BFD_RELOC_LARCH_SOP_PUSH_PCREL",
@@ -3599,6 +3601,16 @@ static const char *const bfd_reloc_code_real_names[] = { "@@uninitialized@@",
   "BFD_RELOC_LARCH_ADD_ULEB128",
   "BFD_RELOC_LARCH_SUB_ULEB128",
   "BFD_RELOC_LARCH_64_PCREL",
+  "BFD_RELOC_LARCH_TLS_DESC_PC_HI20",
+  "BFD_RELOC_LARCH_TLS_DESC_LD_PC_LO12",
+  "BFD_RELOC_LARCH_TLS_DESC_ADD_PC_LO12",
+  "BFD_RELOC_LARCH_TLS_DESC64_PC_LO20",
+  "BFD_RELOC_LARCH_TLS_DESC64_PC_HI12",
+  "BFD_RELOC_LARCH_TLS_DESC_HI20",
+  "BFD_RELOC_LARCH_TLS_DESC_LO12",
+  "BFD_RELOC_LARCH_TLS_DESC64_LO20",
+  "BFD_RELOC_LARCH_TLS_DESC64_HI12",
+  "BFD_RELOC_LARCH_TLS_DESC_CALL",
  "@@overflow: BFD_RELOC_UNUSED@@",
 };
 #endif
diff --git a/bfd/reloc.c b/bfd/reloc.c
index 93ebad879e0..e5717e60416 100644
--- a/bfd/reloc.c
+++ b/bfd/reloc.c
@@ -8111,6 +8111,10 @@ ENUMX
   BFD_RELOC_LARCH_TLS_TPREL32
 ENUMX
   BFD_RELOC_LARCH_TLS_TPREL64
+ENUMX
+  BFD_RELOC_LARCH_TLS_DESC32
+ENUMX
+  BFD_RELOC_LARCH_TLS_DESC64
 ENUMX
   BFD_RELOC_LARCH_MARK_LA
 ENUMX
@@ -8292,6 +8296,31 @@ ENUMX
 ENUMX
   BFD_RELOC_LARCH_64_PCREL
 
+ENUMX
+  BFD_RELOC_LARCH_TLS_DESC_PC_HI20
+ENUMX
+  BFD_RELOC_LARCH_TLS_DESC_LD_PC_LO12
+ENUMX
+  BFD_RELOC_LARCH_TLS_DESC_ADD_PC_LO12
+
+ENUMX
+  BFD_RELOC_LARCH_TLS_DESC64_PC_LO20
+ENUMX
+  BFD_RELOC_LARCH_TLS_DESC64_PC_HI12
+
+ENUMX
+  BFD_RELOC_LARCH_TLS_DESC_HI20
+ENUMX
+  BFD_RELOC_LARCH_TLS_DESC_LO12
+
+ENUMX
+  BFD_RELOC_LARCH_TLS_DESC64_LO20
+ENUMX
+  BFD_RELOC_LARCH_TLS_DESC64_HI12
+
+ENUMX
+  BFD_RELOC_LARCH_TLS_DESC_CALL
+
 ENUMDOC
   LARCH relocations.
 
diff --git a/gas/config/tc-loongarch.c b/gas/config/tc-loongarch.c
index d1ce111c186..b3c9a4d834c 100644
--- a/gas/config/tc-loongarch.c
+++ b/gas/config/tc-loongarch.c
@@ -682,7 +682,7 @@ loongarch_args_parser_can_match_arg_helper (char esc_ch1, char esc_ch2,
 		      esc_ch1, esc_ch2, bit_field, arg);
 
 	  if (ip->reloc_info[0].type >= BFD_RELOC_LARCH_B16
-	      && ip->reloc_info[0].type < BFD_RELOC_LARCH_64_PCREL)
+	      && ip->reloc_info[0].type <= BFD_RELOC_LARCH_TLS_DESC_CALL)
 	    {
 	      /* As we compact stack-relocs, it is no need for pop operation.
 		 But break out until here in order to check the imm field.
@@ -1268,6 +1268,15 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
     case BFD_RELOC_LARCH_TLS_LD_HI20:
     case BFD_RELOC_LARCH_TLS_GD_PC_HI20:
     case BFD_RELOC_LARCH_TLS_GD_HI20:
+    case BFD_RELOC_LARCH_TLS_DESC_PC_HI20:
+    case BFD_RELOC_LARCH_TLS_DESC_LD_PC_LO12:
+    case BFD_RELOC_LARCH_TLS_DESC_ADD_PC_LO12:
+    case BFD_RELOC_LARCH_TLS_DESC64_PC_LO20:
+    case BFD_RELOC_LARCH_TLS_DESC64_PC_HI12:
+    case BFD_RELOC_LARCH_TLS_DESC_HI20:
+    case BFD_RELOC_LARCH_TLS_DESC_LO12:
+    case BFD_RELOC_LARCH_TLS_DESC64_LO20:
+    case BFD_RELOC_LARCH_TLS_DESC64_HI12:
       /* Add tls lo (got_lo reloc type).  */
       if (fixP->fx_addsy == NULL)
 	as_bad_where (fixP->fx_file, fixP->fx_line,
@@ -1288,6 +1297,9 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
 	stack_top = 0;
       break;
 
+    case BFD_RELOC_LARCH_TLS_DESC_CALL:
+      break;
+
     case BFD_RELOC_LARCH_SOP_POP_32_S_10_5:
     case BFD_RELOC_LARCH_SOP_POP_32_S_10_12:
     case BFD_RELOC_LARCH_SOP_POP_32_U_10_12:
diff --git a/include/elf/loongarch.h b/include/elf/loongarch.h
index e31395e13d5..7018d101993 100644
--- a/include/elf/loongarch.h
+++ b/include/elf/loongarch.h
@@ -38,7 +38,8 @@ RELOC_NUMBER (R_LARCH_TLS_DTPREL64, 9)
 RELOC_NUMBER (R_LARCH_TLS_TPREL32, 10)
 RELOC_NUMBER (R_LARCH_TLS_TPREL64, 11)
 RELOC_NUMBER (R_LARCH_IRELATIVE, 12)
-
+RELOC_NUMBER (R_LARCH_TLS_DESC32, 13)
+RELOC_NUMBER (R_LARCH_TLS_DESC64, 14)
 /* Reserved for future relocs that the dynamic linker must understand.  */
 
 /* Used by the static linker for relocating .text.  */
@@ -251,6 +252,25 @@ RELOC_NUMBER (R_LARCH_SUB_ULEB128, 108)
 
 RELOC_NUMBER (R_LARCH_64_PCREL, 109)
 
+/* TLS_DESC PCREL.  */
+RELOC_NUMBER (R_LARCH_TLS_DESC_PC_HI20, 110)
+RELOC_NUMBER (R_LARCH_TLS_DESC_LD_PC_LO12, 111)
+RELOC_NUMBER (R_LARCH_TLS_DESC_ADD_PC_LO12, 112)
+
+/* TLS_DESC LARGE PCREL.  */
+RELOC_NUMBER (R_LARCH_TLS_DESC64_PC_LO20, 113)
+RELOC_NUMBER (R_LARCH_TLS_DESC64_PC_HI12, 114)
+
+/* TLS_DESC ABS.  */
+RELOC_NUMBER (R_LARCH_TLS_DESC_HI20, 115)
+RELOC_NUMBER (R_LARCH_TLS_DESC_LO12, 116)
+
+/* TLSDESC LARGE ABS.  */
+RELOC_NUMBER (R_LARCH_TLS_DESC64_LO20, 117)
+RELOC_NUMBER (R_LARCH_TLS_DESC64_HI12, 118)
+
+RELOC_NUMBER (R_LARCH_TLS_DESC_CALL, 119)
+
 END_RELOC_NUMBERS (R_LARCH_count)
 
 /* Processor specific flags for the ELF header e_flags field.  */
diff --git a/opcodes/loongarch-opc.c b/opcodes/loongarch-opc.c
index 82b88bdad2a..b650419d703 100644
--- a/opcodes/loongarch-opc.c
+++ b/opcodes/loongarch-opc.c
@@ -293,6 +293,55 @@ const char *const loongarch_x_normal_name[32] =
   &LARCH_opts.ase_lp64,		      \
   &LARCH_opts.ase_gpcr
 
+/* For TLS_DESC32 pcrel.  */
+#define INSN_LA_TLS_DESC32		\
+  "pcalau12i %1,%%desc_pc_hi20(%2);"    \
+  "ld.w $r5,%1,%%desc_ld_pc_lo12(%2);"  \
+  "addi.w %1,%1,%%desc_add_pc_lo12(%2);"\
+  "jirl $r1,$r5,%%desc_call(%2);",	\
+  &LARCH_opts.ase_ilp32,		\
+  &LARCH_opts.ase_lp64
+
+/* For TLS_DESC32 abs.  */
+#define INSN_LA_TLS_DESC32_ABS		\
+  "lu12i.w %1,%%desc_hi20(%2);"		\
+  "ori %1,%1,%%desc_lo12(%2);"		\
+  "ld.w $r5,%1,0;"			\
+  "jirl $r1,$r5,%%desc_call(%2);",	\
+  &LARCH_opts.ase_gabs,			\
+  &LARCH_opts.ase_lp64
+
+/* For TLS_DESC64 pcrel.  */
+#define INSN_LA_TLS_DESC64		\
+  "pcalau12i %1,%%desc_pc_hi20(%2);"	\
+  "ld.d $r5,%1,%%desc_ld_pc_lo12(%2);"	\
+  "addi.d %1,%1,%%desc_add_pc_lo12(%2);"\
+  "jirl $r1,$r5,%%desc_call(%2);",	\
+  &LARCH_opts.ase_lp64, 0
+
+/* For TLS_DESC64 large pcrel.  */
+#define INSN_LA_TLS_DESC64_LARGE_PCREL	 \
+  "pcalau12i %1,%%desc_pc_hi20(%3);"	 \
+  "addi.d %2,$r0,%%desc_add_pc_lo12(%3);"\
+  "lu32i.d %2,%%desc64_pc_lo20(%3);"	 \
+  "lu52i.d %2,%2,%%desc64_pc_hi12(%3);"	 \
+  "add.d %1,%1,%2;"			 \
+  "ld.d %2,%1,0;"			 \
+  "jirl $r1,%2,%%desc_call(%3);",	 \
+  &LARCH_opts.ase_lp64,			 \
+  &LARCH_opts.ase_gabs
+
+/* For TLS_DESC64 large abs.  */
+#define INSN_LA_TLS_DESC64_LARGE_ABS  \
+  "lu12i.w %1,%%desc_hi20(%2);"	      \
+  "ori %1,%1,%%desc_lo12(%2);"	      \
+  "lu32i.d %1,%%desc64_lo20(%2);"     \
+  "lu52i.d %1,%1,%%desc64_hi12(%2);"  \
+  "ld.d $r5,%1,0;"		      \
+  "jirl $r1,$r5,%%desc_call(%2);",    \
+  &LARCH_opts.ase_lp64,		      \
+  &LARCH_opts.ase_gpcr
+
 
 static struct loongarch_opcode loongarch_macro_opcodes[] =
 {
@@ -341,6 +390,11 @@ static struct loongarch_opcode loongarch_macro_opcodes[] =
   { 0, 0, "la.tls.gd",	"r,l",	  INSN_LA_TLS_GD64_LARGE_ABS,	0 },
   { 0, 0, "la.tls.gd",	"r,r,l",  INSN_LA_TLS_GD64_LARGE_PCREL,	0 },
   { 0, 0, "pcaddi",	"r,la",	  "pcaddi %1, %%pcrel_20(%2)",	&LARCH_opts.ase_ilp32, 0, 0 },
+  { 0, 0, "la.tls.desc", "r,l",   INSN_LA_TLS_DESC32, 0 },
+  { 0, 0, "la.tls.desc", "r,l",   INSN_LA_TLS_DESC32_ABS, 0 },
+  { 0, 0, "la.tls.desc", "r,l",	  INSN_LA_TLS_DESC64, 0 },
+  { 0, 0, "la.tls.desc", "r,l",   INSN_LA_TLS_DESC64_LARGE_ABS, 0 },
+  { 0, 0, "la.tls.desc", "r,r,l", INSN_LA_TLS_DESC64_LARGE_PCREL, 0 },
   { 0, 0, 0, 0, 0, 0, 0, 0 } /* Terminate the list.  */
 };
 
-- 
2.36.0


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

* [PATCH v1 2/4] LoongArch: Add support for TLSDESC in ld.
  2023-12-01  9:04 [PATCH v1 0/4] LoongArch: Add support for TLS Descriptors (TLSDESC) Lulu Cai
  2023-12-01  9:04 ` [PATCH v1 1/4] LoongArch: Add new relocs and macro for TLSDESC Lulu Cai
@ 2023-12-01  9:04 ` Lulu Cai
  2023-12-01  9:04 ` [PATCH v1 3/4] LoongArch: Add transition support for DESC to LE Lulu Cai
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 11+ messages in thread
From: Lulu Cai @ 2023-12-01  9:04 UTC (permalink / raw)
  To: binutils
  Cc: xuchenghua, chenglulu, liuzhensong, mengqinggang, xry111,
	i.swmail, maskray, luweining, wanglei, hejinyang, Lulu Cai

---
 bfd/elfnn-loongarch.c | 168 ++++++++++++++++++++++++++++++++++++------
 1 file changed, 146 insertions(+), 22 deletions(-)

diff --git a/bfd/elfnn-loongarch.c b/bfd/elfnn-loongarch.c
index 024c5d4cd96..e1cf7c1eda0 100644
--- a/bfd/elfnn-loongarch.c
+++ b/bfd/elfnn-loongarch.c
@@ -48,6 +48,12 @@ struct loongarch_elf_link_hash_entry
 #define GOT_TLS_GD  2
 #define GOT_TLS_IE  4
 #define GOT_TLS_LE  8
+#define GOT_TLS_GDESC 16
+
+#define GOT_TLS_GD_BOTH_P(tls_type) \
+  ((tls_type & GOT_TLS_GD) && (tls_type & GOT_TLS_GDESC))
+#define GOT_TLS_GD_ANY_P(tls_type) \
+  ((tls_type & GOT_TLS_GD) || (tls_type & GOT_TLS_GDESC))
   char tls_type;
 };
 
@@ -563,6 +569,7 @@ loongarch_elf_record_tls_and_got_reference (bfd *abfd,
     case GOT_NORMAL:
     case GOT_TLS_GD:
     case GOT_TLS_IE:
+    case GOT_TLS_GDESC:
       /* Need GOT.  */
       if (htab->elf.sgot == NULL
 	  && !loongarch_elf_create_got_section (htab->elf.dynobj, info))
@@ -750,6 +757,14 @@ loongarch_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
 	    return false;
 	  break;
 
+	case R_LARCH_TLS_DESC_PC_HI20:
+	case R_LARCH_TLS_DESC_HI20:
+	  if (!loongarch_elf_record_tls_and_got_reference (abfd, info, h,
+							   r_symndx,
+							   GOT_TLS_GDESC))
+	    return false;
+	  break;
+
 	case R_LARCH_ABS_HI20:
 	case R_LARCH_SOP_PUSH_ABSOLUTE:
 	  if (h != NULL)
@@ -1129,7 +1144,7 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
 
       s = htab->elf.sgot;
       h->got.offset = s->size;
-      if (tls_type & (GOT_TLS_GD | GOT_TLS_IE))
+      if (tls_type & (GOT_TLS_GD | GOT_TLS_IE | GOT_TLS_GDESC))
 	{
 	  /* TLS_GD needs two dynamic relocs and two GOT slots.  */
 	  if (tls_type & GOT_TLS_GD)
@@ -1166,7 +1181,15 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
 		  htab->elf.srelgot->size += sizeof (ElfNN_External_Rela);
 		}
 	    }
+
+	  /* TLS_DESC needs one dynamic reloc and two GOT slot.  */
+	  if (tls_type & GOT_TLS_GDESC)
+	    {
+	      s->size += GOT_ENTRY_SIZE * 2;
+	      htab->elf.srelgot->size += sizeof (ElfNN_External_Rela);
+	    }
 	}
+
       else
 	{
 	  s->size += GOT_ENTRY_SIZE;
@@ -1669,19 +1692,34 @@ loongarch_elf_size_dynamic_sections (bfd *output_bfd,
 	  if (0 < *local_got)
 	    {
 	      *local_got = s->size;
+	      if (*local_tls_type & (GOT_TLS_GD | GOT_TLS_IE | GOT_TLS_GDESC))
+		{
+		  /* TLS gd use two got.  */
+		  if (*local_tls_type & GOT_TLS_GD)
+		    {
+		      s->size += 2 * GOT_ENTRY_SIZE;
+		      if (!bfd_link_executable (info))
+			srel->size += sizeof (ElfNN_External_Rela);
+		    }
 
-	      /* TLS gd use two got.  */
-	      if (*local_tls_type & GOT_TLS_GD)
-		s->size += GOT_ENTRY_SIZE * 2;
-	      else
-		/* Normal got, tls ie/ld use one got.  */
-		s->size += GOT_ENTRY_SIZE;
+		  /* TLS_DESC use two got.  */
+		  if (*local_tls_type & GOT_TLS_GDESC)
+		    {
+		      s->size += 2 * GOT_ENTRY_SIZE;
+		      srel->size += sizeof (ElfNN_External_Rela);
+		    }
 
-	      if (bfd_link_executable (info)
-		  && (*local_tls_type & (GOT_TLS_GD| GOT_TLS_IE)))
-		;/* Do nothing.  */
+		  /* TLS ie and use one got.  */
+		  if (*local_tls_type & GOT_TLS_IE)
+		    {
+		      s->size += GOT_ENTRY_SIZE;
+		      if (!bfd_link_executable (info))
+			srel->size += sizeof (ElfNN_External_Rela);
+		    }
+		}
 	      else
 		{
+		  s->size += GOT_ENTRY_SIZE;
 		  srel->size += sizeof (ElfNN_External_Rela);
 		}
 	    }
@@ -2120,6 +2158,16 @@ perform_relocation (const Elf_Internal_Rela *rel, asection *input_section,
     case R_LARCH_TLS_GD_PC_HI20:
     case R_LARCH_TLS_GD_HI20:
     case R_LARCH_PCREL20_S2:
+    case R_LARCH_TLS_DESC_PC_HI20:
+    case R_LARCH_TLS_DESC_LD_PC_LO12:
+    case R_LARCH_TLS_DESC_ADD_PC_LO12:
+    case R_LARCH_TLS_DESC64_PC_LO20:
+    case R_LARCH_TLS_DESC64_PC_HI12:
+    case R_LARCH_TLS_DESC_HI20:
+    case R_LARCH_TLS_DESC_LO12:
+    case R_LARCH_TLS_DESC64_LO20:
+    case R_LARCH_TLS_DESC64_HI12:
+
       r = loongarch_check_offset (rel, input_section);
       if (r != bfd_reloc_ok)
 	break;
@@ -2129,6 +2177,10 @@ perform_relocation (const Elf_Internal_Rela *rel, asection *input_section,
 					    contents, value);
       break;
 
+    case R_LARCH_TLS_DESC_CALL:
+      r = bfd_reloc_ok;
+      break;
+
     case R_LARCH_RELAX:
       break;
 
@@ -2377,10 +2429,10 @@ loongarch_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
       struct elf_link_hash_entry *h = NULL;
       const char *name;
       bfd_reloc_status_type r = bfd_reloc_ok;
-      bool is_ie, is_undefweak, unresolved_reloc, defined_local;
+      bool is_ie, is_desc, is_undefweak, unresolved_reloc, defined_local;
       bool resolved_local, resolved_dynly, resolved_to_const;
       char tls_type;
-      bfd_vma relocation, off, ie_off;
+      bfd_vma relocation, off, ie_off, desc_off;
       int i, j;
 
       howto = loongarch_elf_rtype_to_howto (input_bfd, r_type);
@@ -2509,6 +2561,7 @@ loongarch_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
 
       BFD_ASSERT (!resolved_local || defined_local);
 
+      is_desc = false;
       is_ie = false;
       switch (r_type)
 	{
@@ -3398,6 +3451,8 @@ loongarch_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
 	case R_LARCH_TLS_LD_HI20:
 	case R_LARCH_TLS_GD_PC_HI20:
 	case R_LARCH_TLS_GD_HI20:
+	case R_LARCH_TLS_DESC_PC_HI20:
+	case R_LARCH_TLS_DESC_HI20:
 	  BFD_ASSERT (rel->r_addend == 0);
 	  unresolved_reloc = false;
 
@@ -3405,6 +3460,10 @@ loongarch_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
 	      || r_type == R_LARCH_TLS_IE_HI20)
 	    is_ie = true;
 
+	  if (r_type == R_LARCH_TLS_DESC_PC_HI20
+	      || r_type == R_LARCH_TLS_DESC_HI20)
+	    is_desc = true;
+
 	  bfd_vma got_off = 0;
 	  if (h != NULL)
 	    {
@@ -3419,9 +3478,19 @@ loongarch_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
 
 	  BFD_ASSERT (got_off != MINUS_ONE);
 
-	  ie_off = 0;
 	  tls_type = _bfd_loongarch_elf_tls_type (input_bfd, h, r_symndx);
-	  if ((tls_type & GOT_TLS_GD) && (tls_type & GOT_TLS_IE))
+
+	  /* If a tls variable is accessed in multiple ways, GD uses
+	     the first two slots of GOT, desc follows with two slots,
+	     and IE uses one slot at the end.  */
+	  desc_off = 0;
+	  if (GOT_TLS_GD_BOTH_P (tls_type))
+	    desc_off = 2 * GOT_ENTRY_SIZE;
+
+	  ie_off = 0;
+	  if (GOT_TLS_GD_BOTH_P (tls_type) && (tls_type & GOT_TLS_IE))
+	    ie_off = 4 * GOT_ENTRY_SIZE;
+	  else if (GOT_TLS_GD_ANY_P (tls_type) && (tls_type & GOT_TLS_IE))
 	    ie_off = 2 * GOT_ENTRY_SIZE;
 
 	  if ((got_off & 1) == 0)
@@ -3470,6 +3539,21 @@ loongarch_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
 		      loongarch_elf_append_rela (output_bfd, relgot, &rela);
 		    }
 		}
+	      if (tls_type & GOT_TLS_GDESC)
+		{
+		  /* Unless it is a static link, DESC always emits a
+		     dynamic relocation.  */
+		  int indx = h && h->dynindx != -1 ? h->dynindx : 0;
+		  rela.r_offset = sec_addr (got) + got_off + desc_off;
+		  rela.r_addend = 0;
+		  if (indx == 0)
+		    rela.r_addend = relocation - elf_hash_table (info)->tls_sec->vma;
+
+		  rela.r_info = ELFNN_R_INFO (indx, R_LARCH_TLS_DESCNN);
+		  loongarch_elf_append_rela (output_bfd, relgot, &rela);
+		  bfd_put_NN (output_bfd, 0,
+			      got->contents + got_off + desc_off);
+		}
 	      if (tls_type & GOT_TLS_IE)
 		{
 		  rela.r_offset = sec_addr (got) + got_off + ie_off;
@@ -3497,16 +3581,52 @@ loongarch_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
 		    }
 		}
 	    }
-	  relocation = (got_off & (~(bfd_vma)1)) + sec_addr (got)
-			+ (is_ie ? ie_off : 0);
+	  relocation = (got_off & (~(bfd_vma)1)) + sec_addr (got);
+	  if (is_desc)
+	    relocation += desc_off;
+	  else if (is_ie)
+	    relocation += ie_off;
 
 	  if (r_type == R_LARCH_TLS_LD_PC_HI20
 	      || r_type == R_LARCH_TLS_GD_PC_HI20
-	      || r_type == R_LARCH_TLS_IE_PC_HI20)
+	      || r_type == R_LARCH_TLS_IE_PC_HI20
+	      || r_type == R_LARCH_TLS_DESC_PC_HI20)
 	    RELOCATE_CALC_PC32_HI20 (relocation, pc);
 
 	  break;
 
+	case R_LARCH_TLS_DESC_LD_PC_LO12:
+	case R_LARCH_TLS_DESC_ADD_PC_LO12:
+	case R_LARCH_TLS_DESC64_PC_LO20:
+	case R_LARCH_TLS_DESC64_PC_HI12:
+	case R_LARCH_TLS_DESC_LO12:
+	case R_LARCH_TLS_DESC64_LO20:
+	case R_LARCH_TLS_DESC64_HI12:
+	  {
+	    unresolved_reloc = false;
+
+	    if (h)
+	      relocation = sec_addr (got) + (h->got.offset & (~(bfd_vma)1));
+	    else
+	      relocation = sec_addr (got)
+			   + (local_got_offsets[r_symndx] & (~(bfd_vma)1));
+
+	    tls_type = _bfd_loongarch_elf_tls_type (input_bfd, h, r_symndx);
+	    /* Use both TLS_GD and TLS_DESC.  */
+	    if ((tls_type & GOT_TLS_GD) && (tls_type & GOT_TLS_GDESC))
+	      relocation += 2 * GOT_ENTRY_SIZE;
+	  }
+
+	    if (r_type == R_LARCH_TLS_DESC64_PC_LO20
+		|| r_type == R_LARCH_TLS_DESC64_PC_HI12)
+	      RELOCATE_CALC_PC64_HI32 (relocation, pc);
+
+	    break;
+
+	case R_LARCH_TLS_DESC_CALL:
+	  unresolved_reloc = false;
+	  break;
+
 	case R_LARCH_TLS_IE_PC_LO12:
 	case R_LARCH_TLS_IE64_PC_LO20:
 	case R_LARCH_TLS_IE64_PC_HI12:
@@ -3516,14 +3636,17 @@ loongarch_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
 	  unresolved_reloc = false;
 
 	  if (h)
-	    relocation = sec_addr (got) + (h->got.offset & (~(bfd_vma)3));
+	    relocation = sec_addr (got) + (h->got.offset & (~(bfd_vma)1));
 	  else
 	    relocation = sec_addr (got)
-	      + (local_got_offsets[r_symndx] & (~(bfd_vma)3));
+	      + (local_got_offsets[r_symndx] & (~(bfd_vma)1));
 
 	  tls_type = _bfd_loongarch_elf_tls_type (input_bfd, h, r_symndx);
-	  /* Use both TLS_GD and TLS_IE.  */
-	  if ((tls_type & GOT_TLS_GD) && (tls_type & GOT_TLS_IE))
+	  /* Use TLS_GD TLS_DESC and TLS_IE.  */
+	  if (GOT_TLS_GD_BOTH_P (tls_type) && (tls_type & GOT_TLS_IE))
+	    relocation += 4 * GOT_ENTRY_SIZE;
+	  /* Use GOT_TLS_GD_ANY_P (tls_type) and TLS_IE.  */
+	  else if (GOT_TLS_GD_ANY_P (tls_type) && (tls_type & GOT_TLS_IE))
 	    relocation += 2 * GOT_ENTRY_SIZE;
 
 	  if (r_type == R_LARCH_TLS_IE64_PC_LO20
@@ -4149,7 +4272,8 @@ loongarch_elf_finish_dynamic_symbol (bfd *output_bfd,
 
   if (h->got.offset != MINUS_ONE
       /* TLS got entry have been handled in elf_relocate_section.  */
-      && !(loongarch_elf_hash_entry (h)->tls_type & (GOT_TLS_GD | GOT_TLS_IE))
+      && !(loongarch_elf_hash_entry (h)->tls_type
+	   & (GOT_TLS_GD | GOT_TLS_IE | GOT_TLS_GDESC))
       /* Have allocated got entry but not allocated rela before.  */
       && !UNDEFWEAK_NO_DYNAMIC_RELOC (info, h))
     {
-- 
2.36.0


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

* [PATCH v1 3/4] LoongArch: Add transition support for DESC to LE.
  2023-12-01  9:04 [PATCH v1 0/4] LoongArch: Add support for TLS Descriptors (TLSDESC) Lulu Cai
  2023-12-01  9:04 ` [PATCH v1 1/4] LoongArch: Add new relocs and macro for TLSDESC Lulu Cai
  2023-12-01  9:04 ` [PATCH v1 2/4] LoongArch: Add support for TLSDESC in ld Lulu Cai
@ 2023-12-01  9:04 ` Lulu Cai
  2023-12-01  9:04 ` [PATCH v1 4/4] LoongArch: Add testsuits for TLSDESC in gas and ld Lulu Cai
                   ` (2 subsequent siblings)
  5 siblings, 0 replies; 11+ messages in thread
From: Lulu Cai @ 2023-12-01  9:04 UTC (permalink / raw)
  To: binutils
  Cc: xuchenghua, chenglulu, liuzhensong, mengqinggang, xry111,
	i.swmail, maskray, luweining, wanglei, hejinyang, Lulu Cai

---
 bfd/elfnn-loongarch.c      | 108 ++++++++++++++++++++++++++++++++++++-
 include/opcode/loongarch.h |   3 ++
 2 files changed, 110 insertions(+), 1 deletion(-)

diff --git a/bfd/elfnn-loongarch.c b/bfd/elfnn-loongarch.c
index e1cf7c1eda0..d8095aaae54 100644
--- a/bfd/elfnn-loongarch.c
+++ b/bfd/elfnn-loongarch.c
@@ -145,6 +145,12 @@ struct loongarch_elf_link_hash_table
 #define elf_backend_rela_normal 1
 #define elf_backend_default_execstack 0
 
+#define IS_LOONGARCH_TLS_DESC_RELOC(R_TYPE)    \
+  ((R_TYPE) == R_LARCH_TLS_DESC_PC_HI20	\
+   || (R_TYPE) == R_LARCH_TLS_DESC_LD_PC_LO12  \
+   || (R_TYPE) == R_LARCH_TLS_DESC_ADD_PC_LO12 \
+   || (R_TYPE) == R_LARCH_TLS_DESC_CALL)
+
 /* Generate a PLT header.  */
 
 static bool
@@ -605,6 +611,58 @@ loongarch_elf_record_tls_and_got_reference (bfd *abfd,
   return true;
 }
 
+/* Return true if DESC can transition to LE.  */
+static bool
+loongarch_can_relax_tls (struct bfd_link_info *info, unsigned int r_type,
+			 struct elf_link_hash_entry *h)
+{
+  if (! IS_LOONGARCH_TLS_DESC_RELOC (r_type))
+    return false;
+
+  bool local_exec = bfd_link_executable (info)
+		    && SYMBOL_REFERENCES_LOCAL (info, h);
+  if (! local_exec)
+      return false;
+
+  if (h && h->root.type == bfd_link_hash_undefweak)
+    return false;
+
+  return true;
+}
+
+/* Perform the transition from DESC relocation to LE relocation.  */
+static unsigned int
+loongarch_tls_transition_without_check (unsigned int r_type)
+{
+  switch (r_type)
+    {
+      case R_LARCH_TLS_DESC_PC_HI20:
+	return R_LARCH_TLS_LE_HI20;
+
+      case R_LARCH_TLS_DESC_LD_PC_LO12:
+	return R_LARCH_TLS_LE_LO12;
+
+      case R_LARCH_TLS_DESC_ADD_PC_LO12:
+      case R_LARCH_TLS_DESC_CALL:
+	return R_LARCH_NONE;
+
+      default:
+	break;
+    }
+
+  return r_type;
+}
+
+static unsigned int
+loongarch_tls_transition (struct bfd_link_info *info, unsigned int r_type,
+			  struct elf_link_hash_entry *h)
+{
+  if (! loongarch_can_relax_tls (info, r_type, h))
+    return r_type;
+
+  return loongarch_tls_transition_without_check (r_type);
+}
+
 /* Look through the relocs for a section during the first phase, and
    allocate space in the global offset table or procedure linkage
    table.  */
@@ -706,6 +764,7 @@ loongarch_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
       int need_dynreloc = 0;
       int only_need_pcrel = 0;
 
+      r_type = loongarch_tls_transition (info, r_type, h);
       switch (r_type)
 	{
 	case R_LARCH_GOT_PC_HI20:
@@ -2397,6 +2456,45 @@ loongarch_reloc_is_fatal (struct bfd_link_info *info,
       relocation += 0x100000000;			\
   })
 
+/* Transition DESC instruction sequence to LE instruction sequence.  */
+static bool
+loongarch_tls_relax (bfd *abfd, asection *sec, Elf_Internal_Rela *rel,
+		    int r_type)
+{
+  bfd_byte *contents = elf_section_data (sec)->this_hdr.contents;
+  switch (r_type)
+    {
+      case R_LARCH_TLS_DESC_PC_HI20:
+	/* DESC -> LE relaxation:
+	   pcalalau12i $a0,%desc_pc_hi20(var) => lu12i.w $a0,%le_hi20(var)
+	*/
+	bfd_put (32, abfd, LARCH_LU12I_W_A0, contents + rel->r_offset);
+
+	return true;
+
+      case R_LARCH_TLS_DESC_LD_PC_LO12:
+	/* DESC -> LE relaxation:
+	   ld.d $a1,$a0,%desc_ld_pc_lo12(var) => ori $a0,$a0,le_lo12(var)
+	*/
+	bfd_put (32, abfd, LARCH_ORI_A0, contents + rel->r_offset);
+
+	return true;
+
+      case R_LARCH_TLS_DESC_ADD_PC_LO12:
+      case R_LARCH_TLS_DESC_CALL:
+	/* DESC -> LE relaxation:
+	   addi.d $a0,$a0,%desc_add_pc_lo12(var) => NOP
+	   jirl $ra,$a1,%desc_call(var) => NOP
+	*/
+	bfd_put (32, abfd, LARCH_NOP, contents + rel->r_offset);
+
+	return true;
+    }
+
+  return false;
+}
+
+
 static int
 loongarch_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
 				bfd *input_bfd, asection *input_section,
@@ -2420,7 +2518,7 @@ loongarch_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
   relend = relocs + input_section->reloc_count;
   for (rel = relocs; rel < relend; rel++)
     {
-      int r_type = ELFNN_R_TYPE (rel->r_info);
+      unsigned int r_type = ELFNN_R_TYPE (rel->r_info);
       unsigned long r_symndx = ELFNN_R_SYM (rel->r_info);
       bfd_vma pc = sec_addr (input_section) + rel->r_offset;
       reloc_howto_type *howto = NULL;
@@ -2430,6 +2528,7 @@ loongarch_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
       const char *name;
       bfd_reloc_status_type r = bfd_reloc_ok;
       bool is_ie, is_desc, is_undefweak, unresolved_reloc, defined_local;
+      unsigned int relaxed_r_type;
       bool resolved_local, resolved_dynly, resolved_to_const;
       char tls_type;
       bfd_vma relocation, off, ie_off, desc_off;
@@ -2561,6 +2660,13 @@ loongarch_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
 
       BFD_ASSERT (!resolved_local || defined_local);
 
+      relaxed_r_type = loongarch_tls_transition (info, r_type, h);
+      if (relaxed_r_type != r_type)
+      {
+	loongarch_tls_relax (input_bfd, input_section, rel, r_type);
+	r_type = relaxed_r_type;
+      }
+
       is_desc = false;
       is_ie = false;
       switch (r_type)
diff --git a/include/opcode/loongarch.h b/include/opcode/loongarch.h
index da936f7945a..9a4a95d1177 100644
--- a/include/opcode/loongarch.h
+++ b/include/opcode/loongarch.h
@@ -42,6 +42,9 @@ extern "C"
     ((value) < (-(1 << ((bits) - 1) << align)) 	\
       || (value) > ((((1 << ((bits) - 1)) - 1) << align)))
 
+  #define LARCH_LU12I_W_A0 0x14000004
+  #define LARCH_ORI_A0 0x03800084
+
   typedef uint32_t insn_t;
 
   struct loongarch_opcode
-- 
2.36.0


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

* [PATCH v1 4/4] LoongArch: Add testsuits for TLSDESC in gas and ld.
  2023-12-01  9:04 [PATCH v1 0/4] LoongArch: Add support for TLS Descriptors (TLSDESC) Lulu Cai
                   ` (2 preceding siblings ...)
  2023-12-01  9:04 ` [PATCH v1 3/4] LoongArch: Add transition support for DESC to LE Lulu Cai
@ 2023-12-01  9:04 ` Lulu Cai
  2023-12-02  7:38   ` Xi Ruoyao
  2023-12-01 16:14 ` [PATCH v1 0/4] LoongArch: Add support for TLS Descriptors (TLSDESC) Alexandre Oliva
  2023-12-08  3:04 ` Jinyang He
  5 siblings, 1 reply; 11+ messages in thread
From: Lulu Cai @ 2023-12-01  9:04 UTC (permalink / raw)
  To: binutils
  Cc: xuchenghua, chenglulu, liuzhensong, mengqinggang, xry111,
	i.swmail, maskray, luweining, wanglei, hejinyang, Lulu Cai

---
 gas/testsuite/gas/loongarch/tlsdesc_32.d      |  26 +++++
 gas/testsuite/gas/loongarch/tlsdesc_32.s      |  12 +++
 gas/testsuite/gas/loongarch/tlsdesc_64.d      |  26 +++++
 gas/testsuite/gas/loongarch/tlsdesc_64.s      |  12 +++
 .../gas/loongarch/tlsdesc_large_abs.d         |  21 ++++
 .../gas/loongarch/tlsdesc_large_abs.s         |   9 ++
 .../gas/loongarch/tlsdesc_large_pc.d          |  34 ++++++
 .../gas/loongarch/tlsdesc_large_pc.s          |  16 +++
 .../ld-loongarch-elf/ld-loongarch-elf.exp     |  16 +++
 ld/testsuite/ld-loongarch-elf/tls-desc.dd     |  74 +++++++++++++
 ld/testsuite/ld-loongarch-elf/tls-desc.rd     |  79 ++++++++++++++
 ld/testsuite/ld-loongarch-elf/tls-desc.s      | 102 ++++++++++++++++++
 .../ld-loongarch-elf/tls-relax-desc-le.d      |  15 +++
 .../ld-loongarch-elf/tls-relax-desc-le.s      |   8 ++
 14 files changed, 450 insertions(+)
 create mode 100644 gas/testsuite/gas/loongarch/tlsdesc_32.d
 create mode 100644 gas/testsuite/gas/loongarch/tlsdesc_32.s
 create mode 100644 gas/testsuite/gas/loongarch/tlsdesc_64.d
 create mode 100644 gas/testsuite/gas/loongarch/tlsdesc_64.s
 create mode 100644 gas/testsuite/gas/loongarch/tlsdesc_large_abs.d
 create mode 100644 gas/testsuite/gas/loongarch/tlsdesc_large_abs.s
 create mode 100644 gas/testsuite/gas/loongarch/tlsdesc_large_pc.d
 create mode 100644 gas/testsuite/gas/loongarch/tlsdesc_large_pc.s
 create mode 100644 ld/testsuite/ld-loongarch-elf/tls-desc.dd
 create mode 100644 ld/testsuite/ld-loongarch-elf/tls-desc.rd
 create mode 100644 ld/testsuite/ld-loongarch-elf/tls-desc.s
 create mode 100644 ld/testsuite/ld-loongarch-elf/tls-relax-desc-le.d
 create mode 100644 ld/testsuite/ld-loongarch-elf/tls-relax-desc-le.s

diff --git a/gas/testsuite/gas/loongarch/tlsdesc_32.d b/gas/testsuite/gas/loongarch/tlsdesc_32.d
new file mode 100644
index 00000000000..ad1e32666b5
--- /dev/null
+++ b/gas/testsuite/gas/loongarch/tlsdesc_32.d
@@ -0,0 +1,26 @@
+#as:
+#objdump: -dr
+#skip: loongarch64-*-*
+
+.*:[    ]+file format .*
+
+
+Disassembly of section .text:
+
+00000000.* <.*>:
+[ 	]+0:[ 	]+1a000004[ 	]+pcalau12i[ 	]+\$a0,[ 	]+0
+[ 	]+0:[ 	]+R_LARCH_TLS_DESC_PC_HI20[ 	]+var
+[ 	]+4:[ 	]+28800085[ 	]+ld.w[ 	]+\$a1,[ 	]+\$a0,[ 	]+0
+[ 	]+4:[ 	]+R_LARCH_TLS_DESC_LD_PC_LO12[ 	]+var
+[ 	]+8:[ 	]+02800084[ 	]+addi.w[ 	]+\$a0,[ 	]+\$a0,[ 	]+0
+[ 	]+8:[ 	]+R_LARCH_TLS_DESC_ADD_PC_LO12[ 	]+var
+[ 	]+c:[ 	]+4c0000a4[ 	]+jirl[ 	]+\$a0,[ 	]+\$a1,[ 	]+0
+[ 	]+c:[ 	]+R_LARCH_TLS_DESC_CALL[ 	]+var
+[ 	]+10:[ 	]+1a000004[ 	]+pcalau12i[ 	]+\$a0,[ 	]+0
+[ 	]+10:[ 	]+R_LARCH_TLS_DESC_PC_HI20[ 	]+var
+[ 	]+14:[ 	]+28800085[ 	]+ld.w[ 	]+\$a1,[ 	]+\$a0,[ 	]+0
+[ 	]+14:[ 	]+R_LARCH_TLS_DESC_LD_PC_LO12[ 	]+var
+[ 	]+18:[ 	]+02800084[ 	]+addi.w[ 	]+\$a0,[ 	]+\$a0,[ 	]+0
+[ 	]+18:[ 	]+R_LARCH_TLS_DESC_ADD_PC_LO12[ 	]+var
+[ 	]+1c:[ 	]+4c0000a1[ 	]+jirl[ 	]+\$ra,[ 	]+\$a1,[ 	]+0
+[ 	]+1c:[ 	]+R_LARCH_TLS_DESC_CALL[ 	]+var
diff --git a/gas/testsuite/gas/loongarch/tlsdesc_32.s b/gas/testsuite/gas/loongarch/tlsdesc_32.s
new file mode 100644
index 00000000000..98a89ee36fd
--- /dev/null
+++ b/gas/testsuite/gas/loongarch/tlsdesc_32.s
@@ -0,0 +1,12 @@
+.L1:
+	# R_LARCH_TLSDESC_HI20 var
+	pcalau12i       $a0,%desc_pc_hi20(var)
+	# R_LARCH_TLSDESC_LD_PC_LO12 var
+        ld.w    $a1,$a0,%desc_ld_pc_lo12(var)
+	# R_LARCH_TLSDESC_ADD_PC_LO12 var
+	addi.w  $a0,$a0,%desc_add_pc_lo12(var)
+	# R_LARCH_TLSDESC_CALL var
+	jirl    $a0,$a1,%desc_call(var)
+
+	# test macro
+	la.tls.desc	$a0,var
diff --git a/gas/testsuite/gas/loongarch/tlsdesc_64.d b/gas/testsuite/gas/loongarch/tlsdesc_64.d
new file mode 100644
index 00000000000..703ffc0e483
--- /dev/null
+++ b/gas/testsuite/gas/loongarch/tlsdesc_64.d
@@ -0,0 +1,26 @@
+#as:
+#objdump: -dr
+#skip: loongarch32-*-*
+
+.*:[    ]+file format .*
+
+
+Disassembly of section .text:
+
+00000000.* <.*>:
+[ 	]+0:[ 	]+1a000004[ 	]+pcalau12i[ 	]+\$a0,[ 	]+0
+[ 	]+0:[ 	]+R_LARCH_TLS_DESC_PC_HI20[ 	]+var
+[ 	]+4:[ 	]+28c00085[ 	]+ld.d[ 	]+\$a1,[ 	]+\$a0,[ 	]+0
+[ 	]+4:[ 	]+R_LARCH_TLS_DESC_LD_PC_LO12[ 	]+var
+[ 	]+8:[ 	]+02c00084[ 	]+addi.d[ 	]+\$a0,[ 	]+\$a0,[ 	]+0
+[ 	]+8:[ 	]+R_LARCH_TLS_DESC_ADD_PC_LO12[ 	]+var
+[ 	]+c:[ 	]+4c0000a1[ 	]+jirl[ 	]+\$ra,[ 	]+\$a1,[ 	]+0
+[ 	]+c:[ 	]+R_LARCH_TLS_DESC_CALL[ 	]+var
+[ 	]+10:[ 	]+1a000004[ 	]+pcalau12i[ 	]+\$a0,[ 	]+0
+[ 	]+10:[ 	]+R_LARCH_TLS_DESC_PC_HI20[ 	]+var
+[ 	]+14:[ 	]+28c00085[ 	]+ld.d[ 	]+\$a1,[ 	]+\$a0,[ 	]+0
+[ 	]+14:[ 	]+R_LARCH_TLS_DESC_LD_PC_LO12[ 	]+var
+[ 	]+18:[ 	]+02c00084[ 	]+addi.d[ 	]+\$a0,[ 	]+\$a0,[ 	]+0
+[ 	]+18:[ 	]+R_LARCH_TLS_DESC_ADD_PC_LO12[ 	]+var
+[ 	]+1c:[ 	]+4c0000a1[ 	]+jirl[ 	]+\$ra,[ 	]+\$a1,[ 	]+0
+[ 	]+1c:[ 	]+R_LARCH_TLS_DESC_CALL[ 	]+var
diff --git a/gas/testsuite/gas/loongarch/tlsdesc_64.s b/gas/testsuite/gas/loongarch/tlsdesc_64.s
new file mode 100644
index 00000000000..fb24abe2d1f
--- /dev/null
+++ b/gas/testsuite/gas/loongarch/tlsdesc_64.s
@@ -0,0 +1,12 @@
+.L1:
+	# R_LARCH_TLSDESC_HI20 var
+	pcalau12i       $a0,%desc_pc_hi20(var)
+	# R_LARCH_TLSDESC_LD_PC_LO12 var
+        ld.d    $a1,$a0,%desc_ld_pc_lo12(var)
+	# R_LARCH_TLSDESC_ADD_PC_LO12 var
+	addi.d  $a0,$a0,%desc_add_pc_lo12(var)
+	# R_LARCH_TLSDESC_CALL var
+	jirl    $ra,$a1,%desc_call(var)
+
+	# test macro
+	la.tls.desc	$a0,var
diff --git a/gas/testsuite/gas/loongarch/tlsdesc_large_abs.d b/gas/testsuite/gas/loongarch/tlsdesc_large_abs.d
new file mode 100644
index 00000000000..4a2947a41ae
--- /dev/null
+++ b/gas/testsuite/gas/loongarch/tlsdesc_large_abs.d
@@ -0,0 +1,21 @@
+#as:
+#objdump: -dr
+#skip: loongarch32-*-*
+
+.*:[    ]+file format .*
+
+
+Disassembly of section .text:
+
+00000000.* <.*>:
+[ 	]+0:[ 	]+14000004[ 	]+lu12i.w[ 	]+\$a0,[ 	]+0
+[ 	]+0:[ 	]+R_LARCH_TLS_DESC_HI20[ 	]+var
+[ 	]+4:[ 	]+03800084[ 	]+ori[ 	]+\$a0,[ 	]+\$a0,[ 	]+0x0
+[ 	]+4:[ 	]+R_LARCH_TLS_DESC_LO12[ 	]+var
+[ 	]+8:[ 	]+16000004[ 	]+lu32i.d[ 	]+\$a0,[ 	]+0
+[ 	]+8:[ 	]+R_LARCH_TLS_DESC64_LO20[ 	]+var
+[ 	]+c:[ 	]+03000084[ 	]+lu52i.d[ 	]+\$a0,[ 	]+\$a0,[ 	]+0
+[ 	]+c:[ 	]+R_LARCH_TLS_DESC64_HI12[ 	]+var
+[ 	]+10:[ 	]+28c00085[ 	]+ld.d[ 	]+\$a1,[ 	]+\$a0,[ 	]+0
+[ 	]+14:[ 	]+4c0000a1[ 	]+jirl[ 	]+\$ra,[ 	]+\$a1,[ 	]+0
+[ 	]+14:[ 	]+R_LARCH_TLS_DESC_CALL[ 	]+var
diff --git a/gas/testsuite/gas/loongarch/tlsdesc_large_abs.s b/gas/testsuite/gas/loongarch/tlsdesc_large_abs.s
new file mode 100644
index 00000000000..ed33857fc22
--- /dev/null
+++ b/gas/testsuite/gas/loongarch/tlsdesc_large_abs.s
@@ -0,0 +1,9 @@
+.L1:
+	.global var
+	#TLSDESC large abs
+	lu12i.w		$a0,%desc_hi20(var)
+	ori		$a0,$a0,%desc_lo12(var)
+	lu32i.d		$a0,%desc64_lo20(var)
+	lu52i.d		$a0,$a0,%desc64_hi12(var)
+	ld.d		$a1,$a0,0
+	jirl		$ra,$a1,%desc_call(var)
diff --git a/gas/testsuite/gas/loongarch/tlsdesc_large_pc.d b/gas/testsuite/gas/loongarch/tlsdesc_large_pc.d
new file mode 100644
index 00000000000..81333806f8c
--- /dev/null
+++ b/gas/testsuite/gas/loongarch/tlsdesc_large_pc.d
@@ -0,0 +1,34 @@
+#as:
+#objdump: -dr
+#skip: loongarch32-*-*
+
+.*:[    ]+file format .*
+
+
+Disassembly of section .text:
+
+00000000.* <.*>:
+[ 	]+0:[ 	]+1a000004[ 	]+pcalau12i[ 	]+\$a0,[ 	]+0
+[ 	]+0:[ 	]+R_LARCH_TLS_DESC_PC_HI20[ 	]+var
+[ 	]+4:[ 	]+02c00005[ 	]+li.d[ 	]+\$a1,[ 	]+0
+[ 	]+4:[ 	]+R_LARCH_TLS_DESC_ADD_PC_LO12[ 	]+var
+[ 	]+8:[ 	]+16000005[ 	]+lu32i.d[ 	]+\$a1,[ 	]+0
+[ 	]+8:[ 	]+R_LARCH_TLS_DESC64_PC_LO20[ 	]+var
+[ 	]+c:[ 	]+030000a5[ 	]+lu52i.d[ 	]+\$a1,[ 	]+\$a1,[ 	]+0
+[ 	]+c:[ 	]+R_LARCH_TLS_DESC64_PC_HI12[ 	]+var
+[ 	]+10:[ 	]+00109484[ 	]+add.d[ 	]+\$a0,[ 	]+\$a0,[ 	]+\$a1
+[ 	]+14:[ 	]+28c00085[ 	]+ld.d[ 	]+\$a1,[ 	]+\$a0,[ 	]+0
+[ 	]+18:[ 	]+4c0000a1[ 	]+jirl[ 	]+\$ra,[ 	]+\$a1,[ 	]+0
+[ 	]+18:[ 	]+R_LARCH_TLS_DESC_CALL[ 	]+var
+[ 	]+1c:[ 	]+1a000004[ 	]+pcalau12i[ 	]+\$a0,[ 	]+0
+[ 	]+1c:[ 	]+R_LARCH_TLS_DESC_PC_HI20[ 	]+var
+[ 	]+20:[ 	]+02c00005[ 	]+li.d[ 	]+\$a1,[ 	]+0
+[ 	]+20:[ 	]+R_LARCH_TLS_DESC_ADD_PC_LO12[ 	]+var
+[ 	]+24:[ 	]+16000005[ 	]+lu32i.d[ 	]+\$a1,[ 	]+0
+[ 	]+24:[ 	]+R_LARCH_TLS_DESC64_PC_LO20[ 	]+var
+[ 	]+28:[ 	]+030000a5[ 	]+lu52i.d[ 	]+\$a1,[ 	]+\$a1,[ 	]+0
+[ 	]+28:[ 	]+R_LARCH_TLS_DESC64_PC_HI12[ 	]+var
+[ 	]+2c:[ 	]+00109484[ 	]+add.d[ 	]+\$a0,[ 	]+\$a0,[ 	]+\$a1
+[ 	]+30:[ 	]+28c00085[ 	]+ld.d[ 	]+\$a1,[ 	]+\$a0,[ 	]+0
+[ 	]+34:[ 	]+4c0000a1[ 	]+jirl[ 	]+\$ra,[ 	]+\$a1,[ 	]+0
+[ 	]+34:[ 	]+R_LARCH_TLS_DESC_CALL[ 	]+var
diff --git a/gas/testsuite/gas/loongarch/tlsdesc_large_pc.s b/gas/testsuite/gas/loongarch/tlsdesc_large_pc.s
new file mode 100644
index 00000000000..a396060bf28
--- /dev/null
+++ b/gas/testsuite/gas/loongarch/tlsdesc_large_pc.s
@@ -0,0 +1,16 @@
+.L1:
+	# R_LARCH_TLS_DESC_HI20 var
+	pcalau12i       $a0,%desc_pc_hi20(var)
+	# R_LARCH_TLS_DESC_ADD_PC_LO12
+	addi.d		$a1,$zero,%desc_add_pc_lo12(var)
+	# R_LARCH_TLS_DESC64_PC_LO20
+	lu32i.d		$a1,%desc64_pc_lo20(var)
+	# R_LARCH_TLS_DESC64_PC_HI12
+	lu52i.d		$a1,$a1,%desc64_pc_hi12(var)
+	add.d		$a0,$a0,$a1
+	ld.d		$a1,$a0,0
+	# R_LARCH_TLS_DESC
+	jirl		$ra,$a1,%desc_call(var)
+
+	# test macro
+	la.tls.desc	$a0,$a1,var
diff --git a/ld/testsuite/ld-loongarch-elf/ld-loongarch-elf.exp b/ld/testsuite/ld-loongarch-elf/ld-loongarch-elf.exp
index b95cc53e597..f72cc523486 100644
--- a/ld/testsuite/ld-loongarch-elf/ld-loongarch-elf.exp
+++ b/ld/testsuite/ld-loongarch-elf/ld-loongarch-elf.exp
@@ -32,6 +32,7 @@ if [istarget "loongarch64-*-*"] {
     run_dump_test "syscall"
     run_dump_test "disas-jirl"
     run_dump_test "local-ifunc-reloc"
+    run_dump_test "tls-relax-desc-le"
 }
 
 if [istarget "loongarch32-*-*"] {
@@ -55,4 +56,19 @@ if [istarget "loongarch64-*-*"] {
 	      "64_pcrel" \
 	  ] \
       ]
+
+  run_ld_link_tests \
+      [list \
+	  [list \
+	      "tls-desc" \
+	      "-shared -fPIC" "" \
+	      "" \
+	      {tls-desc.s} \
+	      [list \
+		  [list objdump -drj.text tls-desc.dd] \
+		  [list readelf -rWs tls-desc.rd] \
+	      ] \
+	      "tls-desc" \
+	  ] \
+      ]
 }
diff --git a/ld/testsuite/ld-loongarch-elf/tls-desc.dd b/ld/testsuite/ld-loongarch-elf/tls-desc.dd
new file mode 100644
index 00000000000..23ca5a352be
--- /dev/null
+++ b/ld/testsuite/ld-loongarch-elf/tls-desc.dd
@@ -0,0 +1,74 @@
+#source: tls-desc.s
+#as:
+#ld: -shared -fPIC
+#objdump: -drj.text
+#skip: loongarch32-*-*
+
+.*:[    ]+file format .*
+
+
+Disassembly of section .text:
+
+00000000.* <.*>:
+[ 	]+4f0:[ 	]+1a0000ac[ 	]+pcalau12i[ 	]+\$t0,[ 	]+5
+[ 	]+4f4:[ 	]+02e1c184[ 	]+addi.d[ 	]+\$a0,[ 	]+\$t0,[ 	]+-1936
+[ 	]+4f8:[ 	]+57ffebff[ 	]+bl[ 	]+-24[ 	]+#[ 	]+4e0[ 	]+<__tls_get_addr@plt>
+[ 	]+4fc:[ 	]+1a0000ac[ 	]+pcalau12i[ 	]+\$t0,[ 	]+5
+[ 	]+500:[ 	]+28e2018c[ 	]+ld.d[ 	]+\$t0,[ 	]+\$t0,[ 	]+-1920
+[ 	]+504:[ 	]+1a0000ac[ 	]+pcalau12i[ 	]+\$t0,[ 	]+5
+[ 	]+508:[ 	]+02e0a184[ 	]+addi.d[ 	]+\$a0,[ 	]+\$t0,[ 	]+-2008
+[ 	]+50c:[ 	]+57ffd7ff[ 	]+bl[ 	]+-44[ 	]+#[ 	]+4e0[ 	]+<__tls_get_addr@plt>
+[ 	]+510:[ 	]+1a0000a4[ 	]+pcalau12i[ 	]+\$a0,[ 	]+5
+[ 	]+514:[ 	]+28e0e085[ 	]+ld.d[ 	]+\$a1,[ 	]+\$a0,[ 	]+-1992
+[ 	]+518:[ 	]+02e0e084[ 	]+addi.d[ 	]+\$a0,[ 	]+\$a0,[ 	]+-1992
+[ 	]+51c:[ 	]+4c0000a1[ 	]+jirl[ 	]+\$ra,[ 	]+\$a1,[ 	]+0
+[ 	]+520:[ 	]+1a0000a4[ 	]+pcalau12i[ 	]+\$a0,[ 	]+5
+[ 	]+524:[ 	]+28e04085[ 	]+ld.d[ 	]+\$a1,[ 	]+\$a0,[ 	]+-2032
+[ 	]+528:[ 	]+02e04084[ 	]+addi.d[ 	]+\$a0,[ 	]+\$a0,[ 	]+-2032
+[ 	]+52c:[ 	]+4c0000a1[ 	]+jirl[ 	]+\$ra,[ 	]+\$a1,[ 	]+0
+[ 	]+530:[ 	]+1a0000ac[ 	]+pcalau12i[ 	]+\$t0,[ 	]+5
+[ 	]+534:[ 	]+28e0818c[ 	]+ld.d[ 	]+\$t0,[ 	]+\$t0,[ 	]+-2016
+[ 	]+538:[ 	]+1a0000ac[ 	]+pcalau12i[ 	]+\$t0,[ 	]+5
+[ 	]+53c:[ 	]+02e12184[ 	]+addi.d[ 	]+\$a0,[ 	]+\$t0,[ 	]+-1976
+[ 	]+540:[ 	]+57ffa3ff[ 	]+bl[ 	]+-96[ 	]+#[ 	]+4e0[ 	]+<__tls_get_addr@plt>
+[ 	]+544:[ 	]+1a0000a4[ 	]+pcalau12i[ 	]+\$a0,[ 	]+5
+[ 	]+548:[ 	]+28e16085[ 	]+ld.d[ 	]+\$a1,[ 	]+\$a0,[ 	]+-1960
+[ 	]+54c:[ 	]+02e16084[ 	]+addi.d[ 	]+\$a0,[ 	]+\$a0,[ 	]+-1960
+[ 	]+550:[ 	]+4c0000a1[ 	]+jirl[ 	]+\$ra,[ 	]+\$a1,[ 	]+0
+[ 	]+554:[ 	]+1a0000ac[ 	]+pcalau12i[ 	]+\$t0,[ 	]+5
+[ 	]+558:[ 	]+28e1a18c[ 	]+ld.d[ 	]+\$t0,[ 	]+\$t0,[ 	]+-1944
+
+.*0000055c[ 	]+<fun_lo>:
+[ 	]+55c:[ 	]+1a00008c[ 	]+pcalau12i[ 	]+\$t0,[ 	]+4
+[ 	]+560:[ 	]+28de618c[ 	]+ld.d[ 	]+\$t0,[ 	]+\$t0,[ 	]+1944
+[ 	]+564:[ 	]+1a00008c[ 	]+pcalau12i[ 	]+\$t0,[ 	]+4
+[ 	]+568:[ 	]+02de2184[ 	]+addi.d[ 	]+\$a0,[ 	]+\$t0,[ 	]+1928
+[ 	]+56c:[ 	]+57ff77ff[ 	]+bl[ 	]+-140[ 	]+#[ 	]+4e0[ 	]+<__tls_get_addr@plt>
+[ 	]+570:[ 	]+1a000084[ 	]+pcalau12i[ 	]+\$a0,[ 	]+4
+[ 	]+574:[ 	]+28dec085[ 	]+ld.d[ 	]+\$a1,[ 	]+\$a0,[ 	]+1968
+[ 	]+578:[ 	]+02dec084[ 	]+addi.d[ 	]+\$a0,[ 	]+\$a0,[ 	]+1968
+[ 	]+57c:[ 	]+4c0000a1[ 	]+jirl[ 	]+\$ra,[ 	]+\$a1,[ 	]+0
+[ 	]+580:[ 	]+1a00008c[ 	]+pcalau12i[ 	]+\$t0,[ 	]+4
+[ 	]+584:[ 	]+02de8184[ 	]+addi.d[ 	]+\$a0,[ 	]+\$t0,[ 	]+1952
+[ 	]+588:[ 	]+57ff5bff[ 	]+bl[ 	]+-168[ 	]+#[ 	]+4e0[ 	]+<__tls_get_addr@plt>
+[ 	]+58c:[ 	]+1a000084[ 	]+pcalau12i[ 	]+\$a0,[ 	]+4
+[ 	]+590:[ 	]+28df0085[ 	]+ld.d[ 	]+\$a1,[ 	]+\$a0,[ 	]+1984
+[ 	]+594:[ 	]+02df0084[ 	]+addi.d[ 	]+\$a0,[ 	]+\$a0,[ 	]+1984
+[ 	]+598:[ 	]+4c0000a1[ 	]+jirl[ 	]+\$ra,[ 	]+\$a1,[ 	]+0
+[ 	]+59c:[ 	]+1a00008c[ 	]+pcalau12i[ 	]+\$t0,[ 	]+4
+[ 	]+5a0:[ 	]+28df418c[ 	]+ld.d[ 	]+\$t0,[ 	]+\$t0,[ 	]+2000
+[ 	]+5a4:[ 	]+1a000084[ 	]+pcalau12i[ 	]+\$a0,[ 	]+4
+[ 	]+5a8:[ 	]+28dfa085[ 	]+ld.d[ 	]+\$a1,[ 	]+\$a0,[ 	]+2024
+[ 	]+5ac:[ 	]+02dfa084[ 	]+addi.d[ 	]+\$a0,[ 	]+\$a0,[ 	]+2024
+[ 	]+5b0:[ 	]+4c0000a1[ 	]+jirl[ 	]+\$ra,[ 	]+\$a1,[ 	]+0
+[ 	]+5b4:[ 	]+1a00008c[ 	]+pcalau12i[ 	]+\$t0,[ 	]+4
+[ 	]+5b8:[ 	]+02df6184[ 	]+addi.d[ 	]+\$a0,[ 	]+\$t0,[ 	]+2008
+[ 	]+5bc:[ 	]+57ff27ff[ 	]+bl[ 	]+-220[ 	]+#[ 	]+4e0[ 	]+<__tls_get_addr@plt>
+[ 	]+5c0:[ 	]+1a00008c[ 	]+pcalau12i[ 	]+\$t0,[ 	]+4
+[ 	]+5c4:[ 	]+28dfe18c[ 	]+ld.d[ 	]+\$t0,[ 	]+\$t0,[ 	]+2040
+
+.*000005c8[ 	]+<fun_external>:
+[ 	]+5c8:[ 	]+1a0000a4[ 	]+pcalau12i[ 	]+\$a0,[ 	]+5
+[ 	]+5cc:[ 	]+28e00085[ 	]+ld.d[ 	]+\$a1,[ 	]+\$a0,[ 	]+-2048
+[ 	]+5d0:[ 	]+02e00084[ 	]+addi.d[ 	]+\$a0,[ 	]+\$a0,[ 	]+-2048
+[ 	]+5d4:[ 	]+4c0000a1[ 	]+jirl[ 	]+\$ra,[ 	]+\$a1,[ 	]+0
diff --git a/ld/testsuite/ld-loongarch-elf/tls-desc.rd b/ld/testsuite/ld-loongarch-elf/tls-desc.rd
new file mode 100644
index 00000000000..38c27dbc4b5
--- /dev/null
+++ b/ld/testsuite/ld-loongarch-elf/tls-desc.rd
@@ -0,0 +1,79 @@
+#as:
+#ld: -shared -fPIC
+#readelf: -rWs
+#skip: loongarch32-*-*
+
+Relocation section '.rela.dyn' at offset 0x[0-9a-f]+ contains 22 entries:
+    Offset             Info             Type               Symbol's Value  Symbol's Name \+ Addend
+0+4788  +[0-9a-f]+ R_LARCH_TLS_DTPMOD64                      0
+0+4798  +[0-9a-f]+ R_LARCH_TLS_TPREL64                       20
+0+47a0  +[0-9a-f]+ R_LARCH_TLS_DTPMOD64                      0
+0+47b0  +[0-9a-f]+ R_LARCH_TLS_DESC64                        28
+0+47c0  +[0-9a-f]+ R_LARCH_TLS_DESC64                        30
+0+47d0  +[0-9a-f]+ R_LARCH_TLS_TPREL64                       30
+0+47d8  +[0-9a-f]+ R_LARCH_TLS_DTPMOD64                      0
+0+47e8  +[0-9a-f]+ R_LARCH_TLS_DESC64                        38
+0+47f8  +[0-9a-f]+ R_LARCH_TLS_TPREL64                       38
+0+4800  +[0-9a-f]+ R_LARCH_TLS_DESC64     +[0-9a-f]+ sH1 \+ 0
+0+4810  +[0-9a-f]+ R_LARCH_TLS_DESC64     +[0-9a-f]+ gl3 \+ 0
+0+4820  +[0-9a-f]+ R_LARCH_TLS_TPREL64    +[0-9a-f]+ gl3 \+ 0
+0+4828  +[0-9a-f]+ R_LARCH_TLS_DTPMOD64   +[0-9a-f]+ gl2 \+ 0
+0+4830  +[0-9a-f]+ R_LARCH_TLS_DTPREL64   +[0-9a-f]+ gl2 \+ 0
+0+4838  +[0-9a-f]+ R_LARCH_TLS_DESC64     +[0-9a-f]+ gl2 \+ 0
+0+4848  +[0-9a-f]+ R_LARCH_TLS_DTPMOD64   +[0-9a-f]+ gl4 \+ 0
+0+4850  +[0-9a-f]+ R_LARCH_TLS_DTPREL64   +[0-9a-f]+ gl4 \+ 0
+0+4858  +[0-9a-f]+ R_LARCH_TLS_DESC64     +[0-9a-f]+ gl4 \+ 0
+0+4868  +[0-9a-f]+ R_LARCH_TLS_TPREL64    +[0-9a-f]+ gl4 \+ 0
+0+4870  +[0-9a-f]+ R_LARCH_TLS_DTPMOD64   +[0-9a-f]+ gl1 \+ 0
+0+4878  +[0-9a-f]+ R_LARCH_TLS_DTPREL64   +[0-9a-f]+ gl1 \+ 0
+0+4880  +[0-9a-f]+ R_LARCH_TLS_TPREL64    +[0-9a-f]+ gl1 \+ 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+4778  +[0-9a-f]+ R_LARCH_JUMP_SLOT      +[0-9a-f]+ __tls_get_addr \+ 0
+
+Symbol table '.dynsym' contains 9 entries:
+   Num:    Value          Size Type    Bind   Vis      Ndx Name
+     0: +[0-9a-f]+     0 NOTYPE  LOCAL  DEFAULT  UND 
+     1: +[0-9a-f]+     0 SECTION LOCAL  DEFAULT    8 .text
+     2: +[0-9a-f]+     0 SECTION LOCAL  DEFAULT    9 .tdata
+     3: +[0-9a-f]+     0 TLS     GLOBAL DEFAULT  UND sH1
+     4: +[0-9a-f]+     0 NOTYPE  GLOBAL DEFAULT  UND __tls_get_addr
+     5: +[0-9a-f]+     0 TLS     GLOBAL DEFAULT    9 gl3
+     6: +[0-9a-f]+     0 TLS     GLOBAL DEFAULT    9 gl4
+     7: +[0-9a-f]+     0 TLS     GLOBAL DEFAULT    9 gl1
+     8: +[0-9a-f]+     0 TLS     GLOBAL DEFAULT    9 gl2
+
+Symbol table '.symtab' contains 31 entries:
+   Num:    Value          Size Type    Bind   Vis      Ndx Name
+     0: +[0-9a-f]+     0 NOTYPE  LOCAL  DEFAULT  UND 
+     1: +[0-9a-f]+     0 SECTION LOCAL  DEFAULT    1 .hash
+     2: +[0-9a-f]+     0 SECTION LOCAL  DEFAULT    2 .gnu.hash
+     3: +[0-9a-f]+     0 SECTION LOCAL  DEFAULT    3 .dynsym
+     4: +[0-9a-f]+     0 SECTION LOCAL  DEFAULT    4 .dynstr
+     5: +[0-9a-f]+     0 SECTION LOCAL  DEFAULT    5 .rela.dyn
+     6: +[0-9a-f]+     0 SECTION LOCAL  DEFAULT    6 .rela.plt
+     7: +[0-9a-f]+     0 SECTION LOCAL  DEFAULT    7 .plt
+     8: +[0-9a-f]+     0 SECTION LOCAL  DEFAULT    8 .text
+     9: +[0-9a-f]+     0 SECTION LOCAL  DEFAULT    9 .tdata
+    10: +[0-9a-f]+     0 SECTION LOCAL  DEFAULT   10 .dynamic
+    11: +[0-9a-f]+     0 SECTION LOCAL  DEFAULT   11 .got.plt
+    12: +[0-9a-f]+     0 SECTION LOCAL  DEFAULT   12 .got
+    13: +[0-9a-f]+     0 FILE    LOCAL  DEFAULT  ABS tls-desc.o
+    14: +[0-9a-f]+     0 TLS     LOCAL  DEFAULT    9 lo1
+    15: +[0-9a-f]+     0 TLS     LOCAL  DEFAULT    9 lo2
+    16: +[0-9a-f]+     0 TLS     LOCAL  DEFAULT    9 lo3
+    17: +[0-9a-f]+     0 TLS     LOCAL  DEFAULT    9 lo4
+    18: +[0-9a-f]+     0 NOTYPE  LOCAL  DEFAULT    8 fun_gl1
+    19: +[0-9a-f]+     0 NOTYPE  LOCAL  DEFAULT    8 fun_lo
+    20: +[0-9a-f]+     0 NOTYPE  LOCAL  DEFAULT    8 fun_external
+    21: +[0-9a-f]+     0 FILE    LOCAL  DEFAULT  ABS 
+    22: +[0-9a-f]+     0 OBJECT  LOCAL  DEFAULT  ABS _DYNAMIC
+    23: +[0-9a-f]+     0 OBJECT  LOCAL  DEFAULT  ABS _PROCEDURE_LINKAGE_TABLE_
+    24: +[0-9a-f]+     0 OBJECT  LOCAL  DEFAULT  ABS _GLOBAL_OFFSET_TABLE_
+    25: +[0-9a-f]+     0 TLS     GLOBAL DEFAULT  UND sH1
+    26: +[0-9a-f]+     0 TLS     GLOBAL DEFAULT    9 gl3
+    27: +[0-9a-f]+     0 TLS     GLOBAL DEFAULT    9 gl2
+    28: +[0-9a-f]+     0 TLS     GLOBAL DEFAULT    9 gl4
+    29: +[0-9a-f]+     0 NOTYPE  GLOBAL DEFAULT  UND __tls_get_addr
+    30: +[0-9a-f]+     0 TLS     GLOBAL DEFAULT    9 gl1
diff --git a/ld/testsuite/ld-loongarch-elf/tls-desc.s b/ld/testsuite/ld-loongarch-elf/tls-desc.s
new file mode 100644
index 00000000000..322adc11139
--- /dev/null
+++ b/ld/testsuite/ld-loongarch-elf/tls-desc.s
@@ -0,0 +1,102 @@
+	.data
+	.section	.tdata,"awT",@progbits
+	.global gl1, gl2, gl3, gl4
+gl1:	.dword 1
+gl2:	.dword 2
+gl3:	.dword 3
+gl4:	.dword 4
+lo1:	.dword 10
+lo2:	.dword 20
+lo3:	.dword 30
+lo4:	.dword 40
+	.text
+# Access global symbol
+fun_gl1:
+	# GD + IE
+	pcalau12i	$t0,%gd_pc_hi20(gl1)
+	addi.d	$a0,$t0,%got_pc_lo12(gl1)
+	bl	%plt(__tls_get_addr)
+
+	pcalau12i       $t0,%ie_pc_hi20(gl1)
+        ld.d    $t0,$t0,%ie_pc_lo12(gl1)
+
+	# GD + DESC
+	pcalau12i	$t0,%gd_pc_hi20(gl2)
+	addi.d	$a0,$t0,%got_pc_lo12(gl2)
+	bl	%plt(__tls_get_addr)
+
+	pcalau12i       $a0,%desc_pc_hi20(gl2)
+        ld.d    $a1,$a0,%desc_ld_pc_lo12(gl2)
+        addi.d  $a0,$a0,%desc_add_pc_lo12(gl2)
+        jirl    $ra,$a1,%desc_call(gl2)
+
+	# DESC + IE
+	pcalau12i       $a0,%desc_pc_hi20(gl3)
+        ld.d    $a1,$a0,%desc_ld_pc_lo12(gl3)
+        addi.d  $a0,$a0,%desc_add_pc_lo12(gl3)
+        jirl    $ra,$a1,%desc_call(gl3)
+
+	pcalau12i       $t0,%ie_pc_hi20(gl3)
+        ld.d    $t0,$t0,%ie_pc_lo12(gl3)
+
+
+	# GD + DESC + IE
+	pcalau12i	$t0,%gd_pc_hi20(gl4)
+	addi.d	$a0,$t0,%got_pc_lo12(gl4)
+	bl	%plt(__tls_get_addr)
+
+	pcalau12i       $a0,%desc_pc_hi20(gl4)
+        ld.d    $a1,$a0,%desc_ld_pc_lo12(gl4)
+        addi.d  $a0,$a0,%desc_add_pc_lo12(gl4)
+        jirl    $ra,$a1,%desc_call(gl4)
+
+	pcalau12i       $t0,%ie_pc_hi20(gl4)
+        ld.d    $t0,$t0,%ie_pc_lo12(gl4)
+
+# Access local symbol
+fun_lo:
+	# IE + GD
+	pcalau12i       $t0,%ie_pc_hi20(lo1)
+        ld.d    $t0,$t0,%ie_pc_lo12(lo1)
+
+	pcalau12i	$t0,%gd_pc_hi20(lo1)
+	addi.d	$a0,$t0,%got_pc_lo12(lo1)
+	bl	%plt(__tls_get_addr)
+
+	# DESC + GD
+	pcalau12i       $a0,%desc_pc_hi20(lo2)
+        ld.d    $a1,$a0,%desc_ld_pc_lo12(lo2)
+        addi.d  $a0,$a0,%desc_add_pc_lo12(lo2)
+        jirl    $ra,$a1,%desc_call(lo2)
+
+	pcalau12i	$t0,%gd_pc_hi20(lo2)
+	addi.d	$a0,$t0,%got_pc_lo12(lo2)
+	bl	%plt(__tls_get_addr)
+
+	# DESC + IE
+	pcalau12i       $a0,%desc_pc_hi20(lo3)
+        ld.d    $a1,$a0,%desc_ld_pc_lo12(lo3)
+        addi.d  $a0,$a0,%desc_add_pc_lo12(lo3)
+        jirl    $ra,$a1,%desc_call(lo3)
+
+	pcalau12i       $t0,%ie_pc_hi20(lo3)
+        ld.d    $t0,$t0,%ie_pc_lo12(lo3)
+
+	# DESC + GD + IE
+	pcalau12i       $a0,%desc_pc_hi20(lo4)
+        ld.d    $a1,$a0,%desc_ld_pc_lo12(lo4)
+        addi.d  $a0,$a0,%desc_add_pc_lo12(lo4)
+        jirl    $ra,$a1,%desc_call(lo4)
+
+	pcalau12i	$t0,%gd_pc_hi20(lo4)
+	addi.d	$a0,$t0,%got_pc_lo12(lo4)
+	bl	%plt(__tls_get_addr)
+
+	pcalau12i       $t0,%ie_pc_hi20(lo4)
+        ld.d    $t0,$t0,%ie_pc_lo12(lo4)
+# Access external undef symbol
+fun_external:
+	pcalau12i       $a0,%desc_pc_hi20(sH1)
+        ld.d    $a1,$a0,%desc_ld_pc_lo12(sH1)
+        addi.d  $a0,$a0,%desc_add_pc_lo12(sH1)
+        jirl    $ra,$a1,%desc_call(sH1)
diff --git a/ld/testsuite/ld-loongarch-elf/tls-relax-desc-le.d b/ld/testsuite/ld-loongarch-elf/tls-relax-desc-le.d
new file mode 100644
index 00000000000..844d54f725c
--- /dev/null
+++ b/ld/testsuite/ld-loongarch-elf/tls-relax-desc-le.d
@@ -0,0 +1,15 @@
+#as:
+#ld: -e 0x0 -static
+#objdump: -drj.text
+#skip: loongarch32-*-*
+
+.*:[    ]+file format .*
+
+
+Disassembly of section .text:
+
+.*1200000e8 <.*>:
+[ 	]+1200000e8:[ 	]+14000004[ 	]+lu12i.w[ 	]+\$a0,[ 	]+0
+[ 	]+1200000ec:[ 	]+03800084[ 	]+ori[ 	]+\$a0,[ 	]+\$a0,[ 	]+0x0
+[ 	]+1200000f0:[ 	]+03400000[ 	]+nop.*
+[ 	]+1200000f4:[ 	]+03400000[ 	]+nop.*
diff --git a/ld/testsuite/ld-loongarch-elf/tls-relax-desc-le.s b/ld/testsuite/ld-loongarch-elf/tls-relax-desc-le.s
new file mode 100644
index 00000000000..09a86586760
--- /dev/null
+++ b/ld/testsuite/ld-loongarch-elf/tls-relax-desc-le.s
@@ -0,0 +1,8 @@
+	.section .tdata
+var:
+	.word 4
+	.text
+	pcalau12i       $a0,%desc_pc_hi20(var)
+	ld.d    $a1,$a0,%desc_ld_pc_lo12(var)
+	addi.d  $a0,$a0,%desc_add_pc_lo12(var)
+	jirl    $ra,$a1,%desc_call(var)
-- 
2.36.0


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

* Re: [PATCH v1 0/4] LoongArch: Add support for TLS Descriptors (TLSDESC)
  2023-12-01  9:04 [PATCH v1 0/4] LoongArch: Add support for TLS Descriptors (TLSDESC) Lulu Cai
                   ` (3 preceding siblings ...)
  2023-12-01  9:04 ` [PATCH v1 4/4] LoongArch: Add testsuits for TLSDESC in gas and ld Lulu Cai
@ 2023-12-01 16:14 ` Alexandre Oliva
  2023-12-02  3:54   ` mengqinggang
  2023-12-08  3:04 ` Jinyang He
  5 siblings, 1 reply; 11+ messages in thread
From: Alexandre Oliva @ 2023-12-01 16:14 UTC (permalink / raw)
  To: Lulu Cai
  Cc: binutils, xuchenghua, chenglulu, liuzhensong, mengqinggang,
	xry111, i.swmail, maskray, luweining, wanglei, hejinyang

Hello,

On Dec  1, 2023, Lulu Cai <cailulu@loongson.cn> wrote:

> The LoongArch TLS Descriptors implementation contains several points:

I'm excited to see another platform gain TLS Descriptors support.

I'm not deeply acquainted with LoongArch, but I'll dare chime in.

> 1. The instruction sequences is:
>    pcalau12i  $a0,%desc_pc_hi20(var)		#R_LARCH_TLS_DESC_PC_HI20
>    ld.d       $a1,$a0,%desc_ld_pc_lo12(var)	#R_LARCH_TLS_DESC_LD_PC_LO12
>    addi.d     $a0,$a0,%desc_add_pc_lo12(var)	#R_LARCH_TLS_DESC_ADD_PC_LO12
>    jirl       $ra,$a1,%desc_call(var)		#R_LARCH_TLS_DESC_CALL

Are these instructions fixed, and supposed to appear in this sequence,
or can different registers be used, and the instructions intermixed with
other unrelated ones?  The ability to intermix them for better
scheduling and register allocation was one of the guiding design
principles of TLS Descriptors, so the canonical sequence and the design
of relaxations should ideally take flexibility into account, and choose
relaxations with similar scheduling profiles.

Say, would compiler-generated or hand-coded asm still work if one used:

     pcalau12i  $a2,%desc_pc_hi20(var)		#R_LARCH_TLS_DESC_PC_HI20
     ld.d       $a3,$a2,%desc_ld_pc_lo12(var)	#R_LARCH_TLS_DESC_LD_PC_LO12
     addi.d     $a0,$a2,%desc_add_pc_lo12(var)	#R_LARCH_TLS_DESC_ADD_PC_LO12
     jirl       $ra,$a3,%desc_call(var)		#R_LARCH_TLS_DESC_CALL

or even

     pcalau12i  $a2,%desc_pc_hi20(var)		#R_LARCH_TLS_DESC_PC_HI20
     or         $a5,$a2
     or         $a6,$a2
     addi.d     $a4,$a5,%desc_add_pc_lo12(var)	#R_LARCH_TLS_DESC_ADD_PC_LO12
     ld.d       $a3,$a6,%desc_ld_pc_lo12(var)	#R_LARCH_TLS_DESC_LD_PC_LO12
     or         $a0,$a4,$r0
     jirl       $ra,$a3,%desc_call(var)		#R_LARCH_TLS_DESC_CALL

?

(I realize you seem to have not planned/implemented relaxations, aside
from the LE one for static linking, but planning for them ahead of time
about them helps make sure they're doable)

E.g., for IE, I'd suggest turning the latter sequence into (I'm making
up relocation names):

     pcalau12i  $a2,%gotpc_tlsoff_hi20(var)
     or         $a5,$a2,$r0 #not necessary, but not marked, so unchanged
     or         $a6,$a2,$r0
     nop
     ld.d       $a3,$a6,%gotpc_tlsoff_lo12(var)
     or         $a0,$a4,$r0 #not necessary, but not marked, so unchanged
     or         $a0,$a3,$r0

and or LE, I'd suggest:

     pcalau12i  $a2,%tlsoff_hi20(var)
     or         $a5,$a2,$r0
     or         $a6,$a2,$r0 #not necessary, but not marked, so unchanged
     addi.d     $a4,$a5,%tlsoff_lo12(var)
     nop
     or         $a0,$a4,$r0 #not necessary, but not marked, so unchanged
     nop

This addi.d is what I suggest instead of the 'ori' in the LE relaxation.
The main difference in my suggestion is that it takes the same position
of the original addi instruction, thus the very same scheduling profile,
and more importantly participating the same way in the data flow, as the
extra moves help see.

I realize that addi rather than ori may require offsetting the base
address to account for the signed rather than unsigned (I suppose)
immediate, so maybe it's not worth it.  I am not sure, however, whether
you can even separate the pcalau12i hi20 instruction from the subsequent
lo12 one (ISTM that it would be challenging to match them if so,
especially if a single hi20 is reused by multiple lo12 loads), so maybe
there is less flexibility to be exploited than I'm making out.

Anyway, I hope this makes sense and that it helps,

-- 
Alexandre Oliva, happy hacker            https://FSFLA.org/blogs/lxo/
   Free Software Activist                   GNU Toolchain Engineer
More tolerance and less prejudice are key for inclusion and diversity
Excluding neuro-others for not behaving ""normal"" is *not* inclusive

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

* Re: [PATCH v1 0/4] LoongArch: Add support for TLS Descriptors (TLSDESC)
  2023-12-01 16:14 ` [PATCH v1 0/4] LoongArch: Add support for TLS Descriptors (TLSDESC) Alexandre Oliva
@ 2023-12-02  3:54   ` mengqinggang
  0 siblings, 0 replies; 11+ messages in thread
From: mengqinggang @ 2023-12-02  3:54 UTC (permalink / raw)
  To: Alexandre Oliva, Lulu Cai
  Cc: binutils, xuchenghua, chenglulu, liuzhensong, xry111, i.swmail,
	maskray, luweining, wanglei, hejinyang

Thank you very much for your suggestions.


在 2023/12/2 上午12:14, Alexandre Oliva 写道:
> Hello,
>
> On Dec  1, 2023, Lulu Cai <cailulu@loongson.cn> wrote:
>
>> The LoongArch TLS Descriptors implementation contains several points:
> I'm excited to see another platform gain TLS Descriptors support.
>
> I'm not deeply acquainted with LoongArch, but I'll dare chime in.
>
>> 1. The instruction sequences is:
>>     pcalau12i  $a0,%desc_pc_hi20(var)		#R_LARCH_TLS_DESC_PC_HI20
>>     ld.d       $a1,$a0,%desc_ld_pc_lo12(var)	#R_LARCH_TLS_DESC_LD_PC_LO12
>>     addi.d     $a0,$a0,%desc_add_pc_lo12(var)	#R_LARCH_TLS_DESC_ADD_PC_LO12
>>     jirl       $ra,$a1,%desc_call(var)		#R_LARCH_TLS_DESC_CALL
> Are these instructions fixed, and supposed to appear in this sequence,
> or can different registers be used, and the instructions intermixed with
> other unrelated ones?  The ability to intermix them for better
> scheduling and register allocation was one of the guiding design
> principles of TLS Descriptors, so the canonical sequence and the design
> of relaxations should ideally take flexibility into account, and choose
> relaxations with similar scheduling profiles.
>
> Say, would compiler-generated or hand-coded asm still work if one used:
>
>       pcalau12i  $a2,%desc_pc_hi20(var)		#R_LARCH_TLS_DESC_PC_HI20
>       ld.d       $a3,$a2,%desc_ld_pc_lo12(var)	#R_LARCH_TLS_DESC_LD_PC_LO12
>       addi.d     $a0,$a2,%desc_add_pc_lo12(var)	#R_LARCH_TLS_DESC_ADD_PC_LO12
>       jirl       $ra,$a3,%desc_call(var)		#R_LARCH_TLS_DESC_CALL
>
> or even
>
>       pcalau12i  $a2,%desc_pc_hi20(var)		#R_LARCH_TLS_DESC_PC_HI20
>       or         $a5,$a2
>       or         $a6,$a2
>       addi.d     $a4,$a5,%desc_add_pc_lo12(var)	#R_LARCH_TLS_DESC_ADD_PC_LO12
>       ld.d       $a3,$a6,%desc_ld_pc_lo12(var)	#R_LARCH_TLS_DESC_LD_PC_LO12
>       or         $a0,$a4,$r0
>       jirl       $ra,$a3,%desc_call(var)		#R_LARCH_TLS_DESC_CALL
>
> ?


I do a test, these two sequences still work.
But in this version patch, TLS descriptors instructions sequences expand 
for la.tls.desc
and fixed registers and instructions are used.


> (I realize you seem to have not planned/implemented relaxations, aside
> from the LE one for static linking, but planning for them ahead of time
> about them helps make sure they're doable)


We will support relax to IE in the future.
Because glibc can only resolve R_XXX_IRELATIVE relocation in static 
linking,
we relax DESC to LE to avoid generating R_LARCH_TLS_DESC relocation.


> E.g., for IE, I'd suggest turning the latter sequence into (I'm making
> up relocation names):
>
>       pcalau12i  $a2,%gotpc_tlsoff_hi20(var)
>       or         $a5,$a2,$r0 #not necessary, but not marked, so unchanged
>       or         $a6,$a2,$r0
>       nop
>       ld.d       $a3,$a6,%gotpc_tlsoff_lo12(var)
>       or         $a0,$a4,$r0 #not necessary, but not marked, so unchanged
>       or         $a0,$a3,$r0
>
> and or LE, I'd suggest:
>
>       pcalau12i  $a2,%tlsoff_hi20(var)
>       or         $a5,$a2,$r0
>       or         $a6,$a2,$r0 #not necessary, but not marked, so unchanged
>       addi.d     $a4,$a5,%tlsoff_lo12(var)
>       nop
>       or         $a0,$a4,$r0 #not necessary, but not marked, so unchanged
>       nop
>
> This addi.d is what I suggest instead of the 'ori' in the LE relaxation.
> The main difference in my suggestion is that it takes the same position
> of the original addi instruction, thus the very same scheduling profile,
> and more importantly participating the same way in the data flow, as the
> extra moves help see.

We will add  a new relocation for addi.d, the related patch is here:
https://sourceware.org/pipermail/binutils/2023-December/130921.html

>
> I realize that addi rather than ori may require offsetting the base
> address to account for the signed rather than unsigned (I suppose)
> immediate, so maybe it's not worth it.  I am not sure, however, whether
> you can even separate the pcalau12i hi20 instruction from the subsequent
> lo12 one (ISTM that it would be challenging to match them if so,
> especially if a single hi20 is reused by multiple lo12 loads), so maybe
> there is less flexibility to be exploited than I'm making out.
> Anyway, I hope this makes sense and that it helps,
>


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

* Re: [PATCH v1 4/4] LoongArch: Add testsuits for TLSDESC in gas and ld.
  2023-12-01  9:04 ` [PATCH v1 4/4] LoongArch: Add testsuits for TLSDESC in gas and ld Lulu Cai
@ 2023-12-02  7:38   ` Xi Ruoyao
  2023-12-02  7:44     ` Xi Ruoyao
  0 siblings, 1 reply; 11+ messages in thread
From: Xi Ruoyao @ 2023-12-02  7:38 UTC (permalink / raw)
  To: Lulu Cai, binutils
  Cc: xuchenghua, chenglulu, liuzhensong, mengqinggang, i.swmail,
	maskray, luweining, wanglei, hejinyang

On Fri, 2023-12-01 at 17:04 +0800, Lulu Cai wrote:
> +	pcalau12i       $a0,%desc_pc_hi20(var)
> +	ld.d    $a1,$a0,%desc_ld_pc_lo12(var)
> +	addi.d  $a0,$a0,%desc_add_pc_lo12(var)
> +	jirl    $ra,$a1,%desc_call(var)

Should we consider using a different link register for desc_call?  Say

jirl $t0,$a1,%desc_call(var)

And when the TLS descriptor function returns, use "jr $t0" instead of
"ret".  The advantage would be avoiding saving $ra just because TLS
descriptor is used.

-- 
Xi Ruoyao <xry111@xry111.site>
School of Aerospace Science and Technology, Xidian University

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

* Re: [PATCH v1 4/4] LoongArch: Add testsuits for TLSDESC in gas and ld.
  2023-12-02  7:38   ` Xi Ruoyao
@ 2023-12-02  7:44     ` Xi Ruoyao
  2023-12-02  8:24       ` mengqinggang
  0 siblings, 1 reply; 11+ messages in thread
From: Xi Ruoyao @ 2023-12-02  7:44 UTC (permalink / raw)
  To: Lulu Cai, binutils
  Cc: xuchenghua, chenglulu, liuzhensong, mengqinggang, i.swmail,
	maskray, luweining, wanglei, hejinyang

On Sat, 2023-12-02 at 15:38 +0800, Xi Ruoyao wrote:
> On Fri, 2023-12-01 at 17:04 +0800, Lulu Cai wrote:
> > +	pcalau12i       $a0,%desc_pc_hi20(var)
> > +	ld.d    $a1,$a0,%desc_ld_pc_lo12(var)
> > +	addi.d  $a0,$a0,%desc_add_pc_lo12(var)
> > +	jirl    $ra,$a1,%desc_call(var)
> 
> Should we consider using a different link register for desc_call?  Say
> 
> jirl $t0,$a1,%desc_call(var)
> 
> And when the TLS descriptor function returns, use "jr $t0" instead of
> "ret".  The advantage would be avoiding saving $ra just because TLS
> descriptor is used.

Hmm, maybe better:

jirl $a1, $a1, %desc_call(var)

Just reuse a1 as it's clobbered anyway.  Then __tlsdesc_static becomes
something like

__tlsdesc_static:
    ld.d    $a0, $a0, 0
    jr      $a1

-- 
Xi Ruoyao <xry111@xry111.site>
School of Aerospace Science and Technology, Xidian University

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

* Re: [PATCH v1 4/4] LoongArch: Add testsuits for TLSDESC in gas and ld.
  2023-12-02  7:44     ` Xi Ruoyao
@ 2023-12-02  8:24       ` mengqinggang
  0 siblings, 0 replies; 11+ messages in thread
From: mengqinggang @ 2023-12-02  8:24 UTC (permalink / raw)
  To: Xi Ruoyao, Lulu Cai, binutils
  Cc: xuchenghua, chenglulu, liuzhensong, i.swmail, maskray, luweining,
	wanglei, hejinyang


在 2023/12/2 下午3:44, Xi Ruoyao 写道:
> On Sat, 2023-12-02 at 15:38 +0800, Xi Ruoyao wrote:
>> On Fri, 2023-12-01 at 17:04 +0800, Lulu Cai wrote:
>>> +	pcalau12i       $a0,%desc_pc_hi20(var)
>>> +	ld.d    $a1,$a0,%desc_ld_pc_lo12(var)
>>> +	addi.d  $a0,$a0,%desc_add_pc_lo12(var)
>>> +	jirl    $ra,$a1,%desc_call(var)
>> Should we consider using a different link register for desc_call?  Say
>>
>> jirl $t0,$a1,%desc_call(var)
>>
>> And when the TLS descriptor function returns, use "jr $t0" instead of
>> "ret".  The advantage would be avoiding saving $ra just because TLS
>> descriptor is used.
> Hmm, maybe better:
>
> jirl $a1, $a1, %desc_call(var)
>
> Just reuse a1 as it's clobbered anyway.  Then __tlsdesc_static becomes
> something like
>
> __tlsdesc_static:
>      ld.d    $a0, $a0, 0
>      jr      $a1


According to my colleague's suggestion, the jirl instruction must use 
the $ra register (jirl $zero, $ra, 0)
in order to perform hardware instruction prefetching.
We need to do some performance testing to decide which register to use.


>


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

* Re: [PATCH v1 0/4] LoongArch: Add support for TLS Descriptors (TLSDESC)
  2023-12-01  9:04 [PATCH v1 0/4] LoongArch: Add support for TLS Descriptors (TLSDESC) Lulu Cai
                   ` (4 preceding siblings ...)
  2023-12-01 16:14 ` [PATCH v1 0/4] LoongArch: Add support for TLS Descriptors (TLSDESC) Alexandre Oliva
@ 2023-12-08  3:04 ` Jinyang He
  5 siblings, 0 replies; 11+ messages in thread
From: Jinyang He @ 2023-12-08  3:04 UTC (permalink / raw)
  To: Lulu Cai, binutils
  Cc: xuchenghua, chenglulu, liuzhensong, mengqinggang, xry111,
	i.swmail, maskray, luweining, wanglei

On 2023-12-01 17:04, Lulu Cai wrote:

> The LoongArch TLS Descriptors implementation contains several points:
>
> 1. The instruction sequences is:
>     pcalau12i  $a0,%desc_pc_hi20(var)		#R_LARCH_TLS_DESC_PC_HI20
>     ld.d       $a1,$a0,%desc_ld_pc_lo12(var)	#R_LARCH_TLS_DESC_LD_PC_LO12
>     addi.d     $a0,$a0,%desc_add_pc_lo12(var)	#R_LARCH_TLS_DESC_ADD_PC_LO12
>     jirl       $ra,$a1,%desc_call(var)		#R_LARCH_TLS_DESC_CALL
>
>     The linker for each DESC generates a R_LARCH_TLS_DESC64 dynamic relocation,
>     which relocation is placed at .rela.dyn.
>     TLSDESC always allocates two GOT slots and one dynamic relocation space to TLSDESC.

Hi, all,

There is a new idea of la.tls.desc insn sequence.
The sequence is,
pcalau12i  $a0,%desc_pc_hi20(var)     #R_LARCH_TLS_DESC_PC_HI20
                                       #R_LARCH_RELAX if needed
addi.d     $a0,$a0,%desc_pc_lo12(var) #R_LARCH_TLS_DESC_PC_LO12
                                       #R_LARCH_RELAX if needed
ld.d       $ra,$a0,%desc_ld(var)      #R_LARCH_TLS_DESC_LD
                                       #R_LARCH_RELAX if needed
jirl       $ra,$ra,%desc_call(var)    #R_LARCH_TLS_DESC_CALL
                                       #R_LARCH_RELAX if needed
It loads the address of TLSDESC got entry first, and access it and jump 
then.
The pcalau12i + addi.d should be adjacent.

For DESC to LE type transition,
pcalau12i  $a0,%desc_pc_hi20(var)     => lu12i.w $a0,%le_hi20(var)
addi.d     $a0,$a0,%desc_pc_lo12(var) => ori $a0,$a0,%le_lo12(var)
ld.d       $ra,$a0,%desc_ld(var)      => NOP, delete if with RELAX
jirl       $ra,$ra,%desc_call(var)    => NOP, delete if with RELAX

For DESC to IE type transition,
pcalau12i  $a0,%desc_pc_hi20(var)     => pcalau12i $a0,%ie_hi20(var)
addi.d     $a0,$a0,%desc_pc_lo12(var) => ld.d $a0,$a0,%ie_lo12(var)
ld.d       $ra,$a0,%desc_ld(var)      => NOP, delete if with RELAX
jirl       $ra,$ra,%desc_call(var)    => NOP, delete if with RELAX

For DESC relax, Do it if cannot do DESC to LE/IE
pcalau12i + addi.d -> pcaddi $a0, %???(var) (pseudo reloc type maybe 
"R_LARCH_TLS_DESC_PCREL20_S2")
ld.d       $ra,$a0,%desc_ld(var)
jirl       $ra,$ra,%desc_call(var)

And for la.tls.gd or la.tls.ld, we can also do load got entry address relax.
pcalau12i + addi.d -> pcaddi $a0, %???(var) (pseudo reloc type maybe 
"R_LARCH_TLS_GD/LD_PCREL20_S2")

Some relative info can be got in loongarch_elf_relax_section(),
e.g. sec_addr (got), got_off, desc_off. It can be relaxed in theory.
It seems cannot reuse R_LARCH_PCREL20_S2 and needs other relocation types.

All suggestions and ideas are welcome. Thanks in advance.

Jinyang

>
> 2. When using multiple ways to access the same TLS variable, a maximum of 5 GOT
>     slots are used. For example, using GD, TLSDESC, and IE to access the same TLS
>     variable,GD always uses the first two of the five GOT, TLSDESC uses the third
>     and fourth, and IE uses the last.
>
> 3. TLSDESC always requires dynamic relocation because of LoongArch does not yet have
>     a tls type transition. Howerer statically linked programs cannot resolve TLSDESC's
>     dynamic relocation, so we did a type transition for this case.
>     DESC -> LE:
>     pcalau12i  $a0,%desc_pc_hi20(var)	      =>  lu12i.w $a0,%le_hi20(var)
>     ld.d       $a1,$a0,%desc_ld_pc_lo12(var)   =>  ori $a0,$a0,%le_lo12(var)
>     addi.d     $a0,$a0,%desc_add_pc_lo12(var)  =>  NOP	
>     jirl       $ra,$a1,%desc_call(var)	      =>  NOP
>
> 4. The current code passes the tests of gas ld and glibc.
>
> Lulu Cai (4):
>    LoongArch: Add new relocs and macro for TLSDESC.
>    LoongArch: Add support for TLSDESC in ld.
>    LoongArch: Add transition support for DESC to LE.
>    LoongArch: Add testsuits for TLSDESC in gas and ld.
>
>   bfd/bfd-in2.h                                 |  12 +
>   bfd/elfnn-loongarch.c                         | 276 ++++++++++++++++--
>   bfd/elfxx-loongarch.c                         | 209 ++++++++++++-
>   bfd/libbfd.h                                  |  12 +
>   bfd/reloc.c                                   |  29 ++
>   gas/config/tc-loongarch.c                     |  14 +-
>   gas/testsuite/gas/loongarch/tlsdesc_32.d      |  26 ++
>   gas/testsuite/gas/loongarch/tlsdesc_32.s      |  12 +
>   gas/testsuite/gas/loongarch/tlsdesc_64.d      |  26 ++
>   gas/testsuite/gas/loongarch/tlsdesc_64.s      |  12 +
>   .../gas/loongarch/tlsdesc_large_abs.d         |  21 ++
>   .../gas/loongarch/tlsdesc_large_abs.s         |   9 +
>   .../gas/loongarch/tlsdesc_large_pc.d          |  34 +++
>   .../gas/loongarch/tlsdesc_large_pc.s          |  16 +
>   include/elf/loongarch.h                       |  22 +-
>   include/opcode/loongarch.h                    |   3 +
>   .../ld-loongarch-elf/ld-loongarch-elf.exp     |  16 +
>   ld/testsuite/ld-loongarch-elf/tls-desc.dd     |  74 +++++
>   ld/testsuite/ld-loongarch-elf/tls-desc.rd     |  79 +++++
>   ld/testsuite/ld-loongarch-elf/tls-desc.s      | 102 +++++++
>   .../ld-loongarch-elf/tls-relax-desc-le.d      |  15 +
>   .../ld-loongarch-elf/tls-relax-desc-le.s      |   8 +
>   opcodes/loongarch-opc.c                       |  54 ++++
>   23 files changed, 1054 insertions(+), 27 deletions(-)
>   create mode 100644 gas/testsuite/gas/loongarch/tlsdesc_32.d
>   create mode 100644 gas/testsuite/gas/loongarch/tlsdesc_32.s
>   create mode 100644 gas/testsuite/gas/loongarch/tlsdesc_64.d
>   create mode 100644 gas/testsuite/gas/loongarch/tlsdesc_64.s
>   create mode 100644 gas/testsuite/gas/loongarch/tlsdesc_large_abs.d
>   create mode 100644 gas/testsuite/gas/loongarch/tlsdesc_large_abs.s
>   create mode 100644 gas/testsuite/gas/loongarch/tlsdesc_large_pc.d
>   create mode 100644 gas/testsuite/gas/loongarch/tlsdesc_large_pc.s
>   create mode 100644 ld/testsuite/ld-loongarch-elf/tls-desc.dd
>   create mode 100644 ld/testsuite/ld-loongarch-elf/tls-desc.rd
>   create mode 100644 ld/testsuite/ld-loongarch-elf/tls-desc.s
>   create mode 100644 ld/testsuite/ld-loongarch-elf/tls-relax-desc-le.d
>   create mode 100644 ld/testsuite/ld-loongarch-elf/tls-relax-desc-le.s
>


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

end of thread, other threads:[~2023-12-08  3:04 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-12-01  9:04 [PATCH v1 0/4] LoongArch: Add support for TLS Descriptors (TLSDESC) Lulu Cai
2023-12-01  9:04 ` [PATCH v1 1/4] LoongArch: Add new relocs and macro for TLSDESC Lulu Cai
2023-12-01  9:04 ` [PATCH v1 2/4] LoongArch: Add support for TLSDESC in ld Lulu Cai
2023-12-01  9:04 ` [PATCH v1 3/4] LoongArch: Add transition support for DESC to LE Lulu Cai
2023-12-01  9:04 ` [PATCH v1 4/4] LoongArch: Add testsuits for TLSDESC in gas and ld Lulu Cai
2023-12-02  7:38   ` Xi Ruoyao
2023-12-02  7:44     ` Xi Ruoyao
2023-12-02  8:24       ` mengqinggang
2023-12-01 16:14 ` [PATCH v1 0/4] LoongArch: Add support for TLS Descriptors (TLSDESC) Alexandre Oliva
2023-12-02  3:54   ` mengqinggang
2023-12-08  3:04 ` Jinyang He

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).