summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorItamar <itamar8910@gmail.com>2021-01-06 21:53:20 +0200
committerAndreas Kling <kling@serenityos.org>2021-01-09 10:55:46 +0100
commitca9d6d21b5af30ecd19ccf26e29dedbeea5c277e (patch)
treee34b4e48b2d911b474cf98c41be5136b1f6d55f3
parentbb90d961b87f77b1ea129620e27d7fdeac37eca7 (diff)
downloadserenity-ca9d6d21b5af30ecd19ccf26e29dedbeea5c277e.zip
Loader.so+LibELF: Introduce "_LOADER_BREAKPOINT" environment variable
If set, the dynamic loader will perform a software breakpoint after loading all libraries, and just before jumping to the main entry point. This allows a debugger to inspect the loaded libraries before the program starts executing.
-rw-r--r--Libraries/LibELF/DynamicLinker.cpp10
1 files changed, 10 insertions, 0 deletions
diff --git a/Libraries/LibELF/DynamicLinker.cpp b/Libraries/LibELF/DynamicLinker.cpp
index 04d477ea21..000c7d1919 100644
--- a/Libraries/LibELF/DynamicLinker.cpp
+++ b/Libraries/LibELF/DynamicLinker.cpp
@@ -231,6 +231,13 @@ static NonnullRefPtr<DynamicLoader> commit_elf(const String& name)
void ELF::DynamicLinker::linker_main(String&& main_program_name, int main_program_fd, int argc, char** argv, char** envp)
{
g_envp = envp;
+ bool do_breakpoint_trap_before_entry = false;
+ for (char** env = envp; *env; ++env) {
+ if (StringView { *env } == "_LOADER_BREAKPOINT=1") {
+ do_breakpoint_trap_before_entry = true;
+ }
+ }
+
map_library(main_program_name, main_program_fd);
map_dependencies(main_program_name);
@@ -253,6 +260,9 @@ void ELF::DynamicLinker::linker_main(String&& main_program_name, int main_progra
MainFunction main_function = (MainFunction)(entry_point);
VERBOSE("jumping to main program entry point: %p\n", main_function);
+ if (do_breakpoint_trap_before_entry) {
+ asm("int3");
+ }
int rc = main_function(argc, argv, envp);
VERBOSE("rc: %d\n", rc);
if (g_libc_exit != nullptr) {