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]

Error on shared lib call to @local ifunc


On powerpc32, making ifuncs have non-default visibility in shared
libraries or pies can result in runtime failures.  The problem is that
if gcc is told that a given function has non-default visibility, then
calls to that function are assumed to be local (which is true) and
thus need not go via a plt call stub (which is false for ifunc).  If
the caller has no other reason to set up the got pointer (r30), code
won't be emitted to do so.  However, a pic plt call stub makes use of
r30 to load the plt entry.  So a call to an ifunc, which always needs
a plt entry, will fail.

This patch makes ld emit an error for the problem case, and allows
calls to non-default visibility ifuncs to work in normal executables.
I also fix some cases where ifuncs fail when using the old bss-plt.

	* elf32-ppc.c (ppc_elf_check_relocs): For @local call to ifunc,
	error when shared and force a plt call otherwise.
	(ppc_elf_size_dynamic_sections): Don't emit DT_PPC_GOT unless
	plt_type == PLT_NEW.
	(ppc_elf_relocate_section): Add missing test to resolve ifuncs to
	the appropriate call stub.

diff --git a/bfd/elf32-ppc.c b/bfd/elf32-ppc.c
index b601f05..61c45d8 100644
--- a/bfd/elf32-ppc.c
+++ b/bfd/elf32-ppc.c
@@ -4283,6 +4283,20 @@ ppc_elf_check_relocs (bfd *abfd,
 	      htab->plt_type = PLT_OLD;
 	      htab->old_bfd = abfd;
 	    }
+	  if (h != NULL && h->type == STT_GNU_IFUNC)
+	    {
+	      if (info->shared)
+		{
+		  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;
+	    }
 	  break;
 
 	  /* This relocation describes the C++ object vtable hierarchy.
@@ -6481,7 +6495,9 @@ ppc_elf_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
 	    return FALSE;
 	}
 
-      if (htab->glink != NULL && htab->glink->size != 0)
+      if (htab->plt_type == PLT_NEW
+	  && htab->glink != NULL
+	  && htab->glink->size != 0)
 	{
 	  if (!add_dynamic_entry (DT_PPC_GOT, 0))
 	    return FALSE;
@@ -7863,7 +7879,8 @@ ppc_elf_relocate_section (bfd *output_bfd,
 	      unresolved_reloc = FALSE;
 	      if (htab->plt_type == PLT_NEW
 		  || !htab->elf.dynamic_sections_created
-		  || h == NULL)
+		  || h == NULL
+		  || h->dynindx == -1)
 		relocation = (htab->glink->output_section->vma
 			      + htab->glink->output_offset
 			      + (ent->glink_offset & ~1));

-- 
Alan Modra
Australia Development Lab, IBM


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