PR12760 plugin vs. warning syms

H.J. Lu hjl.tools@gmail.com
Mon May 16 01:38:00 GMT 2011


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.



More information about the Binutils mailing list