据我观察,如果有一个应用程序main可以动态加载库first.so,进而动态负载库后second.so,都main和first.so含有RPATH,那么动态连接器将搜索second.so首先使用first.so的RPATH,解决$ ORIGIN为first.so的目录,并且只有当它失败时,链接器才会进入main的 RPATH 现在将 $ORIGIN 解析为main的目录。
这与动态链接器文档(查找 Rpath 令牌扩展)并不矛盾:
$ORIGIN(或等效的 ${ORIGIN}):这会扩展到包含程序或共享对象的目录。...
要检查这个我创建了一个测试应用和两个库:main,liba和libb分别。main与 相关联liba,并liba与 相关联libb:
main -> liba.so -> libb.so
Run Code Online (Sandbox Code Playgroud)
构建的二进制文件位于以下位置:
/cwd/main
/cwd/lib/liba.so
/cwd/lib/libb.so
Run Code Online (Sandbox Code Playgroud)
双方main并liba采用了最--rpath=\$ORIGIN/lib链接标志:
~$ 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]
Run Code Online (Sandbox Code Playgroud)
在LD_DEBUG环境变量的帮助下,我检查了动态链接器如何处理 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
Run Code Online (Sandbox Code Playgroud)
从中我们可以看到,链接器首先遇到加载的需要liba.so并使用main二进制文件的 RPATH 来解决这个问题。然后它遇到加载的需要libb.so,它首先使用liba.so库的 RPATH 来解决这个问题。但由于 RPATH$ORIGIN/lib与libb.so位于同一目录中liba.so,因此链接器无法找到libb.sousingliba.so的 RPATH。之后,它回退到main's RPATH 并且只使用后者它成功地找到libb.so。
测试环境:Linux ubuntu 4.15.0-34-generic #37~16.04.1-Ubuntu(64位)、/lib/x86_64-linux-gnu/ld-2.23.so。
| 归档时间: |
|
| 查看次数: |
4497 次 |
| 最近记录: |