summaryrefslogtreecommitdiff
path: root/libc/sysdeps/linux/common
diff options
context:
space:
mode:
authorVineet Gupta <Vineet.Gupta1@synopsys.com>2013-10-04 15:35:01 +0530
committerBernhard Reutner-Fischer <rep.dot.nop@gmail.com>2013-11-06 22:21:59 +0100
commitacfc107a50344b100b9ea492678928acc047c6ae (patch)
treec39121c6e21843554bf9d419b3b6484fcf83c356 /libc/sysdeps/linux/common
parenta20d9fe5396585b6448aa13c5f6cf8d111b7b7f5 (diff)
Fix weak/strong attribute of __errno_location and it's __GI alias
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> Signed-off-by: Bernhard Reutner-Fischer <rep.dot.nop@gmail.com>
Diffstat (limited to 'libc/sysdeps/linux/common')
-rw-r--r--libc/sysdeps/linux/common/bits/errno.h2
1 files changed, 1 insertions, 1 deletions
diff --git a/libc/sysdeps/linux/common/bits/errno.h b/libc/sysdeps/linux/common/bits/errno.h
index 7ef1b9440..777338fb1 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