.so依赖图中的符号查找顺序

时间:2019-02-13 06:22:45

标签: linker shared-libraries elf

假设我有一个.so中引用的共享对象加载时间相关性图和符号foo。还假设此符号foo在其他几个共享对象中定义。我的问题是:将找到哪个定义,查找顺序是什么,在哪里定义(以什么标准,手册页)?

示例: 考虑依赖图 https://i.imgur.com/jdhD3V0.png

其中库以ldd顺序列出,例如

ldd a.so
b.so
d.so

我们假设foo在c.so和d.so中定义,并且首先在f.so中引用。我的实验表明,链接器将采用d.so的实现。好像是按bfs顺序搜索库。这是正确的吗?这是否与库的加载顺序一致?我在任何文档中都找不到,并且必须确保它没有实现定义。

谢谢!

1 个答案:

答案 0 :(得分:2)

ELF specfication中指定了动态链接。 (请注意,周围有一些非常古老的PDF和Postscript文件,但它们通常已经过时。)Shared Object Dependencies部分描述了符号查找:

  

在解析符号引用时,动态链接器使用广度优先搜索来检查符号表。也就是说,它首先查看可执行程序本身的符号表,然后依次查看DT_NEEDED条目的符号表,然后查看第二级DT_NEEDED条目,依此类推。

(有多种扩展名可以改变这种行为。ELF规范本身定义了DF_SYMBOLIC flag。)

这意味着您的问题无法回答,因为您的图形未显示主要的可执行文件,并且不清楚按哪个顺序搜索多个依赖项(从上到下或从下到上)。

查找顺序是否与对象加载顺序相匹配是由实现定义的,因为根据ELF规范,仅加载对象(不执行其初始化功能)并不具有可观察到的效果。

Initialization order(执行初始化函数的顺序)比符号查找顺序受的约束要少,因为DT_NEEDED条目的顺序对此并不重要。因此,从理论上讲,实现有可能在d.so之前加载初始化b.so,但是b.so中的符号会插入d.so的符号,因为它首先出现在符号搜索中顺序(由于DT_NEEDED条目的排序方式)。