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: bfd_link_hash_traverse


On Mon, Jun 13, 2011 at 01:47:41PM -0700, Ian Lance Taylor wrote:
> Alan Modra <amodra@gmail.com> writes:
> 
> > +  for (i = 0; i < htab->table.size; i++)
> > +    {
> > +      struct bfd_link_hash_entry *p;
> > +
> > +      p = (struct bfd_link_hash_entry *) htab->table.table[i];
> > +      for (; p != NULL; p = (struct bfd_link_hash_entry *) p->root.next)
> > +	if (!(*func) (p->type == bfd_link_hash_warning ? p->u.i.link : p, info))
> > +	  goto out;
> > +    }
> 
> I believe it is technically possible to have two warnings on a single
> symbol, which I believe will show up as a warning symbol pointing to a
> warning symbol pointing to a real symbol.

Really?  Only one of the functions called by link_hash_traverse,
elf64-hppa.c:allocate_global_data_opd handled two levels of warning
symbols, using

      while (hh->eh.root.type == bfd_link_hash_indirect
	     || hh->eh.root.type == bfd_link_hash_warning)
	hh = hppa_elf_hash_entry (hh->eh.root.u.i.link);

which is just plain wrong.  You shouldn't look at the indirect link
like this in a traverse function, because then you'll process the
real symbol twice.

I also don't see how we could create two levels of warning symbols
with current code, given that warning symbols have the same name as
the real symbol they point to.  See linker.c:link_action table
current/prev both WARN gives NOACT.

>  That's why the linker code is
> littered with loops like
> 
>   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;
> 
> You probably want to have such a loop here.

Aren't these loops more to handle multiple levels of indirect
symbols?  I believe you can have warn -> indirect -> indirect -> real
and even deeper nesting of indirects.  In fact, those loops might be
better written as

   if (h->root.type == bfd_link_hash_warning)
     h = (struct elf_link_hash_entry *) h->root.u.i.link;
   while (h->root.type == bfd_link_hash_indirect)
     h = (struct elf_link_hash_entry *) h->root.u.i.link;

-- 
Alan Modra
Australia Development Lab, IBM


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