PowerPC64 PLT vs. mixed objects

Alan Modra amodra@bigpond.net.au
Fri Feb 11 15:59:00 GMT 2005


On Fri, Feb 11, 2005 at 02:16:28PM +1030, Alan Modra wrote:
> We were generating duplicate PLT entries when the linker was fed a mix
> of dot-sym and no-dot-sym objects.

Sigh.  Yet another problem with mixtures of dot-sym and no-dot-sym
object files.  This time it was a bad decision regarding the need for
toc adjusting stubs on calls into a section of an old-style object.
The old-style object in question made plt calls, so needed r2 to be
correct, but the code checking for plt calls ignored all undefined
syms.  With an old-style object making calls to a new-style dynamic lib,
the symbol on the branch reloc will stay undefined.  A bad r2 value
results in a wild call which usually segfaults.

	* elf64-ppc.c (toc_adjusting_stub_needed): Return true for
	old-style branches to undefined dot-symbols which will be
	satisfied by a plt call.

Index: bfd/elf64-ppc.c
===================================================================
RCS file: /cvs/src/src/bfd/elf64-ppc.c,v
retrieving revision 1.190
diff -u -p -r1.190 elf64-ppc.c
--- bfd/elf64-ppc.c	11 Feb 2005 03:47:40 -0000	1.190
+++ bfd/elf64-ppc.c	11 Feb 2005 14:10:16 -0000
@@ -8361,13 +8361,27 @@ toc_adjusting_stub_needed (struct bfd_li
 	  break;
 	}
 
-      /* Ignore branches to undefined syms.  */
+      /* Calls to dynamic lib functions go through a plt call stub
+	 that uses r2.  Branches to undefined symbols might be a call
+	 using old-style dot symbols that can be satisfied by a plt
+	 call into a new-style dynamic library.  */
       if (sym_sec == NULL)
-	continue;
+	{
+	  struct ppc_link_hash_entry *eh = (struct ppc_link_hash_entry *) h;
+	  if (eh != NULL
+	      && eh->oh != NULL
+	      && eh->oh->elf.plt.plist != NULL)
+	    {
+	      ret = 1;
+	      break;
+	    }
 
-      /* Calls to dynamic lib functions go through a plt call stub
-	 that uses r2.  Assume branches to other sections not included
-	 in the link need stubs too, to cover -R and absolute syms.  */
+	  /* Ignore other undefined symbols.  */
+	  continue;
+	}
+
+      /* Assume branches to other sections not included in the link need
+	 stubs too, to cover -R and absolute syms.  */
       if (sym_sec->output_section == NULL)
 	{
 	  ret = 1;
@@ -8389,7 +8403,6 @@ toc_adjusting_stub_needed (struct bfd_li
       opd_adjust = get_opd_info (sym_sec);
       if (opd_adjust != NULL)
 	{
-
 	  if (h == NULL)
 	    {
 	      long adjust;

-- 
Alan Modra
IBM OzLabs - Linux Technology Centre



More information about the Binutils mailing list