This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: binutils causes GLIBC ifunc breakage on PowerPC64 ELFv2


On Sun, Aug 17, 2014 at 04:10:05PM +0200, Aurelien Jarno wrote:
> Bisecting the issue I have found the problem has been introduced by this
> commit:
> 
> | commit d1eca1e41ddae8c3cd925be827640de919301432
> | Author: Alan Modra <amodra@gmail.com>
> | Date:   Wed Jul 2 15:07:18 2014 +0930
> | 
> |     Taking an undefined function's address in an executable
> | 
> |     doesn't always mean you need to define a function symbol on plt code.
> |     If all references are in read-write sections, then using dynamic relocs
> |     is OK.

Thanks for tracking this down.

This probably could be fixed by making changes in relocate_section for
ifunc, but it's simpler to disable this optimisation for ifunc.

	* elf64-ppc.c (ppc64_elf_adjust_dynamic_symbol): Don't attempt to
	use dynrelocs for ifunc.
	* elf32-ppc.c (ppc_elf_adjust_dynamic_symbol): Similarly.

diff --git a/bfd/elf64-ppc.c b/bfd/elf64-ppc.c
index 0efc602..ca2dd4c 100644
--- a/bfd/elf64-ppc.c
+++ b/bfd/elf64-ppc.c
@@ -7002,6 +7002,7 @@ ppc64_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
 	     executable on a global entry stub.  A dynamic reloc can
 	     be used instead.  */
 	  if (h->pointer_equality_needed
+	      && h->type != STT_GNU_IFUNC
 	      && !readonly_dynrelocs (h))
 	    {
 	      h->pointer_equality_needed = 0;
diff --git a/bfd/elf32-ppc.c b/bfd/elf32-ppc.c
index e20e804..97f4724 100644
--- a/bfd/elf32-ppc.c
+++ b/bfd/elf32-ppc.c
@@ -5512,9 +5512,12 @@ ppc_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
 	{
 	  /* Taking a function's address in a read/write section
 	     doesn't require us to define the function symbol in the
-	     executable on a global entry stub.  A dynamic reloc can
+	     executable on a plt call stub.  A dynamic reloc can
 	     be used instead.  */
 	  if (h->pointer_equality_needed
+	      && h->type != STT_GNU_IFUNC
+	      && !htab->is_vxworks
+	      && !ppc_elf_hash_entry (h)->has_sda_refs
 	      && !readonly_dynrelocs (h))
 	    {
 	      h->pointer_equality_needed = 0;

-- 
Alan Modra


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]