static link with NPTL on ARM fails

Johannes Stezenbach js at sig21.net
Mon Nov 28 17:43:25 UTC 2011


Hi,

I'm in the process of building a toolchain with crosstool-ng,
with uClibc-0.9.32 + NPTL for ARM926EJ-S.

Trying to statically link a simple testcase with NPTL fails:

$ cat t.c
#include <pthread.h>

int main(int argc, char *argv[])
{
        return (int)pthread_create;
}
$ arm-linux-gcc -Wall -Os t.c -lpthread -static -Wl,-Map=m
/tmp/tc/arm-unknown-linux-uclibcgnueabi/arm-unknown-linux-uclibcgnueabi/sysroot/usr/lib/libc.a(sigaction.o): In function `__libc_sigaction':
sigaction.c:(.text+0x0): multiple definition of `__libc_sigaction'
/tmp/tc/arm-unknown-linux-uclibcgnueabi/arm-unknown-linux-uclibcgnueabi/sysroot/usr/lib/libpthread.a(pt-sigaction.o):pt-sigaction.c:(.text+0x0): first defined here
/tmp/tc/arm-unknown-linux-uclibcgnueabi/arm-unknown-linux-uclibcgnueabi/sysroot/usr/lib/libc.a(sigaction.o): In function `sigaction':
sigaction.c:(.text+0x78): multiple definition of `__sigaction'
/tmp/tc/arm-unknown-linux-uclibcgnueabi/arm-unknown-linux-uclibcgnueabi/sysroot/usr/lib/libpthread.a(pt-sigaction.o):pt-sigaction.c:(.text+0xa0): first defined here
collect2: ld returned 1 exit status


(Well, actually there were more duplicates e.g. to __aeabi_unwind_cpp_pr0
but I've started to poke the subject with a stick to find out what's up ;-),
but see also
https://bugs.busybox.net/show_bug.cgi?id=4117
More on that later.)


Now, looking at the linker map:

- sysroot/usr/lib/libpthread.a(init.o) depends on __libc_sigaction
- thus pulls in sysroot/usr/lib/libpthread.a(pt-sigaction.o)

- sysroot/usr/lib/libc.a(abort.o) uses __GI_sigaction
  (abort() is called by malloc() is called by something during libc init)
- thus pulls in sysroot/usr/lib/libc.a(sigaction.o)

$ arm-linux-objdump -t pt-sigaction.o
./libpthread/nptl/sysdeps/pthread/pt-sigaction.o:     file format elf32-littlearm

SYMBOL TABLE:
00000000 l    df *ABS*  00000000 pt-sigaction.c
00000000 l    d  .text  00000000 .text
00000000 l    d  .data  00000000 .data
00000000 l    d  .bss   00000000 .bss
00000000 l    d  .note.GNU-stack        00000000 .note.GNU-stack
00000000 l    d  .comment       00000000 .comment
00000000 l    d  .ARM.attributes        00000000 .ARM.attributes
00000000 g     F .text  000000a0 __libc_sigaction
00000000         *UND*  00000000 memcpy
00000000         *UND*  00000000 __syscall_rt_sigaction
00000000         *UND*  00000000 __stack_chk_fail
00000000         *UND*  00000000 __stack_chk_guard
00000000         *UND*  00000000 __default_sa_restorer
00000000         *UND*  00000000 __default_rt_sa_restorer
000000a0 g     F .text  00000078 __sigaction
00000000         *UND*  00000000 __aeabi_read_tp
00000000         *UND*  00000000 errno
000000a0  w    F .text  00000078 sigaction

$ arm-linux-objdump -t sigaction.o
./libpthread/nptl/sysdeps/pthread/sigaction.o:     file format elf32-littlearm

SYMBOL TABLE:
00000000 l    df *ABS*  00000000 sigaction.c
00000000 l    d  .text  00000000 .text
00000000 l    d  .data  00000000 .data
00000000 l    d  .bss   00000000 .bss
00000000 l    d  .note.GNU-stack        00000000 .note.GNU-stack
00000000 l    d  .comment       00000000 .comment
00000000 l    d  .ARM.attributes        00000000 .ARM.attributes
00000000 g     F .text  00000078 __libc_sigaction
00000000         *UND*  00000000 __GI_memcpy
00000000         *UND*  00000000 __syscall_rt_sigaction
00000000         *UND*  00000000 __default_sa_restorer
00000000         *UND*  00000000 __default_rt_sa_restorer
00000078 g     F .text  00000038 __sigaction
00000000         *UND*  00000000 __aeabi_read_tp
00000000         *UND*  00000000 __libc_errno
00000078  w    F .text  00000038 .hidden __GI_sigaction
00000078  w    F .text  00000038 sigaction

I think either the pt-sigaction.c also needs to define __GI_sigaction,
or none of them should.


After a long search I think I found the root cause in an old git commit:

commit 6e97c25777a5da804fa5989c3ef8bebb1734b969
Author: Mike Frysinger <vapier at gentoo.org>
Date:   Mon Jun 19 03:43:20 2006 +0000

    use internal aliases for static objects as well

diff --git a/include/libc-symbols.h b/include/libc-symbols.h
index ef1e217..ec3696b 100644
--- a/include/libc-symbols.h
+++ b/include/libc-symbols.h
@@ -420,7 +420,7 @@
 # define __hidden_proto_hiddenattr(attrs...)
 #endif

-#if !defined STATIC && !defined __BCC__
+#if /*!defined STATIC &&*/ !defined __BCC__
 # ifndef __ASSEMBLER__
 #  define hidden_proto(name, attrs...) __hidden_proto (name, __GI_##name, ##attrs)
 #  define __hidden_proto(name, internal, attrs...) \


But since uClibc worked for 5 years with this change I wonder
if I'm really on the right track...
Note that glibc has the STATIC condition in place, i.e. hidden_proto
is a no-op and glibc libc.a does not seem to contain __GI_ definitions
(on my i386 host).


I'd be grateful for any insights.  Especially I would like to know
if static link with NPTL works for anyone or is it considered
to be untested or even unsupported / known to be non-working?


Thanks
Johannes


More information about the uClibc mailing list