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;
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 "
/* 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. */
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;
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;
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;
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;
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;
--- /dev/null
+ .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)
] \
]
+ # 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-*-*"] {