s390: Avoid dynamic TLS relocs in PIE

No dynamic relocs are needed for TLS defined in an executable, the
TP relative offset is known at link time.

Fixes
FAIL: Build pr22263-1

bfd/
	PR ld/22263
	* elf64-s390.c (elf_s390_tls_transition): Use bfd_link_dll
	instead of bfd_link_pic for TLS.
	(elf_s390_check_relocs): Likewise.
	(allocate_dynrelocs): Likewise.
	(elf_s390_relocate_section): Likewise.
This commit is contained in:
Stefan Liebler
2022-04-28 14:29:58 +02:00
committed by Andreas Krebbel
parent 95ade9a5f4
commit 26b1426577

View File

@ -774,7 +774,7 @@ elf_s390_tls_transition (struct bfd_link_info *info,
int r_type, int r_type,
int is_local) int is_local)
{ {
if (bfd_link_pic (info)) if (bfd_link_dll (info))
return r_type; return r_type;
switch (r_type) switch (r_type)
@ -1026,7 +1026,7 @@ elf_s390_check_relocs (bfd *abfd,
case R_390_TLS_GOTIE20: case R_390_TLS_GOTIE20:
case R_390_TLS_GOTIE64: case R_390_TLS_GOTIE64:
case R_390_TLS_IEENT: case R_390_TLS_IEENT:
if (bfd_link_pic (info)) if (bfd_link_dll (info))
info->flags |= DF_STATIC_TLS; info->flags |= DF_STATIC_TLS;
/* Fall through */ /* Fall through */
@ -1107,7 +1107,7 @@ elf_s390_check_relocs (bfd *abfd,
if (r_type == R_390_TLS_LE64 && bfd_link_pie (info)) if (r_type == R_390_TLS_LE64 && bfd_link_pie (info))
break; break;
if (!bfd_link_pic (info)) if (!bfd_link_dll (info))
break; break;
info->flags |= DF_STATIC_TLS; info->flags |= DF_STATIC_TLS;
/* Fall through */ /* Fall through */
@ -1571,7 +1571,7 @@ allocate_dynrelocs (struct elf_link_hash_entry *h,
to R_390_TLS_LE64 requiring no TLS entry. For GOTIE12 and IEENT to R_390_TLS_LE64 requiring no TLS entry. For GOTIE12 and IEENT
we can save the dynamic TLS relocation. */ we can save the dynamic TLS relocation. */
if (h->got.refcount > 0 if (h->got.refcount > 0
&& !bfd_link_pic (info) && !bfd_link_dll (info)
&& h->dynindx == -1 && h->dynindx == -1
&& elf_s390_hash_entry(h)->tls_type >= GOT_TLS_IE) && elf_s390_hash_entry(h)->tls_type >= GOT_TLS_IE)
{ {
@ -2662,7 +2662,7 @@ elf_s390_relocate_section (bfd *output_bfd,
/* Relocations for tls literal pool entries. */ /* Relocations for tls literal pool entries. */
case R_390_TLS_IE64: case R_390_TLS_IE64:
if (bfd_link_pic (info)) if (bfd_link_dll (info))
{ {
Elf_Internal_Rela outrel; Elf_Internal_Rela outrel;
asection *sreloc; asection *sreloc;
@ -2690,7 +2690,7 @@ elf_s390_relocate_section (bfd *output_bfd,
else if (h != NULL) else if (h != NULL)
{ {
tls_type = elf_s390_hash_entry(h)->tls_type; tls_type = elf_s390_hash_entry(h)->tls_type;
if (!bfd_link_pic (info) && h->dynindx == -1 && tls_type >= GOT_TLS_IE) if (!bfd_link_dll (info) && h->dynindx == -1 && tls_type >= GOT_TLS_IE)
r_type = R_390_TLS_LE64; r_type = R_390_TLS_LE64;
} }
if (r_type == R_390_TLS_GD64 && tls_type >= GOT_TLS_IE) if (r_type == R_390_TLS_GD64 && tls_type >= GOT_TLS_IE)
@ -2801,14 +2801,14 @@ elf_s390_relocate_section (bfd *output_bfd,
if (local_got_offsets == NULL) if (local_got_offsets == NULL)
abort(); abort();
off = local_got_offsets[r_symndx]; off = local_got_offsets[r_symndx];
if (bfd_link_pic (info)) if (bfd_link_dll (info))
goto emit_tls_relocs; goto emit_tls_relocs;
} }
else else
{ {
off = h->got.offset; off = h->got.offset;
tls_type = elf_s390_hash_entry(h)->tls_type; tls_type = elf_s390_hash_entry(h)->tls_type;
if (bfd_link_pic (info) || h->dynindx != -1 || tls_type < GOT_TLS_IE) if (bfd_link_dll (info) || h->dynindx != -1 || tls_type < GOT_TLS_IE)
goto emit_tls_relocs; goto emit_tls_relocs;
} }
@ -2825,7 +2825,7 @@ elf_s390_relocate_section (bfd *output_bfd,
break; break;
case R_390_TLS_LDM64: case R_390_TLS_LDM64:
if (! bfd_link_pic (info)) if (! bfd_link_dll (info))
/* The literal pool entry this relocation refers to gets ignored /* The literal pool entry this relocation refers to gets ignored
by the optimized code of the local exec model. Do nothing by the optimized code of the local exec model. Do nothing
and the value will turn out zero. */ and the value will turn out zero. */
@ -2900,7 +2900,7 @@ elf_s390_relocate_section (bfd *output_bfd,
continue; continue;
case R_390_TLS_LDO64: case R_390_TLS_LDO64:
if (bfd_link_pic (info) || (input_section->flags & SEC_DEBUGGING)) if (bfd_link_dll (info) || (input_section->flags & SEC_DEBUGGING))
relocation -= dtpoff_base (info); relocation -= dtpoff_base (info);
else else
/* When converting LDO to LE, we must negate. */ /* When converting LDO to LE, we must negate. */
@ -2922,7 +2922,7 @@ elf_s390_relocate_section (bfd *output_bfd,
if (r_type == R_390_TLS_LOAD) if (r_type == R_390_TLS_LOAD)
{ {
if (!bfd_link_pic (info) && (h == NULL || h->dynindx == -1)) if (!bfd_link_dll (info) && (h == NULL || h->dynindx == -1))
{ {
/* IE->LE transition. Four valid cases: /* IE->LE transition. Four valid cases:
lg %rx,(0,%ry) -> sllg %rx,%ry,0 lg %rx,(0,%ry) -> sllg %rx,%ry,0
@ -2972,7 +2972,7 @@ elf_s390_relocate_section (bfd *output_bfd,
invalid_tls_insn (input_bfd, input_section, rel); invalid_tls_insn (input_bfd, input_section, rel);
return false; return false;
} }
if (!bfd_link_pic (info) && (h == NULL || h->dynindx == -1)) if (!bfd_link_dll (info) && (h == NULL || h->dynindx == -1))
{ {
/* GD->LE transition. /* GD->LE transition.
brasl %r14,__tls_get_addr@plt -> brcl 0,. */ brasl %r14,__tls_get_addr@plt -> brcl 0,. */
@ -2991,7 +2991,7 @@ elf_s390_relocate_section (bfd *output_bfd,
} }
else if (r_type == R_390_TLS_LDCALL) else if (r_type == R_390_TLS_LDCALL)
{ {
if (!bfd_link_pic (info)) if (!bfd_link_dll (info))
{ {
unsigned int insn0, insn1; unsigned int insn0, insn1;