This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
Re: PATCH: PR ld/2884: Crash in elf64_ia64_relocate_section
- From: "H. J. Lu" <hjl at lucon dot org>
- To: Nick Clifton <nickc at redhat dot com>
- Cc: binutils at sources dot redhat dot com
- Date: Tue, 11 Jul 2006 10:41:03 -0700
- Subject: Re: PATCH: PR ld/2884: Crash in elf64_ia64_relocate_section
- References: <20060706232756.GA20456@lucon.org> <44B3B00C.8030103@redhat.com>
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))