Dyanamic library linking by RTLD_LAZY

c, dynamic-linking, linux

Solution

The following example should make it very clear:

libtest.so:

void bar();

void foo()
{
    bar();
}

_

$> nm libtest.so
000085d0 a _DYNAMIC
000086b0 a _GLOBAL_OFFSET_TABLE_
         w _ITM_deregisterTMCloneTable
         w _ITM_registerTMCloneTable
         w _Jv_RegisterClasses
000005c0 r __FRAME_END__
000085cc d __JCR_END__
000085cc d __JCR_LIST__
000086e0 d __TMC_END__
000086e4 B __bss_end__
000086e0 B __bss_start
000086e0 B __bss_start__
         w __cxa_finalize@@GLIBC_2.4
000004f8 t __do_global_dtors_aux
000085c8 t __do_global_dtors_aux_fini_array_entry
000086dc d __dso_handle
000086e4 B __end__
000085c4 t __frame_dummy_init_array_entry
         w __gmon_start__
000086e4 B _bss_end__
000086e0 D _edata
000086e4 B _end
000005b8 T _fini
000003e0 T _init
         U bar
00000424 t call_weak_fn
000086e0 b completed.8847
00000448 t deregister_tm_clones
000005a8 T foo
00000560 t frame_dummy
0000049c t register_tm_clones

main.c (flag == RTLD_LAZY):

#include <dlfcn.h>
#include <stdio.h>

int
main(int argc, char **argv)
{
    void *lib = dlopen("./libtest.so", RTLD_LAZY);
    if (!lib) {
        printf("error: %s\n", dlerror());
        return 0;
    }
    int (*a)() = dlsym(lib, "foo");
    printf("a: %p\n", a);
    (*a)();

    dlclose(lib);
    return 1;
}

$> ./main.c
a: 0xb6e225a8
./main: symbol lookup error: ./libtest.so: undefined symbol: bar

main.c (flag == RTLD_NOW):

#include <dlfcn.h>
#include <stdio.h>

int
main(int argc, char **argv)
{
    void *lib = dlopen("./libtest.so", RTLD_NOW);
    if (!lib) {
        printf("error: %s\n", dlerror());
        return 0;
    }
    int (*a)() = dlsym(lib, "foo");
    printf("a: %p\n", a);
    (*a)();

    dlclose(lib);
    return 1;
}
$> ./main.c
error: ./libtest.so: undefined symbol: bar

Problem

I am trying to find the differance between RTLD_NOW and RTLD_LAZY flags. My query is why RTLD_LAZY loading the library whose function I've never referanced. I have created a dlrun.c file ``` #include "stdio.h" #include "dlfcn.h" main() { void * ptr; void (*fptr)(void); printf("\nMy ID is- %d \n",getpid()); getchar(); ptr = dlopen("./fun5.so", RTLD_NOW); if(ptr==NULL) printf("failed to open fun5.so"); else { printf("I got fun5.so"); fptr= dlsym(ptr,"fun5"); getchar(); fptr(); printf("end of fun5"); dlclose(ptr); } } ``` the next file fun5.c as ``` #include "stdio.h" void fun2(void); void fun1(void); fun5() { printf("I am in fun5"); getchar(); fun1(); } fun() { getchar(); fun2(); } ``` other file fun1.c is ``` #include "stdio.h" fun1() { printf("I am in fun1"); getchar(); } ``` and file fun2.c is ``` #include "stdio.h" fun2() { printf("I am in fun2"); getchar(); } ``` then I use commands ``` gcc -c -fPIC -o fun1.o fun1.c gcc -c -fPIC -o fun2.o fun2.c gcc -c -fPIC -o fun5.o fun5.c gcc -shared -o fun1.so fun1.o gcc -shared -o fun2.so fun2.o gcc -shared -o fun5.so fun5.o ./fun1.so ./fun2.so gcc dlrun.c -o run -ldl ./run ``` now I want to check which libraries are loaded by ``` cd /proc/<pid> vi maps ``` Here it looks that before fun5.so calling no nonstansard libray is loaded and after calling fun5 function all fun5.so,fun1.so and fun.2.so are loaded as per expectation.Now if I replace RTLD_NOW by RTLD_LAZY then only fun5.so and fun1.so should be loaded because I have never called fun() and fun2() , but actually fun2.so is also loading.so where am I wrong? Am I wrong at creating fun5.so? if so then how should I create it? Thanks

Original source