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

Reply via email to