mirror of
https://github.com/Atmosphere-NX/Atmosphere
synced 2024-12-17 13:13:07 +00:00
62 lines
1.8 KiB
C++
62 lines
1.8 KiB
C++
|
#include <switch.h>
|
||
|
|
||
|
#include "creport_code_info.hpp"
|
||
|
|
||
|
void CodeList::ReadCodeRegionsFromProcess(Handle debug_handle, u64 pc, u64 lr) {
|
||
|
u64 code_base;
|
||
|
|
||
|
/* Guess that either PC or LR will point to a code region. This could be false. */
|
||
|
if (!TryFindCodeRegion(debug_handle, pc, &code_base) && !TryFindCodeRegion(debug_handle, lr, &code_base)) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
u64 cur_ptr = code_base;
|
||
|
while (this->code_count < max_code_count) {
|
||
|
MemoryInfo mi;
|
||
|
u32 pi;
|
||
|
if (R_FAILED(svcQueryDebugProcessMemory(&mi, &pi, debug_handle, cur_ptr))) {
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
if (mi.perm == Perm_Rx) {
|
||
|
/* TODO: Parse CodeInfo. */
|
||
|
this->code_count++;
|
||
|
}
|
||
|
|
||
|
/* If we're out of readable memory, we're done reading code. */
|
||
|
if (mi.type == MemType_Unmapped || mi.type == MemType_Reserved) {
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
/* Verify we're not getting stuck in an infinite loop. */
|
||
|
if (mi.size == 0 || U64_MAX - mi.size <= cur_ptr) {
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
cur_ptr += mi.size;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
bool CodeList::TryFindCodeRegion(Handle debug_handle, u64 guess, u64 *address) {
|
||
|
MemoryInfo mi;
|
||
|
u32 pi;
|
||
|
if (R_FAILED(svcQueryDebugProcessMemory(&mi, &pi, debug_handle, guess)) || mi.perm != Perm_Rx) {
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
/* Iterate backwards until we find the memory before the code region. */
|
||
|
while (mi.addr > 0) {
|
||
|
if (R_FAILED(svcQueryDebugProcessMemory(&mi, &pi, debug_handle, guess))) {
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
if (mi.type == MemType_Unmapped) {
|
||
|
/* Code region will be at the end of the unmapped region preceding it. */
|
||
|
*address = mi.addr + mi.size;
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
guess -= 4;
|
||
|
}
|
||
|
return false;
|
||
|
}
|