From: mengqinggang Date: Tue, 7 Jul 2026 18:27:02 +0000 (+0800) Subject: LoongArch: Support R_LARCH_TLS_DTPREL32/64 used in debug section X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=bfc3ac0d13b;p=thirdparty%2Fbinutils-gdb.git 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 --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"