[v0] LoongArch: Support R_LARCH_TLS_DTPREL32/64 used in debug section

Message ID 20260708094256.2858298-1-mengqinggang@loongson.cn
State New
Headers
Series [v0] LoongArch: Support R_LARCH_TLS_DTPREL32/64 used in debug section |

Checks

Context Check Description
linaro-tcwg-bot/tcwg_binutils_build--master-arm success Build passed
linaro-tcwg-bot/tcwg_binutils_check--master-arm success Test passed
linaro-tcwg-bot/tcwg_binutils_build--master-aarch64 success Build passed
linaro-tcwg-bot/tcwg_binutils_check--master-aarch64 success Test passed

Commit Message

mengqinggang July 8, 2026, 9:42 a.m. UTC
  Simplify R_LARCH_TLS_DTPREL32/64 relocations processing.
Return the offset to TLS block for symbol with its addend.

Change R_LARCH_TLS_DTPREL32/64 partial_inplace to false since
LoongArch uses RELA relocations.
---
 bfd/elfnn-loongarch.c                         | 45 ++-----------------
 bfd/elfxx-loongarch.c                         |  4 +-
 gas/testsuite/gas/loongarch/dtprel.d          |  9 ++++
 gas/testsuite/gas/loongarch/dtprel.s          | 10 +++++
 ld/testsuite/ld-loongarch-elf/dtprel.d        | 11 +++++
 ld/testsuite/ld-loongarch-elf/dtprel.s        | 10 +++++
 .../ld-loongarch-elf/ld-loongarch-elf.exp     |  4 ++
 7 files changed, 49 insertions(+), 44 deletions(-)
 create mode 100644 gas/testsuite/gas/loongarch/dtprel.d
 create mode 100644 gas/testsuite/gas/loongarch/dtprel.s
 create mode 100644 ld/testsuite/ld-loongarch-elf/dtprel.d
 create mode 100644 ld/testsuite/ld-loongarch-elf/dtprel.s
  

Patch

