[PATCH] fix errno location for non-TLS case

Andrew Rybchenko Andrew.Rybchenko at oktetlabs.ru
Thu Dec 1 15:09:14 UTC 2011


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<Andrew.Rybchenko at oktetlabs.ru>
>> ---
>>    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
>> uClibc at uclibc.org
>> 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



More information about the uClibc mailing list