【问题标题】:Why different memory addresses for a function between direct linking and dlopen为什么直接链接和 dlopen 之间函数的内存地址不同
【发布时间】:2018-01-05 08:20:48
【问题描述】:

当同一个库被链接并与 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
#

【问题讨论】:

  • 你为什么要问,真正的用例是什么?请编辑您的问题以激发它并提供更多背景信息。大多数时候,你观察到什么并不重要。
  • 感谢您的回复。我正处于探索使共享库既可链接又可插入的方法的早期阶段。我试图看看这是否可以在不重新编译的情况下实现。一个后续问题:有没有办法在没有 dlopen 上下文的情况下获取函数或符号的地址(已链接到应用程序)。

标签: linker dlopen


【解决方案1】:

阅读 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 的各种标志 ....

【讨论】:

    猜你喜欢
    • 2013-03-20
    • 1970-01-01
    • 2018-06-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-02-15
    • 2016-12-01
    • 2022-07-20
    相关资源
    最近更新 更多