]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
LoongArch: Support R_LARCH_TLS_DTPREL32/64 used in debug section
authormengqinggang <mengqinggang@loongson.cn>
Tue, 7 Jul 2026 18:27:02 +0000 (02:27 +0800)
committermengqinggang <mengqinggang@loongson.cn>
Fri, 10 Jul 2026 02:51:02 +0000 (10:51 +0800)
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.

bfd/elfnn-loongarch.c
bfd/elfxx-loongarch.c
gas/testsuite/gas/loongarch/dtprel.d [new file with mode: 0644]
gas/testsuite/gas/loongarch/dtprel.s [new file with mode: 0644]
ld/testsuite/ld-loongarch-elf/dtprel.d [new file with mode: 0644]
ld/testsuite/ld-loongarch-elf/dtprel.s [new file with mode: 0644]
ld/testsuite/ld-loongarch-elf/ld-loongarch-elf.exp

index 1100813325502a293c84fd72290b14d518062717..03b0eb40ac70aa78048c22356846d85ef578c2b5 100644 (file)
@@ -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:
index b39a5c50b8d46dca5b0cdc5a17e534c0597df807..b36df16b4305899dfc02efa650c97dcd8e57f960 100644 (file)
@@ -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 (file)
index 0000000..9a203f6
--- /dev/null
@@ -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 (file)
index 0000000..43df0bf
--- /dev/null
@@ -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 (file)
index 0000000..33771e7
--- /dev/null
@@ -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 (file)
index 0000000..43df0bf
--- /dev/null
@@ -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
index ce1bf651b5a4366b6daf3be6a6f9188f97feb7b8..7ea99f1d0cc0f76066fd81e62f740cd4e38f305f 100644 (file)
 # MA 02110-1301, USA.
 #
 
+if [istarget loongarch*-*-*] {
+  run_dump_test "dtprel"
+}
+
 if [istarget "loongarch64-*-*"] {
     run_dump_test "macro_op"
     run_dump_test "syscall"