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: GOLD handling of weak symbols (including x86 vs. ARM)


Richard Sandiford <richard.sandiford@linaro.org> writes:

> Yeah, that's basically the first-order question.  Going back to the
> source code:
>
>     extern void foo (void) __attribute__ ((weak));
>     int
>     main ()
>     {
>       if (&foo)
>         foo ();
>
>       return 0;
>     }

I agree that this C code has to work one way or another, where by "work"
I mean that the test of &foo has to return 0 if the symbol is not
defined anywhere, not even by a shared library loaded at runtime.

> GCC, when not compiling PIC, traditionally uses absolute accesses for
> the (&foo != 0) test and a non-@PLT call for "foo ()".  (The x86 code
> I posted is the output from this testcase, which comes from the GCC
> testsuite.)  This approach "works" with both BFD LD and GOLD on x86,
> with neither linker allowing a run-time override of foo.  Both linkers
> resolve the &foo reference to zero without any dynamic relocs.  The foo ()
> call is never executed, even if foo is defined by an LD_PRELOAD.
>
> That's what I was expecting, but I'm not sure from your response
> whether it's what you were expecting or not.

OK, I may be starting to see what you are getting at.  When the linker
sees the relocs generated for &foo, it doesn't know whether the value is
going to be called later or whether it is only going to be compared
against zero.  It's ambiguous.  If we're going to do a comparison
against zero, then the only correct behaviour is to use a dynamic
relocation, which will evaluate to either zero or the address of the
function in a shared library.  If we're going to call the function
later, then we can either use a dynamic relocation or we can refer to
the PLT entry.  Putting those together, the only correct behaviour is to
use a dynamic relocation in all cases.

If we are linking code for which we should not generate a dynamic
relocation, then we are screwed.  There is no possible way to generate
code which is correct in all cases.

However, over in needs_dynamic_reloc, I see this:

    // A reference to an undefined symbol from an executable should be
    // statically resolved to 0, and does not need a dynamic relocation.
    // This matches gnu ld behavior.
    if (this->is_undefined() && !parameters->options().shared())
      return false;

So I think we've already decided that we are screwed in this case.

And that means that we should remove these lines from use_plt_offset:
    if (this->is_weak_undefined())
      return true;
since we've decided that such symbols should be statically resolved to
0.

That seems weird to me but perhaps it makes sense in some universe.

Ian


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