PowerPC64le PLT reference counting
A fix for ELFv2 ABI garbage-collection. * elf64-ppc.c (ppc64_elf_gc_sweep_hook): Support ELFv2 PLT reference counting.
This commit is contained in:
parent
4ac40124ee
commit
8dea77f025
|
@ -1,3 +1,8 @@
|
||||||
|
2017-04-05 Alan Modra <amodra@gmail.com>
|
||||||
|
|
||||||
|
* elf64-ppc.c (ppc64_elf_gc_sweep_hook): Support ELFv2 PLT
|
||||||
|
reference counting.
|
||||||
|
|
||||||
2017-04-02 Jon Turney <jon.turney@dronecode.org.uk>
|
2017-04-02 Jon Turney <jon.turney@dronecode.org.uk>
|
||||||
|
|
||||||
(_bfd_XXi_swap_aouthdr_out): For clarity, use defines rather than
|
(_bfd_XXi_swap_aouthdr_out): For clarity, use defines rather than
|
||||||
|
|
|
@ -6595,7 +6595,7 @@ ppc64_elf_gc_sweep_hook (bfd *abfd, struct bfd_link_info *info,
|
||||||
unsigned long r_symndx;
|
unsigned long r_symndx;
|
||||||
enum elf_ppc64_reloc_type r_type;
|
enum elf_ppc64_reloc_type r_type;
|
||||||
struct elf_link_hash_entry *h = NULL;
|
struct elf_link_hash_entry *h = NULL;
|
||||||
struct plt_entry **plt_list;
|
struct plt_entry **plt_list = NULL;
|
||||||
unsigned char tls_type = 0;
|
unsigned char tls_type = 0;
|
||||||
|
|
||||||
r_symndx = ELF64_R_SYM (rel->r_info);
|
r_symndx = ELF64_R_SYM (rel->r_info);
|
||||||
|
@ -6674,6 +6674,8 @@ ppc64_elf_gc_sweep_hook (bfd *abfd, struct bfd_link_info *info,
|
||||||
if (ent->got.refcount > 0)
|
if (ent->got.refcount > 0)
|
||||||
ent->got.refcount -= 1;
|
ent->got.refcount -= 1;
|
||||||
}
|
}
|
||||||
|
if (h != NULL && !bfd_link_pic (info) && abiversion (abfd) != 1)
|
||||||
|
plt_list = &h->plt.plist;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case R_PPC64_PLT16_HA:
|
case R_PPC64_PLT16_HA:
|
||||||
|
@ -6685,7 +6687,6 @@ ppc64_elf_gc_sweep_hook (bfd *abfd, struct bfd_link_info *info,
|
||||||
case R_PPC64_REL14_BRNTAKEN:
|
case R_PPC64_REL14_BRNTAKEN:
|
||||||
case R_PPC64_REL14_BRTAKEN:
|
case R_PPC64_REL14_BRTAKEN:
|
||||||
case R_PPC64_REL24:
|
case R_PPC64_REL24:
|
||||||
plt_list = NULL;
|
|
||||||
if (h != NULL)
|
if (h != NULL)
|
||||||
plt_list = &h->plt.plist;
|
plt_list = &h->plt.plist;
|
||||||
else if (local_got_ents != NULL)
|
else if (local_got_ents != NULL)
|
||||||
|
@ -6697,21 +6698,39 @@ ppc64_elf_gc_sweep_hook (bfd *abfd, struct bfd_link_info *info,
|
||||||
if ((local_got_tls_masks[r_symndx] & PLT_IFUNC) != 0)
|
if ((local_got_tls_masks[r_symndx] & PLT_IFUNC) != 0)
|
||||||
plt_list = local_plt + r_symndx;
|
plt_list = local_plt + r_symndx;
|
||||||
}
|
}
|
||||||
if (plt_list)
|
break;
|
||||||
{
|
|
||||||
struct plt_entry *ent;
|
|
||||||
|
|
||||||
for (ent = *plt_list; ent != NULL; ent = ent->next)
|
case R_PPC64_ADDR64:
|
||||||
if (ent->addend == rel->r_addend)
|
case R_PPC64_ADDR16:
|
||||||
break;
|
case R_PPC64_ADDR16_DS:
|
||||||
if (ent != NULL && ent->plt.refcount > 0)
|
case R_PPC64_ADDR16_HA:
|
||||||
ent->plt.refcount -= 1;
|
case R_PPC64_ADDR16_HI:
|
||||||
}
|
case R_PPC64_ADDR16_HIGH:
|
||||||
|
case R_PPC64_ADDR16_HIGHA:
|
||||||
|
case R_PPC64_ADDR16_HIGHER:
|
||||||
|
case R_PPC64_ADDR16_HIGHERA:
|
||||||
|
case R_PPC64_ADDR16_HIGHEST:
|
||||||
|
case R_PPC64_ADDR16_HIGHESTA:
|
||||||
|
case R_PPC64_ADDR16_LO:
|
||||||
|
case R_PPC64_ADDR16_LO_DS:
|
||||||
|
if (h != NULL && !bfd_link_pic (info) && abiversion (abfd) != 1
|
||||||
|
&& rel->r_addend == 0)
|
||||||
|
plt_list = &h->plt.plist;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
if (plt_list != NULL)
|
||||||
|
{
|
||||||
|
struct plt_entry *ent;
|
||||||
|
|
||||||
|
for (ent = *plt_list; ent != NULL; ent = ent->next)
|
||||||
|
if (ent->addend == rel->r_addend)
|
||||||
|
break;
|
||||||
|
if (ent != NULL && ent->plt.refcount > 0)
|
||||||
|
ent->plt.refcount -= 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue