Message ID | 1380881101-8581-1-git-send-email-vgupta@synopsys.com |
---|---|
State | New |
Headers | show |
Hi Vineet, On Fri, Oct 04, 2013 at 03:35:01PM +0530, Vineet Gupta wrote: [snip] > 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 <vgupta@synopsys.com> > Cc: Baruch Siach <baruch@tkos.co.il> For xtensa NPTL target: Tested-by: Baruch Siach <baruch@tkos.co.il> Thanks, baruch > --- > include/netdb.h | 2 +- > libc/misc/internals/__errno_location.c | 2 +- > libc/misc/internals/__h_errno_location.c | 2 +- > libc/sysdeps/linux/common/bits/errno.h | 2 +- > 4 files changed, 4 insertions(+), 4 deletions(-) > > diff --git a/include/netdb.h b/include/netdb.h > index 14cf3d24dae0..8fdfa0fccc7d 100644 > --- a/include/netdb.h > +++ b/include/netdb.h > @@ -59,7 +59,7 @@ __BEGIN_DECLS > /* Function to get address of global `h_errno' variable. */ > extern int *__h_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 *__h_errno_location(void); > # endif > #endif > diff --git a/libc/misc/internals/__errno_location.c b/libc/misc/internals/__errno_location.c > index dec913f3031d..be7a9093efa3 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/misc/internals/__h_errno_location.c b/libc/misc/internals/__h_errno_location.c > index 41353d74a648..6653681cbf09 100644 > --- a/libc/misc/internals/__h_errno_location.c > +++ b/libc/misc/internals/__h_errno_location.c > @@ -16,4 +16,4 @@ int *__h_errno_location(void) > { > return &h_errno; > } > -libc_hidden_def(__h_errno_location) > +libc_hidden_weak(__h_errno_location) > diff --git a/libc/sysdeps/linux/common/bits/errno.h b/libc/sysdeps/linux/common/bits/errno.h > index 7ef1b9440a34..777338fb1e0a 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 >
Ping^2 ! On 10/04/2013 03:35 PM, Vineet Gupta 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 > > 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 <vgupta@synopsys.com> > Cc: Baruch Siach <baruch@tkos.co.il> > --- > include/netdb.h | 2 +- > libc/misc/internals/__errno_location.c | 2 +- > libc/misc/internals/__h_errno_location.c | 2 +- > libc/sysdeps/linux/common/bits/errno.h | 2 +- > 4 files changed, 4 insertions(+), 4 deletions(-) > > diff --git a/include/netdb.h b/include/netdb.h > index 14cf3d24dae0..8fdfa0fccc7d 100644 > --- a/include/netdb.h > +++ b/include/netdb.h > @@ -59,7 +59,7 @@ __BEGIN_DECLS > /* Function to get address of global `h_errno' variable. */ > extern int *__h_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 *__h_errno_location(void); > # endif > #endif > diff --git a/libc/misc/internals/__errno_location.c b/libc/misc/internals/__errno_location.c > index dec913f3031d..be7a9093efa3 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/misc/internals/__h_errno_location.c b/libc/misc/internals/__h_errno_location.c > index 41353d74a648..6653681cbf09 100644 > --- a/libc/misc/internals/__h_errno_location.c > +++ b/libc/misc/internals/__h_errno_location.c > @@ -16,4 +16,4 @@ int *__h_errno_location(void) > { > return &h_errno; > } > -libc_hidden_def(__h_errno_location) > +libc_hidden_weak(__h_errno_location) > diff --git a/libc/sysdeps/linux/common/bits/errno.h b/libc/sysdeps/linux/common/bits/errno.h > index 7ef1b9440a34..777338fb1e0a 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 >
diff --git a/include/netdb.h b/include/netdb.h index 14cf3d24dae0..8fdfa0fccc7d 100644 --- a/include/netdb.h +++ b/include/netdb.h @@ -59,7 +59,7 @@ __BEGIN_DECLS /* Function to get address of global `h_errno' variable. */ extern int *__h_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 *__h_errno_location(void); # endif #endif diff --git a/libc/misc/internals/__errno_location.c b/libc/misc/internals/__errno_location.c index dec913f3031d..be7a9093efa3 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/misc/internals/__h_errno_location.c b/libc/misc/internals/__h_errno_location.c index 41353d74a648..6653681cbf09 100644 --- a/libc/misc/internals/__h_errno_location.c +++ b/libc/misc/internals/__h_errno_location.c @@ -16,4 +16,4 @@ int *__h_errno_location(void) { return &h_errno; } -libc_hidden_def(__h_errno_location) +libc_hidden_weak(__h_errno_location) diff --git a/libc/sysdeps/linux/common/bits/errno.h b/libc/sysdeps/linux/common/bits/errno.h index 7ef1b9440a34..777338fb1e0a 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
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 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 <vgupta@synopsys.com> Cc: Baruch Siach <baruch@tkos.co.il> --- include/netdb.h | 2 +- libc/misc/internals/__errno_location.c | 2 +- libc/misc/internals/__h_errno_location.c | 2 +- libc/sysdeps/linux/common/bits/errno.h | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-)