GDB Modernization:
- Can be used in either DynCom or Dynarmic mode - Added support for threads - Proper support for FPU registers - Fix for NibbleToHex conversion that used to produce false error codes - Fix for clang-format failing under Windows
This commit is contained in:
parent
5c5aad09ce
commit
bd658a8801
9 changed files with 281 additions and 62 deletions
|
@ -87,6 +87,8 @@ static void InterpreterFallback(u32 pc, Dynarmic::Jit* jit, void* user_arg) {
|
|||
jit->SetCpsr(state->Cpsr);
|
||||
jit->ExtRegs() = state->ExtReg;
|
||||
jit->SetFpscr(state->VFP[VFP_FPSCR]);
|
||||
|
||||
state->ServeBreak();
|
||||
}
|
||||
|
||||
static bool IsReadOnlyMemory(u32 vaddr) {
|
||||
|
@ -233,6 +235,7 @@ void ARM_Dynarmic::ClearInstructionCache() {
|
|||
for (const auto& j : jits) {
|
||||
j.second->ClearCache();
|
||||
}
|
||||
interpreter_state->instruction_cache.clear();
|
||||
}
|
||||
|
||||
void ARM_Dynarmic::InvalidateCacheRange(u32 start_address, size_t length) {
|
||||
|
|
|
@ -147,6 +147,7 @@ void ARM_DynCom::ExecuteInstructions(u64 num_instructions) {
|
|||
state->NumInstrsToExecute = num_instructions;
|
||||
unsigned ticks_executed = InterpreterMainLoop(state.get());
|
||||
CoreTiming::AddTicks(ticks_executed);
|
||||
state.get()->ServeBreak();
|
||||
}
|
||||
|
||||
std::unique_ptr<ARM_Interface::ThreadContext> ARM_DynCom::NewContext() const {
|
||||
|
|
|
@ -956,7 +956,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
|
|||
if (GDBStub::IsServerEnabled()) { \
|
||||
if (GDBStub::IsMemoryBreak() || (breakpoint_data.type != GDBStub::BreakpointType::None && \
|
||||
PC == breakpoint_data.address)) { \
|
||||
GDBStub::Break(); \
|
||||
cpu->RecordBreak(breakpoint_data); \
|
||||
goto END; \
|
||||
} \
|
||||
}
|
||||
|
|
|
@ -21,6 +21,8 @@
|
|||
#include <unordered_map>
|
||||
#include "common/common_types.h"
|
||||
#include "core/arm/skyeye_common/arm_regformat.h"
|
||||
#include "core/core.h"
|
||||
#include "core/gdbstub/gdbstub.h"
|
||||
|
||||
// Signal levels
|
||||
enum { LOW = 0, HIGH = 1, LOWHIGH = 1, HIGHLOW = 2 };
|
||||
|
@ -189,6 +191,26 @@ public:
|
|||
return TFlag ? 2 : 4;
|
||||
}
|
||||
|
||||
void RecordBreak(GDBStub::BreakpointAddress bkpt) {
|
||||
last_bkpt = bkpt;
|
||||
last_bkpt_hit = true;
|
||||
}
|
||||
|
||||
void ServeBreak() {
|
||||
if (GDBStub::IsServerEnabled()) {
|
||||
if (last_bkpt_hit) {
|
||||
Reg[15] = last_bkpt.address;
|
||||
}
|
||||
Kernel::Thread* thread = Kernel::GetCurrentThread();
|
||||
Core::CPU().SaveContext(thread->context);
|
||||
if (last_bkpt_hit || GDBStub::GetCpuStepFlag()) {
|
||||
last_bkpt_hit = false;
|
||||
GDBStub::Break();
|
||||
GDBStub::SendTrap(thread, 5);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::array<u32, 16> Reg{}; // The current register file
|
||||
std::array<u32, 2> Reg_usr{};
|
||||
std::array<u32, 2> Reg_svc{}; // R13_SVC R14_SVC
|
||||
|
@ -246,4 +268,7 @@ private:
|
|||
|
||||
u32 exclusive_tag; // The address for which the local monitor is in exclusive access mode
|
||||
bool exclusive_state;
|
||||
|
||||
GDBStub::BreakpointAddress last_bkpt{};
|
||||
bool last_bkpt_hit;
|
||||
};
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue