将应用程序与动态共享库(如
)链接时gcc -o myprog myprog.o -lmylib
我知道链接器(我的Linux上的ld
)使用-l选项在生成的myprog ELF可执行文件中存储将使用的库的名称(在本例中为mylib
)在加载和链接时(如果我们忽略惰性动态链接,程序将启动时)。我想知道有关动态共享库的ld
(我只是谈到编译时完成的静态链接步骤)执行的其他工作是什么?
ld
必须检查提供的动态共享库中是否存在未定义的符号此外,我将对您使用的指针(书籍,在线文档)感兴趣,这些指针与ELF格式以及动态链接和加载过程有关。
答案 0 :(得分:4)
当你遇到ld
链接到ELF共享库时需要做的最明显的事情时,还有一些你错过了。我会重新陈述你提到的那些并添加更多:
确保解析所有未定义的符号(除非输出是共享库本身,在这种情况下,未定义的符号有效)。
在输出文件的DT_NEEDED
对象的_DYNAMIC
记录中存储对库的引用。
如果输出不是与位置无关的,并且在共享库中引用对象(在数据的意义上,而不是函数),则生成复制重定位以将对象的原始图像复制到主程序中加载时的数据段和正确的符号表条目,以便对共享库本身中的对象的引用解析为主程序中的新副本,而不是库中的原始副本。
为ld
中未解析的输出中的每个函数调用的目标生成PLT thunks - 时间到输出中的定义。
这些是我能想到的特定于共享库使用的任务,当然不包括链接器已经完成的与静态链接相同的所有工作。考虑ld
对动态链接的作用的一种方法是它使对象文件具有大量的重定位类型(表示编译器或汇编器可以生成的任何内容)并解析除少数它们之外的所有内容(对于静态)链接,该数字将为零),其中所有剩余的重定位都适合动态链接器在加载时可解析的更有限的类型集。
答案 1 :(得分:2)
一个重要的步骤是创建动态符号表,运行时链接程序ld.so
可以使用它在运行时将可执行文件链接到库。它还将编写动态重定位表,以记录需要更改哪些机器代码位置以指向动态链接的符号。要查看详细信息:
objdump -T myprog
objdump -R myprog
另请注意,写入可执行文件的字符串实际上是库的SONAME
,可能类似于mylib.so.0
。这将确保即使您稍后安装较新且不兼容的mylib.so.1.42
,可执行文件也将使用兼容的ABI版本0。有关详细信息:
ldd myprog
当然,链接器还会将您的目标文件相互链接,但由于即使在没有动态共享库的情况下也会这样做,我认为您对它的这部分操作不感兴趣。