2013-11-01 44 views
2

当链接到的动态共享库的应用程序,如当链接到动态共享库时,ld会做什么?

gcc -o myprog myprog.o -lmylib 

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

  • ld必须检查未定义的符号存在于提供动态共享库
  • 任何其他东西?

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

回答

3

虽然你在链接到ELF共享库时最需要做的事情是ld,但还有一些你错过了。我会重新状态,你提到的那些更增添了一些:

  1. 确保所有未定义的符号都解决了(除非输出是共享库本身,在这种情况下未定义符号是有效的)。

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

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

  4. 为输出中的每个函数调用的目的地生成PLT thunks,该输出中未解析的输出中的ld时间为输出中的定义。

这是我能想到的,是专门针对使用共享库的任务,当然不包括链接已经没有这将是一样的静态链接的所有工作。一种考虑ld对动态链接做什么的方法是,它需要带有大量重定位类型的目标文件(代表编译器或汇编程序可以生成的任何东西),并解析除少数目标文件外的所有文件(对于静态链接,将为零),其中所有剩余的重定位适合动态链接器在加载时可解析的更多有限类型的集合。

2

一个重要的步骤是创建一个动态符号表,运行时链接程序ld.so可用于在运行时将该可执行文件链接到库。它还将编写动态重定位表以注意哪些机器代码位置需要更改为指向动态链接的符号。要查看详细信息:

objdump -T myprog 
objdump -R myprog 

还要注意的是写入可执行文件的字符串实际上是图书馆的SONAME,这可能是这样的mylib.so.0。这将确保即使您稍后安装了较新且不兼容的mylib.so.1.42,可执行文件也会使用兼容的ABI版本0。有关详情:

ldd myprog 

当然,链接器也将链接对象文件中对彼此,但因为它即使在没有动态共享库的,我认为你这个不感兴趣部分操作。