On osx loader, @loader_path resolves to the position of the generic binary object, and @executable_path to the position of the executable. On Linux, apparently there's only $ORIGIN, which resolves to the executable path. Is there a hidden feature in the linux loader to specify a dynamic search path for a generic ELF object? Or maybe $ORIGIN behaves differently for so objects?
Linux also has $LIB and $PLATFORM, but they don't provide what I need.
$ORIGIN
is the location of the object being loaded, so it is different in the executable and shared libraries loaded by the executable.
Edit: Here's a small test I performed to check:
~$ mkdir /tmp/tests
~$ cd /tmp/tests
tests$ mkdir good bad
tests$ gcc -fPIC -shared -o good/libtest.so -Wl,-rpath,\$ORIGIN -x c - <<< 'int puts(const char*); void foo() { puts("good"); }'
tests$ gcc -fPIC -shared -o bad/libtest.so -Wl,-rpath,\$ORIGIN -x c - <<< 'int puts(const char*); void foo() { puts("bad"); }'
tests$ gcc -fPIC -shared -o good/libtest2.so -Wl,-rpath,\$ORIGIN -x c - -ltest -Lgood <<< 'void foo(); void bar() { foo(); }'
tests$ gcc -o bad/a.out good/libtest2.so -x c - -Wl,-rpath,\$ORIGIN -Wl,-rpath-link,good <<< 'void bar(); int main() { bar(); }'
tests$
tests$ readelf -d bad/* good/* | grep RPATH
0x000000000000000f (RPATH) Library rpath: [$ORIGIN]
0x000000000000000f (RPATH) Library rpath: [$ORIGIN]
0x000000000000000f (RPATH) Library rpath: [$ORIGIN]
0x000000000000000f (RPATH) Library rpath: [$ORIGIN]
tests$
tests$ ldd bad/a.out
linux-vdso.so.1 => (0x00007faf2f295000)
good/libtest2.so (0x00007faf2f092000)
libc.so.6 => /lib64/libc.so.6 (0x0000003949800000)
libtest.so => /tmp/tests/good/libtest.so (0x00007faf2ee66000)
/lib64/ld-linux-x86-64.so.2 (0x0000003949400000)
tests$ bad/a.out
good
I think that demonstrates it works, everything has RPATH=$ORIGIN
, the executable is explicitly linked to libtest2.so
, which picks up libtest.so
in its own directory not the executable's.
Using LD_DEBUG=libs bad/a.out
shows:
[...]
17779: find library=libtest.so [0]; searching
17779: search path=/tmp/tests/good/tls/x86_64:/tmp/tests/good/tls:/tmp/tests/good/x86_64:/tmp/tests/good (RPATH from file good/libtest2.so)
[...]
i.e. when looking for the libtest.so
dependency of good/libtest2.so
the search path uses the RPATH from good/libtest2.so
, which expands to /tmp/tests/good
which is the $ORIGIN
from good/libtest2.so
not the $ORIGIN
of the executable.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With