为什么直接链接和dlopen之间的函数的不同内存地址

时间:2018-01-05 08:20:48

标签: linker dlopen

当链接相同的库并与dlopen一起使用时,相同的函数(本例中为sqrt)具有不同的内存地址。你能解释一下为什么会这样吗?是否有一些间接?

# cat dl-test.c
#include <stdio.h>
#include <stdlib.h>
#include <dlfcn.h>
#include <math.h>
#include <inttypes.h>

int main()
{
        void *dl, *dl_sqrt;

        dl = dlopen("/lib/x86_64-linux-gnu/libm.so.6", RTLD_LAZY);
        if (!dl) {
                fprintf(stderr, "%s\n", dlerror());
                exit(1);
        }

        dl_sqrt = dlsym(dl,"sqrt");
        if (!dl_sqrt) {
                fprintf(stderr, "%s\n", dlerror());
                exit(1);
        }

        printf("Address of sqrt %p\n", (void*) sqrt);
        printf("Address of (dl)sqrt %p\n", (void*) dl_sqrt);
        return 0;
}
#
# gcc dl-test.c -lm -ldl -o dl-test
# ldd dl-test
        linux-vdso.so.1 =>  (0x00007fff9132b000)
        libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f4caee90000)
        libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f4caec8c000)
        libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f4cae8c1000)
        /lib64/ld-linux-x86-64.so.2 (0x0000559a02daa000)
# ./dl-test
Address of sqrt 0x4006d0
Address of (dl)sqrt 0x7fa7ce6f7250
#

1 个答案:

答案 0 :(得分:2)

阅读Drepper的(长篇)论文How To Write Shared Libraries并仔细研究ELF格式。见elf(5)objdump(1)ldd(1)readelf(1)ld-linux(8)dlopen(3)dlsym(3)

  

是否有一些间接?

是,程序链接表,请参阅this

另请注意dlopen具有NULL文件路径(以获取整个程序的句柄)的特殊情况,以及dlopen的各种标志....