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: PATCH: PR ld/14323: Linker fails to handle weak alias with __start_SECNAME symbol


On Wed, Jul 04, 2012 at 06:46:59AM -0700, H.J. Lu wrote:
> On Tue, Jul 3, 2012 at 5:46 PM, Alan Modra <amodra@gmail.com> wrote:
> > On Mon, Jul 02, 2012 at 02:16:57PM -0700, H.J. Lu wrote:
> >> When we check symbol alias in a dynamic object, we should also check
> >> symbol size.
> >
> > Always? ?How does this play with cases where _bfd_elf_merge_symbol
> > returns size_change_ok.
> 
> Here we are matching a symbol to a weak alias.  Their
> sizes must match.

Two problems.  The first one is that your testsuite addition doesn't
fail for me on x64_64-linux without your elflink.c change.  So the
testcase isn't very useful.  Binary search for a given key when
multiple entries match the key gives you one of the matching entries
but which one depends on exactly how the binary search went, ie. it
depends on other entries in the array.  So when I linked your testcase
I happened to get foo_alias matching foo rather than the failure mode
of foo_alias matching __start__data_foo.

Second problem is that I'm uncertain you can claim "sizes must
match".  If they do match, fine, go with the match.  However if no
size matches exactly, I think it would be better to match the largest
size symbol at the given address.  That way you at least get a match,
and the largest .dynbss/copy reloc.  Maybe I'm fussing a little here.
Aliases generated by gcc with "__attribute__ ((weak, alias (...)))"
require the target be defined in the same compilation unit, so they
will be the same size.  What about __attribute__ ((weakref (..)))?
I don't want to break some existing code that has only two symbols at
one address, a weak and a global, but their sizes don't match.  HJ,
have you built glibc with your patch?

For those a little mystified by what is going on here, we have a
shared library with aliases.  This from the testcase in the PR.

     8: 0000000000201038     0 NOTYPE  GLOBAL DEFAULT   23 __start__data_foo
     9: 0000000000201038     4 OBJECT  WEAK   DEFAULT   23 foo_alias
    10: 0000000000201038     4 OBJECT  GLOBAL DEFAULT   23 foo

Note the differences in sizes (3rd col).  Main program accesses
foo_alias, and the linker is left with a choice of two possible
matching globals for the weak symbol.  Furthermore, the main program
is non-PIC so wants to set up it's own foo_alias in .dynbss.  This
means the size matters, so the choice of global matters.  Choosing the
largest or choosing matching size gets the right one in this case.

There is another twist too.  HJ's testcase also accesses
__start__data_foo in main, and it too is allocated in .dynbss, except
that since its size was zero no space is actually allocated.  So
__start__data_foo in main has the same address as foo/foo_alias only
if the symbols are processed in exactly the right order and no other
.dynbss symbols intervene.  Yes, aliases and .dynbss are horrible.  We
don't pretend to handle this correctly.

-- 
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]