bug-binutils
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Bug ld/24718] BFD ld does not set VER_FLG_WEAK on version reference if


From: fweimer at redhat dot com
Subject: [Bug ld/24718] BFD ld does not set VER_FLG_WEAK on version reference if all symbols are weak
Date: Mon, 24 Jun 2019 17:08:38 +0000

https://sourceware.org/bugzilla/show_bug.cgi?id=24718

--- Comment #14 from Florian Weimer <fweimer at redhat dot com> ---
(In reply to Carlos O'Donell from comment #13)
> (In reply to Florian Weimer from comment #12)
> > <https://www.akkadia.org/drepper/symbol-versioning> says this:
> > 
> >   vna_flags
> >    Bitmask of flags.  Currently the following are defined:
> > 
> >      VER_FLG_WEAK   the reference to this version is weak.
> 
> This specification was written and implemented before the glibc community
> corrected their interpretation of the ELF standard and introduced
> LD_DYNAMIC_WEAK to undo similar weak-style changes. That is to say that the
> VER_FLG_WEAK description in "symbol-vresioning" is based on an incorrect
> interpretation of the ELF standard. It was based on the idea that you would
> scan all loaded shared objects for a potentially strong definition that
> overrode the weak one, and you can see this means lazy loading would be
> useless in this case because even one weak symbol means you need to load
> *everything* to confirm no strong symbols override.

Wasn't that disagreement about weak *definitions*?

For weak references, we still have a long-standing ambiguity if the link editor
encounters both weak and non-weak references.

I don't think any of this matters at the versioning level because the version
reference would be weak if all references are weak.  This means that
limitations due to relocation types available for a particular architectures
etc. do not come into play (which impact what you can implement with the actual
symbol bindings).

> > I believe this is what is implemented in glibc, but it's not bean tested so
> > far because binutils doesn't set this flag.  It should be quite safe to
> > introduce this feature in binutils (obviously for GNU only).
> 
> It is because it is a historical implementation. We could deprecate
> LD_DYANMIC_WEAK and remove lots of code and simplify things.

I think it's totally unrelated.  LD_DYANMIC_WEAK only affects weak definitions
in shared objects.  The example does not contain a weak definition.

> > The Solaris documentation is not helpful at all in this case because our
> > implementation is so very different.  Based on reading that documentation,
> > Solaris does not bind individual symbols to versions, only shared object
> > dependencies as a whole. 
> 
> Correct, and if we wanted we could implement the Solaris meaning of
> VER_FLG_WEAK for "weak version definitions." I don't know how we would
> instruct a binding between the binary and the "weak version definition",
> some new linker file construct like Solaris has.

We have the SHT_GNU_verneed section referenced from the dynamic segment.  The
glibc loader processes that, in much the same way as the Solaris loader does
with their data structure.  The key difference is that our link editor puts
only symbol version references there for symbols which are actually referenced
by the link.

Without that, you would be able to run glibc 2.30 binaries only on systems
having glibc 2.30 or later, for example.

> I think the original "symbol-versioning" design simply tried to carry the
> static linker semantics of weak symbol version processing to the dynamic
> linker without consideration for the impact it would have on lazy binding.
> Namely that if you have an undefined weak reference to a symbol, you have to
> search every object looking for a potential strong reference, instead of
> stopping at the first definition (weak or strong) that you find based on
> search order.

You always have to search all objects for an undefined weak symbol.  There is
no defined symbol at which the search can stop.

> > Instead, you can just instruct the link editor to omit certain symbol
> > version references from the resulting binary, keep a weak (unversioned)
> > symbol reference, and apply a run-time check, as with any weak symbol.
> > Since it is not possible to define multiple symbol versions for the same
> > symbol name on Solaris, restricting the set of bound symbol versions at
> > static link time is safe.  (In the GNU implementation, this is unsafe
> > because different versioned symbols can require different declarations and
> > have different behavior in general, so deferring this decision to the link
> > editor does not work.)
> 
> I don't follow what you're trying to state here. Can you expand on this with
> an exmaple please?

Solaris has a capability to specify the symbol versions you want to require
from a specific soname.  See “Specifying a Version Binding” in the
documentation you cited, and in particular “If a shared object has been
versioned over several software releases, application developers can restrict
themselves to the interfaces that were available in a previous software
release. Thus, an application can be built using the latest release of the
shared object in the knowledge that the application's interface requirements
can be met by a previous release of the shared object.”.  Since individual
symbols do not carry versions in the Solaris implementation, programmers can do
this to get rid of the load failure, and avoid relying on specific weak symbols
if some version probing (outside the specification) indicates that the
installed version does not provide support.  (Due to relocation issue, directly
probing the weak symbol itself can be problematic, but this is not the point
here.)

On glibc, nothing like this is possible.  If you use .symver to bind to an
earlier version of a symbol, then you need to make sure that you meet all the
different requirements of that earlier symbol version manually, such as
different parameter lists, different struct sizes, and so on.

-- 
You are receiving this mail because:
You are on the CC list for the bug.


reply via email to

[Prev in Thread] Current Thread [Next in Thread]