mirror of
https://github.com/Atmosphere-NX/Atmosphere
synced 2024-11-09 22:56:35 +00:00
creport: Skeleton reading of Code Regions.
This commit is contained in:
parent
fd6fa89122
commit
f189610af8
5 changed files with 92 additions and 1 deletions
62
stratosphere/creport/source/creport_code_info.cpp
Normal file
62
stratosphere/creport/source/creport_code_info.cpp
Normal file
|
@ -0,0 +1,62 @@
|
|||
#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;
|
||||
}
|
24
stratosphere/creport/source/creport_code_info.hpp
Normal file
24
stratosphere/creport/source/creport_code_info.hpp
Normal file
|
@ -0,0 +1,24 @@
|
|||
#pragma once
|
||||
#include <switch.h>
|
||||
|
||||
#include "creport_debug_types.hpp"
|
||||
|
||||
struct CodeInfo {
|
||||
char name[0x20];
|
||||
u8 id[0x20];
|
||||
u64 start_address;
|
||||
u64 end_address;
|
||||
};
|
||||
|
||||
class CodeList {
|
||||
private:
|
||||
static const size_t max_code_count = 0x10;
|
||||
u32 code_count;
|
||||
CodeInfo code_infos[max_code_count];
|
||||
public:
|
||||
CodeList() : code_count(0), code_infos({}) { }
|
||||
|
||||
void ReadCodeRegionsFromProcess(Handle debug_handle, u64 pc, u64 lr);
|
||||
private:
|
||||
bool TryFindCodeRegion(Handle debug_handle, u64 guess, u64 *address);
|
||||
};
|
|
@ -11,7 +11,7 @@ void CrashReport::BuildReport(u64 pid, bool has_extra_info) {
|
|||
if (OpenProcess(pid)) {
|
||||
ProcessExceptions();
|
||||
if (kernelAbove500()) {
|
||||
/* TODO: Process Code Regions. */
|
||||
this->code_list.ReadCodeRegionsFromProcess(this->debug_handle, this->crashed_thread_info.GetPC(), this->crashed_thread_info.GetLR());
|
||||
this->thread_list.ReadThreadsFromProcess(this->debug_handle, Is64Bit());
|
||||
}
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
|
||||
#include "creport_debug_types.hpp"
|
||||
#include "creport_thread_info.hpp"
|
||||
#include "creport_code_info.hpp"
|
||||
|
||||
enum class CrashReportResult : Result {
|
||||
UndefinedInstruction = 0x00A8,
|
||||
|
@ -38,6 +39,7 @@ class CrashReport {
|
|||
ThreadInfo crashed_thread_info;
|
||||
|
||||
/* Extra Info. */
|
||||
CodeList code_list;
|
||||
ThreadList thread_list;
|
||||
|
||||
public:
|
||||
|
|
|
@ -41,6 +41,9 @@ class ThreadInfo {
|
|||
(*this) = {};
|
||||
}
|
||||
|
||||
u64 GetPC() { return context.pc; }
|
||||
u64 GetLR() { return context.lr; }
|
||||
|
||||
bool ReadFromProcess(Handle debug_handle, u64 thread_id, bool is_64_bit);
|
||||
private:
|
||||
void TryGetStackInfo(Handle debug_handle);
|
||||
|
|
Loading…
Reference in a new issue