mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2025-01-18 12:24:38 +08:00
LoongArch: Allocate GOT entry for TLS DESC when -mno-relax is enabled
The type transition of TLSDESC is only done when -mrelax is enabled. So when -mno-relax is enabled, keep GOT_TLS_GDESC to allocate the GOT entry instead of just keeping GOT_TLS_IE.
This commit is contained in:
parent
2c4b5f54b8
commit
48984d3da7
@ -683,7 +683,8 @@ loongarch_elf_record_tls_and_got_reference (bfd *abfd,
|
||||
struct bfd_link_info *info,
|
||||
struct elf_link_hash_entry *h,
|
||||
unsigned long symndx,
|
||||
char tls_type)
|
||||
char tls_type,
|
||||
bool with_relax_reloc)
|
||||
{
|
||||
struct loongarch_elf_link_hash_table *htab = loongarch_elf_hash_table (info);
|
||||
Elf_Internal_Shdr *symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
|
||||
@ -729,9 +730,12 @@ loongarch_elf_record_tls_and_got_reference (bfd *abfd,
|
||||
char *new_tls_type = &_bfd_loongarch_elf_tls_type (abfd, h, symndx);
|
||||
*new_tls_type |= tls_type;
|
||||
|
||||
/* If a symbol is accessed by both IE and DESC, relax DESC to IE. */
|
||||
if ((*new_tls_type & GOT_TLS_IE) && (*new_tls_type & GOT_TLS_GDESC))
|
||||
/* If DESC relocs can do transitions and accessed by both IE and DESC,
|
||||
transition DESC to IE. */
|
||||
if (with_relax_reloc
|
||||
&& (*new_tls_type & GOT_TLS_IE) && (*new_tls_type & GOT_TLS_GDESC))
|
||||
*new_tls_type &= ~ (GOT_TLS_GDESC);
|
||||
|
||||
if ((*new_tls_type & GOT_NORMAL) && (*new_tls_type & ~GOT_NORMAL))
|
||||
{
|
||||
_bfd_error_handler (_("%pB: `%s' accessed both as normal and "
|
||||
@ -1014,9 +1018,13 @@ loongarch_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
|
||||
|
||||
/* Type transitions are only possible with relocations accompanied
|
||||
by R_LARCH_RELAX. */
|
||||
bool with_relax_reloc = false;
|
||||
if (rel + 1 != relocs + sec->reloc_count
|
||||
&& ELFNN_R_TYPE (rel[1].r_info) == R_LARCH_RELAX)
|
||||
r_type = loongarch_tls_transition (abfd, info, h, r_symndx, r_type);
|
||||
{
|
||||
r_type = loongarch_tls_transition (abfd, info, h, r_symndx, r_type);
|
||||
with_relax_reloc = true;
|
||||
}
|
||||
|
||||
/* I don't want to spend time supporting DT_RELR with old object
|
||||
files doing stack-based relocs. */
|
||||
@ -1041,7 +1049,8 @@ loongarch_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
|
||||
h->pointer_equality_needed = 1;
|
||||
if (!loongarch_elf_record_tls_and_got_reference (abfd, info, h,
|
||||
r_symndx,
|
||||
GOT_NORMAL))
|
||||
GOT_NORMAL,
|
||||
with_relax_reloc))
|
||||
return false;
|
||||
break;
|
||||
|
||||
@ -1052,7 +1061,8 @@ loongarch_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
|
||||
case R_LARCH_SOP_PUSH_TLS_GD:
|
||||
if (!loongarch_elf_record_tls_and_got_reference (abfd, info, h,
|
||||
r_symndx,
|
||||
GOT_TLS_GD))
|
||||
GOT_TLS_GD,
|
||||
with_relax_reloc))
|
||||
return false;
|
||||
break;
|
||||
|
||||
@ -1065,7 +1075,8 @@ loongarch_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
|
||||
|
||||
if (!loongarch_elf_record_tls_and_got_reference (abfd, info, h,
|
||||
r_symndx,
|
||||
GOT_TLS_IE))
|
||||
GOT_TLS_IE,
|
||||
with_relax_reloc))
|
||||
return false;
|
||||
break;
|
||||
|
||||
@ -1077,7 +1088,8 @@ loongarch_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
|
||||
|
||||
if (!loongarch_elf_record_tls_and_got_reference (abfd, info, h,
|
||||
r_symndx,
|
||||
GOT_TLS_LE))
|
||||
GOT_TLS_LE,
|
||||
with_relax_reloc))
|
||||
return false;
|
||||
break;
|
||||
|
||||
@ -1085,7 +1097,8 @@ loongarch_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
|
||||
case R_LARCH_TLS_DESC_HI20:
|
||||
if (!loongarch_elf_record_tls_and_got_reference (abfd, info, h,
|
||||
r_symndx,
|
||||
GOT_TLS_GDESC))
|
||||
GOT_TLS_GDESC,
|
||||
with_relax_reloc))
|
||||
return false;
|
||||
break;
|
||||
|
||||
|
8
ld/testsuite/ld-loongarch-elf/desc-ie-norelax.dd
Normal file
8
ld/testsuite/ld-loongarch-elf/desc-ie-norelax.dd
Normal file
@ -0,0 +1,8 @@
|
||||
#...
|
||||
.*pcalau12i.*
|
||||
.*addi.d.*
|
||||
.*ld.d.*
|
||||
.*jirl.*
|
||||
.*pcalau12i.*
|
||||
.*ld.d.*
|
||||
#pass
|
3
ld/testsuite/ld-loongarch-elf/desc-ie-norelax.rd
Normal file
3
ld/testsuite/ld-loongarch-elf/desc-ie-norelax.rd
Normal file
@ -0,0 +1,3 @@
|
||||
#...
|
||||
.*R_LARCH_TLS_DESC64.*
|
||||
#pass
|
15
ld/testsuite/ld-loongarch-elf/desc-ie-norelax.s
Normal file
15
ld/testsuite/ld-loongarch-elf/desc-ie-norelax.s
Normal file
@ -0,0 +1,15 @@
|
||||
.globl var
|
||||
.section .tdata,"awT",@progbits
|
||||
.type tls, @object
|
||||
var:
|
||||
.word 1
|
||||
.text
|
||||
.globl _start
|
||||
_start:
|
||||
pcalau12i $a0,%desc_pc_hi20(var)
|
||||
addi.d $a0,$a0,%desc_pc_lo12(var)
|
||||
ld.d $ra,$a0,%desc_ld(var)
|
||||
jirl $ra,$ra,%desc_call(var)
|
||||
|
||||
pcalau12i $t0,%ie_pc_hi20(var)
|
||||
ld.d $t0,$t0,%ie_pc_lo12(var)
|
6
ld/testsuite/ld-loongarch-elf/desc-ie-norelax.sd
Normal file
6
ld/testsuite/ld-loongarch-elf/desc-ie-norelax.sd
Normal file
@ -0,0 +1,6 @@
|
||||
|
||||
.*: file format .*
|
||||
|
||||
Contents of section .got:
|
||||
[0-9a-f]+ [0-9a-f]+ 00000000 00000000 00000000 ................
|
||||
[0-9a-f]+ 00000000 00000000 00000000 00000000 ................
|
@ -154,6 +154,21 @@ if [istarget "loongarch64-*-*"] {
|
||||
] \
|
||||
]
|
||||
|
||||
# Using DESC and IE to access the same tls symbol but with
|
||||
# -mno-relax requires allocating GOT entries for both DESC and IE,
|
||||
# not just IE
|
||||
run_ld_link_tests [list \
|
||||
[list \
|
||||
"desc and ie do not type transition" \
|
||||
"-pie -e0 --hash-style=both" "" \
|
||||
"-mno-relax" \
|
||||
{desc-ie-norelax.s} \
|
||||
{{objdump {-d} desc-ie-norelax.dd} \
|
||||
{readelf {-rW} desc-ie-norelax.rd} \
|
||||
{objdump {-sj.got} desc-ie-norelax.sd}} \
|
||||
"desc-ie-norelax" \
|
||||
] \
|
||||
] \
|
||||
}
|
||||
|
||||
if [istarget "loongarch64-*-*"] {
|
||||
|
Loading…
Reference in New Issue
Block a user