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

* GDBStub works with both Unicorn and Dynarmic now

* Tidy up
This commit is contained in:
Hedges 2018-08-07 03:01:24 +01:00 committed by bunnei
parent e218d79cc2
commit e2b74f6354
5 changed files with 26 additions and 9 deletions

View file

@ -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);

View file

@ -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;
} }

View file

@ -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();

View file

@ -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}",

View file

@ -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>