This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Re: Duplicate data objects in shared libraries
From: "Jason Merrill" <jason@redhat.com>
> >>>>> "David" == David Abrahams <david.abrahams@rcn.com> writes:
>
> > One thing we didn't discuss in detail was what should happen in case
two
> > of a library's dependencies are already loaded, each with its own
> > definition for some shared symbol S.
>
> i.e.
>
> A.so -> T.so
> -> U.so
>
> B.so -> U.so
>
> ? Here, if T and U both define S, refs in U will resolve to the copy in
T,
> but refs in B won't, so we get the same problem. Hmm.
No, that's not what I had in mind. In fact I assumed *** that B would get
the same copy of S that was currently used by U, which is to say the one in
T. Is there any reason it couldn't work that way?
> This problem would be solved if T were to link against U, or vice versa,
or
> if both were linked against a third library which defined S.
>
> The problem is that RTLD_LOCAL really wants a strict delineation of
> provider and user;
At the RTLD_LOCAL boundary there already is a strict delineation.
> if a DSO uses a symbol from a DSO that it doesn't
> depend on, this premise is violated, and users will get confused.
I don't see the potential for confusion (leaving aside unloading for the
moment), since matching symbols in T and U above were required to be
identical anyway according to the ODR.
----
What I had in mind was more like this:
A.so -> T.so
B.so -> U.so
Now there are two shared spaces (A,T) and (B,U), each with its own copy of
S. Then:
C.so -> T.so, U.so
C wanted a single shared copy but ends up having to choose one or error. I
vote for the former.
---
> I would further clarify my proposal #6 thus:
>
> 7) Resolution of a relocation in a DSO loaded with RTLD_LOCAL only
> considers definitions in the DSO itself and its dependencies. If a
> strong definition is seen in the normal breadth-first search of these
> DSOs, it is used; otherwise, a weak definition is chosen by
depth-first
> search.
If you believe Martin, symbols we care about like RTTI info and template
static members are not weak... so I don't understand the relevance of 7.
Could you describe how it would play out in practice?
> Actually, I'd be inclined to adopt the second sentence for all cases, not
> just RTLD_LOCAL. If a library provides a weak definition of something,
and
> the executable provides a weak definition as well, it makes sense to me
to
> use the library version. Doing so would improve the usefulness of
> -Wl,--gc-sections (once it works).
>
> Anyway, adopting this proposal, T and U would each use their own
> definition, A would use the one from T, and B would use the one from U.
So
> the problem would come when trying to, say, throw from U into A.
>
> It's not difficult to imagine this sort of situation arising with
> vague-linkage entities that are emitted when needed. For example: a
> library V defines a non-polymorphic class J but doesn't use its RTTI
node.
> T and U link against V and both throw objects of type J. A catches the
one
> thrown in T, but not the one thrown in U. We would have been fine if the
> RTTI node had been emitted in V, but it wasn't needed, so it wasn't
> emitted.
>
> I don't see any way to get ld.so to just give us the semantics we want
for
> this subcase.
What about just following the semantics I had assumed you'd get anyway
(***)?
-Dave