LIEF
LIEF copied to clipboard
Support Golang or have patchelf-compatible standalone binary
Is your feature request related to a problem? Please describe. I'm always frustrated when I cannot use LIEF from within Golang.
Describe the solution you'd like Please make it possible (and easy) to use LIEF from within Golang.
Describe alternatives you've considered
Calling patchelf
from Golang (which is what I am currently doing).
Additional context
The use of CGo should be avoided. A standalone, statically linked LIEF binary with the same features as patchelf
that could be called from Golang would be sufficient for my needs.
Yes, bindings for Java and Golang would be nice! I don't think I'll have time to handle them so feel free to contribute if you want.
How complicated do you think would it be to make a drop-in patchelf compatible standalone binary in C or C++?
It should not be very complicated. Which feature(s) or patchelf do you need ?
That would be a tremendous help @romainthomas, I'd need especially:
syntax: patchelf
[--set-rpath RPATH]
[--print-rpath]
Nice to have:
[--set-interpreter FILENAME]
[--print-interpreter]
[--force-rpath]
[--remove-needed LIBRARY]
[--shrink-rpath]
C would be preferred because it allows for the generation of statically linked binaries most easily, but C++ would be usable too.
Ack
@romainthomas do you think you could help me here?
Has there been any progress on this? A drop-in command line replacement tool for patchelf would be very handy (I'm using the --set-rpath and --remove-rpath options currently)
Actually LIEF should have all the capabilities to replace patchelf
. I guess the main effort is to provide a CLI wrapper over the LIEF API.
In case it's helpful, I took a crack at setting this up for a couple of the options in question:
https://github.com/BRL-CAD/brlcad_externals/tree/main/plief/plief
I didn't implement all the options @probonopd listed above, but it might be a useful reference if anybody wants to make a more full-fledged tool.
Thank you very much @starseeker. How would I go about building this thing? (Which dependencies to install, etc.)
@probonopd In stand-alone mode, it's pretty simple - just grab the plief directory with those three files, install LIEF, and set LIEF_DIR to the LIEF install's share/LIEF/cmake directory in CMake. On the command line that's done with -DLIEF_DIR=<your_install>/share/lief/cmake - if you're using the CMake gui just add the LIEF_DIR path variable there.
Then it's just make to create the executable.
Note to self, the following worked for me on FreeBSD:
git clone https://github.com/lief-project/LIEF/
cd LIEF
mkdir build
cd build
cmake ..
make -j8
sudo make install
cd ..
mkdir plief
cd plief
fetch https://github.com/BRL-CAD/brlcad_externals/raw/main/plief/plief/CMakeLists.txt
fetch https://github.com/BRL-CAD/brlcad_externals/raw/main/plief/plief/cxxopts.hpp
fetch https://github.com/BRL-CAD/brlcad_externals/raw/main/plief/plief/plief.cpp
mkdir build
cd build
cmake ..
make -j8
sudo make install
% plief -h
A program to clear or replace rpaths in binaries
Usage:
plief [OPTIONS...] binary_file
-a, --add-rpath arg Add the specified path to the rpath
-c, --remove-rpath Clear the binary's rpath
--force-rpath Report/process the obsolete DT_RPATH property,
not DT_RUNPATH
--print-rpath Print the value of the rpath
-s, --set-rpath arg Set rpath to the specified path, clearing
existing values
-v, --verbose Enable verbose reporting during processing.
Multiple specifications of -v increase
reporting level, up to a maximum of 5.
-h, --help Print help
Default no-options behavior is to print DT_RUNPATH.
Returns -1 if unable to parse the supplied file.
If both modification and printing options are supplied, values reported
will represent post-processing values. If both a clear and an add are
specified, the clear will be performed first.
% ldd $(which plief)
/usr/local/bin/plief:
libc++.so.1 => /usr/lib/libc++.so.1 (0x80081d000)
libcxxrt.so.1 => /lib/libcxxrt.so.1 (0x8008f4000)
libm.so.5 => /lib/libm.so.5 (0x800916000)
libgcc_s.so.1 => /lib/libgcc_s.so.1 (0x800951000)
libc.so.7 => /lib/libc.so.7 (0x80096b000)