diff options
| author | Liam <byteslice@airmail.cc> | 2022-06-06 12:56:01 -0400 |
|---|---|---|
| committer | Liam <byteslice@airmail.cc> | 2022-06-16 13:18:07 -0400 |
| commit | 208ed712f42cfd277405a22663197dc1c5e84cfe (patch) | |
| tree | 56c1a3cbddf392d700e817cd4093564e3f096013 /src/core/hle/kernel/k_process.cpp | |
| parent | f86b770ff75efff029fa82b959b3f33eca1750fe (diff) | |
core/debugger: memory breakpoint support
Diffstat (limited to 'src/core/hle/kernel/k_process.cpp')
| -rw-r--r-- | src/core/hle/kernel/k_process.cpp | 46 |
1 files changed, 46 insertions, 0 deletions
diff --git a/src/core/hle/kernel/k_process.cpp b/src/core/hle/kernel/k_process.cpp index cd863e715..6a73f6783 100644 --- a/src/core/hle/kernel/k_process.cpp +++ b/src/core/hle/kernel/k_process.cpp @@ -584,6 +584,52 @@ ResultCode KProcess::DeleteThreadLocalRegion(VAddr addr) { return ResultSuccess; } +bool KProcess::InsertWatchpoint(Core::System& system, VAddr addr, u64 size, + DebugWatchpointType type) { + const auto watch{std::find_if(watchpoints.begin(), watchpoints.end(), [&](const auto& wp) { + return wp.type == DebugWatchpointType::None; + })}; + + if (watch == watchpoints.end()) { + return false; + } + + watch->start_address = addr; + watch->end_address = addr + size; + watch->type = type; + + for (VAddr page = Common::AlignDown(addr, PageSize); page < addr + size; page += PageSize) { + debug_page_refcounts[page]++; + system.Memory().MarkRegionDebug(page, PageSize, true); + } + + return true; +} + +bool KProcess::RemoveWatchpoint(Core::System& system, VAddr addr, u64 size, + DebugWatchpointType type) { + const auto watch{std::find_if(watchpoints.begin(), watchpoints.end(), [&](const auto& wp) { + return wp.start_address == addr && wp.end_address == addr + size && wp.type == type; + })}; + + if (watch == watchpoints.end()) { + return false; + } + + watch->start_address = 0; + watch->end_address = 0; + watch->type = DebugWatchpointType::None; + + for (VAddr page = Common::AlignDown(addr, PageSize); page < addr + size; page += PageSize) { + debug_page_refcounts[page]--; + if (!debug_page_refcounts[page]) { + system.Memory().MarkRegionDebug(page, PageSize, false); + } + } + + return true; +} + void KProcess::LoadModule(CodeSet code_set, VAddr base_addr) { const auto ReprotectSegment = [&](const CodeSet::Segment& segment, Svc::MemoryPermission permission) { |
