This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
Re: Quick question about _bfd_generic_link_add_one_symbol state machine and weak symbols
- From: Dave Korn <dave dot korn dot cygwin at googlemail dot com>
- To: Dave Korn <dave dot korn dot cygwin at googlemail dot com>, binutils at sourceware dot org
- Date: Mon, 30 Mar 2009 02:07:23 +0100
- Subject: Re: Quick question about _bfd_generic_link_add_one_symbol state machine and weak symbols
- References: <49CF21FA.7060702@gmail.com> <20090329121417.GJ30645@bubble.grove.modra.org>
Alan Modra wrote:
[ btw I'm digressing here, most of this post is for the benefit of any
onlookers who might be wondering where I was getting with weak symbol support
on cygwin. ]
> On Sun, Mar 29, 2009 at 08:23:38AM +0100, Dave Korn wrote:
>> static const enum link_action link_action[8][8] =
>> {
>> /* current\prev new undef undefw def defw com indr warn */
>> /* UNDEF_ROW */ {UND, NOACT, UND, REF, REF, NOACT, REFC, WARNC },
>> ^^^
>
> Don't think in terms of the references. We have a global symbol hash
> table. The entry for the given symbol was marked undefined weak. It
> is now marked as undefined.
>
Ah, I think I get it, it's done in order to make sure the symbol *does* get
pulled in from a lib archive, which wouldn't happen with a weak undef. In C
terms, if I have one file that has
-----------------------------------------------------
extern void __attribute__ ((weak)) foo (void);
void bar (void)
{
foo ();
}
-----------------------------------------------------
and another that has
-----------------------------------------------------
extern void foo (void);
void baz (void)
{
foo ();
}
-----------------------------------------------------
then when I link them both, we want to get foo() out of an archive to satisfy
baz() even though bar() would just have left it undefined if it had been the
only file in the link.
I'm running into this situation because of the way the current PE weak
symbol support (which was only designed with one simple usage model in mind,
and which I'm experimenting with to see if I can extend it in a
backward-compatible fashion to make the full ELF semantics work) is
implemented by using an undefined weak extern with an auxiliary symbol for the
default (weak) definition, what the PE spec calls "weak externals".
So far I've got it to seemingly work just by being a bit careful about what
we do in coff_link_add_symbols when we see new definitions come along, but
this corner case gives me problems. Because PE "weak externals" combine a
defined symbol and an undefined symbol as a pair, with the undefined one being
the master and the defined one the auxiliary (alias definition), I don't want
to lose track of the details of the undefweak when a strong undef comes along,
but a strong undef has no place to track a default alias.
I think what I might want in this situation is to 'semi-resolve' the weak
undef into a weak def with the value of the default sym, but mark it with the
IMAGE_WEAK_EXTERN_SEARCH_LIBRARY characteristic. (And implement handling for
that and the other as-yet-unsupported PE weak external characteristic type.)
Another option would be to stop trying to extend the C_NT_WEAK semantic and
just use C_WEAKEXT symbols. Not sure which would be best yet.
cheers,
DaveK