Hi Peter,

On 12/01/2011 06:35 PM, Peter Mazinger wrote:
hi

__errno_location() function should not be library-wide hidden in
non-TLS (thread local storage) case since it should be overriden
by thread-aware function from linuxthreads.old/linuxthreads.
If the function is hidden, calls from libc itself always use it
regardless libpthread linked or not. As the result errno set
in, for example, recv() function is stored in global errno variable
instead of thread-specific location.

Signed-off-by: Andrew Rybchenko<[email protected]>
---
   libc/misc/internals/__errno_location.c |    3 +++
   libc/sysdeps/linux/common/bits/errno.h |    2 ++
   2 files changed, 5 insertions(+), 0 deletions(-)

diff --git a/libc/misc/internals/__errno_location.c
b/libc/misc/internals/__errno_location.c
index aec7641..371bd26 100644
--- a/libc/misc/internals/__errno_location.c
+++ b/libc/misc/internals/__errno_location.c
@@ -7,6 +7,9 @@
   #include "internal_errno.h"
    /* psm: moved to bits/errno.h: */
+#ifndef __UCLIBC_HAS_TLS__
+libc_hidden_proto(__errno_location)
+#endif
libc_hidden_proto does not hide __errno_location, it hides in reality 
__GI___errno_location
Yes, exactly. I'm afraid "hidden" term is brought here from GCC and a bit confusing/misleading.

As I understand (please, correct me if I'm wrong) ./include/libc-symbols.h line 368 clear states that libc_hidden_proto() should be used for PLT bypassing withing libc.so. It is exactly what happens with __errno_location() if libc_hidden_proto() is used in header - all calls to __errno_location() inside libc go directly to libc implementation of __errno_location() regardless libpthread() linked.

linuxthreads.old implementation just wraps libc socket calls like recv() which set errno. Since errno is set from libc call and libc_hidden_proto() is used for __errno_location(), libc version of the function is called and provides pointer to global errno variable (not
thread-specific location).

Also it is important here that linuxthreads.old does not use TLS. That's why I use
__UCLIBC_HAS_TLS__ conditional.

There is no such bug in 0.9.30.x.

Andrew.
Peter
   int *
   #ifndef __UCLIBC_HAS_THREADS__
   weak_const_function
diff --git a/libc/sysdeps/linux/common/bits/errno.h
b/libc/sysdeps/linux/common/bits/errno.h
index 0bf6354..5f96c31 100644
--- a/libc/sysdeps/linux/common/bits/errno.h
+++ b/libc/sysdeps/linux/common/bits/errno.h
@@ -43,7 +43,9 @@
   # ifndef __ASSEMBLER__
   /* Function to get address of global `errno' variable.  */
   extern int *__errno_location (void) __THROW __attribute__ ((__const__));
+#ifdef __UCLIBC_HAS_TLS__
   libc_hidden_proto(__errno_location)
+#endif
    #  ifdef __UCLIBC_HAS_THREADS__
   /* When using threads, errno is a per-thread value.  */
--
1.7.2.5
_______________________________________________
uClibc mailing list
[email protected]
http://lists.busybox.net/mailman/listinfo/uclibc


--
Andrew Rybchenko
OKTET Labs, St.-Petersburg, Russia    Web: www.oktetlabs.ru
Office: +7 812 7832191  Fax: +7 812 7846591  Mobile: +7 921 7479683

_______________________________________________
uClibc mailing list
[email protected]
http://lists.busybox.net/mailman/listinfo/uclibc

Reply via email to