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

mengqinggang <[email protected]>
Newsgroups gmane.comp.gnu.binutils
Message-ID <[email protected]>
Simplify R_LARCH_TLS_DTPREL32/64 relocations processing.
Return the offset to TLS block for symbol.

Change R_LARCH_TLS_DTPREL32/64 partial_inplace to false since
LoongArch uses RELA relocations.
---
v2 -> v3:
- Update dtprel.d to remove addend value.  
- Add comments for why delete addend for dtprel relocations.

v1 -> v2:
- gcc output redundant addend 0x8000 in loongarch_output_dwarf_dtprel.
  Remove the addend temporarily for compatibility as it is rarely used.

 bfd/elfnn-loongarch.c                         | 47 ++-----------------
 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, 51 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

diff --git a/bfd/elfnn-loongarch.c b/bfd/elfnn-loongarch.c
index 11008133255..03b0eb40ac7 100644
--- a/bfd/elfnn-loongarch.c
+++ b/bfd/elfnn-loongarch.c
@@ -3822,48 +3822,11 @@ 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.");
-	    }
-
+	  /* GCC version <= 16.1 output extra addend 0x8000 in
+	     loongarch_output_dwarf_dtprel.  Add the addend here
+	     wuold cause problems for TLS debug info.  */
+	  relocation = tlsoff (info, relocation);
+	  unresolved_reloc = false;
 	  break;
 
 	case R_LARCH_SOP_PUSH_TLS_TPREL:
diff --git a/bfd/elfxx-loongarch.c b/bfd/elfxx-loongarch.c
index b39a5c50b8d..b36df16b430 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..33771e764f4
--- /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:	00000008 	.word		0x00000008
+   8:	00000008 	.word		0x00000008
+   c:	00000000 	.word		0x00000000
+  10:	00000008 	.word		0x00000008
+  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 ce1bf651b5a..7ea99f1d0cc 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 "macro_op"
     run_dump_test "syscall"
-- 
2.34.1
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.