94a2ac6
diff -rup ../binutils-2.19.51.0.14.original/bfd/ChangeLog bfd/ChangeLog
94a2ac6
--- ../binutils-2.19.51.0.14.original/bfd/ChangeLog	2010-02-08 15:39:17.000000000 +0000
94a2ac6
+++ bfd/ChangeLog	2010-02-08 15:40:38.000000000 +0000
94a2ac6
@@ -1,3 +1,30 @@
94a2ac6
+2010-02-08  Nick Clifton  <nickc@redhat.com>
94a2ac6
+
94a2ac6
+	BZ 562249
94a2ac6
+	Import this patch from the mainline:
94a2ac6
+
94a2ac6
+	2009-12-17  Alan Modra  <amodra@bigpond.net.au>
94a2ac6
+
94a2ac6
+	PR ld/11088
94a2ac6
+	* elf64-ppc.c (ppc64_elf_gc_sweep_hook): Don't abort if symbol
94a2ac6
+	hiding has nulled out plt.plist.
94a2ac6
+
94a2ac6
+	PR ld/11088
94a2ac6
+	* elf32-ppc.c (update_plt_info): Clear sec here when addend is
94a2ac6
+	less than 32768..
94a2ac6
+	(ppc_elf_check_relocs): ..rather than doing so here.  Ignore new
94a2ac6
+	relax relocs.
94a2ac6
+	(ppc_elf_gc_sweep_hook): Don't segfault when symbol hiding has
94a2ac6
+	removed plt_entry records.
94a2ac6
+	(ppc_elf_tls_setup): Handle PIE calls to __tls_get_addr correctly.
94a2ac6
+	(ppc_elf_tls_optimize): Likewise.  Also dec __tls_get_addr refcount
94a2ac6
+	when optimizing code using new tlsgd and tlsld marker relocs.
94a2ac6
+	(ppc_elf_relax_section): Differentiate relaxed PLTREL24 relocs
94a2ac6
+	from ADDR24 relocs using plt or glink.  Don't clear the addend
94a2ac6
+	for R_PPC_RELAX_PLTREL24.
94a2ac6
+	(ppc_elf_relocate_section): Correctly handle addends on relaxed
94a2ac6
+	PLTREL24 relocs.
94a2ac6
+
94a2ac6
 2009-07-22  H.J. Lu  <hongjiu.lu@intel.com>
94a2ac6
 
94a2ac6
 	 PR ld/10433
94a2ac6
diff -rup ../binutils-2.19.51.0.14.original/bfd/elf32-ppc.c bfd/elf32-ppc.c
94a2ac6
--- ../binutils-2.19.51.0.14.original/bfd/elf32-ppc.c	2010-02-08 15:39:17.000000000 +0000
94a2ac6
+++ bfd/elf32-ppc.c	2010-02-08 16:01:59.000000000 +0000
94a2ac6
@@ -3309,9 +3309,13 @@ update_plt_info (bfd *abfd, struct plt_e
94a2ac6
 {
94a2ac6
   struct plt_entry *ent;
94a2ac6
 
94a2ac6
+  if (addend < 32768)
94a2ac6
+    sec = NULL;
94a2ac6
+
94a2ac6
   for (ent = *plist; ent != NULL; ent = ent->next)
94a2ac6
     if (ent->sec == sec && ent->addend == addend)
94a2ac6
       break;
94a2ac6
+
94a2ac6
   if (ent == NULL)
94a2ac6
     {
94a2ac6
       bfd_size_type amt = sizeof (*ent);
94a2ac6
@@ -3500,8 +3504,7 @@ ppc_elf_check_relocs (bfd *abfd,
94a2ac6
 		  ppc_elf_tdata (abfd)->makes_plt_call = 1;
94a2ac6
 		  addend = rel->r_addend;
94a2ac6
 		}
94a2ac6
-	      if (!update_plt_info (abfd, ifunc,
94a2ac6
-				    addend < 32768 ? NULL : got2, addend))
94a2ac6
+	      if (!update_plt_info (abfd, ifunc, got2, addend))
94a2ac6
 		return FALSE;
94a2ac6
 
94a2ac6
 	      if (htab->glink == NULL)
94a2ac6
@@ -3727,8 +3730,7 @@ ppc_elf_check_relocs (bfd *abfd,
94a2ac6
 		  addend = rel->r_addend;
94a2ac6
 		}
94a2ac6
 	      h->needs_plt = 1;
94a2ac6
-	      if (!update_plt_info (abfd, &h->plt.plist,
94a2ac6
-				    addend < 32768 ? NULL : got2, addend))
94a2ac6
+	      if (!update_plt_info (abfd, &h->plt.plist, got2, addend))
94a2ac6
 		return FALSE;
94a2ac6
 	    }
94a2ac6
 	  break;
94a2ac6
@@ -3759,10 +3761,9 @@ ppc_elf_check_relocs (bfd *abfd,
94a2ac6
 	case R_PPC_EMB_MRKREF:
94a2ac6
 	case R_PPC_NONE:
94a2ac6
 	case R_PPC_max:
94a2ac6
-	case R_PPC_RELAX32:
94a2ac6
-	case R_PPC_RELAX32PC:
94a2ac6
-	case R_PPC_RELAX32_PLT:
94a2ac6
-	case R_PPC_RELAX32PC_PLT:
94a2ac6
+	case R_PPC_RELAX:
94a2ac6
+	case R_PPC_RELAX_PLT:
94a2ac6
+	case R_PPC_RELAX_PLTREL24:
94a2ac6
 	  break;
94a2ac6
 
94a2ac6
 	  /* These should only appear in dynamic objects.  */
94a2ac6
@@ -4431,7 +4432,8 @@ ppc_elf_gc_sweep_hook (bfd *abfd,
94a2ac6
 	    {
94a2ac6
 	      bfd_vma addend = r_type == R_PPC_PLTREL24 ? rel->r_addend : 0;
94a2ac6
 	      struct plt_entry *ent = find_plt_ent (ifunc, got2, addend);
94a2ac6
-	      if (ent->plt.refcount > 0)
94a2ac6
+
94a2ac6
+	      if (ent != NULL && ent->plt.refcount > 0)
94a2ac6
 		ent->plt.refcount -= 1;
94a2ac6
 	      continue;
94a2ac6
 	    }
94a2ac6
@@ -4505,7 +4507,8 @@ ppc_elf_gc_sweep_hook (bfd *abfd,
94a2ac6
 	      bfd_vma addend = r_type == R_PPC_PLTREL24 ? rel->r_addend : 0;
94a2ac6
 	      struct plt_entry *ent = find_plt_ent (&h->plt.plist,
94a2ac6
 						    got2, addend);
94a2ac6
-	      if (ent->plt.refcount > 0)
94a2ac6
+
94a2ac6
+	      if (ent != NULL && ent->plt.refcount > 0)
94a2ac6
 		ent->plt.refcount -= 1;
94a2ac6
 	    }
94a2ac6
 	  break;
94a2ac6
@@ -4591,6 +4594,7 @@ ppc_elf_tls_optimize (bfd *obfd ATTRIBUT
94a2ac6
       {
94a2ac6
 	Elf_Internal_Sym *locsyms = NULL;
94a2ac6
 	Elf_Internal_Shdr *symtab_hdr = &elf_symtab_hdr (ibfd);
94a2ac6
+	asection *got2 = bfd_get_section_by_name (ibfd, ".got2");
94a2ac6
 
94a2ac6
 	for (sec = ibfd->sections; sec != NULL; sec = sec->next)
94a2ac6
 	  if (sec->has_tls_reloc && !bfd_is_abs_section (sec->output_section))
94a2ac6
@@ -4684,6 +4688,13 @@ ppc_elf_tls_optimize (bfd *obfd ATTRIBUT
94a2ac6
 		      else
94a2ac6
 			continue;
94a2ac6
 
94a2ac6
+		    case R_PPC_TLSGD:
94a2ac6
+		    case R_PPC_TLSLD:
94a2ac6
+		      expecting_tls_get_addr = 2;
94a2ac6
+		      tls_set = 0;
94a2ac6
+		      tls_clear = 0;
94a2ac6
+		      break;
94a2ac6
+
94a2ac6
 		    default:
94a2ac6
 		      continue;
94a2ac6
 		    }
94a2ac6
@@ -4691,7 +4702,8 @@ ppc_elf_tls_optimize (bfd *obfd ATTRIBUT
94a2ac6
 		  if (pass == 0)
94a2ac6
 		    {
94a2ac6
 		      if (!expecting_tls_get_addr
94a2ac6
-			  || !sec->has_tls_get_addr_call)
94a2ac6
+			  || (expecting_tls_get_addr == 1
94a2ac6
+			      && ! sec->has_tls_get_addr_call))
94a2ac6
 			continue;
94a2ac6
 
94a2ac6
 		      if (rel + 1 < relend
94a2ac6
@@ -4707,6 +4719,23 @@ ppc_elf_tls_optimize (bfd *obfd ATTRIBUT
94a2ac6
 		      break;
94a2ac6
 		    }
94a2ac6
 
94a2ac6
+		  if (expecting_tls_get_addr)
94a2ac6
+		    {
94a2ac6
+		      struct plt_entry *ent;
94a2ac6
+		      bfd_vma addend = 0;
94a2ac6
+
94a2ac6
+		      if (info->shared
94a2ac6
+			  && ELF32_R_TYPE (rel[1].r_info) == R_PPC_PLTREL24)
94a2ac6
+			addend = rel[1].r_addend;
94a2ac6
+		      ent = find_plt_ent (&htab->tls_get_addr->plt.plist,
94a2ac6
+					  got2, addend);
94a2ac6
+		      if (ent != NULL && ent->plt.refcount > 0)
94a2ac6
+			ent->plt.refcount -= 1;
94a2ac6
+
94a2ac6
+		      if (expecting_tls_get_addr == 2)
94a2ac6
+			continue;
94a2ac6
+		    }
94a2ac6
+
94a2ac6
 		  if (h != NULL)
94a2ac6
 		    {
94a2ac6
 		      tls_mask = &ppc_elf_hash_entry (h)->tls_mask;
94a2ac6
@@ -4751,16 +4780,6 @@ ppc_elf_tls_optimize (bfd *obfd ATTRIBUT
94a2ac6
 			*got_count -= 1;
94a2ac6
 		    }
94a2ac6
 
94a2ac6
-		  if (expecting_tls_get_addr)
94a2ac6
-		    {
94a2ac6
-		      struct plt_entry *ent;
94a2ac6
-
94a2ac6
-		      ent = find_plt_ent (&htab->tls_get_addr->plt.plist,
94a2ac6
-					  NULL, 0);
94a2ac6
-		      if (ent != NULL && ent->plt.refcount > 0)
94a2ac6
-			ent->plt.refcount -= 1;
94a2ac6
-		    }
94a2ac6
-
94a2ac6
 		  *tls_mask |= tls_set;
94a2ac6
 		  *tls_mask &= ~tls_clear;
94a2ac6
 		}
94a2ac6
@@ -6098,28 +6117,29 @@ ppc_elf_relax_section (bfd *abfd,
94a2ac6
 	    {
94a2ac6
 	      size = 4 * ARRAY_SIZE (shared_stub_entry);
94a2ac6
 	      insn_offset = 12;
94a2ac6
-	      stub_rtype = R_PPC_RELAX32PC;
94a2ac6
 	    }
94a2ac6
 	  else
94a2ac6
 	    {
94a2ac6
 	      size = 4 * ARRAY_SIZE (stub_entry);
94a2ac6
 	      insn_offset = 0;
94a2ac6
-	      stub_rtype = R_PPC_RELAX32;
94a2ac6
 	    }
94a2ac6
 
94a2ac6
-	  if (R_PPC_RELAX32_PLT - R_PPC_RELAX32
94a2ac6
-	      != R_PPC_RELAX32PC_PLT - R_PPC_RELAX32PC)
94a2ac6
-	    abort ();
94a2ac6
+	  stub_rtype = R_PPC_RELAX;
94a2ac6
 	  if (tsec == htab->plt
94a2ac6
 	      || tsec == htab->glink)
94a2ac6
-	    stub_rtype += R_PPC_RELAX32_PLT - R_PPC_RELAX32;
94a2ac6
+	    {
94a2ac6
+	      stub_rtype = R_PPC_RELAX_PLT;
94a2ac6
+	      if (r_type == R_PPC_PLTREL24)
94a2ac6
+		stub_rtype = R_PPC_RELAX_PLTREL24;
94a2ac6
+	    }
94a2ac6
 
94a2ac6
 	  /* Hijack the old relocation.  Since we need two
94a2ac6
 	     relocations for this use a "composite" reloc.  */
94a2ac6
 	  irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
94a2ac6
 				       stub_rtype);
94a2ac6
 	  irel->r_offset = trampoff + insn_offset;
94a2ac6
-	  if (r_type == R_PPC_PLTREL24)
94a2ac6
+	  if (r_type == R_PPC_PLTREL24
94a2ac6
+	      && stub_rtype != R_PPC_RELAX_PLTREL24)
94a2ac6
 	    irel->r_addend = 0;
94a2ac6
 
94a2ac6
 	  /* Record the fixup so we don't do it again this section.  */
94a2ac6
@@ -6289,7 +6309,7 @@ ppc_elf_relax_section (bfd *abfd,
94a2ac6
     {
94a2ac6
       /* Convert the internal relax relocs to external form.  */
94a2ac6
       for (irel = internal_relocs; irel < irelend; irel++)
94a2ac6
-	if (ELF32_R_TYPE (irel->r_info) == R_PPC_RELAX32)
94a2ac6
+	if (ELF32_R_TYPE (irel->r_info) == R_PPC_RELAX)
94a2ac6
 	  {
94a2ac6
 	    unsigned long r_symndx = ELF32_R_SYM (irel->r_info);
94a2ac6
 
94a2ac6
@@ -7461,32 +7481,36 @@ ppc_elf_relocate_section (bfd *output_bf
94a2ac6
 	    }
94a2ac6
 	  break;
94a2ac6
 
94a2ac6
-	case R_PPC_RELAX32PC_PLT:
94a2ac6
-	case R_PPC_RELAX32_PLT:
94a2ac6
-	  {
94a2ac6
-	    struct plt_entry *ent = find_plt_ent (&h->plt.plist, got2, addend);
94a2ac6
-
94a2ac6
-	    if (htab->plt_type == PLT_NEW)
94a2ac6
-	      relocation = (htab->glink->output_section->vma
94a2ac6
-			    + htab->glink->output_offset
94a2ac6
-			    + ent->glink_offset);
94a2ac6
-	    else
94a2ac6
-	      relocation = (htab->plt->output_section->vma
94a2ac6
-			    + htab->plt->output_offset
94a2ac6
-			    + ent->plt.offset);
94a2ac6
-	  }
94a2ac6
-	  if (r_type == R_PPC_RELAX32_PLT)
94a2ac6
-	    goto relax32;
94a2ac6
-	  /* Fall thru */
94a2ac6
+	case R_PPC_RELAX_PLT:
94a2ac6
+	case R_PPC_RELAX_PLTREL24:
94a2ac6
+	  if (h != NULL)
94a2ac6
+	    {
94a2ac6
+	      struct plt_entry *ent;
94a2ac6
+	      bfd_vma got2_addend = 0;
94a2ac6
 
94a2ac6
-	case R_PPC_RELAX32PC:
94a2ac6
-	  relocation -= (input_section->output_section->vma
94a2ac6
-			 + input_section->output_offset
94a2ac6
-			 + rel->r_offset - 4);
94a2ac6
+	      if (r_type == R_PPC_RELAX_PLTREL24)
94a2ac6
+		{
94a2ac6
+		  if (info->shared)
94a2ac6
+		    got2_addend = addend;
94a2ac6
+		  addend = 0;
94a2ac6
+		}
94a2ac6
+	      ent = find_plt_ent (&h->plt.plist, got2, got2_addend);
94a2ac6
+	      if (htab->plt_type == PLT_NEW)
94a2ac6
+		relocation = (htab->glink->output_section->vma
94a2ac6
+			      + htab->glink->output_offset
94a2ac6
+			      + ent->glink_offset);
94a2ac6
+	      else
94a2ac6
+		relocation = (htab->plt->output_section->vma
94a2ac6
+			      + htab->plt->output_offset
94a2ac6
+			      + ent->plt.offset);
94a2ac6
+	    }
94a2ac6
 	  /* Fall thru */
94a2ac6
 
94a2ac6
-	case R_PPC_RELAX32:
94a2ac6
-	relax32:
94a2ac6
+	case R_PPC_RELAX:
94a2ac6
+	  if (info->shared)
94a2ac6
+	    relocation -= (input_section->output_section->vma
94a2ac6
+			   + input_section->output_offset
94a2ac6
+			   + rel->r_offset - 4);
94a2ac6
 	  {
94a2ac6
 	    unsigned long t0;
94a2ac6
 	    unsigned long t1;
94a2ac6
diff -rup ../binutils-2.19.51.0.14.original/include/elf/ppc.h include/elf/ppc.h
94a2ac6
--- ../binutils-2.19.51.0.14.original/include/elf/ppc.h	2010-02-08 15:39:06.000000000 +0000
94a2ac6
+++ include/elf/ppc.h	2010-02-08 16:47:05.000000000 +0000
94a2ac6
@@ -73,10 +73,9 @@ START_RELOC_NUMBERS (elf_ppc_reloc_type)
94a2ac6
 
94a2ac6
 #ifndef RELOC_MACROS_GEN_FUNC
94a2ac6
 /* Fake relocations for branch stubs, only used internally by ld.  */
94a2ac6
-  RELOC_NUMBER (R_PPC_RELAX32,		 48)
94a2ac6
-  RELOC_NUMBER (R_PPC_RELAX32PC,	 49)
94a2ac6
-  RELOC_NUMBER (R_PPC_RELAX32_PLT,	 50)
94a2ac6
-  RELOC_NUMBER (R_PPC_RELAX32PC_PLT,	 51)
94a2ac6
+  RELOC_NUMBER (R_PPC_RELAX,		 48)
94a2ac6
+  RELOC_NUMBER (R_PPC_RELAX_PLT,	 49)
94a2ac6
+  RELOC_NUMBER (R_PPC_RELAX_PLTREL24,	 50)
94a2ac6
 #endif
94a2ac6
 
94a2ac6
   /* Relocs added to support TLS.  */
26321fc
--- ../binutils-2.19.51.0.14.original/bfd/elf64-ppc.c	2010-02-08 15:39:17.000000000 +0000
26321fc
+++ bfd/elf64-ppc.c	2010-02-09 15:36:43.000000000 +0000
26321fc
@@ -5640,9 +5640,7 @@ ppc64_elf_gc_sweep_hook (bfd *abfd, stru
26321fc
 	      for (ent = *ifunc; ent != NULL; ent = ent->next)
26321fc
 		if (ent->addend == rel->r_addend)
26321fc
 		  break;
26321fc
-	      if (ent == NULL)
26321fc
-		abort ();
26321fc
-	      if (ent->plt.refcount > 0)
26321fc
+	      if (ent != NULL && ent->plt.refcount > 0)
26321fc
 		ent->plt.refcount -= 1;
26321fc
 	      continue;
26321fc
 	    }
26321fc
@@ -5721,9 +5719,7 @@ ppc64_elf_gc_sweep_hook (bfd *abfd, stru
26321fc
 	      for (ent = h->plt.plist; ent != NULL; ent = ent->next)
26321fc
 		if (ent->addend == rel->r_addend)
26321fc
 		  break;
26321fc
-	      if (ent == NULL)
26321fc
-		abort ();
26321fc
-	      if (ent->plt.refcount > 0)
26321fc
+	      if (ent != NULL && ent->plt.refcount > 0)
26321fc
 		ent->plt.refcount -= 1;
26321fc
 	    }
26321fc
 	  break;