共享库RPATH和二进制RPATH优先级 [英] the shared library RPATH and the binary RPATH priority

查看:602
本文介绍了共享库RPATH和二进制RPATH优先级的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果共享库链接到二进制文件,并且共享库也依赖于其他库,则共享库的RPATH和二进制文件的RPATH的优先级(链接程序搜索顺序)是什么?二进制文件的RPATH可以覆盖共享库中的RPATH吗?我在共享库RPATH中设置的$ ORIGIN是指库位置还是二进制位置?
预先感谢.

if a shared library is linked to a binary, and the shared library also depends on other libs , what are the priorities (linker search order) of the RPATH of the shared library and the RPATH of the binary ? Could the RPATH of the binary override the one in the shared library? and the $ORIGIN I set in the shared library RPATH refers to the lib location or the binary location?
Thanks in advance.

推荐答案

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

According to my observation, if there is an application main which dynamically loads library first.so, and the latter in turn dynamically loads library second.so, and both main and first.so contain RPATH, then dynamic linker will search second.so first using the first.so's RPATH, resolving $ORIGIN as the first.so's directory, and only if it fails, the linker will proceed to the main's RPATH now resolving $ORIGIN as main's directory.

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

$ ORIGIN(或等效为$ {ORIGIN}):这会扩展到包含程序或共享对象的目录. ...

$ORIGIN (or equivalently ${ORIGIN}): This expands to the directory containing the program or shared object. ...

要进行检查,我创建了一个测试应用程序和两个库:分别为mainlibalibb. mainliba链接,而libalibb链接:

To check this I've created a test application and two libraries: main, liba and libb respectively. main is linked against liba, and liba is linked against libb:

main -> liba.so -> libb.so

构建的二进制文件的定位方式如下:

The built binaries are located this way:

/cwd/main
/cwd/lib/liba.so
/cwd/lib/libb.so

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

Both main and liba are built with the --rpath=\$ORIGIN/lib linker flag:

~$ 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]

借助 LD_DEBUG环境变量我已经检查了动态链接器如何处理RPATH:

With the help of the LD_DEBUG environment variable I've checked how dynamic linker processes RPATH:

~$ 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.soliba.so在同一目录中,因此链接程序无法使用liba.so的RPATH找到libb.so.之后,它回退到main的RPATH,仅使用后者,它才能成功找到libb.so.

From that we can see, that the linker first encounters the need to load liba.so and uses the main binary's RPATH to resolve this. Then it encounters the need to load libb.so and it first uses the liba.so library's RPATH to resolve this. But since the RPATH is $ORIGIN/lib and libb.so is in the same directory as liba.so, the linker fails to find libb.so using liba.so's RPATH. After that it falls back to main's RPATH and only using the latter it succeeds to find libb.so.

测试环境:Linux ubuntu 4.15.0-34-通用#37〜16.04.1-Ubuntu(64位),/lib/x86_64-linux-gnu/ld-2.23.so.

Test environment: Linux ubuntu 4.15.0-34-generic #37~16.04.1-Ubuntu (64-bit), /lib/x86_64-linux-gnu/ld-2.23.so.

这篇关于共享库RPATH和二进制RPATH优先级的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