mirror of https://github.com/mgba-emu/mgba.git
Restructure watchpoints
This commit is contained in:
parent
0f68dbc832
commit
7a4ca414e5
|
@ -36,7 +36,7 @@ if(BUILD_BBB OR BUILD_RASPI)
|
|||
endif()
|
||||
endif()
|
||||
|
||||
set(DEBUGGER_SRC "${CMAKE_SOURCE_DIR}/src/debugger/debugger.c")
|
||||
set(DEBUGGER_SRC "${CMAKE_SOURCE_DIR}/src/debugger/debugger.c;${CMAKE_SOURCE_DIR}/src/debugger/memory-debugger.c")
|
||||
|
||||
if(USE_CLI_DEBUGGER)
|
||||
set(DEBUGGER_SRC "${DEBUGGER_SRC};${CMAKE_SOURCE_DIR}/src/debugger/cli-debugger.c")
|
||||
|
|
|
@ -111,7 +111,7 @@ struct ARMInterruptHandler {
|
|||
};
|
||||
|
||||
struct ARMComponent {
|
||||
long id;
|
||||
uint32_t id;
|
||||
void (*init)(struct ARMCore* cpu, struct ARMComponent* component);
|
||||
void (*deinit)(struct ARMComponent* component);
|
||||
};
|
||||
|
|
|
@ -221,8 +221,8 @@ static void _setWatchpoint(struct CLIDebugger* debugger, struct DebugVector* dv)
|
|||
printf("%s\n", ERROR_MISSING_ARGS);
|
||||
return;
|
||||
}
|
||||
// TODO: Redo watchpoints
|
||||
(void) (debugger);
|
||||
uint32_t address = dv->intValue;
|
||||
ARMDebuggerSetWatchpoint(&debugger->d, address);
|
||||
}
|
||||
|
||||
static void _breakIntoDefault(int signal) {
|
||||
|
|
|
@ -4,6 +4,8 @@
|
|||
|
||||
#include "memory-debugger.h"
|
||||
|
||||
const uint32_t ARM_DEBUGGER_ID = 0xDEADBEEF;
|
||||
|
||||
static void _checkBreakpoints(struct ARMDebugger* debugger) {
|
||||
struct DebugBreakpoint* breakpoint;
|
||||
int instructionLength;
|
||||
|
@ -25,6 +27,7 @@ static void ARMDebuggerInit(struct ARMCore*, struct ARMComponent*);
|
|||
static void ARMDebuggerDeinit(struct ARMComponent*);
|
||||
|
||||
void ARMDebuggerCreate(struct ARMDebugger* debugger) {
|
||||
debugger->d.id = ARM_DEBUGGER_ID;
|
||||
debugger->d.init = ARMDebuggerInit;
|
||||
debugger->d.deinit = ARMDebuggerDeinit;
|
||||
}
|
||||
|
@ -34,9 +37,8 @@ void ARMDebuggerInit(struct ARMCore* cpu, struct ARMComponent* component) {
|
|||
debugger->cpu = cpu;
|
||||
debugger->state = DEBUGGER_RUNNING;
|
||||
debugger->breakpoints = 0;
|
||||
debugger->memoryShim.original = cpu->memory;
|
||||
debugger->memoryShim.p = debugger;
|
||||
debugger->memoryShim.watchpoints = 0;
|
||||
debugger->originalMemory = cpu->memory;
|
||||
debugger->watchpoints = 0;
|
||||
if (debugger->init) {
|
||||
debugger->init(debugger);
|
||||
}
|
||||
|
@ -105,9 +107,11 @@ void ARMDebuggerClearBreakpoint(struct ARMDebugger* debugger, uint32_t address)
|
|||
}
|
||||
|
||||
void ARMDebuggerSetWatchpoint(struct ARMDebugger* debugger, uint32_t address) {
|
||||
// FIXME: Make watchpoints work again
|
||||
if (!debugger->watchpoints) {
|
||||
ARMDebuggerInstallMemoryShim(debugger);
|
||||
}
|
||||
struct DebugBreakpoint* watchpoint = malloc(sizeof(struct DebugBreakpoint));
|
||||
watchpoint->address = address;
|
||||
watchpoint->next = debugger->memoryShim.watchpoints;
|
||||
debugger->memoryShim.watchpoints = watchpoint;
|
||||
watchpoint->next = debugger->watchpoints;
|
||||
debugger->watchpoints = watchpoint;
|
||||
}
|
||||
|
|
|
@ -5,6 +5,8 @@
|
|||
|
||||
#include "arm.h"
|
||||
|
||||
const uint32_t ARM_DEBUGGER_ID;
|
||||
|
||||
enum DebuggerState {
|
||||
DEBUGGER_PAUSED,
|
||||
DEBUGGER_RUNNING,
|
||||
|
@ -17,13 +19,6 @@ struct DebugBreakpoint {
|
|||
uint32_t address;
|
||||
};
|
||||
|
||||
struct DebugMemoryShim {
|
||||
struct ARMMemory original;
|
||||
|
||||
struct ARMDebugger* p;
|
||||
struct DebugBreakpoint* watchpoints;
|
||||
};
|
||||
|
||||
enum DebuggerEntryReason {
|
||||
DEBUGGER_ENTER_MANUAL,
|
||||
DEBUGGER_ENTER_ATTACHED,
|
||||
|
@ -45,7 +40,8 @@ struct ARMDebugger {
|
|||
struct ARMCore* cpu;
|
||||
|
||||
struct DebugBreakpoint* breakpoints;
|
||||
struct DebugMemoryShim memoryShim;
|
||||
struct DebugBreakpoint* watchpoints;
|
||||
struct ARMMemory originalMemory;
|
||||
|
||||
void (*init)(struct ARMDebugger*);
|
||||
void (*deinit)(struct ARMDebugger*);
|
||||
|
|
|
@ -4,23 +4,36 @@
|
|||
|
||||
#include <string.h>
|
||||
|
||||
static void ARMDebuggerShim_store32(struct ARMMemory*, uint32_t address, int32_t value, int* cycleCounter);
|
||||
static void ARMDebuggerShim_store16(struct ARMMemory*, uint32_t address, int16_t value, int* cycleCounter);
|
||||
static void ARMDebuggerShim_store8(struct ARMMemory*, uint32_t address, int8_t value, int* cycleCounter);
|
||||
static void ARMDebuggerShim_setActiveRegion(struct ARMMemory* memory, uint32_t address);
|
||||
static void ARMDebuggerShim_store32(struct ARMCore*, uint32_t address, int32_t value, int* cycleCounter);
|
||||
static void ARMDebuggerShim_store16(struct ARMCore*, uint32_t address, int16_t value, int* cycleCounter);
|
||||
static void ARMDebuggerShim_store8(struct ARMCore*, uint32_t address, int8_t value, int* cycleCounter);
|
||||
static void ARMDebuggerShim_setActiveRegion(struct ARMCore* cpu, uint32_t address);
|
||||
|
||||
#define FIND_DEBUGGER(DEBUGGER, CPU) \
|
||||
{ \
|
||||
DEBUGGER = 0; \
|
||||
int i; \
|
||||
for (i = 0; i < CPU->numComponents; ++i) { \
|
||||
if (CPU->components[i]->id == ARM_DEBUGGER_ID) { \
|
||||
DEBUGGER = (struct ARMDebugger*) cpu->components[i]; \
|
||||
break; \
|
||||
} \
|
||||
} \
|
||||
}
|
||||
|
||||
#define CREATE_SHIM(NAME, RETURN, TYPES, ARGS...) \
|
||||
static RETURN ARMDebuggerShim_ ## NAME TYPES { \
|
||||
struct DebugMemoryShim* debugMemory = (struct DebugMemoryShim*) memory; \
|
||||
return debugMemory->original->NAME(debugMemory->original, ARGS); \
|
||||
struct ARMDebugger* debugger; \
|
||||
FIND_DEBUGGER(debugger, cpu); \
|
||||
return debugger->originalMemory.NAME(cpu, ARGS); \
|
||||
}
|
||||
|
||||
CREATE_SHIM(load32, int32_t, (struct ARMMemory* memory, uint32_t address, int* cycleCounter), address, cycleCounter)
|
||||
CREATE_SHIM(load16, int16_t, (struct ARMMemory* memory, uint32_t address, int* cycleCounter), address, cycleCounter)
|
||||
CREATE_SHIM(loadU16, uint16_t, (struct ARMMemory* memory, uint32_t address, int* cycleCounter), address, cycleCounter)
|
||||
CREATE_SHIM(load8, int8_t, (struct ARMMemory* memory, uint32_t address, int* cycleCounter), address, cycleCounter)
|
||||
CREATE_SHIM(loadU8, uint8_t, (struct ARMMemory* memory, uint32_t address, int* cycleCounter), address, cycleCounter)
|
||||
CREATE_SHIM(waitMultiple, int, (struct ARMMemory* memory, uint32_t startAddress, int count), startAddress, count)
|
||||
CREATE_SHIM(load32, int32_t, (struct ARMCore* cpu, uint32_t address, int* cycleCounter), address, cycleCounter)
|
||||
CREATE_SHIM(load16, int16_t, (struct ARMCore* cpu, uint32_t address, int* cycleCounter), address, cycleCounter)
|
||||
CREATE_SHIM(loadU16, uint16_t, (struct ARMCore* cpu, uint32_t address, int* cycleCounter), address, cycleCounter)
|
||||
CREATE_SHIM(load8, int8_t, (struct ARMCore* cpu, uint32_t address, int* cycleCounter), address, cycleCounter)
|
||||
CREATE_SHIM(loadU8, uint8_t, (struct ARMCore* cpu, uint32_t address, int* cycleCounter), address, cycleCounter)
|
||||
CREATE_SHIM(waitMultiple, int, (struct ARMCore* cpu, uint32_t startAddress, int count), startAddress, count)
|
||||
|
||||
static int _checkWatchpoints(struct DebugBreakpoint* watchpoints, uint32_t address, int width) {
|
||||
width -= 1;
|
||||
|
@ -33,52 +46,48 @@ static int _checkWatchpoints(struct DebugBreakpoint* watchpoints, uint32_t addre
|
|||
}
|
||||
|
||||
void ARMDebuggerInstallMemoryShim(struct ARMDebugger* debugger) {
|
||||
debugger->memoryShim.original = debugger->cpu->memory;
|
||||
memcpy(&debugger->memoryShim.d, debugger->cpu->memory, sizeof(struct ARMMemory));
|
||||
debugger->memoryShim.d.store32 = ARMDebuggerShim_store32;
|
||||
debugger->memoryShim.d.store16 = ARMDebuggerShim_store16;
|
||||
debugger->memoryShim.d.store8 = ARMDebuggerShim_store8;
|
||||
debugger->memoryShim.d.load32 = ARMDebuggerShim_load32;
|
||||
debugger->memoryShim.d.load16 = ARMDebuggerShim_load16;
|
||||
debugger->memoryShim.d.loadU16 = ARMDebuggerShim_loadU16;
|
||||
debugger->memoryShim.d.load8 = ARMDebuggerShim_load8;
|
||||
debugger->memoryShim.d.loadU8 = ARMDebuggerShim_loadU8;
|
||||
debugger->memoryShim.d.setActiveRegion = ARMDebuggerShim_setActiveRegion;
|
||||
debugger->memoryShim.d.waitMultiple = ARMDebuggerShim_waitMultiple;
|
||||
debugger->cpu->memory = &debugger->memoryShim.d;
|
||||
debugger->originalMemory = debugger->cpu->memory;
|
||||
debugger->cpu->memory.store32 = ARMDebuggerShim_store32;
|
||||
debugger->cpu->memory.store16 = ARMDebuggerShim_store16;
|
||||
debugger->cpu->memory.store8 = ARMDebuggerShim_store8;
|
||||
debugger->cpu->memory.load32 = ARMDebuggerShim_load32;
|
||||
debugger->cpu->memory.load16 = ARMDebuggerShim_load16;
|
||||
debugger->cpu->memory.loadU16 = ARMDebuggerShim_loadU16;
|
||||
debugger->cpu->memory.load8 = ARMDebuggerShim_load8;
|
||||
debugger->cpu->memory.loadU8 = ARMDebuggerShim_loadU8;
|
||||
debugger->cpu->memory.setActiveRegion = ARMDebuggerShim_setActiveRegion;
|
||||
debugger->cpu->memory.waitMultiple = ARMDebuggerShim_waitMultiple;
|
||||
}
|
||||
|
||||
void ARMDebuggerShim_store32(struct ARMMemory* memory, uint32_t address, int32_t value, int* cycleCounter) {
|
||||
struct DebugMemoryShim* debugMemory = (struct DebugMemoryShim*) memory;
|
||||
if (_checkWatchpoints(debugMemory->watchpoints, address, 4)) {
|
||||
ARMDebuggerEnter(debugMemory->p, DEBUGGER_ENTER_WATCHPOINT);
|
||||
void ARMDebuggerShim_store32(struct ARMCore* cpu, uint32_t address, int32_t value, int* cycleCounter) {
|
||||
struct ARMDebugger* debugger;
|
||||
FIND_DEBUGGER(debugger, cpu);
|
||||
if (_checkWatchpoints(debugger->watchpoints, address, 4)) {
|
||||
ARMDebuggerEnter(debugger, DEBUGGER_ENTER_WATCHPOINT);
|
||||
}
|
||||
debugMemory->original->store32(debugMemory->original, address, value, cycleCounter);
|
||||
debugger->originalMemory.store32(debugger->cpu, address, value, cycleCounter);
|
||||
}
|
||||
|
||||
void ARMDebuggerShim_store16(struct ARMMemory* memory, uint32_t address, int16_t value, int* cycleCounter) {
|
||||
struct DebugMemoryShim* debugMemory = (struct DebugMemoryShim*) memory;
|
||||
if (_checkWatchpoints(debugMemory->watchpoints, address, 2)) {
|
||||
ARMDebuggerEnter(debugMemory->p, DEBUGGER_ENTER_WATCHPOINT);
|
||||
void ARMDebuggerShim_store16(struct ARMCore* cpu, uint32_t address, int16_t value, int* cycleCounter) {
|
||||
struct ARMDebugger* debugger;
|
||||
FIND_DEBUGGER(debugger, cpu);
|
||||
if (_checkWatchpoints(debugger->watchpoints, address, 2)) {
|
||||
ARMDebuggerEnter(debugger, DEBUGGER_ENTER_WATCHPOINT);
|
||||
}
|
||||
debugMemory->original->store16(debugMemory->original, address, value, cycleCounter);
|
||||
debugger->originalMemory.store16(debugger->cpu, address, value, cycleCounter);
|
||||
}
|
||||
|
||||
void ARMDebuggerShim_store8(struct ARMMemory* memory, uint32_t address, int8_t value, int* cycleCounter) {
|
||||
struct DebugMemoryShim* debugMemory = (struct DebugMemoryShim*) memory;
|
||||
if (_checkWatchpoints(debugMemory->watchpoints, address, 1)) {
|
||||
ARMDebuggerEnter(debugMemory->p, DEBUGGER_ENTER_WATCHPOINT);
|
||||
void ARMDebuggerShim_store8(struct ARMCore* cpu, uint32_t address, int8_t value, int* cycleCounter) {
|
||||
struct ARMDebugger* debugger;
|
||||
FIND_DEBUGGER(debugger, cpu);
|
||||
if (_checkWatchpoints(debugger->watchpoints, address, 1)) {
|
||||
ARMDebuggerEnter(debugger, DEBUGGER_ENTER_WATCHPOINT);
|
||||
}
|
||||
debugMemory->original->store8(debugMemory->original, address, value, cycleCounter);
|
||||
debugger->originalMemory.store8(debugger->cpu, address, value, cycleCounter);
|
||||
}
|
||||
|
||||
void ARMDebuggerShim_setActiveRegion(struct ARMMemory* memory, uint32_t address) {
|
||||
struct DebugMemoryShim* debugMemory = (struct DebugMemoryShim*) memory;
|
||||
debugMemory->original->setActiveRegion(debugMemory->original, address);
|
||||
memory->activeRegion = debugMemory->original->activeRegion;
|
||||
memory->activeMask = debugMemory->original->activeMask;
|
||||
memory->activePrefetchCycles32 = debugMemory->original->activePrefetchCycles32;
|
||||
memory->activePrefetchCycles16 = debugMemory->original->activePrefetchCycles16;
|
||||
memory->activeNonseqCycles32 = debugMemory->original->activeNonseqCycles32;
|
||||
memory->activeNonseqCycles16 = debugMemory->original->activeNonseqCycles16;
|
||||
void ARMDebuggerShim_setActiveRegion(struct ARMCore* cpu, uint32_t address) {
|
||||
struct ARMDebugger* debugger;
|
||||
FIND_DEBUGGER(debugger, cpu);
|
||||
debugger->originalMemory.setActiveRegion(cpu, address);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue