PowerPC TLS miscounting PLT for __tls_get_addr
ppc*_elf_tls_optimize decrements the PLT refcount for __tls_get_addr when a GD or LD sequence can be optimized. Without tls marker relocs this must be done when processing the argument setup relocations. With marker relocs it's better done when processing the marker reloc. But don't count them both ways. Seen as "unresolvable R_PPC_REL24 relocation against symbol `__tls_get_addr_opt'" (and other branch relocs). * elf32-ppc.c (ppc_elf_tls_optimize): Don't process R_PPC_TLSLD with non-local symbol. Don't double count __tls_get_addr calls with marker relocs. * elf64-ppc.c (ppc64_elf_tls_optimize): Likewise.
This commit is contained in:
parent
9737e8af48
commit
7d04a20ae4
3 changed files with 19 additions and 7 deletions
|
@ -1,3 +1,10 @@
|
|||
2019-10-07 Alan Modra <amodra@gmail.com>
|
||||
|
||||
* elf32-ppc.c (ppc_elf_tls_optimize): Don't process R_PPC_TLSLD
|
||||
with non-local symbol. Don't double count __tls_get_addr calls
|
||||
with marker relocs.
|
||||
* elf64-ppc.c (ppc64_elf_tls_optimize): Likewise.
|
||||
|
||||
2019-10-07 Alan Modra <amodra@gmail.com>
|
||||
|
||||
* elf32-ppc.c (nomark_tls_get_addr): Rename from has_tls_get_addr_call
|
||||
|
|
|
@ -4530,8 +4530,11 @@ ppc_elf_tls_optimize (bfd *obfd ATTRIBUTE_UNUSED,
|
|||
else
|
||||
continue;
|
||||
|
||||
case R_PPC_TLSGD:
|
||||
case R_PPC_TLSLD:
|
||||
if (!is_local)
|
||||
continue;
|
||||
/* Fall through. */
|
||||
case R_PPC_TLSGD:
|
||||
if (rel + 1 < relend
|
||||
&& is_plt_seq_reloc (ELF32_R_TYPE (rel[1].r_info)))
|
||||
{
|
||||
|
@ -4633,7 +4636,7 @@ ppc_elf_tls_optimize (bfd *obfd ATTRIBUTE_UNUSED,
|
|||
!= (TLS_TLS | TLS_MARK)))
|
||||
continue;
|
||||
|
||||
if (expecting_tls_get_addr)
|
||||
if (expecting_tls_get_addr == 1 + !sec->nomark_tls_get_addr)
|
||||
{
|
||||
struct plt_entry *ent;
|
||||
bfd_vma addend = 0;
|
||||
|
@ -4646,10 +4649,9 @@ ppc_elf_tls_optimize (bfd *obfd ATTRIBUTE_UNUSED,
|
|||
got2, addend);
|
||||
if (ent != NULL && ent->plt.refcount > 0)
|
||||
ent->plt.refcount -= 1;
|
||||
|
||||
if (expecting_tls_get_addr == 2)
|
||||
continue;
|
||||
}
|
||||
if (tls_clear == 0)
|
||||
continue;
|
||||
|
||||
if (tls_set == 0)
|
||||
{
|
||||
|
|
|
@ -7906,8 +7906,11 @@ ppc64_elf_tls_optimize (struct bfd_link_info *info)
|
|||
}
|
||||
continue;
|
||||
|
||||
case R_PPC64_TLSGD:
|
||||
case R_PPC64_TLSLD:
|
||||
if (!is_local)
|
||||
continue;
|
||||
/* Fall through. */
|
||||
case R_PPC64_TLSGD:
|
||||
if (rel + 1 < relend
|
||||
&& is_plt_seq_reloc (ELF64_R_TYPE (rel[1].r_info)))
|
||||
{
|
||||
|
@ -8092,7 +8095,7 @@ ppc64_elf_tls_optimize (struct bfd_link_info *info)
|
|||
!= (TLS_TLS | TLS_MARK)))
|
||||
continue;
|
||||
|
||||
if (expecting_tls_get_addr)
|
||||
if (expecting_tls_get_addr == 1 + !sec->nomark_tls_get_addr)
|
||||
{
|
||||
struct plt_entry *ent = NULL;
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue