假设我有一个.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顺序搜索库。这是正确的吗?这是否与库的加载顺序一致?我在任何文档中都找不到,并且必须确保它没有实现定义。
谢谢!
答案 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
条目的排序方式)。