Joakim Tjernlund wrote:
Timo Teräs <[email protected]> wrote on 2010/04/16 10:00:59:
Joakim Tjernlund wrote:
Austin Foxley wrote:
On 04/14/2010 10:01 AM, Timo Teräs wrote:
Hum. Actually looks like this is not right either. It appears that there's
several different ways how the pthreads mutexes are called from libc.
Previously uclibc had these:
1. internal libc locking:
seems to resolve to use the internal __pthread_mutex_*
weaks defined for__pthread_* in libc/misc/pthread/weaks.c to give
dummy functions if linked statically or without libpthread
2. pthread_* forwarding for applications
so single/multithread libs can link to basic pthreads stuff without
libpthread; it uses the pthread_functions forwarding stubs in thread
implementation specific forwarders.c
3. stdio locking
that uses futexes (from nptl headers), or revers to #1 style locking
However, (1) will never work properly. The reason is that weak vs. strong
aliases are not resolved dynamically. If ld.so picks the weak definition from
libc first (e.g. -lc before -lpthread), you end up using the libc version.
Is this a big problem? To me this looks like an error in the app and the
link order should be fixed there.
It just isn't possible always easily.
That can't be a big deal, feels like a bug in the app that should/could be
fixed.
This also hits the case if libpthread
gets pulled in by dependency library and not by the main app.
But this is a bigger concern. Is this supposed to work or is it an glibc
extension?
Both of the cases work on glibc, because it sets the symbol visibility
correctly, and also uses the weak symbols in correct way.
We would not even need to whole 'forwarding' stuff at all if could trust
that libpthread was always linked before libc. The sole purpose of forwarders
is to have "strongs" versions of these symbols in libpthread, and weak ones
in libc. It may have been doable before via strongs/weak alias thingy. But
it's not doable anymore since LD_DYNAMIC_WEAK is off by default.
The other part is how the internatl __pthread_* is handled. And glibc
does this right by using weak references from libc, and defining them
only in libpthread. This way libc gets null pointers if libpthread is
not pulled in. And this is what we should do too.
(Only glibc ever had dynamic weak resolution, meaning strong alias from later
library would override weak alias; but this behaviour was reverted as it
was considered bad. It's still doable by setting LD_DYNAMIC_WEAK=1).
Now, glibc seems to do (1) as follows:
1. define *protected* versions of __pthread_* from libpthread, so libpthread
will use them always, but also exports (at least subset of them)
2. libc has *weak definition in headers* of __pthread_* causing the
references to be weak, and linking succeed even if __pthread_* symbols
are not present
3. it uses __libc_maybe_call to first check if the function symbol is null,
and if not then calls it
I think we should the same as glibc, by converting uClibc_mutex.h to use
libc-lock.h from threading implementation.
I don't think ld.so supports PROTECTED syms yet(unless someone added these
lately)
Shouldn't be too hard to add I guess.
Isn't protected: define symbol as global, but generate "local"
non-overridable relocations. Thus it's just code generation change
compared to hidden visibility. Not entirely sure about this, though.
But I think it should just work.
Ah, like LD option -Bsymbolic does? That is library wide so one has to find
some __attribute__ that operates on a single symbol.
Yes. Exactly that. It's __attribute__(( visibility("protected") )).
Or .protected for asm. I'm doing a patch on this right now.
http://www.ohse.de/uwe/articles/gcc-attributes.html#func-visibility
_______________________________________________
uClibc mailing list
[email protected]
http://lists.busybox.net/mailman/listinfo/uclibc