Explorar el Código

GDBStub works with both Unicorn and Dynarmic now (#941)

* GDBStub works with both Unicorn and Dynarmic now

* Tidy up
Hedges hace 8 años
padre
commit
e2b74f6354

+ 1 - 1
src/core/arm/unicorn/arm_unicorn.cpp

@@ -203,7 +203,7 @@ void ARM_Unicorn::ExecuteInstructions(int num_instructions) {
         }
         }
         Kernel::Thread* thread = Kernel::GetCurrentThread();
         Kernel::Thread* thread = Kernel::GetCurrentThread();
         SaveContext(thread->context);
         SaveContext(thread->context);
-        if (last_bkpt_hit || (num_instructions == 1)) {
+        if (last_bkpt_hit || GDBStub::GetCpuStepFlag()) {
             last_bkpt_hit = false;
             last_bkpt_hit = false;
             GDBStub::Break();
             GDBStub::Break();
             GDBStub::SendTrap(thread, 5);
             GDBStub::SendTrap(thread, 5);

+ 4 - 1
src/core/core.cpp

@@ -62,7 +62,6 @@ System::ResultStatus System::RunLoop(bool tight_loop) {
         // execute. Otherwise, get out of the loop function.
         // execute. Otherwise, get out of the loop function.
         if (GDBStub::GetCpuHaltFlag()) {
         if (GDBStub::GetCpuHaltFlag()) {
             if (GDBStub::GetCpuStepFlag()) {
             if (GDBStub::GetCpuStepFlag()) {
-                GDBStub::SetCpuStepFlag(false);
                 tight_loop = false;
                 tight_loop = false;
             } else {
             } else {
                 return ResultStatus::Success;
                 return ResultStatus::Success;
@@ -78,6 +77,10 @@ System::ResultStatus System::RunLoop(bool tight_loop) {
         }
         }
     }
     }
 
 
+    if (GDBStub::IsServerEnabled()) {
+        GDBStub::SetCpuStepFlag(false);
+    }
+
     return status;
     return status;
 }
 }
 
 

+ 11 - 0
src/core/core.h

@@ -82,6 +82,17 @@ public:
      */
      */
     ResultStatus SingleStep();
     ResultStatus SingleStep();
 
 
+    /**
+     * Invalidate the CPU instruction caches
+     * This function should only be used by GDB Stub to support breakpoints, memory updates and
+     * step/continue commands.
+     */
+    void InvalidateCpuInstructionCaches() {
+        for (auto& cpu : cpu_cores) {
+            cpu->ArmInterface().ClearInstructionCache();
+        }
+    }
+
     /// Shutdown the emulated system.
     /// Shutdown the emulated system.
     void Shutdown();
     void Shutdown();
 
 

+ 10 - 0
src/core/gdbstub/gdbstub.cpp

@@ -173,6 +173,7 @@ struct Breakpoint {
     bool active;
     bool active;
     VAddr addr;
     VAddr addr;
     u64 len;
     u64 len;
+    std::array<u8, 4> inst;
 };
 };
 
 
 using BreakpointMap = std::map<VAddr, Breakpoint>;
 using BreakpointMap = std::map<VAddr, Breakpoint>;
@@ -453,6 +454,8 @@ static void RemoveBreakpoint(BreakpointType type, VAddr addr) {
 
 
     LOG_DEBUG(Debug_GDBStub, "gdb: removed a breakpoint: {:016X} bytes at {:016X} of type {}",
     LOG_DEBUG(Debug_GDBStub, "gdb: removed a breakpoint: {:016X} bytes at {:016X} of type {}",
               bp->second.len, bp->second.addr, static_cast<int>(type));
               bp->second.len, bp->second.addr, static_cast<int>(type));
+    Memory::WriteBlock(bp->second.addr, bp->second.inst.data(), bp->second.inst.size());
+    Core::System::GetInstance().InvalidateCpuInstructionCaches();
     p.erase(addr);
     p.erase(addr);
 }
 }
 
 
@@ -937,6 +940,7 @@ static void WriteMemory() {
 
 
     GdbHexToMem(data.data(), len_pos + 1, len);
     GdbHexToMem(data.data(), len_pos + 1, len);
     Memory::WriteBlock(addr, data.data(), len);
     Memory::WriteBlock(addr, data.data(), len);
+    Core::System::GetInstance().InvalidateCpuInstructionCaches();
     SendReply("OK");
     SendReply("OK");
 }
 }
 
 
@@ -956,6 +960,7 @@ static void Step() {
     step_loop = true;
     step_loop = true;
     halt_loop = true;
     halt_loop = true;
     send_trap = true;
     send_trap = true;
+    Core::System::GetInstance().InvalidateCpuInstructionCaches();
 }
 }
 
 
 /// Tell the CPU if we hit a memory breakpoint.
 /// Tell the CPU if we hit a memory breakpoint.
@@ -972,6 +977,7 @@ static void Continue() {
     memory_break = false;
     memory_break = false;
     step_loop = false;
     step_loop = false;
     halt_loop = false;
     halt_loop = false;
+    Core::System::GetInstance().InvalidateCpuInstructionCaches();
 }
 }
 
 
 /**
 /**
@@ -988,6 +994,10 @@ static bool CommitBreakpoint(BreakpointType type, VAddr addr, u64 len) {
     breakpoint.active = true;
     breakpoint.active = true;
     breakpoint.addr = addr;
     breakpoint.addr = addr;
     breakpoint.len = len;
     breakpoint.len = len;
+    Memory::ReadBlock(addr, breakpoint.inst.data(), breakpoint.inst.size());
+    static constexpr std::array<u8, 4> btrap{{0xd4, 0x20, 0x7d, 0x0}};
+    Memory::WriteBlock(addr, btrap.data(), btrap.size());
+    Core::System::GetInstance().InvalidateCpuInstructionCaches();
     p.insert({addr, breakpoint});
     p.insert({addr, breakpoint});
 
 
     LOG_DEBUG(Debug_GDBStub, "gdb: added {} breakpoint: {:016X} bytes at {:016X}",
     LOG_DEBUG(Debug_GDBStub, "gdb: added {} breakpoint: {:016X} bytes at {:016X}",

+ 0 - 7
src/yuzu/configuration/configure_debug.ui

@@ -22,13 +22,6 @@
         <string>GDB</string>
         <string>GDB</string>
        </property>
        </property>
        <layout class="QVBoxLayout" name="verticalLayout_3">
        <layout class="QVBoxLayout" name="verticalLayout_3">
-        <item>
-         <widget class="QLabel" name="label_1">
-          <property name="text">
-           <string>The GDB Stub only works correctly when the CPU JIT is off.</string>
-          </property>
-         </widget>
-        </item>
         <item>
         <item>
          <layout class="QHBoxLayout" name="horizontalLayout_1">
          <layout class="QHBoxLayout" name="horizontalLayout_1">
           <item>
           <item>