Error on unsupported PowerPC ifuncs

The pr19784 tests fail on ppc32 due to a gcc bug.  The failure should
be noticed when building both libpr19784a.so and libpr19784b.so,
rather than ld building a buggy libpr19784a.so that fails at run time.
This patch fixes that by moving the @local ifunc check out of
check_relocs, where a call destination may not yet be known to be
ifunc.  The patch also adds a related error for -mbss-plt code.

	* elf32-ppc.c (ppc_elf_check_relocs): Move error for @local ifunc..
	(ppc_elf_relocate_section): ..to here.  Comment.  Error on
	detecting -mbss-plt -fPIC local ifuncs too.
	(ppc_elf_size_dynamic_sections): Comment on unnecessary glink
	branch table entries.
This commit is contained in:
Alan Modra 2016-08-22 10:42:26 +09:30
parent ca942b53ce
commit 888a7fc366
2 changed files with 45 additions and 10 deletions

View file

@ -1,3 +1,11 @@
2016-08-22 Alan Modra <amodra@gmail.com>
* elf32-ppc.c (ppc_elf_check_relocs): Move error for @local ifunc..
(ppc_elf_relocate_section): ..to here. Comment. Error on
detecting -mbss-plt -fPIC local ifuncs too.
(ppc_elf_size_dynamic_sections): Comment on unnecessary glink
branch table entries.
2016-08-19 Nick Clifton <nickc@redhat.com>
* elf.c (assign_section_numbers): Assign number for the .shstrtab

View file

@ -4390,15 +4390,6 @@ ppc_elf_check_relocs (bfd *abfd,
}
if (h != NULL && h->type == STT_GNU_IFUNC)
{
if (bfd_link_pic (info))
{
info->callbacks->einfo
(_("%P: %H: @local call to ifunc %s\n"),
abfd, sec, rel->r_offset,
h->root.root.string);
bfd_set_error (bfd_error_bad_value);
return FALSE;
}
h->needs_plt = 1;
if (!update_plt_info (abfd, &h->plt.plist, NULL, 0))
return FALSE;
@ -6504,7 +6495,9 @@ ppc_elf_size_dynamic_sections (bfd *output_bfd,
&& htab->elf.dynamic_sections_created)
{
htab->glink_pltresolve = htab->glink->size;
/* Space for the branch table. */
/* Space for the branch table. ??? We don't need entries for
non-dynamic symbols in this table. This case can arise with
static ifuncs or forced local ifuncs. */
htab->glink->size += htab->glink->size / (GLINK_ENTRY_SIZE / 4) - 4;
/* Pad out to align the start of PLTresolve. */
htab->glink->size += -htab->glink->size & (htab->params->ppc476_workaround
@ -8308,6 +8301,26 @@ ppc_elf_relocate_section (bfd *output_bfd,
}
if (ent != NULL)
{
if (bfd_link_pic (info)
&& ent->sec != got2
&& htab->plt_type != PLT_NEW
&& (!htab->elf.dynamic_sections_created
|| h == NULL
|| h->dynindx == -1))
{
/* Uh oh, we are going to create a pic glink stub
for an ifunc (here for h == NULL and later in
finish_dynamic_symbol for h != NULL), and
apparently are using code compiled with
-mbss-plt. The difficulty is that -mbss-plt code
gives no indication via a magic PLTREL24 addend
whether r30 is equal to _GLOBAL_OFFSET_TABLE_ or
is pointing into a .got2 section (and how far
into .got2). */
info->callbacks->einfo
(_("%X%P: %H: unsupported bss-plt -fPIC ifunc %s\n"),
input_bfd, input_section, rel->r_offset, sym_name);
}
if (h == NULL && (ent->plt.offset & 1) == 0)
{
Elf_Internal_Rela rela;
@ -8656,6 +8669,20 @@ ppc_elf_relocate_section (bfd *output_bfd,
TRUE);
goto copy_reloc;
}
if (h != NULL && h->type == STT_GNU_IFUNC && bfd_link_pic (info))
{
/* @local on an ifunc does not really make sense since
the ifunc resolver can take you anywhere. More
seriously, calls to ifuncs must go through a plt call
stub, and for pic the plt call stubs uses r30 to
access the PLT. The problem is that a call that is
local won't have the +32k reloc addend trick marking
-fPIC code, so the linker won't know whether r30 is
_GLOBAL_OFFSET_TABLE_ or pointing into a .got2 section. */
info->callbacks->einfo (_("%X%P: %H: @local call to ifunc %s\n"),
input_bfd, input_section, rel->r_offset,
h->root.root.string);
}
break;
case R_PPC_DTPREL16: