This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
Re: PowerpC pointer_equality_needed optimisation
- From: "H.J. Lu" <hjl dot tools at gmail dot com>
- To: binutils at sourceware dot org
- Date: Sat, 23 Feb 2008 14:50:30 -0800
- Subject: Re: PowerpC pointer_equality_needed optimisation
- References: <20080223015227.GE9407@bubble.grove.modra.org>
Hi Alan,
Is this related to
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=32219
Does the testcase work with PIE on PPC?
Thanks.
H.J.
On Fri, Feb 22, 2008 at 5:52 PM, Alan Modra <amodra@bigpond.net.au> wrote:
> This implements Jakub's pointer_equality_needed optimisation for
> PowerPC. x86 and x86_64 maintainers might like to copy the warning
> I added for weak symbols in ppc_elf_finish_dynamic_symbol.
>
> * elf32-ppc.c (ppc_elf_copy_indirect_symbol): Copy
> pointer_equality_needed.
> (ppc_elf_check_relocs): Split out non-branch relocs from others
> that might emit dynamic relocs. Set pointer_equality_needed
> for their symbols. Don't set non_got_ref on branch reloc symbols.
> (ppc_elf_hash_symbol): New function.
> (elf_backend_hash_symbol): Define.
> (ppc_elf_finish_dynamic_symbol): Handle pointer_equality_needed.
> Error if pointer_equality_needed on weak plt symbol.
>
> Index: bfd/elf32-ppc.c
> ===================================================================
> RCS file: /cvs/src/src/bfd/elf32-ppc.c,v
> retrieving revision 1.229
> diff -u -p -r1.229 elf32-ppc.c
> --- bfd/elf32-ppc.c 20 Feb 2008 17:42:35 -0000 1.229
> +++ bfd/elf32-ppc.c 23 Feb 2008 01:41:44 -0000
> @@ -2696,6 +2696,7 @@ ppc_elf_copy_indirect_symbol (struct bfd
> edir->elf.ref_regular |= eind->elf.ref_regular;
> edir->elf.ref_regular_nonweak |= eind->elf.ref_regular_nonweak;
> edir->elf.needs_plt |= eind->elf.needs_plt;
> + edir->elf.pointer_equality_needed |= eind->elf.pointer_equality_needed;
>
> /* If we were called to copy over info for a weak sym, that's all. */
> if (eind->elf.root.type != bfd_link_hash_indirect)
> @@ -3388,6 +3389,26 @@ ppc_elf_check_relocs (bfd *abfd,
> info->flags |= DF_STATIC_TLS;
> goto dodyn;
>
> + case R_PPC_ADDR32:
> + case R_PPC_ADDR16:
> + case R_PPC_ADDR16_LO:
> + case R_PPC_ADDR16_HI:
> + case R_PPC_ADDR16_HA:
> + case R_PPC_UADDR32:
> + case R_PPC_UADDR16:
> + if (h != NULL && !info->shared)
> + {
> + /* We may need a plt entry if the symbol turns out to be
> + a function defined in a dynamic object. */
> + if (!update_plt_info (abfd, h, NULL, 0))
> + return FALSE;
> +
> + /* We may need a copy reloc too. */
> + h->non_got_ref = 1;
> + h->pointer_equality_needed = 1;
> + }
> + goto dodyn;
> +
> case R_PPC_REL32:
> if (h == NULL
> && got2 != NULL
> @@ -3432,17 +3453,10 @@ ppc_elf_check_relocs (bfd *abfd,
> }
> /* fall through */
>
> - case R_PPC_ADDR32:
> case R_PPC_ADDR24:
> - case R_PPC_ADDR16:
> - case R_PPC_ADDR16_LO:
> - case R_PPC_ADDR16_HI:
> - case R_PPC_ADDR16_HA:
> case R_PPC_ADDR14:
> case R_PPC_ADDR14_BRTAKEN:
> case R_PPC_ADDR14_BRNTAKEN:
> - case R_PPC_UADDR32:
> - case R_PPC_UADDR16:
> dodyn1:
> if (h != NULL && !info->shared)
> {
> @@ -3450,9 +3464,6 @@ ppc_elf_check_relocs (bfd *abfd,
> a function defined in a dynamic object. */
> if (!update_plt_info (abfd, h, NULL, 0))
> return FALSE;
> -
> - /* We may need a copy reloc too. */
> - h->non_got_ref = 1;
> }
>
> dodyn:
> @@ -5186,6 +5197,20 @@ ppc_elf_size_dynamic_sections (bfd *outp
>
> return TRUE;
> }
> +
> +/* Return TRUE if symbol should be hashed in the `.gnu.hash' section. */
> +
> +static bfd_boolean
> +ppc_elf_hash_symbol (struct elf_link_hash_entry *h)
> +{
> + if (h->plt.plist != NULL
> + && !h->def_regular
> + && (!h->pointer_equality_needed
> + || !h->ref_regular_nonweak))
> + return FALSE;
> +
> + return _bfd_elf_hash_symbol (h);
> +}
>
> #define ARRAY_SIZE(a) (sizeof (a) / sizeof ((a)[0]))
>
> @@ -7127,15 +7152,28 @@ ppc_elf_finish_dynamic_symbol (bfd *outp
>
> if (!h->def_regular)
> {
> - /* Mark the symbol as undefined, rather than as defined in
> - the .plt section. Leave the value alone. */
> + /* Mark the symbol as undefined, rather than as
> + defined in the .plt section. Leave the value if
> + there were any relocations where pointer equality
> + matters (this is a clue for the dynamic linker, to
> + make function pointer comparisons work between an
> + application and shared library), otherwise set it
> + to zero. */
> sym->st_shndx = SHN_UNDEF;
> - /* If the symbol is weak, we do need to clear the value.
> - Otherwise, the PLT entry would provide a definition for
> - the symbol even if the symbol wasn't defined anywhere,
> - and so the symbol would never be NULL. */
> - if (!h->ref_regular_nonweak)
> + if (!h->pointer_equality_needed)
> sym->st_value = 0;
> + else if (!h->ref_regular_nonweak)
> + {
> + /* Choose your poison. We must have either text
> + dynamic relocations, broken function pointer
> + comparisons, or broken tests for a NULL
> + function pointer. */
> + (*_bfd_error_handler)
> + (_("weak reference to %s in non-pic code"
> + " will break function pointer comparisons"),
> + h->root.root.string);
> + sym->st_value = 0;
> + }
> }
> doneone = TRUE;
> }
> @@ -7687,6 +7725,7 @@ ppc_elf_finish_dynamic_sections (bfd *ou
> #define elf_backend_adjust_dynamic_symbol ppc_elf_adjust_dynamic_symbol
> #define elf_backend_add_symbol_hook ppc_elf_add_symbol_hook
> #define elf_backend_size_dynamic_sections ppc_elf_size_dynamic_sections
> +#define elf_backend_hash_symbol ppc_elf_hash_symbol
> #define elf_backend_finish_dynamic_symbol ppc_elf_finish_dynamic_symbol
> #define elf_backend_finish_dynamic_sections ppc_elf_finish_dynamic_sections
> #define elf_backend_fake_sections ppc_elf_fake_sections
>
> --
> Alan Modra
> Australia Development Lab, IBM
>