[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: |
carlos 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 19:44:37 +0000 |
https://sourceware.org/bugzilla/show_bug.cgi?id=24718
--- Comment #15 from Carlos O'Donell <carlos at redhat dot com> ---
(In reply to Florian Weimer from comment #14)
> (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*?
I think we talked past eachother here. Thank you for responding to my other
points. I am going to try and stay on point here for this issue. We should
discuss semantics of dynamic bindings on libc-alpha, sorry for going off topic
earlier.
I raised the issue of LD_DYNAMIC_WEAK only as an instructive reference that
discussions about weak symbols in dynamic binding are not correct.
Both weak version symbol references and weak version symbol definitions should
not be used when discussing dynamic binding.
In this particular bug, in this particular example, you have an undefined
reference to foo being bound to a non-weak version definition of foo in
foo-link2.so. The weak attribute in the source C file only tells the linker to
create a new symbol named foo if one doesn't already exist and mark it weak.
The static linker does the actual binding from the executable to foo-link2.so,
and the version symbol definition is non-weak.
The only time VER_FLG_WEAK should be set in vernaux vna_flags is to indicate
that the original binding was against a weak version definition. Something
which doesn't happen in this example. Even if we adjust the sources to make it
happen, binutils doesn't record it as a being weak. So the first bug is that
weak version symbol definitions don't mark the version definition as
VER_FLG_WEAK.
I can inject the flag:
Version definition section '.gnu.version_d' contains 2 entries:
Addr: 0x00000000000003e8 Offset: 0x0003e8 Link: 4 (.dynstr)
000000: Rev: 1 Flags: BASE Index: 1 Cnt: 1 Name: ./foo-run.so
0x001c: Rev: 1 Flags: WEAK Index: 2 Cnt: 1 Name: FOO_1
And *then* we get the correct WEAK version reference:
Version needs section '.gnu.version_r' contains 2 entries:
Addr: 0x0000000000400428 Offset: 0x000428 Link: 6 (.dynstr)
000000: Version: 1 File: ./foo-run.so Cnt: 1
0x0010: Name: FOO_1 Flags: WEAK Version: 3
0x0020: Version: 1 File: libc.so.6 Cnt: 1
0x0030: Name: GLIBC_2.2.5 Flags: none Version: 2
but we still fail:
./a.out2
./a.out2: ./foo-run.so: no version information available (required by ./a.out2)
./a.out2: relocation error: ./a.out2: symbol foo version FOO_1 not defined in
file ./foo-run.so with link time reference
So we have a recorded binding in the binary saying that originally we were
bound to a weak version definition.
The enhancement we can make to binutils and glibc is to do exactly as Solaris
does, which is to ignore any reference to a weak version declaration, and we
know this is the case because the version reference is weak which indicates it
was bound at static link time to a weak version definition.
The language in "symbol-versioning", particularly this language:
~~~
There is one situation where a missing symbol definition is not an
error. This is when the vna_flags in the Elfxx_Vernaux entry has the
VER_FLG_WEAK bit set. In this case only a warning is issued and the
object is used normally.
~~~
I believe this is trying to set out the same semantics as in Solaris. At
runtime when you use a slightly older version of the library without the
optional performance fix, you want to still be able to run but perhaps do
something different.
Therefore I think the ask is for glibc *and* binutils to do this:
- Implement Solaris weak version definition handling:
- Binutils to record in .gnu.version_d that if all symbol definitions are
weak then the version is WEAK.
- glibc to avoid issuing an error if VER_FLG_WEAK is set on a version
reference because it indicates that
the original static linkage was against a weak version definition and it
should be ignored at runtime.
The subject should be flipped the other way around I think:
"BFD ld does not set VER_FLG_WEAK on version definition if all symbols are
weak."
> For weak references, we still have a long-standing ambiguity if the link
> editor encounters both weak and non-weak references.
This should promote to a non-weak reference IMO. You must ensure all references
are weak if you want weak semantics.
I hope this clarifies my position.
Again, we aren't talking about symbols as being weak or non-weak, we are only
talking about version references and version definitions.
We are in effect asking to implement the Solaris semantics for weak version
definitions.
Once we fix this in glibc, then Paul's fix is to hexedit his binaries to have
WEAK version references to FOO_1, because otherwise it won't work.
--
You are receiving this mail because:
You are on the CC list for the bug.