-
Notifications
You must be signed in to change notification settings - Fork 10
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Split main executable and preload library
Since glibc version 2.30, using dlopen or LD_PRELOAD on PIE objects/executables is no longer allowed and doing so will result in an error like this: ERROR: ld.so: object ... from LD_PRELOAD cannot be preloaded (cannot dynamically load position-independent executable): ignored. The upstream patch that introduced this change can be found here: https://patchwork.ozlabs.org/patch/1055380/ Also linked over there is the comment to the bugtracker, with the quote from https://sourceware.org/bugzilla/show_bug.cgi?id=11754#c13: > We cannot support this because it is not possible to perform correct > relocations if another executable has already been loaded. There is > also no way to correctly execute the ELF constructors of the second > executable. > If you want to inject code into another executable, you can use > LD_PRELOAD or LD_AUDIT, which does not have these problems. So if I understand this correctly, we shouldn't be affected since we first of all actually *want* to override symbols and second, we already have a linker script that should make sure that we don't "leak" out too many symbols. Nevertheless however, I decided that the best way to move forward is to split up the library and the executable since it probably would result in less trouble on other platforms. Unfortunately, having a separate library makes things a bit more complicated, since the executable no longer just needs to find itself and use itself in LD_PRELOAD. My first attempt was to hardcode the path to the installed library location into the source code of the executable, but this not only made it difficult to relocate the library but we'd also need a way to specify a different location during our tests. The next attempt was to use utilise the runtime dynamic loader via dlopen() to find the library. This however would also mean that we'd actually need to know the shared library suffix and library name for the dlopen call. However, Meson currently doesn't seem to have a very good way to refer to the shared library prefix and the only way to figure out the name was to use .full_path() on the shared library. The latter however doesn't return the *installed* location and getting just the basename would also mean using another run_command() call during build. Another idea I was toying around was to actually link the library to the main executable, so that even when shrinking/stripping the rpath, both will always be linked together in one form or another and to use dladdr() or /proc/self/maps to determine the path from the loaded library. Unfortunately this approach is not very portable since dladdr() is a nonstandord GNU extension. To make sure I'm not missing anything I went to the #mesonbuild IRC channel to ask for best practices and @eli-schwartz managed to convince me (thanks!) to indeed go for the last route by refering to the following SO question: https://stackoverflow.com/q/43409167 The comments/answers pretty much cover all the systems we're trying to support and we probably won't ever be able to be *fully* cross- platform since we already wrap a particular kind of socket interface. Additionally, this solution also seems to be the one that has the least amount of predetermined breaking points and we don't need to hardcode anything or implement funny heuristics to search for the library. Right now, I've only provided an implementation for GNU/Linux, since I don't have a Darwin machine. Adding support however shouldn't be that hard and will be coming soon. Signed-off-by: aszlig <aszlig@nix.build>
- Loading branch information
Showing
10 changed files
with
88 additions
and
40 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters