mirror of
https://github.com/Atmosphere-NX/Atmosphere
synced 2024-12-22 12:21:18 +00:00
dmnt: reload modules on NRO load/unload
This commit is contained in:
parent
32818a7a99
commit
252b890a12
3 changed files with 41 additions and 2 deletions
|
@ -155,6 +155,9 @@ namespace ams::dmnt {
|
|||
}
|
||||
|
||||
Result DebugProcess::CollectModules() {
|
||||
/* Reset our module count. */
|
||||
m_module_count = 0;
|
||||
|
||||
/* Traverse the address space, looking for modules. */
|
||||
uintptr_t address = 0;
|
||||
|
||||
|
|
|
@ -137,13 +137,13 @@ namespace ams::dmnt {
|
|||
Result GetProcessDebugEvent(svc::DebugEventInfo *out);
|
||||
|
||||
void GetBranchTarget(svc::ThreadContext &ctx, u64 thread_id, u64 ¤t_pc, u64 &target);
|
||||
|
||||
Result CollectModules();
|
||||
private:
|
||||
Result Start();
|
||||
|
||||
s32 ThreadCreate(u64 thread_id);
|
||||
void ThreadExit(u64 thread_id);
|
||||
|
||||
Result CollectModules();
|
||||
};
|
||||
|
||||
}
|
|
@ -638,6 +638,42 @@ namespace ams::dmnt {
|
|||
reply = true;
|
||||
}
|
||||
break;
|
||||
case svc::DebugException_UserBreak:
|
||||
{
|
||||
const uintptr_t address = d.info.exception.address;
|
||||
const auto &info = d.info.exception.specific.user_break;
|
||||
AMS_DMNT2_GDB_LOG_DEBUG("UserBreak %lx, addr=%lx, reason=%x, data=0x%lx, size=0x%lx\n", thread_id, address, info.break_reason, info.address, info.size);
|
||||
|
||||
/* Check reason. */
|
||||
/* TODO: libnx/Nintendo provide addresses in different ways, but we could optimize to avoid iterating all memory repeatedly. */
|
||||
if ((info.break_reason & svc::BreakReason_NotificationOnlyFlag) != 0) {
|
||||
const auto reason = info.break_reason & ~svc::BreakReason_NotificationOnlyFlag;
|
||||
if (reason == svc::BreakReason_PostLoadDll || reason == svc::BreakReason_PostUnloadDll) {
|
||||
/* Re-collect the process's modules. */
|
||||
m_debug_process.CollectModules();
|
||||
}
|
||||
}
|
||||
|
||||
/* Check if we should automatically continue. */
|
||||
svc::ThreadContext ctx;
|
||||
if (R_SUCCEEDED(m_debug_process.GetThreadContext(std::addressof(ctx), thread_id, svc::ThreadContextFlag_Control))) {
|
||||
u32 insn = 0;
|
||||
if (R_SUCCEEDED(m_debug_process.ReadMemory(std::addressof(insn), ctx.pc, sizeof(insn)))) {
|
||||
constexpr u32 Aarch64SvcBreakValue = 0xD4000001 | (svc::SvcId_Break << 5);
|
||||
constexpr u32 Aarch32SvcBreakValue = 0xEF000000 | (svc::SvcId_Break);
|
||||
bool is_svc_break = m_debug_process.Is64Bit() ? (insn == Aarch64SvcBreakValue) : (insn == Aarch32SvcBreakValue);
|
||||
|
||||
if (!is_svc_break) {
|
||||
AMS_DMNT2_GDB_LOG_ERROR("UserBreak from non-SvcBreak (%08x)\n", insn);
|
||||
m_debug_process.Continue();
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
signal = GdbSignal_BreakpointTrap;
|
||||
}
|
||||
break;
|
||||
case svc::DebugException_DebuggerBreak:
|
||||
{
|
||||
AMS_DMNT2_GDB_LOG_DEBUG("DebuggerBreak %lx, last=%lx\n", thread_id, m_debug_process.GetLastThreadId());
|
||||
|
|
Loading…
Reference in a new issue