mirror of https://github.com/mgba-emu/mgba.git
Debugger: Further differentiate read and write watchpoints, fix gdb watch behavior
This commit is contained in:
parent
db6113d970
commit
ce45f6ea3f
|
@ -802,7 +802,11 @@ static void _reportEntry(struct ARMDebugger* debugger, enum DebuggerEntryReason
|
|||
break;
|
||||
case DEBUGGER_ENTER_WATCHPOINT:
|
||||
if (info) {
|
||||
printf("Hit watchpoint at 0x%08X: (old value = 0x%08X)\n", info->address, info->oldValue);
|
||||
if (info->accessType & WATCHPOINT_WRITE) {
|
||||
printf("Hit watchpoint at 0x%08X: (new value = 0x%08x, old value = 0x%08X)\n", info->address, info->newValue, info->oldValue);
|
||||
} else {
|
||||
printf("Hit watchpoint at 0x%08X: (value = 0x%08x)\n", info->address, info->oldValue);
|
||||
}
|
||||
} else {
|
||||
printf("Hit watchpoint\n");
|
||||
}
|
||||
|
|
|
@ -56,7 +56,9 @@ struct DebuggerEntryInfo {
|
|||
union {
|
||||
struct {
|
||||
uint32_t oldValue;
|
||||
uint32_t newValue;
|
||||
enum WatchpointType watchType;
|
||||
enum WatchpointType accessType;
|
||||
};
|
||||
|
||||
struct {
|
||||
|
|
|
@ -47,6 +47,12 @@ static void _gdbStubEntered(struct ARMDebugger* debugger, enum DebuggerEntryReas
|
|||
const char* type = 0;
|
||||
switch (info->watchType) {
|
||||
case WATCHPOINT_WRITE:
|
||||
if (info->newValue == info->oldValue) {
|
||||
if (stub->d.state == DEBUGGER_PAUSED) {
|
||||
stub->d.state = DEBUGGER_RUNNING;
|
||||
}
|
||||
return;
|
||||
}
|
||||
type = "watch";
|
||||
break;
|
||||
case WATCHPOINT_READ:
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
|
||||
#include <string.h>
|
||||
|
||||
static bool _checkWatchpoints(struct ARMDebugger* debugger, uint32_t address, struct DebuggerEntryInfo* info, enum WatchpointType type, int width);
|
||||
static bool _checkWatchpoints(struct ARMDebugger* debugger, uint32_t address, struct DebuggerEntryInfo* info, enum WatchpointType type, uint32_t newValue, int width);
|
||||
|
||||
#define FIND_DEBUGGER(DEBUGGER, CPU) \
|
||||
{ \
|
||||
|
@ -32,12 +32,23 @@ static bool _checkWatchpoints(struct ARMDebugger* debugger, uint32_t address, st
|
|||
return debugger->originalMemory.NAME(cpu, __VA_ARGS__); \
|
||||
}
|
||||
|
||||
#define CREATE_WATCHPOINT_SHIM(NAME, WIDTH, RETURN, TYPES, ACCESS_TYPE, ...) \
|
||||
#define CREATE_WATCHPOINT_READ_SHIM(NAME, WIDTH, RETURN, TYPES, ...) \
|
||||
static RETURN ARMDebuggerShim_ ## NAME TYPES { \
|
||||
struct ARMDebugger* debugger; \
|
||||
FIND_DEBUGGER(debugger, cpu); \
|
||||
struct DebuggerEntryInfo info; \
|
||||
if (_checkWatchpoints(debugger, address, &info, ACCESS_TYPE, WIDTH)) { \
|
||||
if (_checkWatchpoints(debugger, address, &info, WATCHPOINT_READ, 0, WIDTH)) { \
|
||||
ARMDebuggerEnter(debugger, DEBUGGER_ENTER_WATCHPOINT, &info); \
|
||||
} \
|
||||
return debugger->originalMemory.NAME(cpu, __VA_ARGS__); \
|
||||
}
|
||||
|
||||
#define CREATE_WATCHPOINT_WRITE_SHIM(NAME, WIDTH, RETURN, TYPES, ...) \
|
||||
static RETURN ARMDebuggerShim_ ## NAME TYPES { \
|
||||
struct ARMDebugger* debugger; \
|
||||
FIND_DEBUGGER(debugger, cpu); \
|
||||
struct DebuggerEntryInfo info; \
|
||||
if (_checkWatchpoints(debugger, address, &info, WATCHPOINT_WRITE, value, WIDTH)) { \
|
||||
ARMDebuggerEnter(debugger, DEBUGGER_ENTER_WATCHPOINT, &info); \
|
||||
} \
|
||||
return debugger->originalMemory.NAME(cpu, __VA_ARGS__); \
|
||||
|
@ -60,24 +71,24 @@ static bool _checkWatchpoints(struct ARMDebugger* debugger, uint32_t address, st
|
|||
unsigned i; \
|
||||
for (i = 0; i < popcount; ++i) { \
|
||||
struct DebuggerEntryInfo info; \
|
||||
if (_checkWatchpoints(debugger, base + 4 * i, &info, ACCESS_TYPE, 4)) { \
|
||||
if (_checkWatchpoints(debugger, base + 4 * i, &info, ACCESS_TYPE, 0, 4)) { \
|
||||
ARMDebuggerEnter(debugger, DEBUGGER_ENTER_WATCHPOINT, &info); \
|
||||
} \
|
||||
} \
|
||||
return debugger->originalMemory.NAME(cpu, address, mask, direction, cycleCounter); \
|
||||
}
|
||||
|
||||
CREATE_WATCHPOINT_SHIM(load32, 4, uint32_t, (struct ARMCore* cpu, uint32_t address, int* cycleCounter), WATCHPOINT_READ, address, cycleCounter)
|
||||
CREATE_WATCHPOINT_SHIM(load16, 2, uint32_t, (struct ARMCore* cpu, uint32_t address, int* cycleCounter), WATCHPOINT_READ, address, cycleCounter)
|
||||
CREATE_WATCHPOINT_SHIM(load8, 1, uint32_t, (struct ARMCore* cpu, uint32_t address, int* cycleCounter), WATCHPOINT_READ, address, cycleCounter)
|
||||
CREATE_WATCHPOINT_SHIM(store32, 4, void, (struct ARMCore* cpu, uint32_t address, int32_t value, int* cycleCounter), WATCHPOINT_WRITE, address, value, cycleCounter)
|
||||
CREATE_WATCHPOINT_SHIM(store16, 2, void, (struct ARMCore* cpu, uint32_t address, int16_t value, int* cycleCounter), WATCHPOINT_WRITE, address, value, cycleCounter)
|
||||
CREATE_WATCHPOINT_SHIM(store8, 1, void, (struct ARMCore* cpu, uint32_t address, int8_t value, int* cycleCounter), WATCHPOINT_WRITE, address, value, cycleCounter)
|
||||
CREATE_WATCHPOINT_READ_SHIM(load32, 4, uint32_t, (struct ARMCore* cpu, uint32_t address, int* cycleCounter), address, cycleCounter)
|
||||
CREATE_WATCHPOINT_READ_SHIM(load16, 2, uint32_t, (struct ARMCore* cpu, uint32_t address, int* cycleCounter), address, cycleCounter)
|
||||
CREATE_WATCHPOINT_READ_SHIM(load8, 1, uint32_t, (struct ARMCore* cpu, uint32_t address, int* cycleCounter), address, cycleCounter)
|
||||
CREATE_WATCHPOINT_WRITE_SHIM(store32, 4, void, (struct ARMCore* cpu, uint32_t address, int32_t value, int* cycleCounter), address, value, cycleCounter)
|
||||
CREATE_WATCHPOINT_WRITE_SHIM(store16, 2, void, (struct ARMCore* cpu, uint32_t address, int16_t value, int* cycleCounter), address, value, cycleCounter)
|
||||
CREATE_WATCHPOINT_WRITE_SHIM(store8, 1, void, (struct ARMCore* cpu, uint32_t address, int8_t value, int* cycleCounter), address, value, cycleCounter)
|
||||
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 DebuggerEntryInfo* info, enum WatchpointType type, int width) {
|
||||
static bool _checkWatchpoints(struct ARMDebugger* debugger, uint32_t address, struct DebuggerEntryInfo* info, enum WatchpointType type, uint32_t newValue, int width) {
|
||||
--width;
|
||||
struct DebugWatchpoint* watchpoint;
|
||||
size_t i;
|
||||
|
@ -95,8 +106,10 @@ static bool _checkWatchpoints(struct ARMDebugger* debugger, uint32_t address, st
|
|||
info->oldValue = debugger->originalMemory.load32(debugger->cpu, address, 0);
|
||||
break;
|
||||
}
|
||||
info->newValue = newValue;
|
||||
info->address = address;
|
||||
info->watchType = watchpoint->type;
|
||||
info->accessType = type;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue