hi,
consider the following code, call it loader.c:
petrie:~/weak$ cat loader.c
#include <stdio.h>
#include <stdlib.h>
#include <dlfcn.h>
int main(int argc, const char *argv[]) {
/* make gcc -pedantic happy. --nenolod */
union {
void *addr;
void (*func)(void);
} dlcompat_runner_f;
void *dlptr;
dlptr = dlopen("./test-attribute-weak.so", RTLD_GLOBAL |
RTLD_LAZY); if (dlptr == NULL)
{
printf("error: %s\n", dlerror());
return EXIT_FAILURE;
}
dlcompat_runner_f.addr = dlsym(dlptr, "runner");
dlcompat_runner_f.func();
dlclose(dlptr);
return EXIT_SUCCESS;
}
compile it like so:
petrie:~/weak$ gcc -o loader loader.c -ldl
now, consider the test-attribute-weak sources:
petrie:~/weak$ cat test-attribute-weak.c
#include <stdio.h>
void strong_symbol(void) {
printf("this is a strongly-linked symbol\n");
}
void weak_symbol(void) __attribute__((weak));
void undef_symbol(void);
void runner(void) {
strong_symbol();
if (weak_symbol != NULL)
weak_symbol();
else
printf("weak_symbol() couldn't be resolved\n");
undef_symbol();
}
compile it like so:
petrie:~/weak$ gcc -fPIC -shared -o test-attribute-weak.so
test-attribute-weak.c
now run:
petrie:~/weak$ ./loader
/home/nenolod/weak/loader: symbol 'undef_symbol': can't resolve symbol
error: (null)
this is wrong. since it's RTLD_LAZY, we shouldn't care about
undef_symbol until we actually try to use it.
this is what happens on a libc6 system (Debian EGLIBC-based):
nenolod@carpathia:~/weak$ ./loader
this is a strongly-linked symbol
weak_symbol() couldn't be resolved
./loader: symbol lookup error: ./test-attribute-weak.so: undefined
symbol: undef_symbol
the behaviour is similar on freebsd and solaris.
when running ./loader with LD_DEBUG=all, we get:
do_dlopen():365: Trying to dlopen './test-attribute-weak.so', RTLD_GLOBAL:1
RTLD_NOW:0
_dl_load_shared_library:219: find library='test-attribute-weak.so'; searching
_dl_load_shared_library:225: trying file='./test-attribute-weak.so'
_dl_load_elf_shared_library:898:
file='./test-attribute-weak.so'; generating link map
_dl_load_elf_shared_library:899: dynamic: 0x7fe20569d770 base:
0x7fe20549d000
_dl_load_elf_shared_library:901: entry: 0x7fe20549d524 phdr:
0x7fe20549d040 phnum: 0x5
do_dlopen():399: Looking for needed libraries
do_dlopen():416: Trying to load 'libc.so.0.9.32', needed by
'./test-attribute-weak.so'
_dl_load_shared_library:219: find library='libc.so.0.9.32'; searching
_dl_load_shared_library:281: searching cache='/etc/ld.so.cache'
do_dlopen():416: Trying to load 'ld64-uClibc.so.0.9.32', needed by
'/lib/libc.so.0.9.32'
_dl_load_shared_library:219: find library='ld64-uClibc.so.0.9.32'; searching
_dl_load_shared_library:281: searching cache='/etc/ld.so.cache'
INIT/FINI order and dependencies:
lib: ./test-attribute-weak.so has deps:
/lib/libc.so.0.9.32
lib: /lib/libc.so.0.9.32 has deps:
/lib/ld64-uClibc.so.0.9.32
lib: /lib/ld64-uClibc.so.0.9.32 has deps:
do_dlopen():501: Beginning dlopen relocation fixups
_dl_fixup:923: relocation processing: ./test-attribute-weak.so
__cxa_finalize
value=0x0 size=0x0 info=0x22 other=0x0
shndx=0x0
R_X86_64_GLOB_DAT offset=0x2008e0 addend=0x0
patched: 0x0 ==> 0x7fe2056e419c @ 0x7fe20569d8e0
weak_symbol
value=0x0 size=0x0 info=0x20 other=0x0
shndx=0x0
R_X86_64_GLOB_DAT offset=0x2008e8 addend=0x0
patched: 0x0 ==> 0x0 @ 0x7fe20569d8e8
_Jv_RegisterClasses
value=0x0 size=0x0 info=0x20 other=0x0
shndx=0x0
R_X86_64_GLOB_DAT offset=0x2008f0 addend=0x0
patched: 0x0 ==> 0x0 @ 0x7fe20569d8f0
undef_symbol
value=0x0 size=0x0 info=0x10 other=0x0
shndx=0x0
R_X86_64_JUMP_SLOT offset=0x200910 addend=0x0
/home/nenolod/weak/loader: symbol 'undef_symbol': can't resolve symbol
do_dlclose():765: ./test-attribute-weak.so: usage count: 1
do_dlclose():792: unmapping: ./test-attribute-weak.so
do_dlclose():919: removing loaded_modules: ./test-attribute-weak.so
do_dlclose():937: removing symbol_tables: ./test-attribute-weak.so
error: (null)
_dl_fini:265:
calling FINI: /lib/libdl.so.0.9.32
is there some reason why the behaviour is this way? i couldn't imagine
that being the case as it's not posixly-correct.
william
_______________________________________________
uClibc mailing list
[email protected]
http://lists.busybox.net/mailman/listinfo/uclibc