[英]how does dynamic linker resolve references while the application is running?
假设我有一个源文件dll.c
,它使用dlopen
和dlsym
函数在运行时加载一个名为F.so
的共享库。
dll.c
有对some_function()
的引用,而F.so
有some_function()
的定义。
假设下图是通过以下方式获得的可执行对象prog
linux> gcc -rdynamic -o prog dll.c -ldl
所以.text
部分包含了some_function()
的引用,当 porgram 加载F.so
并开始调用some_function()
时需要解析该引用
我的问题是:
Q1-在我看来,RAM 中的.text
部分( some_function()
所属的部分)(可执行文件被复制到内存中)需要由动态链接器修改,以便可以解析some_function()
的引用,是我的理解正确吗?
Q2-如果动态链接器需要修改RAM中的.text
段,它是怎么做的? 根据我的理解, .text
段是 RAM 中的只读段,如果它被称为只读,如何修改只读段?
Q1-在我看来,RAM(可执行文件被复制到内存中)中的 .text 部分(some_function() 所属的部分)需要由动态链接器修改,以便可以解析 some_function() 的引用,是我的理解正确吗?
不必如此。 有PLT(程序链接表)。 它本质上是这样的:
foo@PLT:
jmp <someTemporaryAddress>
main:
call foo@PLT
然后,在运行时,动态链接器只修补这一部分,因为它比在大量机器代码中查找调用更简单。
Q2-如果动态链接器需要修改RAM中的.text段,它是怎么做的? 根据我的理解,.text 段是 RAM 中的只读段,如果它被称为只读,如何修改只读段?
它在使其可执行/只读之前完成。
Q1 - 在我看来,RAM 中的 .text 部分(some_function() 所属的部分)(可执行文件被复制到内存中)需要由动态链接器修改......
不。实际代码使用间接跳转:
.text
...
call *xsome_function
...
.data
xsome_function:
.long some_function
...所以call
指令不会跳转到某个地址,而是会跳转到存储在.data
部分中的某个地址。 动态链接器必须替换.long some_function
行中的地址,而不是call
指令中的地址。
如果链接包含“直接” call
指令的代码,链接器将执行 JCWasmx86 在其回答中所写的操作:
.text
...
call some_function@PLT
...
some_function@PLT:
jmp *xsome_function
.data
xsome_function:
.long some_function
再一次,动态链接器只需要替换.data
部分中的地址。
dlopen
如果您使用dlopen
和dlsym
访问您的库,则动态链接器甚至不会替换任何内容:
dlsym()
返回一些函数指针,该指针的处理方式与其他函数返回的任何其他指针一样(如malloc()
返回的指针)。 调用dlsym()
的程序负责以某种方式存储指针。
当使用函数指针调用函数时,编译器总是会创建一个间接跳转指令(例如call %eax
)。
Q2 - 如果动态链接器需要修改 RAM 中的 .text 部分,...
几年前,我为 Linux 编写了一些小型编译器/链接器。
因为我来自 Windows 开发,并且 Window 的动态链接器实际上替换了.text
部分中的地址,所以我编写编译器/链接器的方式与在 Windows 下相同:
结果:动态链接器 ( ld-linux.so
) 在运行使用我的编译器编译的程序时崩溃,导致“分段错误”,因为动态链接器无法写入 Linux 下的.text
段。
- 编辑 -
一个例子:
如果使用dlopen()
和dlsym()
,C 代码看起来不是这样的:
extern double sin(double x);
...
sine = sin(angle);
相反,C 代码如下所示:
static double (*psin)(double x);
...
sofile = dlopen("libm.so",FLAGS);
psin = dlsym(sofile,"sin");
...
sine = psin(angle);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.