summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/core/arm/unicorn/arm_unicorn.cpp2
-rw-r--r--src/core/core.cpp5
-rw-r--r--src/core/core.h11
-rw-r--r--src/core/gdbstub/gdbstub.cpp10
-rw-r--r--src/yuzu/configuration/configure_debug.ui7
5 files changed, 26 insertions, 9 deletions
diff --git a/src/core/arm/unicorn/arm_unicorn.cpp b/src/core/arm/unicorn/arm_unicorn.cpp
index 4c11f35a4..6bc349460 100644
--- a/src/core/arm/unicorn/arm_unicorn.cpp
+++ b/src/core/arm/unicorn/arm_unicorn.cpp
@@ -203,7 +203,7 @@ void ARM_Unicorn::ExecuteInstructions(int num_instructions) {
203 } 203 }
204 Kernel::Thread* thread = Kernel::GetCurrentThread(); 204 Kernel::Thread* thread = Kernel::GetCurrentThread();
205 SaveContext(thread->context); 205 SaveContext(thread->context);
206 if (last_bkpt_hit || (num_instructions == 1)) { 206 if (last_bkpt_hit || GDBStub::GetCpuStepFlag()) {
207 last_bkpt_hit = false; 207 last_bkpt_hit = false;
208 GDBStub::Break(); 208 GDBStub::Break();
209 GDBStub::SendTrap(thread, 5); 209 GDBStub::SendTrap(thread, 5);
diff --git a/src/core/core.cpp b/src/core/core.cpp
index e01c45cdd..085ba68d0 100644
--- a/src/core/core.cpp
+++ b/src/core/core.cpp
@@ -62,7 +62,6 @@ System::ResultStatus System::RunLoop(bool tight_loop) {
62 // execute. Otherwise, get out of the loop function. 62 // execute. Otherwise, get out of the loop function.
63 if (GDBStub::GetCpuHaltFlag()) { 63 if (GDBStub::GetCpuHaltFlag()) {
64 if (GDBStub::GetCpuStepFlag()) { 64 if (GDBStub::GetCpuStepFlag()) {
65 GDBStub::SetCpuStepFlag(false);
66 tight_loop = false; 65 tight_loop = false;
67 } else { 66 } else {
68 return ResultStatus::Success; 67 return ResultStatus::Success;
@@ -78,6 +77,10 @@ System::ResultStatus System::RunLoop(bool tight_loop) {
78 } 77 }
79 } 78 }
80 79
80 if (GDBStub::IsServerEnabled()) {
81 GDBStub::SetCpuStepFlag(false);
82 }
83
81 return status; 84 return status;
82} 85}
83 86
diff --git a/src/core/core.h b/src/core/core.h
index a3be88aa8..c8ca4b247 100644
--- a/src/core/core.h
+++ b/src/core/core.h
@@ -82,6 +82,17 @@ public:
82 */ 82 */
83 ResultStatus SingleStep(); 83 ResultStatus SingleStep();
84 84
85 /**
86 * Invalidate the CPU instruction caches
87 * This function should only be used by GDB Stub to support breakpoints, memory updates and
88 * step/continue commands.
89 */
90 void InvalidateCpuInstructionCaches() {
91 for (auto& cpu : cpu_cores) {
92 cpu->ArmInterface().ClearInstructionCache();
93 }
94 }
95
85 /// Shutdown the emulated system. 96 /// Shutdown the emulated system.
86 void Shutdown(); 97 void Shutdown();
87 98
diff --git a/src/core/gdbstub/gdbstub.cpp b/src/core/gdbstub/gdbstub.cpp
index 884e64e99..332e5c3d0 100644
--- a/src/core/gdbstub/gdbstub.cpp
+++ b/src/core/gdbstub/gdbstub.cpp
@@ -173,6 +173,7 @@ struct Breakpoint {
173 bool active; 173 bool active;
174 VAddr addr; 174 VAddr addr;
175 u64 len; 175 u64 len;
176 std::array<u8, 4> inst;
176}; 177};
177 178
178using BreakpointMap = std::map<VAddr, Breakpoint>; 179using BreakpointMap = std::map<VAddr, Breakpoint>;
@@ -453,6 +454,8 @@ static void RemoveBreakpoint(BreakpointType type, VAddr addr) {
453 454
454 LOG_DEBUG(Debug_GDBStub, "gdb: removed a breakpoint: {:016X} bytes at {:016X} of type {}", 455 LOG_DEBUG(Debug_GDBStub, "gdb: removed a breakpoint: {:016X} bytes at {:016X} of type {}",
455 bp->second.len, bp->second.addr, static_cast<int>(type)); 456 bp->second.len, bp->second.addr, static_cast<int>(type));
457 Memory::WriteBlock(bp->second.addr, bp->second.inst.data(), bp->second.inst.size());
458 Core::System::GetInstance().InvalidateCpuInstructionCaches();
456 p.erase(addr); 459 p.erase(addr);
457} 460}
458 461
@@ -937,6 +940,7 @@ static void WriteMemory() {
937 940
938 GdbHexToMem(data.data(), len_pos + 1, len); 941 GdbHexToMem(data.data(), len_pos + 1, len);
939 Memory::WriteBlock(addr, data.data(), len); 942 Memory::WriteBlock(addr, data.data(), len);
943 Core::System::GetInstance().InvalidateCpuInstructionCaches();
940 SendReply("OK"); 944 SendReply("OK");
941} 945}
942 946
@@ -956,6 +960,7 @@ static void Step() {
956 step_loop = true; 960 step_loop = true;
957 halt_loop = true; 961 halt_loop = true;
958 send_trap = true; 962 send_trap = true;
963 Core::System::GetInstance().InvalidateCpuInstructionCaches();
959} 964}
960 965
961/// Tell the CPU if we hit a memory breakpoint. 966/// Tell the CPU if we hit a memory breakpoint.
@@ -972,6 +977,7 @@ static void Continue() {
972 memory_break = false; 977 memory_break = false;
973 step_loop = false; 978 step_loop = false;
974 halt_loop = false; 979 halt_loop = false;
980 Core::System::GetInstance().InvalidateCpuInstructionCaches();
975} 981}
976 982
977/** 983/**
@@ -988,6 +994,10 @@ static bool CommitBreakpoint(BreakpointType type, VAddr addr, u64 len) {
988 breakpoint.active = true; 994 breakpoint.active = true;
989 breakpoint.addr = addr; 995 breakpoint.addr = addr;
990 breakpoint.len = len; 996 breakpoint.len = len;
997 Memory::ReadBlock(addr, breakpoint.inst.data(), breakpoint.inst.size());
998 static constexpr std::array<u8, 4> btrap{{0xd4, 0x20, 0x7d, 0x0}};
999 Memory::WriteBlock(addr, btrap.data(), btrap.size());
1000 Core::System::GetInstance().InvalidateCpuInstructionCaches();
991 p.insert({addr, breakpoint}); 1001 p.insert({addr, breakpoint});
992 1002
993 LOG_DEBUG(Debug_GDBStub, "gdb: added {} breakpoint: {:016X} bytes at {:016X}", 1003 LOG_DEBUG(Debug_GDBStub, "gdb: added {} breakpoint: {:016X} bytes at {:016X}",
diff --git a/src/yuzu/configuration/configure_debug.ui b/src/yuzu/configuration/configure_debug.ui
index 118e91cf1..5ae7276bd 100644
--- a/src/yuzu/configuration/configure_debug.ui
+++ b/src/yuzu/configuration/configure_debug.ui
@@ -23,13 +23,6 @@
23 </property> 23 </property>
24 <layout class="QVBoxLayout" name="verticalLayout_3"> 24 <layout class="QVBoxLayout" name="verticalLayout_3">
25 <item> 25 <item>
26 <widget class="QLabel" name="label_1">
27 <property name="text">
28 <string>The GDB Stub only works correctly when the CPU JIT is off.</string>
29 </property>
30 </widget>
31 </item>
32 <item>
33 <layout class="QHBoxLayout" name="horizontalLayout_1"> 26 <layout class="QHBoxLayout" name="horizontalLayout_1">
34 <item> 27 <item>
35 <widget class="QCheckBox" name="toggle_gdbstub"> 28 <widget class="QCheckBox" name="toggle_gdbstub">