the shared library RPATH and the binary RPATH priority

别来无恙 提交于 2019-12-07 16:34:29

问题


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.


回答1:


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.

This does not contradict the dynamic linker doc (look for Rpath token expansion):

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

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

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]

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

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.

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.



来源:https://stackoverflow.com/questions/23006930/the-shared-library-rpath-and-the-binary-rpath-priority

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!