patchelf
patchelf copied to clipboard
Add option to replace an imported symbol
Is your feature request related to a problem? Please describe.
Using the rpath arguments (e.g. --add-rpath
), patchelf can override the location of libraries. However, libraries have other ways of depending on file system paths. A common example is drivers containing a hard-coded path to firmware binaries, which the library fopen()
s.
Example: Broadcom fingerprint driver, the .so contains a hardcoded path to /var/lib/fprint/fw
.
Currently it is difficult to replace such paths.
Describe the solution you'd like
Add a new argument to patchelf, --replace-symbol NAME_ORIG NAME_NEW
. If specified, patchelf will iterate over the symbol table (.dynsym
section), and replace the symbol with the name NAME_ORIG with NAME_NEW, adding it to the .dynstr
section if neccessary.
This allows one to replace the fopen
call from the library with a wrapper function, which can inspect the path it receives and change it if neccessary.
Example invocation:
$ # assume that fopen_wrapper.c defines a `fopen_wrapper()` function with the same signature as `fopen()`
$ cc -fPIC -shared fopen_wrapper.c -o libfopen_wrapper.so
$ patchelf \
--replace-symbol fopen fopen_wrapper \
--add-needed libfopen_wrapper.so \
libdriver.so
Describe alternatives you've considered
- Use
buildFHSUserEnv
from nixpkgs to give the process the filesystem layout it needs. - Use LD_PRELOAD to inject the wrapper into the process.
These methods have the disadvantage that they affect an entire process tree, not just the single library that needs patching.
Additional context I have a prototype quality implementation of this feature. If this feature request is accepted, I'll clean it up and add tests/documentation for it.
Upstreaming of this feature has been requested by the iscan-snap project, which attempts to package scanner drivers using snap.
Sorry for the late response. I just now catched up with the latest issues and PRs in the project again. This sounds like a useful feature to me, so I would accept it. Please also add a test and the documentation for it. Thanks.
This issue has been mentioned on NixOS Discourse. There might be relevant details there:
https://discourse.nixos.org/t/writing-derivation-for-binary-driver-that-accesses-hard-coded-paths-in-the-fhs/22969/6
This might be helpful: https://github.com/NixOS/patchelf/pull/459
I think this can be closed after #459 was merged
#459 is failing for me in https://github.com/RyanGibb/nixos/commit/62a7d093e617b37909f3713bd37b068b3e65e18a with: patchelf: error: Span access out of range.
Thanks for reporting this! I'll investigate.
Thank you @brenoguim!
You can build it (on x86_64-linux
) with nix build github:ryangibb/nixos/cctk-patchelf-rename-dynamic-symbols#cctk
(and nix build github:ryangibb/nixos#cctk
with raphaelr's fork).
Opened a PR with a fix: https://github.com/NixOS/patchelf/pull/473 I will add the test first and then make it ready to merge.
It works!
Oops, I force pushed. That might affect your patch (I don't know if the hash is still valid).
Thanks for the heads up! I don't think github garbage collects repositories that often, but I'll update date it if it becomes an issue (and when it's merged anyway).
I am getting the span access out of range with rename-dynamic-symbols.sh and I am building for s390x,
Error below,
[ 17s] renaming dynamic symbol f1450 to f1450_special_suffix [ 17s] patchelf: error: Span access out of range. [ 17s] FAIL rename-dynamic-symbols.sh (exit status: 1)
Created #503 for the same.