diff options
author | Alan Modra <amodra@gmail.com> | 2016-08-22 10:42:26 +0930 |
---|---|---|
committer | Alan Modra <amodra@gmail.com> | 2016-08-22 10:55:08 +0930 |
commit | 888a7fc3665a67e20da1bce2f865b0ff9ef15842 (patch) | |
tree | a77aa2665fc2ede6e874d4d424dc6d505c2a20c6 | |
parent | ca942b53cec608a3df1a351b504852e4e64c5e90 (diff) | |
download | fsf-binutils-gdb-888a7fc3665a67e20da1bce2f865b0ff9ef15842.zip fsf-binutils-gdb-888a7fc3665a67e20da1bce2f865b0ff9ef15842.tar.gz fsf-binutils-gdb-888a7fc3665a67e20da1bce2f865b0ff9ef15842.tar.bz2 |
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.
-rw-r--r-- | bfd/ChangeLog | 8 | ||||
-rw-r--r-- | bfd/elf32-ppc.c | 47 |
2 files changed, 45 insertions, 10 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog index ea810cd..b588fae 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -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 diff --git a/bfd/elf32-ppc.c b/bfd/elf32-ppc.c index 8d5131a..92299bc 100644 --- a/bfd/elf32-ppc.c +++ b/bfd/elf32-ppc.c @@ -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: |