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]

Re: PATCH: PR ld/2884: Crash in elf64_ia64_relocate_section


On Tue, Jul 11, 2006 at 03:05:00PM +0100, Nick Clifton wrote:
> Hi H. J.
> 
> >2006-07-06  H.J. Lu  <hongjiu.lu@intel.com>
> >
> >	PR ld/2884
> >	* elflink.c (_bfd_elf_merge_symbol): Set ref_dynamic to 0 for
> >	hidden and internal visibility.  Copy the symbol info from the
> >	old versioned dynamic definition to the new one with
> >	non-default visibility.
> 
> Approved (with the grammatical correction mentioned by Jim).
> 

That piece code is very tricky. When elf_backend_copy_indirect_symbol
was called, we copied many bits, some of which are incorrect and
unexpected for hidden and internal symbols. We need to call
elf_backend_hide_symbol to remove those extra bits.


H.J.
-----
2006-07-11  H.J. Lu  <hongjiu.lu@intel.com>

	PR ld/2884
	* elflink.c (_bfd_elf_merge_symbol): Copy the symbol info from
	the old versioned dynamic definition to the new one with
	non-default visibility.  Hide the symbol if it is hidden or
	internal.

--- bfd/elflink.c.foo	2006-07-05 11:50:35.000000000 -0700
+++ bfd/elflink.c	2006-07-11 10:32:55.000000000 -0700
@@ -1007,7 +1007,41 @@ _bfd_elf_merge_symbol (bfd *abfd,
 	 relocatable file and the old definition comes from a dynamic
 	 object, we remove the old definition.  */
       if ((*sym_hash)->root.type == bfd_link_hash_indirect)
-	h = *sym_hash;
+	{
+	  /* Handle the case where the old dynamic definition is
+	     default versioned.  We need to copy the symbol info from
+	     the symbol with default version to the normal one if it
+	     was referenced before.  */
+	  if (h->ref_regular)
+	    {
+	      const struct elf_backend_data *bed
+		= get_elf_backend_data (abfd);
+	      struct elf_link_hash_entry *vh = *sym_hash;
+	      vh->root.type = h->root.type;
+	      h->root.type = bfd_link_hash_indirect;
+	      (*bed->elf_backend_copy_indirect_symbol) (info, vh, h);
+	      /* Protected symbols will override the dynamic definition
+		 with default version.  */
+	      if (ELF_ST_VISIBILITY (sym->st_other) == STV_PROTECTED)
+		{
+		  h->root.u.i.link = (struct bfd_link_hash_entry *) vh;
+		  vh->dynamic_def = 1;
+		  vh->ref_dynamic = 1;
+		}
+	      else
+		{
+		  h->root.type = vh->root.type;
+		  vh->ref_dynamic = 0;
+		  /* We have to hide it here since it was made dynamic
+		     global with extra bits when the symbol info was
+		     copied from the old dynamic definition.  */
+		  (*bed->elf_backend_hide_symbol) (info, vh, TRUE);
+		}
+	      h = vh;
+	    }
+	  else
+	    h = *sym_hash;
+	}
 
       if ((h->root.u.undef.next || info->hash->undefs_tail == &h->root)
 	  && bfd_is_und_section (sec))


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