This is the mail archive of the
libc-alpha@sources.redhat.com
mailing list for the glibc project.
Re: PATCH: Treat RTLD_LOCAL like Solaris (Re: Duplicate dataobjects in shared libraries)
- From: Jason Merrill <jason at redhat dot com>
- To: "David Abrahams" <david dot abrahams at rcn dot com>
- Cc: "H . J . Lu" <hjl at lucon dot org>,"Martin v. Loewis" <martin at v dot loewis dot de>, <drepper at redhat dot com>,"Ralf W. Grosse-Kunstleve" <rwgk at cci dot lbl dot gov>,"GNU C Library" <libc-alpha at sources dot redhat dot com>
- Date: Thu, 30 May 2002 16:01:00 -0400
- Subject: Re: PATCH: Treat RTLD_LOCAL like Solaris (Re: Duplicate dataobjects in shared libraries)
- References: <76260000.1021912729@warlock.codesourcery.com><wvlhel2ocz3.fsf@prospero.cambridge.redhat.com><60630000.1021922077@gandalf.codesourcery.com><00ba01c20035$805388a0$6601a8c0@boostconsulting.com><wvln0uumvqt.fsf@prospero.cambridge.redhat.com><08b101c201f0$d511fd60$6601a8c0@boostconsulting.com><wvloff7ea9a.fsf@prospero.cambridge.redhat.com><20020529130945.A16909@lucon.org><039401c20759$a3ba1400$6601a8c0@boostconsulting.com>
>>>>> "David" == David Abrahams <david.abrahams@rcn.com> writes:
> From: "H . J . Lu" <hjl@lucon.org>
>> This patch makes glibc more like Solaris for RTLD_LOCAL. It also passed
>> "make check" in glibc. Any comments?
> It's not clear to me that working "more like Solaris" was what we were
> after
No; Solaris' behavior is no more helpful for real-world C++ examples.
Sorry I didn't emphasize this more when you (H.J.) started talking about
doing this.
Is there any kind of a standard for ld.so symbol resolution behavior? I've
tried looking at the ELF spec, and didn't notice anything, but I haven't
read very closely yet.
A simple ~80% solution for C++ problems with RTLD_LOCAL would be:
1) Always prefer the last weak definition if no strong definition is seen.
So if an RTLD_LOCAL DSO and a library it uses both provide weak
definitions of a type_info node, the version from the library will be
used in both objects; as a result, another DSO linked against the same
library can use the same definition.
Implementation of this is extremely simple; an untested patch is attached
below. Comments? I think something like this is necessary to get
reasonable plugin semantics from C++, where the barrier between library and
user is much more porous, especially with templates.
An additional modification, inspired by a suggestion of David's:
2) If a DSO A has two unrelated dependencies B and C which both define (and
use) the same weak symbol, add C to the dependency list of this loaded
copy of B.
So if we load (with RTLD_LOCAL) A, which depends on B and C, we would
add C to B's dependency list, and all references to a symbol would use
the version from C. If we then load D, which only depends on B, we
would get C as well, so references in D can also use that definition.
This depends on #1 above to be useful; without that change, references
would use the definition in D regardless of what other versions were
available. It might, however, still be useful to avoid unloading C
while B is still pointing at one of its symbols; do we already protect
against that somehow?
#1 would fix C++ vague linkage semantics in plugins for ~80% (arbitrary
estimate) of cases. #2 would fix it for another ~10% (such as the case
described), but seems somewhat inelegant; I'd be happy with just #1.
A further case that David described, whereby B and C are first loaded
separately, seems intractable without re-resolving relocations, which I
don't think we want to get into.
Another suggestion, which is independent of the above, but seems to me like
The Right Thing for strong definitions in the presence of RTLD_LOCAL:
3) When resolving a relocation from a DSO loaded with RTLD_LOCAL, start
looking from the DSO itself; do not consider other RTLD_LOCAL objects
which depend on it.
This would allow a plugin to override operator new without affecting the
definition used by the standard library and messing up other users.
Thoughts?
2002-05-30 Jason Merrill <jason@redhat.com>
* elf/do-lookup.h (FCT): Use the last weak definition if we don't
see a strong one.
*** do-lookup.h.~1~ Wed Jun 7 23:31:03 2000
--- do-lookup.h Thu May 30 13:11:46 2002
*************** FCT (const char *undef_name, struct link
*** 158,171 ****
switch (ELFW(ST_BIND) (sym->st_info))
{
case STB_WEAK:
! /* Weak definition. Use this value if we don't find another. */
if (__builtin_expect (_dl_dynamic_weak, 0))
{
! if (! result->s)
! {
! result->s = sym;
! result->m = map;
! }
break;
}
/* FALLTHROUGH */
--- 158,169 ----
switch (ELFW(ST_BIND) (sym->st_info))
{
case STB_WEAK:
! /* Weak definition. Use the last one encountered if we don't
! find a strong definition. */
if (__builtin_expect (_dl_dynamic_weak, 0))
{
! result->s = sym;
! result->m = map;
break;
}
/* FALLTHROUGH */