On 10/04/2013 10:12 PM, Bernhard Reutner-Fischer wrote:
> On 1 October 2013 14:21:44 Vineet Gupta <vineet.gup...@synopsys.com> wrote:
>> A simple statically linked hello world program was segfaulting for ARC
>> in linuxthreads.old configuration (although the root casue applies
>> cross-arch for NPTL as well as linuxthreads.old as described)
>>
>> The crash was due to branch to NULL in _stdio_init
> 
> is this gcc.gnu.org/PR32219 ?
> See GCC ML for proposed patches..
> Thanks,

Nope, I don't think this specific case is related to that PR.
There are actually 2 issues here:

1. For NPTL config, uClibc is not attributing vanilla __errno_location to be 
weak.
This causes the redefinition when static linking with libpthread which defines
it's own strong __errno_location. This is a regression due to commit
f418f52701de02 "errno, h_errno: correct them for non-TLS". So one of the hunks 
in
my patch fixes that.

2. With above, for !NPTL case, now both __errno_location and it's GI alias 
become
weak. That should only happen when we don't have any threading library as !NPTL 
is
true when we have linuxthreads.old.

This understanding comes from an existing commig log.

Quoting Peter S. Mazinger, commit 87936cd013041 "errno and *_init cleanup"

  | The rule adopted:
  | for enabled threads we make in libc the __GI_x() variants strong, x() weak
  | and (should) provide another strong x() in libpthread.
  | If threads are disabled, even the __GI_x() variants are weak.


P.S. My Patch v2, attributed to comments from Baruch is better, since it handles
__h_errno as well. Baruch, whenever you get a chance, can you please give it a
quick spin so we can have a Tested-by or some such from you.

>>
>>   0001026c <_stdio_init>:
>>      1026c:    push_s     blink
>>      1026e:    st.a       r13,[sp,-8]
>>      10272:    bl.d       0  --> supposed call to __errno_location
>>
>> The call was NOT getting patched to libc internal only alias
>> __GI___errno_location, because it was weak while it's exported cousin,
>> __errno_location was strong/normal.
>>
>>   arc-linux-uclibc-nm libc/misc/internals/__errno_location.os
>>
>>   00000000 W __GI___errno_location
>>   00000000 T __errno_location
>>
>> This is exactly opposite to what is expected.
>>
>> Quoting Peter S. Mazinger, commit 87936cd013041 "errno and *_init cleanup"
>>
>>  | The rule adopted:
>>  | for enabled threads we make in libc the __GI_x() variants strong, x() weak
>>  | and (should) provide another strong x() in libpthread.
>>  | If threads are disabled, even the __GI_x() variants are weak.
>>
>> With the fix, we see the right settings as below
>>
>>   00000000 T __GI___errno_location
>>   00000000 W __errno_location
>>
>> Note that problem won't show up in a static busybox build as it references
>> errno and that seems to elide the issue.
>>
>> I can confirm the same/more issues with latest ARM buildroot builds w/o
>> my fix.
>>
>> (1). linuxthreads.old (broken just like ARC)
>>
>>   arm-linux-nm uclibc-snapshot/libc/misc/internals/__errno_location.os
>>
>>   00000000 W __GI___errno_location
>>   00000000 T __errno_location
>>
>>   But presumably the issue there is NOT catestrophic because ARM linker is
>>   likely smarter and patches a NOP instead of NULL branch.
>>
>>   00008388 <_stdio_init>:
>>       8388:    e92d4038     push    {r3, r4, r5, lr}
>>       838c:    e320f000     nop    {0}
>>
>> (2) NPTL build (exported version is not weak)
>>
>>   00000000 T __GI___errno_location
>>   00000000 T __errno_location
>>
>>   This causes a static link with libpthread and test program
>>   referencing errno to fail to link.
>>
>>   #include <errno.h>
>>   int main(void)
>>   {
>>       printf("%d\n", errno);
>>   }
>>
>>   arm-linux-gcc -static -pthread -o tst tst.o
>>
>>   
>> arm-buildroot-linux-uclibcgnueabi/sysroot/usr/lib/libc.a(__errno_location.os):
>>   In function `__errno_location':  __errno_location.c:(.text+0x0):
>>                            multiple definition of `__errno_location'
>>   arm-buildroot-linux-uclibcgnueabi/sysroot/usr/lib/libpthread.a
>>             (errno_location.os):errno_location.c:(.text+0x0): first defined 
>> here
>>
>> Signed-off-by: Vineet Gupta <vgu...@synopsys.com>
>> ---
>>  libc/misc/internals/__errno_location.c | 2 +-
>>  libc/sysdeps/linux/common/bits/errno.h | 2 +-
>>  2 files changed, 2 insertions(+), 2 deletions(-)
>>
>> diff --git a/libc/misc/internals/__errno_location.c
>> b/libc/misc/internals/__errno_location.c
>> index dec913f..be7a909 100644
>> --- a/libc/misc/internals/__errno_location.c
>> +++ b/libc/misc/internals/__errno_location.c
>> @@ -16,4 +16,4 @@ int *__errno_location(void)
>>  {
>>      return &errno;
>>  }
>> -libc_hidden_def(__errno_location)
>> +libc_hidden_weak(__errno_location)
>> diff --git a/libc/sysdeps/linux/common/bits/errno.h
>> b/libc/sysdeps/linux/common/bits/errno.h
>> index 7ef1b94..777338f 100644
>> --- a/libc/sysdeps/linux/common/bits/errno.h
>> +++ b/libc/sysdeps/linux/common/bits/errno.h
>> @@ -43,7 +43,7 @@
>>  /* Function to get address of global `errno' variable.  */
>>  extern int *__errno_location (void) __THROW __attribute__ ((__const__));
>>  #  ifdef _LIBC
>> -#   ifndef __UCLIBC_HAS_TLS__
>> +#   if !defined(__UCLIBC_HAS_TLS__) && !defined(__UCLIBC_HAS_THREADS__)
>>  extern int weak_const_function *__errno_location(void);
>>  #   endif
>>  #  endif
>> -- 
>> 1.8.1.2
>>
>> _______________________________________________
>> uClibc mailing list
>> uClibc@uclibc.org
>> http://lists.busybox.net/mailman/listinfo/uclibc
> 
> 
> 
> Sent with AquaMail for Android
> http://www.aqua-mail.com

_______________________________________________
uClibc mailing list
uClibc@uclibc.org
http://lists.busybox.net/mailman/listinfo/uclibc

Reply via email to