[oe-commits] Jeremy Lainé : binutils-2.20: add patch for ld segfault on powerpc

git version control git at git.openembedded.org
Tue Dec 29 08:16:43 UTC 2009


Module: openembedded.git
Branch: shr/merge
Commit: b9368e612020a4f11e4abbab78da967c0e409058
URL:    http://gitweb.openembedded.net/?p=openembedded.git&a=commit;h=b9368e612020a4f11e4abbab78da967c0e409058

Author: Jeremy Lainé <jeremy.laine at bolloretelecom.eu>
Date:   Mon Dec 28 22:09:58 2009 +0100

binutils-2.20: add patch for ld segfault on powerpc

---

 .../binutils-2.20/binutils-powerpc-pr11088.patch   |  275 ++++++++++++++++++++
 recipes/binutils/binutils_2.20.bb                  |    7 +-
 2 files changed, 280 insertions(+), 2 deletions(-)

diff --git a/recipes/binutils/binutils-2.20/binutils-powerpc-pr11088.patch b/recipes/binutils/binutils-2.20/binutils-powerpc-pr11088.patch
new file mode 100644
index 0000000..d5be176
--- /dev/null
+++ b/recipes/binutils/binutils-2.20/binutils-powerpc-pr11088.patch
@@ -0,0 +1,275 @@
+Fix ld segfault when compiling Qt 4.6.0 on powerpc. See:
+
+http://sourceware.org/bugzilla/show_bug.cgi?id=11088
+
+===================================================================
+RCS file: /cvs/src/src/include/elf/ppc.h,v
+retrieving revision 1.26
+retrieving revision 1.27
+diff -u -r1.26 -r1.27
+--- src/include/elf/ppc.h	2009/09/21 11:51:01	1.26
++++ src/include/elf/ppc.h	2009/12/17 05:45:25	1.27
+@@ -73,10 +73,9 @@
+ 
+ #ifndef RELOC_MACROS_GEN_FUNC
+ /* Fake relocations for branch stubs, only used internally by ld.  */
+-  RELOC_NUMBER (R_PPC_RELAX32,		 48)
+-  RELOC_NUMBER (R_PPC_RELAX32PC,	 49)
+-  RELOC_NUMBER (R_PPC_RELAX32_PLT,	 50)
+-  RELOC_NUMBER (R_PPC_RELAX32PC_PLT,	 51)
++  RELOC_NUMBER (R_PPC_RELAX,		 48)
++  RELOC_NUMBER (R_PPC_RELAX_PLT,	 49)
++  RELOC_NUMBER (R_PPC_RELAX_PLTREL24,	 50)
+ #endif
+ 
+   /* Relocs added to support TLS.  */
+===================================================================
+RCS file: /cvs/src/src/bfd/elf32-ppc.c,v
+retrieving revision 1.272
+retrieving revision 1.273
+diff -u -r1.272 -r1.273
+--- src/bfd/elf32-ppc.c	2009/12/11 13:42:02	1.272
++++ src/bfd/elf32-ppc.c	2009/12/17 05:45:25	1.273
+@@ -3323,6 +3323,8 @@
+ {
+   struct plt_entry *ent;
+ 
++  if (addend < 32768)
++    sec = NULL;
+   for (ent = *plist; ent != NULL; ent = ent->next)
+     if (ent->sec == sec && ent->addend == addend)
+       break;
+@@ -3508,8 +3510,7 @@
+ 		      if (info->shared)
+ 			addend = rel->r_addend;
+ 		    }
+-		  if (!update_plt_info (abfd, ifunc,
+-					addend < 32768 ? NULL : got2, addend))
++		  if (!update_plt_info (abfd, ifunc, got2, addend))
+ 		    return FALSE;
+ 		}
+ 	    }
+@@ -3748,8 +3749,7 @@
+ 		    addend = rel->r_addend;
+ 		}
+ 	      h->needs_plt = 1;
+-	      if (!update_plt_info (abfd, &h->plt.plist,
+-				    addend < 32768 ? NULL : got2, addend))
++	      if (!update_plt_info (abfd, &h->plt.plist, got2, addend))
+ 		return FALSE;
+ 	    }
+ 	  break;
+@@ -3780,10 +3780,9 @@
+ 	case R_PPC_EMB_MRKREF:
+ 	case R_PPC_NONE:
+ 	case R_PPC_max:
+-	case R_PPC_RELAX32:
+-	case R_PPC_RELAX32PC:
+-	case R_PPC_RELAX32_PLT:
+-	case R_PPC_RELAX32PC_PLT:
++	case R_PPC_RELAX:
++	case R_PPC_RELAX_PLT:
++	case R_PPC_RELAX_PLTREL24:
+ 	  break;
+ 
+ 	  /* These should only appear in dynamic objects.  */
+@@ -4486,7 +4485,7 @@
+ 		  struct plt_entry *ent;
+ 
+ 		  ent = find_plt_ent (&h->plt.plist, NULL, 0);
+-		  if (ent->plt.refcount > 0)
++		  if (ent != NULL && ent->plt.refcount > 0)
+ 		    ent->plt.refcount -= 1;
+ 		}
+ 	    }
+@@ -4534,7 +4533,7 @@
+ 	      if (r_type == R_PPC_PLTREL24 && info->shared)
+ 		addend = rel->r_addend;
+ 	      ent = find_plt_ent (&h->plt.plist, got2, addend);
+-	      if (ent->plt.refcount > 0)
++	      if (ent != NULL && ent->plt.refcount > 0)
+ 		ent->plt.refcount -= 1;
+ 	    }
+ 	  break;
+@@ -4582,9 +4581,10 @@
+ 		       && tga->root.type == bfd_link_hash_undefweak)))
+ 	    {
+ 	      struct plt_entry *ent;
+-	      ent = find_plt_ent (&tga->plt.plist, NULL, 0);
+-	      if (ent != NULL
+-		  && ent->plt.refcount > 0)
++	      for (ent = tga->plt.plist; ent != NULL; ent = ent->next)
++		if (ent->plt.refcount > 0)
++		  break;
++	      if (ent != NULL)
+ 		{
+ 		  tga->root.type = bfd_link_hash_indirect;
+ 		  tga->root.u.i.link = &opt->root;
+@@ -4669,6 +4669,7 @@
+       {
+ 	Elf_Internal_Sym *locsyms = NULL;
+ 	Elf_Internal_Shdr *symtab_hdr = &elf_symtab_hdr (ibfd);
++	asection *got2 = bfd_get_section_by_name (ibfd, ".got2");
+ 
+ 	for (sec = ibfd->sections; sec != NULL; sec = sec->next)
+ 	  if (sec->has_tls_reloc && !bfd_is_abs_section (sec->output_section))
+@@ -4762,6 +4763,13 @@
+ 		      else
+ 			continue;
+ 
++		    case R_PPC_TLSGD:
++		    case R_PPC_TLSLD:
++		      expecting_tls_get_addr = 2;
++		      tls_set = 0;
++		      tls_clear = 0;
++		      break;
++
+ 		    default:
+ 		      continue;
+ 		    }
+@@ -4769,7 +4777,8 @@
+ 		  if (pass == 0)
+ 		    {
+ 		      if (!expecting_tls_get_addr
+-			  || !sec->has_tls_get_addr_call)
++			  || (expecting_tls_get_addr == 1
++			      && !sec->has_tls_get_addr_call))
+ 			continue;
+ 
+ 		      if (rel + 1 < relend
+@@ -4785,6 +4794,23 @@
+ 		      break;
+ 		    }
+ 
++		  if (expecting_tls_get_addr)
++		    {
++		      struct plt_entry *ent;
++		      bfd_vma addend = 0;
++
++		      if (info->shared
++			  && ELF32_R_TYPE (rel[1].r_info) == R_PPC_PLTREL24)
++			addend = rel[1].r_addend;
++		      ent = find_plt_ent (&htab->tls_get_addr->plt.plist,
++					  got2, addend);
++		      if (ent != NULL && ent->plt.refcount > 0)
++			ent->plt.refcount -= 1;
++
++		      if (expecting_tls_get_addr == 2)
++			continue;
++		    }
++
+ 		  if (h != NULL)
+ 		    {
+ 		      tls_mask = &ppc_elf_hash_entry (h)->tls_mask;
+@@ -4829,16 +4855,6 @@
+ 			*got_count -= 1;
+ 		    }
+ 
+-		  if (expecting_tls_get_addr)
+-		    {
+-		      struct plt_entry *ent;
+-
+-		      ent = find_plt_ent (&htab->tls_get_addr->plt.plist,
+-					  NULL, 0);
+-		      if (ent != NULL && ent->plt.refcount > 0)
+-			ent->plt.refcount -= 1;
+-		    }
+-
+ 		  *tls_mask |= tls_set;
+ 		  *tls_mask &= ~tls_clear;
+ 		}
+@@ -6239,28 +6255,28 @@
+ 	    {
+ 	      size = 4 * ARRAY_SIZE (shared_stub_entry);
+ 	      insn_offset = 12;
+-	      stub_rtype = R_PPC_RELAX32PC;
+ 	    }
+ 	  else
+ 	    {
+ 	      size = 4 * ARRAY_SIZE (stub_entry);
+ 	      insn_offset = 0;
+-	      stub_rtype = R_PPC_RELAX32;
+ 	    }
+-
+-	  if (R_PPC_RELAX32_PLT - R_PPC_RELAX32
+-	      != R_PPC_RELAX32PC_PLT - R_PPC_RELAX32PC)
+-	    abort ();
++	  stub_rtype = R_PPC_RELAX;
+ 	  if (tsec == htab->plt
+ 	      || tsec == htab->glink)
+-	    stub_rtype += R_PPC_RELAX32_PLT - R_PPC_RELAX32;
++	    {
++	      stub_rtype = R_PPC_RELAX_PLT;
++	      if (r_type == R_PPC_PLTREL24)
++		stub_rtype = R_PPC_RELAX_PLTREL24;
++	    }
+ 
+ 	  /* Hijack the old relocation.  Since we need two
+ 	     relocations for this use a "composite" reloc.  */
+ 	  irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
+ 				       stub_rtype);
+ 	  irel->r_offset = trampoff + insn_offset;
+-	  if (r_type == R_PPC_PLTREL24)
++	  if (r_type == R_PPC_PLTREL24
++	      && stub_rtype != R_PPC_RELAX_PLTREL24)
+ 	    irel->r_addend = 0;
+ 
+ 	  /* Record the fixup so we don't do it again this section.  */
+@@ -6430,7 +6446,7 @@
+     {
+       /* Convert the internal relax relocs to external form.  */
+       for (irel = internal_relocs; irel < irelend; irel++)
+-	if (ELF32_R_TYPE (irel->r_info) == R_PPC_RELAX32)
++	if (ELF32_R_TYPE (irel->r_info) == R_PPC_RELAX)
+ 	  {
+ 	    unsigned long r_symndx = ELF32_R_SYM (irel->r_info);
+ 
+@@ -7669,12 +7685,20 @@
+ 	    }
+ 	  break;
+ 
+-	case R_PPC_RELAX32PC_PLT:
+-	case R_PPC_RELAX32_PLT:
++	case R_PPC_RELAX_PLT:
++	case R_PPC_RELAX_PLTREL24:
+ 	  if (h != NULL)
+ 	    {
+-	      struct plt_entry *ent = find_plt_ent (&h->plt.plist, got2,
+-						    info->shared ? addend : 0);
++	      struct plt_entry *ent;
++	      bfd_vma got2_addend = 0;
++
++	      if (r_type == R_PPC_RELAX_PLTREL24)
++		{
++		  if (info->shared)
++		    got2_addend = addend;
++		  addend = 0;
++		}
++	      ent = find_plt_ent (&h->plt.plist, got2, got2_addend);
+ 	      if (htab->plt_type == PLT_NEW)
+ 		relocation = (htab->glink->output_section->vma
+ 			      + htab->glink->output_offset
+@@ -7684,18 +7708,14 @@
+ 			      + htab->plt->output_offset
+ 			      + ent->plt.offset);
+ 	    }
+-	  if (r_type == R_PPC_RELAX32_PLT)
+-	    goto relax32;
+ 	  /* Fall thru */
+ 
+-	case R_PPC_RELAX32PC:
+-	  relocation -= (input_section->output_section->vma
+-			 + input_section->output_offset
+-			 + rel->r_offset - 4);
+-	  /* Fall thru */
++	case R_PPC_RELAX:
++	  if (info->shared)
++	    relocation -= (input_section->output_section->vma
++			   + input_section->output_offset
++			   + rel->r_offset - 4);
+ 
+-	case R_PPC_RELAX32:
+-	relax32:
+ 	  {
+ 	    unsigned long t0;
+ 	    unsigned long t1;
diff --git a/recipes/binutils/binutils_2.20.bb b/recipes/binutils/binutils_2.20.bb
index 5398688..6961377 100644
--- a/recipes/binutils/binutils_2.20.bb
+++ b/recipes/binutils/binutils_2.20.bb
@@ -2,7 +2,7 @@ require binutils.inc
 LICENSE = "GPLv3"
 
 INC_PR = "r1"
-PR = "${INC_PR}.2"
+PR = "${INC_PR}.3"
 
 SRC_URI = "\
      ${GNU_MIRROR}/binutils/binutils-${PV}.tar.bz2 \
@@ -17,4 +17,7 @@ SRC_URI = "\
      "
 
 # powerpc patches
-SRC_URI += "file://binutils-2.16.1-e300c2c3.patch;patch=1"
+SRC_URI += "\
+     file://binutils-2.16.1-e300c2c3.patch;patch=1 \
+     file://binutils-powerpc-pr11088.patch;patch=1 \
+     "





More information about the Openembedded-commits mailing list