[PATCH v2] 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.
---
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                         | 44 +------------------
 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, 48 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..82a3050e30e 100644
--- a/bfd/elfnn-loongarch.c
+++ b/bfd/elfnn-loongarch.c
@@ -3822,48 +3822,8 @@ 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);
+	  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"
-- 
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.