diff options
| author | bunnei <bunneidev@gmail.com> | 2022-06-21 16:04:57 -0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2022-06-21 16:04:57 -0700 |
| commit | f4201ec44e9063dadaf01e206ac0f1fc76b485fb (patch) | |
| tree | 881e88bcc52e4d0639906f61a9b1a5292e36767d /src/core/hle/kernel/k_process.cpp | |
| parent | d1d50f28c896f829e2bce22ad23a3b15637eb7fc (diff) | |
| parent | 8d2abc710cbcf98f0e2e5ed4645bb6f53301dfb1 (diff) | |
Merge pull request #8432 from liamwhite/watchpoint
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 61a4fb4641..cb84c20e37 100644 --- a/src/core/hle/kernel/k_process.cpp +++ b/src/core/hle/kernel/k_process.cpp @@ -579,6 +579,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) { |
