首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >共享库RPATH和二进制RPATH优先级

共享库RPATH和二进制RPATH优先级
EN

Stack Overflow用户
提问于 2014-04-11 08:05:25
回答 1查看 7K关注 0票数 11

如果共享库链接到二进制文件,而共享库也依赖于其他库,那么共享库的RPATH和二进制的RPATH的优先级(链接器搜索顺序)是什么?二进制的RPATH可以覆盖共享库中的一个吗?我在共享库RPATH中设置的$ORIGIN引用库位置还是二进制位置?

提前谢谢。

EN

回答 1

Stack Overflow用户

发布于 2018-10-04 12:47:50

根据我的观察,如果有一个应用程序main动态加载库first.so,而后者又动态加载库second.so,并且mainfirst.so都包含RPATH,那么动态链接器将首先使用first.so的RPATH搜索second.so,将$ORIGIN解析为first.so的目录,只有当它失败时,链接器才会继续到main's RPATH现在将$ORIGIN解析为d9的目录。

这与动态链接器文档(查找Rpath令牌扩展)并不矛盾:

$ORIGIN (或等效${原产地}):这将扩展到包含程序或共享对象的目录。..。

为了检查这一点,我创建了一个测试应用程序和两个库:main、liba和libb。main与liba链接,liba与libb链接。

代码语言:javascript
复制
main -> liba.so -> libb.so

构建的二进制文件是这样定位的:

代码语言:javascript
复制
/cwd/main
/cwd/lib/liba.so
/cwd/lib/libb.so

main和liba都是使用--rpath=\$ORIGIN/lib链接器标志构建的:

代码语言:javascript
复制
~$ readelf -a /cwd/main | grep ORIGIN
 0x000000000000000f (RPATH)              Library rpath: [$ORIGIN/lib]
~$ readelf -a /cwd/lib/liba.so | grep ORIGIN
 0x000000000000000f (RPATH)              Library rpath: [$ORIGIN/lib]

环境变量的帮助下,我检查了动态链接器如何处理RPATH:

代码语言:javascript
复制
~$ LD_DEBUG=libs /cwd/main
:     find library=liba.so [0]; searching
:      search path=/cwd/lib/tls/x86_64:/cwd/lib/tls:/cwd/lib/x86_64:/cwd/lib              (RPATH from file /cwd/main)
:       trying file=/cwd/lib/tls/x86_64/liba.so
:       trying file=/cwd/lib/tls/liba.so
:       trying file=/cwd/lib/x86_64/liba.so
:       trying file=/cwd/lib/liba.so
94313:
:     find library=libc.so.6 [0]; searching
:      search path=/cwd/lib                (RPATH from file /cwd/main)
:       trying file=/cwd/lib/libc.so.6
:      search cache=/etc/ld.so.cache
:       trying file=/lib/x86_64-linux-gnu/libc.so.6
94313:
:     find library=libb.so [0]; searching
:      search path=/cwd/lib/lib/tls/x86_64:/cwd/lib/lib/tls:/cwd/lib/lib/x86_64:/cwd/lib/lib              (RPATH from file /cwd/lib/liba.so)
:       trying file=/cwd/lib/lib/tls/x86_64/libb.so
:       trying file=/cwd/lib/lib/tls/libb.so
:       trying file=/cwd/lib/lib/x86_64/libb.so
:       trying file=/cwd/lib/lib/libb.so
:      search path=/cwd/lib                (RPATH from file /cwd/main)
:       trying file=/cwd/lib/libb.so

从中我们可以看到,链接器首先遇到了加载liba.so的需要,并使用main二进制的RPATH来解决这个问题。然后,它满足了加载libb.so的需要,它首先使用liba.so库的RPATH来解决这个问题。但是,由于RPATH是$ORIGIN/lib,而libb.so与liba.so位于同一个目录中,所以链接器无法使用liba.so的RPATH找到libb.so,然后返回到main的RPATH,只有使用后者才能成功地找到libb.so。

测试环境: Linux 4.15.0-34-泛型#37~16.04.1-Ubuntu (64位),/lib/x86_64-linux-gnu/ld-2.23.so。

票数 11
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/23006930

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档