This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
Re: PR12760 plugin vs. warning syms
- From: "H.J. Lu" <hjl dot tools at gmail dot com>
- To: Binutils <binutils at sourceware dot org>
- Date: Sun, 15 May 2011 18:37:58 -0700
- Subject: Re: PR12760 plugin vs. warning syms
- References: <20110516005524.GD20800@bubble.grove.modra.org>
On Sun, May 15, 2011 at 5:55 PM, Alan Modra <amodra@gmail.com> wrote:
> I've committed this version of HJ's patch to fix the segfault caused
> by having a NULL u.undef.abfd. ?I think this should be done even
> though it's not a full fix for warning symbols.
>
> ? ? ? ?PR ld/12760
> ? ? ? ?* plugin.c (plugin_notice): Set u.undef.abfd for symbols made
> ? ? ? ?undefweak.
>
> Index: ld/plugin.c
> ===================================================================
> RCS file: /cvs/src/src/ld/plugin.c,v
> retrieving revision 1.33
> diff -u -p -r1.33 plugin.c
> --- ld/plugin.c 24 Apr 2011 10:02:14 -0000 ? ? ?1.33
> +++ ld/plugin.c 15 May 2011 13:18:27 -0000
> @@ -912,6 +912,8 @@ plugin_notice (struct bfd_link_info *inf
> ?{
> ? if (h != NULL)
> ? ? {
> + ? ? ?bfd *sym_bfd;
> +
> ? ? ? /* No further processing if this def/ref is from an IR dummy BFD. ?*/
> ? ? ? if (is_ir_dummy_bfd (abfd))
> ? ? ? ?return TRUE;
> @@ -928,10 +930,13 @@ plugin_notice (struct bfd_link_info *inf
> ? ? ? ? to be undefined. ?*/
> ? ? ? else if (((h->type == bfd_link_hash_defweak
> ? ? ? ? ? ? ? ? || h->type == bfd_link_hash_defined)
> - ? ? ? ? ? ? ? && is_ir_dummy_bfd (h->u.def.section->owner))
> + ? ? ? ? ? ? ? && is_ir_dummy_bfd (sym_bfd = h->u.def.section->owner))
> ? ? ? ? ? ? ? || (h->type == bfd_link_hash_common
> - ? ? ? ? ? ? ? ? ?&& is_ir_dummy_bfd (h->u.c.p->section->owner)))
> - ? ? ? h->type = bfd_link_hash_undefweak;
> + ? ? ? ? ? ? ? ? ?&& is_ir_dummy_bfd (sym_bfd = h->u.c.p->section->owner)))
> + ? ? ? {
> + ? ? ? ? h->type = bfd_link_hash_undefweak;
> + ? ? ? ? h->u.undef.abfd = sym_bfd;
> + ? ? ? }
> ? ? }
>
This isn't enough. My current version is
else if ((h->type == bfd_link_hash_defweak
|| h->type == bfd_link_hash_defined)
&& is_ir_dummy_bfd (h->u.def.section->owner))
{
h->u.undef.abfd = h->u.def.section->owner;
h->type = bfd_link_hash_undefweak;
if (h->u.undef.next != NULL
|| link_info.hash->undefs_tail == h)
bfd_link_repair_undef_list (link_info.hash);
}
else if (h->type == bfd_link_hash_common
&& is_ir_dummy_bfd (h->u.c.p->section->owner))
{
h->u.undef.abfd = h->u.c.p->section->owner;
h->type = bfd_link_hash_undefweak;
if (h->u.undef.next != NULL
|| link_info.hash->undefs_tail == h)
bfd_link_repair_undef_list (link_info.hash);
}
We must call bfd_link_repair_undef_list when we change symbol
type to bfd_link_hash_undefweak. Otherwise, assert may fail in:
void
bfd_link_add_undef (struct bfd_link_hash_table *table,
struct bfd_link_hash_entry *h)
{
BFD_ASSERT (h->u.undef.next == NULL);
if (table->undefs_tail != NULL)
table->undefs_tail->u.undef.next = h;
if (table->undefs == NULL)
table->undefs = h;
table->undefs_tail = h;
}
--
H.J.