kern/creport: use mod0 to locate symbol table for all modules

This commit is contained in:
Michael Scire 2024-09-24 13:15:21 -07:00
parent 009f581721
commit 10c7a39528
2 changed files with 26 additions and 53 deletions

View file

@ -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. */ /* Get the module name. */
char module_name[0x20]; char module_name[0x20];
const bool has_module_name = GetModuleName(module_name, sizeof(module_name), process, base_address); 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); return PrintAddressWithModuleName(address, has_module_name, module_name, base_address);
} }
if (temp_32 == 0) { /* Locate .dyn using rocrt::ModuleHeader. */
/* Module is dynamically loaded by rtld. */ {
/* Determine the ModuleHeader offset. */
u32 mod_offset; u32 mod_offset;
if (!ReadValue(std::addressof(mod_offset), process, base_address + sizeof(u32))) { if (!ReadValue(std::addressof(mod_offset), process, base_address + sizeof(u32))) {
return PrintAddressWithModuleName(address, has_module_name, module_name, base_address); 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); 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); 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); return PrintAddressWithModuleName(address, has_module_name, module_name, base_address);
} }
dyn_address = base_address + mod_offset + temp_32;
} else if (temp_32 == 0x14000002) { dyn_address = module.start_address + mod_offset + temp_32;
/* 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);
} }
/* Locate tables inside .dyn. */ /* Locate tables inside .dyn. */

View file

@ -282,56 +282,38 @@ namespace ams::creport {
return; return;
} }
/* Read the first instruction of .text. */
if (R_FAILED(svc::ReadDebugProcessMemory(reinterpret_cast<uintptr_t>(std::addressof(temp_32)), m_debug_handle, module.start_address, sizeof(temp_32)))) {
return;
}
/* We want to find the symbol table/.dynamic. */ /* We want to find the symbol table/.dynamic. */
uintptr_t dyn_address = 0; uintptr_t dyn_address = 0;
uintptr_t sym_tab = 0; uintptr_t sym_tab = 0;
uintptr_t str_tab = 0; uintptr_t str_tab = 0;
size_t num_sym = 0; size_t num_sym = 0;
/* Detect module type. */ /* Locate .dyn using rocrt::ModuleHeader. */
if (temp_32 == 0) { {
/* Module is dynamically loaded by rtld. */ /* Determine the ModuleHeader offset. */
u32 mod_offset; u32 mod_offset;
if (R_FAILED(svc::ReadDebugProcessMemory(reinterpret_cast<uintptr_t>(std::addressof(mod_offset)), m_debug_handle, module.start_address + sizeof(u32), sizeof(u32)))) { if (R_FAILED(svc::ReadDebugProcessMemory(reinterpret_cast<uintptr_t>(std::addressof(mod_offset)), m_debug_handle, module.start_address + sizeof(u32), sizeof(u32)))) {
return; return;
} }
if (R_FAILED(svc::ReadDebugProcessMemory(reinterpret_cast<uintptr_t>(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<uintptr_t>(std::addressof(temp_32)), m_debug_handle, module.start_address + mod_offset + SignatureFieldOffset, sizeof(u32)))) {
return; return;
} }
/* Check that the module signature is expected. */
if (temp_32 != rocrt::ModuleHeaderVersion) { /* MOD0 */ if (temp_32 != rocrt::ModuleHeaderVersion) { /* MOD0 */
return; return;
} }
if (R_FAILED(svc::ReadDebugProcessMemory(reinterpret_cast<uintptr_t>(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<uintptr_t>(std::addressof(temp_32)), m_debug_handle, module.start_address + mod_offset + DynamicFieldOffset, sizeof(u32)))) {
return; return;
} }
dyn_address = module.start_address + mod_offset + temp_32; dyn_address = module.start_address + mod_offset + temp_32;
} else if (temp_32 == 0x14000002) {
/* Module embeds rtld. */
if (R_FAILED(svc::ReadDebugProcessMemory(reinterpret_cast<uintptr_t>(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<uintptr_t>(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;
} }