diff --git a/bfd/elfnn-loongarch.c b/bfd/elfnn-loongarch.c
index 11008133255..3b4607efcba 100644
--- a/bfd/elfnn-loongarch.c
+++ b/bfd/elfnn-loongarch.c
@@ -3822,48 +3822,9 @@  loongarch_elf_relocate_section (struct bfd_link_info *info,
 
 	case R_LARCH_TLS_DTPREL32:
 	case R_LARCH_TLS_DTPREL64:
-	  if (resolved_dynly)
-	    {
-	      Elf_Internal_Rela outrel;
-
-	      outrel.r_offset = _bfd_elf_section_offset (info->output_bfd, info,
-							 input_section,
-							 rel->r_offset);
-	      unresolved_reloc = (!((bfd_vma) -2 <= outrel.r_offset)
-				  && (input_section->flags & SEC_ALLOC));
-	      outrel.r_info = ELFNN_R_INFO (h->dynindx, r_type);
-	      outrel.r_offset += sec_addr (input_section);
-	      outrel.r_addend = rel->r_addend;
-	      if (unresolved_reloc)
-		loongarch_elf_append_rela (info->output_bfd, sreloc, &outrel);
-	      break;
-	    }
-
-	  if (resolved_to_const)
-	    fatal = loongarch_reloc_is_fatal (info, input_bfd, input_section,
-					      rel, howto,
-					      bfd_reloc_notsupported,
-					      is_undefweak, name,
-					      "Internal:");
-	  if (resolved_local)
-	    {
-	      if (!elf_hash_table (info)->tls_sec)
-		{
-		fatal = loongarch_reloc_is_fatal (info, input_bfd,
-			  input_section, rel, howto, bfd_reloc_notsupported,
-			  is_undefweak, name, "TLS section not be created");
-		}
-	      else
-		relocation = tlsoff (info, relocation);
-	    }
-	  else
-	    {
-	    fatal = loongarch_reloc_is_fatal (info, input_bfd,
-		      input_section, rel, howto, bfd_reloc_undefined,
-		      is_undefweak, name,
-		      "TLS LE just can be resolved local only.");
-	    }
-
+	  relocation = tlsoff (info, relocation);
+	  relocation += rel->r_addend;
+	  unresolved_reloc = false;
 	  break;
 
 	case R_LARCH_SOP_PUSH_TLS_TPREL:
diff --git a/bfd/elfxx-loongarch.c b/bfd/elfxx-loongarch.c
index 11754d62737..1be5a8822dc 100644
--- a/bfd/elfxx-loongarch.c
+++ b/bfd/elfxx-loongarch.c
@@ -219,7 +219,7 @@  static loongarch_reloc_howto_type loongarch_howto_table[] =
 	 complain_overflow_dont,	  /* complain_on_overflow */
 	 bfd_elf_generic_reloc,		  /* special_function */
 	 "R_LARCH_TLS_DTPREL32",	  /* name */
-	 true,				  /* partial_inplace */
+	 false,				  /* partial_inplace */
 	 0,				  /* src_mask */
 	 ALL_ONES,			  /* dst_mask */
 	 false,				  /* pcrel_offset */
@@ -236,7 +236,7 @@  static loongarch_reloc_howto_type loongarch_howto_table[] =
 	 complain_overflow_dont,	  /* complain_on_overflow */
 	 bfd_elf_generic_reloc,		  /* special_function */
 	 "R_LARCH_TLS_DTPREL64",	  /* name */
-	 true,				  /* partial_inplace */
+	 false,				  /* partial_inplace */
 	 0,				  /* src_mask */
 	 ALL_ONES,			  /* dst_mask */
 	 false,				  /* pcrel_offset */
diff --git a/gas/testsuite/gas/loongarch/dtprel.d b/gas/testsuite/gas/loongarch/dtprel.d
new file mode 100644
index 00000000000..9a203f61303
--- /dev/null
+++ b/gas/testsuite/gas/loongarch/dtprel.d
@@ -0,0 +1,9 @@ 
+#source: dtprel.s
+#as:
+#readelf: -rW
+
+#...
+0*00.*R_LARCH_TLS_DTPREL32.*8.*var.*0
+0*04.*R_LARCH_TLS_DTPREL32.*8.*var.*4
+0*08.*R_LARCH_TLS_DTPREL64.*8.*var.*0
+0*10.*R_LARCH_TLS_DTPREL64.*8.*var.*8
diff --git a/gas/testsuite/gas/loongarch/dtprel.s b/gas/testsuite/gas/loongarch/dtprel.s
new file mode 100644
index 00000000000..43df0bff778
--- /dev/null
+++ b/gas/testsuite/gas/loongarch/dtprel.s
@@ -0,0 +1,10 @@ 
+.section .tdata,"awT",@progbits
+.skip 8
+var:
+  .word 0
+
+.section        .debug_info,"",@progbits
+  .dtprelword var
+  .dtprelword var+4
+  .dtpreldword var
+  .dtpreldword var+8
diff --git a/ld/testsuite/ld-loongarch-elf/dtprel.d b/ld/testsuite/ld-loongarch-elf/dtprel.d
new file mode 100644
index 00000000000..c203f3eb3b3
--- /dev/null
+++ b/ld/testsuite/ld-loongarch-elf/dtprel.d
@@ -0,0 +1,11 @@ 
+#ld: -e0
+#objdump: -D -j .debug_info
+
+#...
+0* <.debug_info>:
+   0:	00000008 	.word		0x00000008
+   4:	0000000c 	.word		0x0000000c
+   8:	00000008 	.word		0x00000008
+   c:	00000000 	.word		0x00000000
+  10:	00000010 	.word		0x00000010
+  14:	00000000 	.word		0x00000000
diff --git a/ld/testsuite/ld-loongarch-elf/dtprel.s b/ld/testsuite/ld-loongarch-elf/dtprel.s
new file mode 100644
index 00000000000..43df0bff778
--- /dev/null
+++ b/ld/testsuite/ld-loongarch-elf/dtprel.s
@@ -0,0 +1,10 @@ 
+.section .tdata,"awT",@progbits
+.skip 8
+var:
+  .word 0
+
+.section        .debug_info,"",@progbits
+  .dtprelword var
+  .dtprelword var+4
+  .dtpreldword var
+  .dtpreldword var+8
diff --git a/ld/testsuite/ld-loongarch-elf/ld-loongarch-elf.exp b/ld/testsuite/ld-loongarch-elf/ld-loongarch-elf.exp
index d702e5138c6..705bc84bda3 100644
--- a/ld/testsuite/ld-loongarch-elf/ld-loongarch-elf.exp
+++ b/ld/testsuite/ld-loongarch-elf/ld-loongarch-elf.exp
@@ -19,6 +19,10 @@ 
 # MA 02110-1301, USA.
 #
 
+if [istarget loongarch*-*-*] {
+  run_dump_test "dtprel"
+}
+
 if [istarget "loongarch64-*-*"] {
     run_dump_test "jmp_op"
     run_dump_test "macro_op"