aboutsummaryrefslogtreecommitdiff
path: root/src/core/hle/kernel/k_process.cpp
diff options
context:
space:
mode:
authorbunnei <bunneidev@gmail.com>2022-06-21 16:04:57 -0700
committerGitHub <noreply@github.com>2022-06-21 16:04:57 -0700
commit737c446fc18618cf80a1243104ac8f5114c29a22 (patch)
tree881e88bcc52e4d0639906f61a9b1a5292e36767d /src/core/hle/kernel/k_process.cpp
parent73e13aa09051ce802ad6a4c98e0ce325a2cd707c (diff)
parent208ed712f42cfd277405a22663197dc1c5e84cfe (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.cpp46
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 61a4fb464..cb84c20e3 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) {