Permalink
Switch branches/tags
Nothing to show
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
112 lines (80 sloc) 3.77 KB
[% WRAPPER layout.tt title="PatchELF" menu='patchelf' %]
<p>PatchELF is a small utility to modify the dynamic linker and <a
href="https://en.wikipedia.org/wiki/Rpath_%28linking%29">RPATH</a> of
<a
href="https://en.wikipedia.org/wiki/Executable_and_Linkable_Format">ELF
executables</a>.</p>
<section><h2>Description</h2>
<p>Dynamically linked ELF executables always specify a dynamic linker
or <em>interpreter</em>, 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
<tt>/lib/ld-linux.so.2</tt>. 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 <tt>/lib</tt>. And in the <a
href="nixpkgs">Nix Packages collection</a> 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
<tt>-dynamic-linker</tt>:</p>
<pre class="code">
gcc -Wl,-dynamic-linker,/my/lib/ld-linux.so.2 ...
</pre>
<p>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:</p>
<pre class="code">
patchelf --set-interpreter /my/lib/my-ld-linux.so.2 program
</pre>
<p>This modifies the interpreter section of <tt>program</tt> 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.</p>
<p>Likewise, you can change the <em>RPATH</em>, the linker search
path embedded into executables and dynamic libraries:</p>
<pre class="code">
patchelf --set-rpath /opt/my-libs/lib:/foo/lib program
</pre>
<p>This causes the dynamic linker to search in <tt>/opt/my-libs/lib</tt>
and <tt>/foo/lib</tt> for the shared libraries needed by
<tt>program</tt>. Of course, you could also set the environment
variable <tt>LD_LIBRARY_PATH</tt>, but that’s often inconvenient as it
requires a wrapper script to set up the environment.</p>
<p>Finally, it is possible to remove unused paths from the RPATH:</p>
<pre class="code">
patchelf --shrink-rpath program
</pre>
<p>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.</p>
</section>
<section><h2>Compatibility</h2>
<p>PatchELF has been tested on <tt>i386-linux</tt>,
<tt>x86_64-linux</tt> and <tt>powerpc-linux</tt>. 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.</p>
</section>
<section><h2>Download</h2>
<p>The most recent stable release is <a
href="https://nixos.org/releases/patchelf/patchelf-0.9/">PatchELF
0.9</a>.</p>
</section>
<section><h2>Unstable releases</h2>
<p>You can get the latest source code of PatchELF from its <a
href="https://github.com/NixOS/patchelf">Git
repository</a>. You can also download the <a
href="https://hydra.nixos.org/job/patchelf/trunk/release/latest#tabs-constituents">latest
pre-release</a>, or view a <a
href="https://hydra.nixos.org/job/patchelf/trunk/release#tabs-constituents">list of all
prereleases</a> built in our build farm.</p>
</section>
<section><h2>Bugs</h2>
<p>You can <strong>report bugs</strong> in the <a
href="https://github.com/NixOS/patchelf/issues">issue tracker</a>.</p>
</section>
[% END %]