How does this program statically link to a .so in a non-default path
A program I am using can only be installed with a custom installer (IDA Freeware Demo). I have installed it in my home dir, it all works fine.
Now I noticed when checking the program with ldd: it ships with its own Qt libraries, which is places as shared libraries in its install dir (so the same directory its main executable file resides in, not /usr/lib or similar).
$ ldd ida64
linux-vdso.so.1 => (0x00007ffec5fb9000)
libida64.so => /home/asdf/idafree-7.0/./libida64.so
libQt5PrintSupport.so.5 => /home/asdf/idafree-7.0/./libQt5PrintSupport.so.5
libQt5Widgets.so.5 => /home/asdf/idafree-7.0/./libQt5Widgets.so.5
....
(install dir = /home/asdf/idafree-7.0/)
Now I wonder: How does it do that? I execute the program directly without any LD_LIB_PATH magic.
Solution 1:
This is completely different from and unrelated to static linking. While I suppose a wrapper script could modify LD_LIBRARY_PATH before launching the program, that's not what IDA does.
When a shared library is first linked from its constituent object files, a runtime path can be specified, i.e. the --set-rpath
(short form -r
) flag. This informs the loader to look in the named directory before looking elsewhere. The path may be hard coded, or it may use the $ORIGIN
flag.
The $ORIGIN
flag allows the loader to resolve the executable's current filepath, which in turn allows an rpath to more readily work from any directory. IDA was likely just built with a flag such as -Wl,-r,$ORIGIN
. If the Qt libraries had been in a subdirectory, it would just be -Wl,-r,$ORIGIN/qtlibdir
.
There are also utilities that can edit this field after linking, such as patchelf.
All of this information may be found in the ld manual. https://man7.org/linux/man-pages/man1/ld.1.html