From fd62d3077357cf410e8aaa40f1da1673623819c8 Mon Sep 17 00:00:00 2001 From: parport0 Date: Sun, 26 Jul 2020 01:18:16 +0300 Subject: [PATCH] Debugger: Add memory.read_*, memory write_* --- CMakeLists.txt | 2 + Core/Core.vcxproj | 2 + Core/Core.vcxproj.filters | 6 + Core/Debugger/WebSocket.cpp | 2 + Core/Debugger/WebSocket/MemorySubscriber.cpp | 205 +++++++++++++++++++ Core/Debugger/WebSocket/MemorySubscriber.h | 29 +++ UWP/CoreUWP/CoreUWP.vcxproj | 2 + UWP/CoreUWP/CoreUWP.vcxproj.filters | 6 + android/jni/Android.mk | 1 + 9 files changed, 255 insertions(+) create mode 100644 Core/Debugger/WebSocket/MemorySubscriber.cpp create mode 100644 Core/Debugger/WebSocket/MemorySubscriber.h diff --git a/CMakeLists.txt b/CMakeLists.txt index d43cb98324..8d4157062c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1482,6 +1482,8 @@ add_library(${CoreLibName} ${CoreLinkType} Core/Debugger/WebSocket/HLESubscriber.h Core/Debugger/WebSocket/LogBroadcaster.cpp Core/Debugger/WebSocket/LogBroadcaster.h + Core/Debugger/WebSocket/MemorySubscriber.cpp + Core/Debugger/WebSocket/MemorySubscriber.h Core/Debugger/WebSocket/SteppingBroadcaster.cpp Core/Debugger/WebSocket/SteppingBroadcaster.h Core/Debugger/WebSocket/SteppingSubscriber.cpp diff --git a/Core/Core.vcxproj b/Core/Core.vcxproj index 91f0fd5830..baf1d89505 100644 --- a/Core/Core.vcxproj +++ b/Core/Core.vcxproj @@ -378,6 +378,7 @@ + @@ -909,6 +910,7 @@ + diff --git a/Core/Core.vcxproj.filters b/Core/Core.vcxproj.filters index f3e5bea144..a5460b6d4f 100644 --- a/Core/Core.vcxproj.filters +++ b/Core/Core.vcxproj.filters @@ -713,6 +713,9 @@ Debugger\WebSocket + + Debugger\WebSocket + Debugger\WebSocket @@ -1352,6 +1355,9 @@ Debugger\WebSocket + + Debugger\WebSocket + Debugger\WebSocket diff --git a/Core/Debugger/WebSocket.cpp b/Core/Debugger/WebSocket.cpp index 6175279363..62d1879cda 100644 --- a/Core/Debugger/WebSocket.cpp +++ b/Core/Debugger/WebSocket.cpp @@ -55,6 +55,7 @@ #include "Core/Debugger/WebSocket/GPUBufferSubscriber.h" #include "Core/Debugger/WebSocket/GPURecordSubscriber.h" #include "Core/Debugger/WebSocket/HLESubscriber.h" +#include "Core/Debugger/WebSocket/MemorySubscriber.h" #include "Core/Debugger/WebSocket/SteppingSubscriber.h" typedef DebuggerSubscriber *(*SubscriberInit)(DebuggerEventHandlerMap &map); @@ -66,6 +67,7 @@ static const std::vector subscribers({ &WebSocketGPUBufferInit, &WebSocketGPURecordInit, &WebSocketHLEInit, + &WebSocketMemoryInit, &WebSocketSteppingInit, }); diff --git a/Core/Debugger/WebSocket/MemorySubscriber.cpp b/Core/Debugger/WebSocket/MemorySubscriber.cpp new file mode 100644 index 0000000000..6710b7492c --- /dev/null +++ b/Core/Debugger/WebSocket/MemorySubscriber.cpp @@ -0,0 +1,205 @@ +// Copyright (c) 2018- PPSSPP Project. + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, version 2.0 or later versions. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official git repository and contact information can be found at +// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. + +#include "Common/StringUtils.h" +#include "Core/MemMap.h" +#include "Core/System.h" +#include "Core/Debugger/WebSocket/MemorySubscriber.h" +#include "Core/Debugger/WebSocket/WebSocketUtils.h" + +DebuggerSubscriber *WebSocketMemoryInit(DebuggerEventHandlerMap &map) { + // No need to bind or alloc state, these are all global. + map["memory.read_u8"] = &WebSocketMemoryReadU8; + map["memory.read_u16"] = &WebSocketMemoryReadU16; + map["memory.read_u32"] = &WebSocketMemoryReadU32; + map["memory.write_u8"] = &WebSocketMemoryWriteU8; + map["memory.write_u16"] = &WebSocketMemoryWriteU16; + map["memory.write_u32"] = &WebSocketMemoryWriteU32; + + return nullptr; +} + +// Read a byte from memory (memory.read_u8) +// +// Parameters: +// - address: unsigned integer +// +// Response (same event name): +// - value: unsigned integer +void WebSocketMemoryReadU8(DebuggerRequest &req) { + auto memLock = Memory::Lock(); + uint32_t addr; + + if (!req.ParamU32("address", &addr, false)) { + req.Fail("No address given"); + return; + } + + if (!Memory::IsValidAddress(addr)) { + req.Fail("Invalid address"); + return; + } + + JsonWriter &json = req.Respond(); + json.writeUint("value", Memory::Read_U8(addr)); +} + +// Read two bytes from memory (memory.read_u16) +// +// Parameters: +// - address: unsigned integer +// +// Response (same event name): +// - value: unsigned integer +void WebSocketMemoryReadU16(DebuggerRequest &req) { + auto memLock = Memory::Lock(); + uint32_t addr; + + if (!req.ParamU32("address", &addr, false)) { + req.Fail("No address given"); + return; + } + + if (!Memory::IsValidAddress(addr)) { + req.Fail("Invalid address"); + return; + } + + JsonWriter &json = req.Respond(); + json.writeUint("value", Memory::Read_U16(addr)); +} + +// Read four bytes from memory (memory.read_u32) +// +// Parameters: +// - address: unsigned integer +// +// Response (same event name): +// - value: unsigned integer +void WebSocketMemoryReadU32(DebuggerRequest &req) { + auto memLock = Memory::Lock(); + uint32_t addr; + + if (!req.ParamU32("address", &addr, false)) { + req.Fail("No address given"); + return; + } + + if (!Memory::IsValidAddress(addr)) { + req.Fail("Invalid address"); + return; + } + + JsonWriter &json = req.Respond(); + json.writeUint("value", Memory::Read_U32(addr)); +} + +// Write a byte to memory (memory.write_u8) +// +// Parameters: +// - address: unsigned integer +// - value: unsigned integer +// +// Response (same event name): +// - value: new value, unsigned integer +void WebSocketMemoryWriteU8(DebuggerRequest &req) { + auto memLock = Memory::Lock(); + uint32_t addr, val; + + if (!req.ParamU32("address", &addr, false)) { + req.Fail("No address given"); + return; + } + + if (!req.ParamU32("value", &val, false)) { + req.Fail("No value given"); + return; + } + + if (!Memory::IsValidAddress(addr)) { + req.Fail("Invalid address"); + return; + } + Memory::Write_U8(val, addr); + + JsonWriter &json = req.Respond(); + json.writeUint("value", Memory::Read_U8(addr)); +} + +// Write two bytes to memory (memory.write_u16) +// +// Parameters: +// - address: unsigned integer +// - value: unsigned integer +// +// Response (same event name): +// - value: new value, unsigned integer +void WebSocketMemoryWriteU16(DebuggerRequest &req) { + auto memLock = Memory::Lock(); + uint32_t addr, val; + + if (!req.ParamU32("address", &addr, false)) { + req.Fail("No address given"); + return; + } + + if (!req.ParamU32("value", &val, false)) { + req.Fail("No value given"); + return; + } + + if (!Memory::IsValidAddress(addr)) { + req.Fail("Invalid address"); + return; + } + Memory::Write_U16(val, addr); + + JsonWriter &json = req.Respond(); + json.writeUint("value", Memory::Read_U16(addr)); +} + +// Write four bytes to memory (memory.write_u32) +// +// Parameters: +// - address: unsigned integer +// - value: unsigned integer +// +// Response (same event name): +// - value: new value, unsigned integer +void WebSocketMemoryWriteU32(DebuggerRequest &req) { + auto memLock = Memory::Lock(); + uint32_t addr, val; + + if (!req.ParamU32("address", &addr, false)) { + req.Fail("No address given"); + return; + } + + if (!req.ParamU32("value", &val, false)) { + req.Fail("No value given"); + return; + } + + if (!Memory::IsValidAddress(addr)) { + req.Fail("Invalid address"); + return; + } + Memory::Write_U32(val, addr); + + JsonWriter &json = req.Respond(); + json.writeUint("value", Memory::Read_U32(addr)); +} diff --git a/Core/Debugger/WebSocket/MemorySubscriber.h b/Core/Debugger/WebSocket/MemorySubscriber.h new file mode 100644 index 0000000000..32e8e898c0 --- /dev/null +++ b/Core/Debugger/WebSocket/MemorySubscriber.h @@ -0,0 +1,29 @@ +// Copyright (c) 2018- PPSSPP Project. + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, version 2.0 or later versions. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official git repository and contact information can be found at +// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. + +#pragma once + +#include "Core/Debugger/WebSocket/WebSocketUtils.h" + +DebuggerSubscriber *WebSocketMemoryInit(DebuggerEventHandlerMap &map); + +void WebSocketMemoryReadU8(DebuggerRequest &req); +void WebSocketMemoryReadU16(DebuggerRequest &req); +void WebSocketMemoryReadU32(DebuggerRequest &req); +void WebSocketMemoryWriteU8(DebuggerRequest &req); +void WebSocketMemoryWriteU16(DebuggerRequest &req); +void WebSocketMemoryWriteU32(DebuggerRequest &req); diff --git a/UWP/CoreUWP/CoreUWP.vcxproj b/UWP/CoreUWP/CoreUWP.vcxproj index 8d706d5566..4f9545c490 100644 --- a/UWP/CoreUWP/CoreUWP.vcxproj +++ b/UWP/CoreUWP/CoreUWP.vcxproj @@ -400,6 +400,7 @@ + @@ -618,6 +619,7 @@ + diff --git a/UWP/CoreUWP/CoreUWP.vcxproj.filters b/UWP/CoreUWP/CoreUWP.vcxproj.filters index b4eaac21a4..781833645f 100644 --- a/UWP/CoreUWP/CoreUWP.vcxproj.filters +++ b/UWP/CoreUWP/CoreUWP.vcxproj.filters @@ -666,6 +666,9 @@ Debugger\WebSocket + + Debugger\WebSocket + Debugger\WebSocket @@ -1289,6 +1292,9 @@ Debugger\WebSocket + + Debugger\WebSocket + Debugger\WebSocket diff --git a/android/jni/Android.mk b/android/jni/Android.mk index f8651f3146..510c6a0a1d 100644 --- a/android/jni/Android.mk +++ b/android/jni/Android.mk @@ -324,6 +324,7 @@ EXEC_AND_LIB_FILES := \ $(SRC)/Core/Debugger/WebSocket/GPURecordSubscriber.cpp \ $(SRC)/Core/Debugger/WebSocket/HLESubscriber.cpp \ $(SRC)/Core/Debugger/WebSocket/LogBroadcaster.cpp \ + $(SRC)/Core/Debugger/WebSocket/MemorySubscriber.cpp \ $(SRC)/Core/Debugger/WebSocket/SteppingBroadcaster.cpp \ $(SRC)/Core/Debugger/WebSocket/SteppingSubscriber.cpp \ $(SRC)/Core/Debugger/WebSocket/WebSocketUtils.cpp \