本文介绍了为什么在直接链接和dlopen之间的功能使用不同的内存地址的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当同一个库链接并与dlopen一起使用时,同一个函数(在本示例中为sqrt)具有不同的内存地址.你能解释为什么会这样吗?有间接关系吗?

When same library is linked and used with dlopen, same function (sqrt in this example) has different memory addresses. Can you please explain why it is so? Is there some indirection?

# 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
#

推荐答案

阅读Drepper的(长篇论文) 如何编写共享库 ,并仔细研究 ELF 格式.参见 elf(5) objdump(1) ldd(1) readelf(1) ld-linux(8) dlopen(3) dlsym(3 )

Read Drepper's (long) paper How To Write Shared Libraries and study carefully the ELF format. See elf(5), objdump(1), ldd(1), readelf(1), ld-linux(8), dlopen(3), dlsym(3)

是,过程链接表,请参见.

Yes, the Procedure Linkage Table, see this.

还请注意dlopen的特殊情况,该文件带有NULL文件路径(以获取整个程序的句柄),以及dlopen ....

Notice also the special case of dlopen with a NULL file path (to get a handle to your entire program), and the various flags to dlopen ....

这篇关于为什么在直接链接和dlopen之间的功能使用不同的内存地址的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!