From ca9d6d21b5af30ecd19ccf26e29dedbeea5c277e Mon Sep 17 00:00:00 2001 From: Itamar Date: Wed, 6 Jan 2021 21:53:20 +0200 Subject: [PATCH] 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. --- Libraries/LibELF/DynamicLinker.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) 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 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) {