From 10c7a395285c133e4c17c52d84728a4c7b24accd Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Tue, 24 Sep 2024 13:15:21 -0700 Subject: [PATCH] kern/creport: use mod0 to locate symbol table for all modules --- .../source/arch/arm64/kern_k_debug.cpp | 41 ++++++++----------- .../creport/source/creport_modules.cpp | 38 +++++------------ 2 files changed, 26 insertions(+), 53 deletions(-) diff --git a/libraries/libmesosphere/source/arch/arm64/kern_k_debug.cpp b/libraries/libmesosphere/source/arch/arm64/kern_k_debug.cpp index eb04243cf..89587597b 100644 --- a/libraries/libmesosphere/source/arch/arm64/kern_k_debug.cpp +++ b/libraries/libmesosphere/source/arch/arm64/kern_k_debug.cpp @@ -623,11 +623,6 @@ namespace ams::kern::arch::arm64 { } } - /* Read the first instruction. */ - if (!ReadValue(std::addressof(temp_32), process, base_address)) { - return PrintAddress(address); - } - /* Get the module name. */ char module_name[0x20]; const bool has_module_name = GetModuleName(module_name, sizeof(module_name), process, base_address); @@ -637,36 +632,32 @@ namespace ams::kern::arch::arm64 { return PrintAddressWithModuleName(address, has_module_name, module_name, base_address); } - if (temp_32 == 0) { - /* Module is dynamically loaded by rtld. */ + /* Locate .dyn using rocrt::ModuleHeader. */ + { + /* Determine the ModuleHeader offset. */ u32 mod_offset; if (!ReadValue(std::addressof(mod_offset), process, base_address + sizeof(u32))) { return PrintAddressWithModuleName(address, has_module_name, module_name, base_address); } - if (!ReadValue(std::addressof(temp_32), process, base_address + mod_offset)) { + + /* Read the signature. */ + constexpr u32 SignatureFieldOffset = AMS_OFFSETOF(rocrt::ModuleHeader, signature); + if (!ReadValue(std::addressof(temp_32), process, base_address + mod_offset + SignatureFieldOffset)) { return PrintAddressWithModuleName(address, has_module_name, module_name, base_address); } - if (temp_32 != 0x30444F4D) { /* MOD0 */ + + /* Check that the module signature is expected. */ + if (temp_32 != rocrt::ModuleHeaderVersion) { /* MOD0 */ return PrintAddressWithModuleName(address, has_module_name, module_name, base_address); } - if (!ReadValue(std::addressof(temp_32), process, base_address + mod_offset + sizeof(u32))) { + + /* Determine the dynamic offset. */ + constexpr u32 DynamicFieldOffset = AMS_OFFSETOF(rocrt::ModuleHeader, dynamic_offset); + if (!ReadValue(std::addressof(temp_32), process, base_address + mod_offset + DynamicFieldOffset)) { return PrintAddressWithModuleName(address, has_module_name, module_name, base_address); } - dyn_address = base_address + mod_offset + temp_32; - } else if (temp_32 == 0x14000002) { - /* Module embeds rtld. */ - if (!ReadValue(std::addressof(temp_32), process, base_address + 0x5C)) { - return PrintAddressWithModuleName(address, has_module_name, module_name, base_address); - } - if (temp_32 != 0x94000002) { - return PrintAddressWithModuleName(address, has_module_name, module_name, base_address); - } - if (!ReadValue(std::addressof(temp_32), process, base_address + 0x60)) { - return PrintAddressWithModuleName(address, has_module_name, module_name, base_address); - } - dyn_address = base_address + 0x60 + temp_32; - } else { - return PrintAddressWithModuleName(address, has_module_name, module_name, base_address); + + dyn_address = module.start_address + mod_offset + temp_32; } /* Locate tables inside .dyn. */ diff --git a/stratosphere/creport/source/creport_modules.cpp b/stratosphere/creport/source/creport_modules.cpp index b6a3486e1..7ea58e0dd 100644 --- a/stratosphere/creport/source/creport_modules.cpp +++ b/stratosphere/creport/source/creport_modules.cpp @@ -282,56 +282,38 @@ namespace ams::creport { return; } - /* Read the first instruction of .text. */ - if (R_FAILED(svc::ReadDebugProcessMemory(reinterpret_cast(std::addressof(temp_32)), m_debug_handle, module.start_address, sizeof(temp_32)))) { - return; - } - /* We want to find the symbol table/.dynamic. */ uintptr_t dyn_address = 0; uintptr_t sym_tab = 0; uintptr_t str_tab = 0; size_t num_sym = 0; - /* Detect module type. */ - if (temp_32 == 0) { - /* Module is dynamically loaded by rtld. */ + /* Locate .dyn using rocrt::ModuleHeader. */ + { + /* Determine the ModuleHeader offset. */ u32 mod_offset; if (R_FAILED(svc::ReadDebugProcessMemory(reinterpret_cast(std::addressof(mod_offset)), m_debug_handle, module.start_address + sizeof(u32), sizeof(u32)))) { return; } - if (R_FAILED(svc::ReadDebugProcessMemory(reinterpret_cast(std::addressof(temp_32)), m_debug_handle, module.start_address + mod_offset, sizeof(u32)))) { + /* Read the signature. */ + constexpr u32 SignatureFieldOffset = AMS_OFFSETOF(rocrt::ModuleHeader, signature); + if (R_FAILED(svc::ReadDebugProcessMemory(reinterpret_cast(std::addressof(temp_32)), m_debug_handle, module.start_address + mod_offset + SignatureFieldOffset, sizeof(u32)))) { return; } + /* Check that the module signature is expected. */ if (temp_32 != rocrt::ModuleHeaderVersion) { /* MOD0 */ return; } - if (R_FAILED(svc::ReadDebugProcessMemory(reinterpret_cast(std::addressof(temp_32)), m_debug_handle, module.start_address + mod_offset + sizeof(u32), sizeof(u32)))) { + /* Determine the dynamic offset. */ + constexpr u32 DynamicFieldOffset = AMS_OFFSETOF(rocrt::ModuleHeader, dynamic_offset); + if (R_FAILED(svc::ReadDebugProcessMemory(reinterpret_cast(std::addressof(temp_32)), m_debug_handle, module.start_address + mod_offset + DynamicFieldOffset, sizeof(u32)))) { return; } dyn_address = module.start_address + mod_offset + temp_32; - } else if (temp_32 == 0x14000002) { - /* Module embeds rtld. */ - if (R_FAILED(svc::ReadDebugProcessMemory(reinterpret_cast(std::addressof(temp_32)), m_debug_handle, module.start_address + 0x5C, sizeof(u32)))) { - return; - } - - if (temp_32 != 0x94000002) { - return; - } - - if (R_FAILED(svc::ReadDebugProcessMemory(reinterpret_cast(std::addressof(temp_32)), m_debug_handle, module.start_address + 0x60, sizeof(u32)))) { - return; - } - - dyn_address = module.start_address + 0x60 + temp_32; - } else { - /* Module has unknown format. */ - return; }