首页 > 解决方案 > 将可执行文件复制到内存后,动态链接器会修改引用吗?

问题描述

假设我们有以下代码:

主程序

extern void some_function();

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

mylib.c

void some_function()
{
   ...
}

我创建了一个共享库mylib.so并将 i 链接到可执行目标文件prog

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

假设下图是可执行对象格式prog

在此处输入图像描述

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

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

加载器何时prog将其加载到内存中,如下图所示

在此处输入图像描述

然后动态链接器将修改内存中的.data部分,prog以便它可以链接/重定位到 部分中some_function的指令地址。.textmylib.so

我的理解正确吗?

标签: clinuxgccdlldynamic-linking

解决方案


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


推荐阅读