c - ld 在链接动态共享库时做什么?

标签 c linux linker ld

将应用程序链接到动态共享库时,例如

gcc -o myprog myprog.o -lmylib

我知道链接器(ld 在我的 Linux 上)使用 -l 选项在生成的 myprog ELF 可执行文件中存储库的名称(mylib 在这个case) 将在加载和链接时使用(如果我们忽略惰性动态链接,则程序将在这两个时间启动)。我想知道 ld 执行的关于动态共享库的其他工作是什么(我只是说编译时完成的静态链接步骤)?

  • ld 必须检查提供的动态共享库中是否存在 undefined symbol
  • 还有其他事情吗?

此外,我会对您使用的有关 ELF 格式和动态链接和加载过程的指针(书籍、在线文档)感兴趣。

最佳答案

虽然您遇到了 ld 在链接到 ELF 共享库时需要做的最明显的事情,但您还错过了一些事情。我将重述您提到的内容并添加更多内容:

  1. 确保解析所有 undefined symbol (除非输出是共享库本身,在这种情况下 undefined symbol 是有效的)。

  2. 在输出文件的 _DYNAMIC 对象的 DT_NEEDED 记录中存储对库的引用。

  3. 如果输出不是位置无关的并且引用共享库中的对象(在数据意义上,而不是函数),则生成一个复制重定位以将对象的原始图像复制到主程序的加载时的数据段,以及正确的符号表条目,以便对共享库本身中对象的引用解析为主程序中的新副本,而不是库中的原始副本。

  4. 为输出中未在 ld 时解析为输出中的定义的每个函数调用的目标生成 PLT thunk。

这些是我能想到的特定于使用共享库的任务,当然不包括链接器已经完成的与静态链接相同的所有工作。考虑 ld 对动态链接所做的事情的一种方法是,它使用具有大量重定位类型的目标文件(代表编译器或汇编程序可以生成的任何内容)并解析除少数之外的所有目标文件(对于静态链接,该数字将为零),其中所有剩余的重定位都适合动态链接器在加载时可解析的一组更有限的类型。

关于c - ld 在链接动态共享库时做什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19736853/

相关文章:

C 管道分段故障

c - 斐波那契数列

linux - 向 btrfs 卷添加新设备,但可用大小几乎没有增长

linux - 导入错误 : No module named 'tensorrt'

gcc - 是否可以从gcc中的其他目标文件创建目标文件?

c - C 中的定点无符号除法

c - printf() 函数出错

python - 如何使用 parallel-ssh 执行 'su' 命令

c - Linux 上具有单独数据段的库的多个实例

c - IAR 为自定义数据定义内存区域