可执行文件复制到内存后,动态链接程序是否会修改引用?

问题描述

假设我们有以下代码

main.c

extern void some_function();

int main()
{
   some_function();
   return 0;
}

mylib.c

void some_function()
{
   ...
}

我已经创建了一个共享库mylib.so,并将我链接到可执行对象文件prog

linux> gcc -shared -fpic -o mylib.so mylib.c
linux> gcc -o prog main.c ./mylib.so

我们假设下图是prog

的可执行对象格式

enter image description here

通过动态链接,我们知道此时mylib.so代码段或数据段实际上均未复制到可执行文件prog2l中。相反,链接器将复制一些重定位和符号表信息,以允许在加载时解析对mylib.so中的代码和数据的引用。

我只想仔细检查一下我的理解是否正确:

prog由加载程序加载到内存中时,如下图所示

enter image description here

然后,动态链接器将修改内存中.data的{​​{1}}部分,以便可以将其链接/重定位到prog部分中的some_function的指令地址。的.text

我的理解正确吗?

解决方法

完全关闭。动态链接器将修改数据段中的某些内容,而不是.data节中的特定内容-这些段是粗粒度的内容,与文件如何映射到内存而不是原始语义分解相对应。实际部分通常称为.got.got.plt,但可能因平台而异。修改不是“将其重定位到指令地址”,而是解析对函数名称的重定位引用以获取加载该地址的地址,然后将该地址填充到其中。