On Mon, 06 Jun 2011 18:14:59 -0500, DJ Lucas <d...@linuxfromscratch.org> wrote:
> On 06/06/2011 03:07 PM, Matthew Burgess wrote:
>>
>> I'd prefer for us not to use HJL's binutils
>>
> Then don't. That patch doesn't look all that invasive..no need to add
> tests for local build fix, just the 3 corrected files (bottom of the
> list).

Yep, right you are.  The 1st & 2nd hunk of the elf64-x86_64.c file needed
to be fixed up, but the attached patch now applies cleanly for me.  Obviously,
I can't test it myself, so if you or Andy would be so kind, I'll get it
added to the book along with the Glibc upgrade.

Also, can you confirm that the Glibc issue mentioned by Bruce at
http://wiki.linuxfromscratch.org/lfs/ticket/2883#comment:1 hits you as well,
and we'll need to add the trivial sed to fix that too?  Again, I didn't hit
this during my build.

Ta,

Matt.
Submitted By:            Matt Burgess <matthew_at_linuxfromscratch_dot_org>
Date:                    2011-06-07
Initial Package Version: 2.21
Upstream Status:         Already in upstream patch repo
Origin:                  Upstream
Description:             Fixes build failures in Glibc on x86_64 machines.

diff -Naur binutils-2.21.orig/bfd/elf-ifunc.c binutils-2.21/bfd/elf-ifunc.c
--- binutils-2.21.orig/bfd/elf-ifunc.c	2010-07-13 16:59:10.000000000 +0000
+++ binutils-2.21/bfd/elf-ifunc.c	2011-06-07 14:19:09.236113186 +0000
@@ -190,10 +190,29 @@
   /* Support garbage collection against STT_GNU_IFUNC symbols.  */
   if (h->plt.refcount <= 0 && h->got.refcount <= 0)
     {
-      h->got = htab->init_got_offset;
-      h->plt = htab->init_plt_offset;
-      *head = NULL;
-      return TRUE;
+      /* When building shared library, we need to handle the case
+         where it is marked with regular reference, but not non-GOT
+	 reference.  It may happen if we didn't see STT_GNU_IFUNC
+	 symbol at the time when checking relocations.  */
+      bfd_size_type count = 0;
+
+      if (info->shared
+	  && !h->non_got_ref
+	  && h->ref_regular)
+	{
+	  for (p = *head; p != NULL; p = p->next)
+	    count += p->count;
+	  if (count != 0)
+	    h->non_got_ref = 1;
+	}
+
+      if (count == 0)
+	{
+	  h->got = htab->init_got_offset;
+	  h->plt = htab->init_plt_offset;
+	  *head = NULL;
+	  return TRUE;
+	}
     }
 
   /* Return and discard space for dynamic relocations against it if
diff -Naur binutils-2.21.orig/bfd/elf32-i386.c binutils-2.21/bfd/elf32-i386.c
--- binutils-2.21.orig/bfd/elf32-i386.c	2010-10-21 12:29:02.000000000 +0000
+++ binutils-2.21/bfd/elf32-i386.c	2011-06-07 14:19:12.469299499 +0000
@@ -1807,23 +1807,10 @@
       r_symndx = ELF32_R_SYM (rel->r_info);
       if (r_symndx >= symtab_hdr->sh_info)
 	{
-	  struct elf_i386_link_hash_entry *eh;
-	  struct elf_dyn_relocs **pp;
-	  struct elf_dyn_relocs *p;
-
 	  h = sym_hashes[r_symndx - symtab_hdr->sh_info];
 	  while (h->root.type == bfd_link_hash_indirect
 		 || h->root.type == bfd_link_hash_warning)
 	    h = (struct elf_link_hash_entry *) h->root.u.i.link;
-	  eh = (struct elf_i386_link_hash_entry *) h;
-
-	  for (pp = &eh->dyn_relocs; (p = *pp) != NULL; pp = &p->next)
-	    if (p->sec == sec)
-	      {
-		/* Everything must go for SEC.  */
-		*pp = p->next;
-		break;
-	      }
 	}
       else
 	{
@@ -1843,6 +1830,22 @@
 	    }
 	}
 
