[binutils-gdb] LoongArch: Support R_LARCH_TLS_DTPREL32/64 used in debug section
liu zhensong
liuzhensong@sourceware.org
Fri Jul 10 07:01:58 GMT 2026
https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=bfc3ac0d13b52a400aea7221603a5ac69510f471
commit bfc3ac0d13b52a400aea7221603a5ac69510f471
Author: mengqinggang <mengqinggang@loongson.cn>
Date: Wed Jul 8 02:27:02 2026 +0800
LoongArch: Support R_LARCH_TLS_DTPREL32/64 used in debug section
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.
Diff:
---
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/testsuite/ld-loongarch-elf/ld-loongarch-elf.exp | 4 ++
7 files changed, 51 insertions(+), 44 deletions(-)
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"
More information about the Binutils-cvs
mailing list