From c78838c2d247d9e838095f15faebb8a404c07242 Mon Sep 17 00:00:00 2001 From: Itamar Date: Thu, 9 Sep 2021 12:25:02 +0300 Subject: [PATCH] LibDebug: Use the first memory segment of a library as the ELF's base When parsing the libraries of the debugee process, we previously assumed that the region that's called `: .text` was also the base of the ELF file. However, since we started linking with `-z separate-code`, this is no longer the case - our executables have a read-only segment before the .text segment, and that segment is actually at the base of the ELF. This broke inserting breakpoints with the debugger since they were inserted at a wrong offset. To fix that, we now use the address of the first segment in the memory map for the ELF's base address (The memory map is sorted by address). --- Userland/Libraries/LibDebug/DebugSession.cpp | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/Userland/Libraries/LibDebug/DebugSession.cpp b/Userland/Libraries/LibDebug/DebugSession.cpp index ae7a32d01b..9fec825a22 100644 --- a/Userland/Libraries/LibDebug/DebugSession.cpp +++ b/Userland/Libraries/LibDebug/DebugSession.cpp @@ -409,13 +409,13 @@ void DebugSession::update_loaded_libs() VERIFY(json.has_value()); auto vm_entries = json.value().as_array(); - Regex re("(.+): \\.text"); + Regex segment_name_re("(.+): "); - auto get_path_to_object = [&re](String const& vm_name) -> Optional { + auto get_path_to_object = [&segment_name_re](String const& vm_name) -> Optional { if (vm_name == "/usr/lib/Loader.so") return vm_name; RegexResult result; - auto rc = re.search(vm_name, result); + auto rc = segment_name_re.search(vm_name, result); if (!rc) return {}; auto lib_name = result.capture_group_matches.at(0).at(0).view.string_view().to_string(); @@ -440,14 +440,17 @@ void DebugSession::update_loaded_libs() if (lib_name == "libgcc_s.so") return IterationDecision::Continue; - if (m_loaded_libraries.contains(lib_name)) + FlatPtr base_address = entry.as_object().get("address").to_addr(); + if (auto it = m_loaded_libraries.find(lib_name); it != m_loaded_libraries.end()) { + // We expect the VM regions to be sorted by address. + VERIFY(base_address >= it->value->base_address); return IterationDecision::Continue; + } - auto file_or_error = MappedFile ::map(object_path.value()); + auto file_or_error = MappedFile::map(object_path.value()); if (file_or_error.is_error()) return IterationDecision::Continue; - FlatPtr base_address = entry.as_object().get("address").to_addr(); auto image = make(file_or_error.value()->bytes()); auto debug_info = make(*image, m_source_root, base_address); auto lib = make(lib_name, file_or_error.release_value(), move(image), move(debug_info), base_address);