+      if (h)
+	{
+	  struct elf_i386_link_hash_entry *eh;
+	  struct elf_dyn_relocs **pp;
+	  struct elf_dyn_relocs *p;
+
+	  eh = (struct elf_i386_link_hash_entry *) h;
+	  for (pp = &eh->dyn_relocs; (p = *pp) != NULL; pp = &p->next)
+	    if (p->sec == sec)
+	      {
+		/* Everything must go for SEC.  */
+		*pp = p->next;
+		break;
+	      }
+	}
+
       r_type = ELF32_R_TYPE (rel->r_info);
       if (! elf_i386_tls_transition (info, abfd, sec, NULL,
 				     symtab_hdr, sym_hashes,
@@ -1883,7 +1886,8 @@
 
 	case R_386_32:
 	case R_386_PC32:
-	  if (info->shared)
+	  if (info->shared
+	      && (h == NULL || h->type != STT_GNU_IFUNC))
 	    break;
 	  /* Fall through */
 
diff -Naur binutils-2.21.orig/bfd/elf64-x86-64.c binutils-2.21/bfd/elf64-x86-64.c
--- binutils-2.21.orig/bfd/elf64-x86-64.c	2010-10-21 12:29:02.000000000 +0000
+++ binutils-2.21/bfd/elf64-x86-64.c	2011-06-07 14:31:57.009124359 +0000
@@ -1645,23 +1645,10 @@
       r_symndx = ELF64_R_SYM (rel->r_info);
       if (r_symndx >= symtab_hdr->sh_info)
 	{
-	  struct elf64_x86_64_link_hash_entry *eh;
-	  struct elf_dyn_relocs **pp;
-	  struct elf_dyn_relocs *p;
-
 	  h = sym_hashes[r_symndx - symtab_hdr->sh_info];
 	  while (h->root.type == bfd_link_hash_indirect
 		 || h->root.type == bfd_link_hash_warning)
 	    h = (struct elf_link_hash_entry *) h->root.u.i.link;
-	  eh = (struct elf64_x86_64_link_hash_entry *) h;
-
-	  for (pp = &eh->dyn_relocs; (p = *pp) != NULL; pp = &p->next)
-	    if (p->sec == sec)
-	      {
-		/* Everything must go for SEC.  */
-		*pp = p->next;
-		break;
-	      }
 	}
       else
 	{
@@ -1682,6 +1669,23 @@
 	    }
 	}
 
+	if (h)
+	{
+	  struct elf_x86_64_link_hash_entry *eh;
+	  struct elf_dyn_relocs **pp;
+	  struct elf_dyn_relocs *p;
+
+	  eh = (struct elf_x86_64_link_hash_entry *) h;
+
+	  for (pp = &eh->dyn_relocs; (p = *pp) != NULL; pp = &p->next)
+	    if (p->sec == sec)
+	      {
+		/* Everything must go for SEC.  */
+		*pp = p->next;
+		break;
+	      }
+	}
+
       r_type = ELF64_R_TYPE (rel->r_info);
       if (! elf64_x86_64_tls_transition (info, abfd, sec, NULL,
 					 symtab_hdr, sym_hashes,
@@ -1733,7 +1737,8 @@
 	case R_X86_64_PC16:
 	case R_X86_64_PC32:
 	case R_X86_64_PC64:
-	  if (info->shared)
+	  if (info->shared
+	      && (h == NULL || h->type != STT_GNU_IFUNC))
 	    break;
 	  /* Fall thru */
 
-- 
http://linuxfromscratch.org/mailman/listinfo/lfs-dev
FAQ: http://www.linuxfromscratch.org/faq/
Unsubscribe: See the above information page

Reply via email to