mirror of https://github.com/mgba-emu/mgba.git
Debugger: Support calling into multiple debuggers per watchpoint
This commit is contained in:
parent
cbc8e4f11a
commit
c1421afccb
|
@ -12,7 +12,7 @@
|
|||
|
||||
#include <string.h>
|
||||
|
||||
static bool _checkWatchpoints(struct ARMDebugger* debugger, uint32_t address, struct mDebuggerEntryInfo* info, enum mWatchpointType type, uint32_t newValue, int width);
|
||||
static void _checkWatchpoints(struct ARMDebugger* debugger, uint32_t address, enum mWatchpointType type, uint32_t newValue, int width);
|
||||
|
||||
#define FIND_DEBUGGER(DEBUGGER, CPU) \
|
||||
do { \
|
||||
|
@ -39,10 +39,7 @@ static bool _checkWatchpoints(struct ARMDebugger* debugger, uint32_t address, st
|
|||
static RETURN DebuggerShim_ ## NAME TYPES { \
|
||||
struct ARMDebugger* debugger; \
|
||||
FIND_DEBUGGER(debugger, cpu); \
|
||||
struct mDebuggerEntryInfo info; \
|
||||
if (_checkWatchpoints(debugger, address, &info, WATCHPOINT_READ, 0, WIDTH)) { \
|
||||
mDebuggerEnter(debugger->d.p, DEBUGGER_ENTER_WATCHPOINT, &info); \
|
||||
} \
|
||||
_checkWatchpoints(debugger, address, WATCHPOINT_READ, 0, WIDTH); \
|
||||
return debugger->originalMemory.NAME(cpu, __VA_ARGS__); \
|
||||
}
|
||||
|
||||
|
@ -50,10 +47,7 @@ static bool _checkWatchpoints(struct ARMDebugger* debugger, uint32_t address, st
|
|||
static RETURN DebuggerShim_ ## NAME TYPES { \
|
||||
struct ARMDebugger* debugger; \
|
||||
FIND_DEBUGGER(debugger, cpu); \
|
||||
struct mDebuggerEntryInfo info; \
|
||||
if (_checkWatchpoints(debugger, address, &info, WATCHPOINT_WRITE, value, WIDTH)) { \
|
||||
mDebuggerEnter(debugger->d.p, DEBUGGER_ENTER_WATCHPOINT, &info); \
|
||||
} \
|
||||
_checkWatchpoints(debugger, address, WATCHPOINT_WRITE, value, WIDTH); \
|
||||
return debugger->originalMemory.NAME(cpu, __VA_ARGS__); \
|
||||
}
|
||||
|
||||
|
@ -73,10 +67,7 @@ static bool _checkWatchpoints(struct ARMDebugger* debugger, uint32_t address, st
|
|||
} \
|
||||
unsigned i; \
|
||||
for (i = 0; i < popcount; ++i) { \
|
||||
struct mDebuggerEntryInfo info; \
|
||||
if (_checkWatchpoints(debugger, base + 4 * i, &info, ACCESS_TYPE, 0, 4)) { \
|
||||
mDebuggerEnter(debugger->d.p, DEBUGGER_ENTER_WATCHPOINT, &info); \
|
||||
} \
|
||||
_checkWatchpoints(debugger, base + 4 * i, ACCESS_TYPE, 0, 4); \
|
||||
} \
|
||||
return debugger->originalMemory.NAME(cpu, address, mask, direction, cycleCounter); \
|
||||
}
|
||||
|
@ -91,7 +82,7 @@ CREATE_MULTIPLE_WATCHPOINT_SHIM(loadMultiple, WATCHPOINT_READ)
|
|||
CREATE_MULTIPLE_WATCHPOINT_SHIM(storeMultiple, WATCHPOINT_WRITE)
|
||||
CREATE_SHIM(setActiveRegion, void, (struct ARMCore* cpu, uint32_t address), address)
|
||||
|
||||
static bool _checkWatchpoints(struct ARMDebugger* debugger, uint32_t address, struct mDebuggerEntryInfo* info, enum mWatchpointType type, uint32_t newValue, int width) {
|
||||
static void _checkWatchpoints(struct ARMDebugger* debugger, uint32_t address, enum mWatchpointType type, uint32_t newValue, int width) {
|
||||
struct mWatchpoint* watchpoint;
|
||||
size_t i;
|
||||
uint32_t minAddress = address & ~(width - 1);
|
||||
|
@ -124,17 +115,18 @@ static bool _checkWatchpoints(struct ARMDebugger* debugger, uint32_t address, st
|
|||
if ((watchpoint->type & WATCHPOINT_CHANGE) && newValue == oldValue) {
|
||||
continue;
|
||||
}
|
||||
info->type.wp.oldValue = oldValue;
|
||||
info->type.wp.newValue = newValue;
|
||||
info->address = address;
|
||||
info->type.wp.watchType = watchpoint->type;
|
||||
info->type.wp.accessType = type;
|
||||
info->pointId = watchpoint->id;
|
||||
info->target = TableLookup(&debugger->d.p->pointOwner, watchpoint->id);
|
||||
return true;
|
||||
|
||||
struct mDebuggerEntryInfo info;
|
||||
info.type.wp.oldValue = oldValue;
|
||||
info.type.wp.newValue = newValue;
|
||||
info.address = address;
|
||||
info.type.wp.watchType = watchpoint->type;
|
||||
info.type.wp.accessType = type;
|
||||
info.pointId = watchpoint->id;
|
||||
info.target = TableLookup(&debugger->d.p->pointOwner, watchpoint->id);
|
||||
mDebuggerEnter(debugger->d.p, DEBUGGER_ENTER_WATCHPOINT, &info);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void ARMDebuggerInstallMemoryShim(struct ARMDebugger* debugger) {
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
|
||||
#include <string.h>
|
||||
|
||||
static bool _checkWatchpoints(struct SM83Debugger* debugger, uint16_t address, struct mDebuggerEntryInfo* info, enum mWatchpointType type, uint8_t newValue);
|
||||
static void _checkWatchpoints(struct SM83Debugger* debugger, uint16_t address, enum mWatchpointType type, uint8_t newValue);
|
||||
|
||||
#define FIND_DEBUGGER(DEBUGGER, CPU) \
|
||||
do { \
|
||||
|
@ -32,17 +32,14 @@ static bool _checkWatchpoints(struct SM83Debugger* debugger, uint16_t address, s
|
|||
static RETURN DebuggerShim_ ## NAME TYPES { \
|
||||
struct SM83Debugger* debugger; \
|
||||
FIND_DEBUGGER(debugger, cpu); \
|
||||
struct mDebuggerEntryInfo info; \
|
||||
if (_checkWatchpoints(debugger, address, &info, WATCHPOINT_ ## RW, VALUE)) { \
|
||||
mDebuggerEnter(debugger->d.p, DEBUGGER_ENTER_WATCHPOINT, &info); \
|
||||
} \
|
||||
_checkWatchpoints(debugger, address, WATCHPOINT_ ## RW, VALUE); \
|
||||
return debugger->originalMemory.NAME(cpu, __VA_ARGS__); \
|
||||
}
|
||||
|
||||
CREATE_WATCHPOINT_SHIM(load8, READ, 0, uint8_t, (struct SM83Core* cpu, uint16_t address), address)
|
||||
CREATE_WATCHPOINT_SHIM(store8, WRITE, value, void, (struct SM83Core* cpu, uint16_t address, int8_t value), address, value)
|
||||
|
||||
static bool _checkWatchpoints(struct SM83Debugger* debugger, uint16_t address, struct mDebuggerEntryInfo* info, enum mWatchpointType type, uint8_t newValue) {
|
||||
static void _checkWatchpoints(struct SM83Debugger* debugger, uint16_t address, enum mWatchpointType type, uint8_t newValue) {
|
||||
struct mWatchpoint* watchpoint;
|
||||
size_t i;
|
||||
for (i = 0; i < mWatchpointListSize(&debugger->watchpoints); ++i) {
|
||||
|
@ -59,18 +56,18 @@ static bool _checkWatchpoints(struct SM83Debugger* debugger, uint16_t address, s
|
|||
if ((watchpoint->type & WATCHPOINT_CHANGE) && newValue == oldValue) {
|
||||
continue;
|
||||
}
|
||||
info->type.wp.oldValue = oldValue;
|
||||
info->type.wp.newValue = newValue;
|
||||
info->address = address;
|
||||
info->segment = debugger->originalMemory.currentSegment(debugger->cpu, address);
|
||||
info->type.wp.watchType = watchpoint->type;
|
||||
info->type.wp.accessType = type;
|
||||
info->pointId = watchpoint->id;
|
||||
info->target = TableLookup(&debugger->d.p->pointOwner, watchpoint->id);
|
||||
return true;
|
||||
struct mDebuggerEntryInfo info;
|
||||
info.type.wp.oldValue = oldValue;
|
||||
info.type.wp.newValue = newValue;
|
||||
info.address = address;
|
||||
info.segment = debugger->originalMemory.currentSegment(debugger->cpu, address);
|
||||
info.type.wp.watchType = watchpoint->type;
|
||||
info.type.wp.accessType = type;
|
||||
info.pointId = watchpoint->id;
|
||||
info.target = TableLookup(&debugger->d.p->pointOwner, watchpoint->id);
|
||||
mDebuggerEnter(debugger->d.p, DEBUGGER_ENTER_WATCHPOINT, &info);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void SM83DebuggerInstallMemoryShim(struct SM83Debugger* debugger) {
|
||||
|
|
Loading…
Reference in New Issue