static linking is broken with -ldl

Natanael Copa natanael.copa at gmail.com
Wed Sep 8 13:56:48 UTC 2010


Hi,

It seems like static linking is broken when -ldl is there:

ncdev:~/testcase$ cat dlopen-test.c
#include <stdlib.h>
#include <dlfcn.h>

int main(int argc, char *argv[])
{
	return dlopen(argv[1], RTLD_NOW) != NULL;
}
ncdev:~/testcase$ gcc -static  dlopen-test.c -ldl
/usr/lib/gcc/i486-alpine-linux-uclibc/4.4.4/../../../libdl.a(libdl.os):
In function `_dl_load_elf_shared_library':
libdl.c:(.text._dl_load_elf_shared_library+0xa7c): undefined reference
to `_dl_next_tls_modid'
/usr/lib/gcc/i486-alpine-linux-uclibc/4.4.4/../../../libdl.a(libdl.os):
In function `dlopen':
libdl.c:(.text.dlopen+0x419): undefined reference to `_dl_add_to_slotinfo'
/usr/lib/gcc/i486-alpine-linux-uclibc/4.4.4/../../../libdl.a(libdl.os):(.text._dl_do_reloc+0x189):
undefined reference to `_dl_allocate_static_tls'
/usr/lib/gcc/i486-alpine-linux-uclibc/4.4.4/../../../libdl.a(libdl.os):(.text._dl_do_reloc+0x1a7):
undefined reference to `_dl_allocate_static_tls'
/usr/lib/gcc/i486-alpine-linux-uclibc/4.4.4/../../../../i486-alpine-linux-uclibc/bin/ld:
a.out: hidden symbol `_dl_allocate_static_tls' isn't defined
/usr/lib/gcc/i486-alpine-linux-uclibc/4.4.4/../../../../i486-alpine-linux-uclibc/bin/ld:
final link failed: Nonrepresentable section on output
collect2: ld returned 1 exit status

the missing symbols seems to be defined in
ldso/ldso/dl-tls.c

Ater grepping around in the source tree my first reaction was to do
something like:

diff --git a/ldso/libdl/libdl.c b/ldso/libdl/libdl.c
index 3957e84..d0cbfe8 100644
--- a/ldso/libdl/libdl.c
+++ b/ldso/libdl/libdl.c
@@ -117,6 +117,7 @@ struct r_debug *_dl_debug_addr = NULL;
  * static TLS area, see __libc_setup_tls (libc-tls.c).
  */
 size_t _dl_tls_static_size = 2048;
+#include "../ldso/dl-tls.c"
 # endif
 #include LDSO_ELFINTERP
 #include "../ldso/dl-hash.c"

But that gave lots of duplicate symbols when building apk-tools static
(alpine linux package manager)
/usr/lib/gcc/i486-alpine-linux-uclibc/4.4.4/../../../libc.a(libc-tls.os):
In function `_dl_tls_setup':
libc-tls.c:(.text._dl_tls_setup+0x0): multiple definition of `_dl_tls_setup'
/usr/lib/gcc/i486-alpine-linux-uclibc/4.4.4/../../../libdl.a(libdl.os):libdl.c:(.text._dl_tls_setup+0x0):
first defined here
/usr/lib/gcc/i486-alpine-linux-uclibc/4.4.4/../../../libc.a(sigaction.os):
In function `__libc_sigaction':
sigaction.c:(.text.__libc_sigaction+0x0): multiple definition of
`__libc_sigaction'
/usr/lib/gcc/i486-alpine-linux-uclibc/4.4.4/../../../libpthread.a(pt-sigaction.os):pt-sigaction.c:(.text.__libc_sigaction+0x0):
first defined here
/usr/lib/gcc/i486-alpine-linux-uclibc/4.4.4/../../../libc.a(sigaction.os):
In function `sigaction':
sigaction.c:(.text.__sigaction+0x0): multiple definition of `__sigaction'
/usr/lib/gcc/i486-alpine-linux-uclibc/4.4.4/../../../libpthread.a(pt-sigaction.os):pt-sigaction.c:(.text.__sigaction+0x0):
first defined here
/usr/lib/gcc/i486-alpine-linux-uclibc/4.4.4/../../../libdl.a(libdl.os):
In function `_dl_deallocate_tls':
libdl.c:(.text._dl_deallocate_tls+0x49): undefined reference to
`_dl_initial_dtv'
/usr/lib/gcc/i486-alpine-linux-uclibc/4.4.4/../../../libdl.a(libdl.os):
In function `_dl_update_slotinfo':
libdl.c:(.text._dl_update_slotinfo+0xf5): undefined reference to
`_dl_initial_dtv'
/usr/lib/gcc/i486-alpine-linux-uclibc/4.4.4/../../../libdl.a(libdl.os):
In function `__tls_get_addr':
libdl.c:(.text.__tls_get_addr+0x80): undefined reference to `_dl_memalign'
/usr/lib/gcc/i486-alpine-linux-uclibc/4.4.4/../../../libdl.a(libdl.os):
In function `_dl_allocate_tls_storage':
libdl.c:(.text._dl_allocate_tls_storage+0x22): undefined reference to
`_dl_memalign'
collect2: ld returned 1 exit status

Anyone have idea what the proper fix is?

-- 
Natanael Copa


More information about the uClibc mailing list