Dynamically linked ELF executables always specify a dynamic linker or interpreter, which is a program that actually loads the executable along with all its dynamically linked libraries. (The kernel just loads the interpreter, not the executable.) For example, on a Linux/x86 system the ELF interpreter is typically the file /lib/ld-linux.so.2. It is sometimes necessary to use a different ELF interpreter, say, when you want to test a version of Glibc installed in a location other than /lib. And in the Nix Packages collection we build our own Glibc, which we obviously want to use. Building programs with a different interpreter is a matter of using the linker flag -dynamic-linker:
gcc -Wl,-dynamic-linker,/my/lib/ld-linux.so.2 ...
However, this doesn’t work with third-party binaries (such as Adobe Reader in Nixpkgs). This is where PatchELF comes in. You can simply rewrite the executable:
patchelf --set-interpreter /my/lib/my-ld-linux.so.2 program
This modifies the interpreter section of program to refer to the specified file. This is not quite trivial because the path of the new interpreter may be longer than the old one, in which case it won’t fit. PatchELF takes care of “growing” the executable with sufficient space at the beginning to contain the new interpreter field. As a result, the resulting program may be one page (4 KiB) larger.
Likewise, you can change the RPATH, the linker search path embedded into executables and dynamic libraries:
patchelf --set-rpath /opt/my-libs/lib:/foo/lib program
This causes the dynamic linker to search in /opt/my-libs/lib and /foo/lib for the shared libraries needed by program. Of course, you could also set the environment variable LD_LIBRARY_PATH, but that’s often inconvenient as it requires a wrapper script to set up the environment.
Finally, it is possible to remove unused paths from the RPATH:
patchelf --shrink-rpath program
A path is considered unused if none of the program’s library dependencies can be found in that path. This is primarily useful in the standard build environment of Nixpkgs, where it is used to get rid of unnecessary runtime dependencies.
PatchELF has been tested on i386-linux, x86_64-linux and powerpc-linux. It should definitely work on all 32 or 64-bit, big or little-endian Linux platforms. With minor modifications it should also work on other ELF platforms.
You can report bugs in the issue tracker.