the shared library RPATH and the binary RPATH priority

前端 未结 1 1726
一整个雨季
一整个雨季 2021-02-15 15:25

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 a

1条回答
  •  盖世英雄少女心
    2021-02-15 15:59

    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.

    0 讨论(0)
提交回复
热议问题