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.
This commit is contained in:
mengqinggang 2026-07-08 02:27:02 +08:00
parent ad945ff8bb
commit bfc3ac0d13
7 changed files with 51 additions and 44 deletions

View 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:

View 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 */

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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"