This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
ppc32 -fPIC and ifunc
- From: Alan Modra <amodra at gmail dot com>
- To: binutils at sourceware dot org
- Date: Mon, 4 Mar 2013 22:41:09 +1030
- Subject: ppc32 -fPIC and ifunc
I noticed today that ppc32 -fPIC code calling STT_GNU_IFUNC functions
was seriously broken by BFD ld, with the branch and link to the plt
call stub missing the stub by 32k. Fixed by ensuring the addend on
R_PPC_PLTREL24 relocs is zeroed before applying.
The first hunk of this patch also tweaks ld -r adjustment of these
addends, for consistency with other code. The addends are either zero
or >= 32768, so there is no real functional change there.
Applying mainline and 2.23
* elf32-ppc.c (ppc_elf_relocate_section <R_PPC_PLTREL24>): Adjust
non-zero addends when relocatable, rather than addends >= 32768.
Always zero "addend" before applying relocation.
Index: bfd/elf32-ppc.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-ppc.c,v
retrieving revision 1.326
diff -u -p -r1.326 elf32-ppc.c
--- bfd/elf32-ppc.c 21 Feb 2013 03:02:29 -0000 1.326
+++ bfd/elf32-ppc.c 4 Mar 2013 10:03:56 -0000
@@ -7472,7 +7472,7 @@ ppc_elf_relocate_section (bfd *output_bf
{
if (got2 != NULL
&& r_type == R_PPC_PLTREL24
- && rel->r_addend >= 32768)
+ && rel->r_addend != 0)
{
/* R_PPC_PLTREL24 is rather special. If non-zero, the
addend specifies the GOT pointer offset within .got2. */
@@ -8477,33 +8477,37 @@ ppc_elf_relocate_section (bfd *output_bf
break;
case R_PPC_PLTREL24:
- if (h == NULL || ifunc != NULL)
- break;
- /* Relocation is to the entry for this symbol in the
- procedure linkage table. */
- {
- struct plt_entry *ent = find_plt_ent (&h->plt.plist, got2,
- info->shared ? addend : 0);
- addend = 0;
- if (ent == NULL
- || htab->plt == NULL)
- {
- /* We didn't make a PLT entry for this symbol. This
- happens when statically linking PIC code, or when
- using -Bsymbolic. */
- break;
- }
+ if (h != NULL && ifunc == NULL)
+ {
+ struct plt_entry *ent = find_plt_ent (&h->plt.plist, got2,
+ info->shared ? addend : 0);
+ if (ent == NULL
+ || htab->plt == NULL)
+ {
+ /* We didn't make a PLT entry for this symbol. This
+ happens when statically linking PIC code, or when
+ using -Bsymbolic. */
+ }
+ else
+ {
+ /* Relocation is to the entry for this symbol in the
+ procedure linkage table. */
+ unresolved_reloc = FALSE;
+ if (htab->plt_type == PLT_NEW)
+ relocation = (htab->glink->output_section->vma
+ + htab->glink->output_offset
+ + ent->glink_offset);
+ else
+ relocation = (htab->plt->output_section->vma
+ + htab->plt->output_offset
+ + ent->plt.offset);
+ }
+ }
- unresolved_reloc = FALSE;
- if (htab->plt_type == PLT_NEW)
- relocation = (htab->glink->output_section->vma
- + htab->glink->output_offset
- + ent->glink_offset);
- else
- relocation = (htab->plt->output_section->vma
- + htab->plt->output_offset
- + ent->plt.offset);
- }
+ /* R_PPC_PLTREL24 is rather special. If non-zero, the
+ addend specifies the GOT pointer offset within .got2.
+ Don't apply it to the relocation field. */
+ addend = 0;
break;
/* Relocate against _SDA_BASE_. */
--
Alan Modra
Australia Development Lab, IBM