Debugger: Convert breakpoints and watchpoints from linked-lists to vectors

This commit is contained in:
Jeffrey Pfau 2016-01-12 18:07:04 -08:00
parent 16ba5bd05f
commit e30674d053
4 changed files with 48 additions and 51 deletions

View File

@ -58,6 +58,7 @@ Misc:
- GBA RR: Add preliminary SRAM support for VBM loading - GBA RR: Add preliminary SRAM support for VBM loading
- GBA RR: Add support for resets in movies - GBA RR: Add support for resets in movies
- GBA Input: Consolidate GBA_KEY_NONE and GBA_NO_MAPPING - GBA Input: Consolidate GBA_KEY_NONE and GBA_NO_MAPPING
- Debugger: Convert breakpoints and watchpoints from linked-lists to vectors
0.3.2: (2015-12-16) 0.3.2: (2015-12-16)
Bugfixes: Bugfixes:

View File

@ -12,10 +12,14 @@
const uint32_t ARM_DEBUGGER_ID = 0xDEADBEEF; const uint32_t ARM_DEBUGGER_ID = 0xDEADBEEF;
static struct DebugBreakpoint* _lookupBreakpoint(struct DebugBreakpoint* breakpoints, uint32_t address) { DEFINE_VECTOR(DebugBreakpointList, struct DebugBreakpoint);
for (; breakpoints; breakpoints = breakpoints->next) { DEFINE_VECTOR(DebugWatchpointList, struct DebugWatchpoint);
if (breakpoints->address == address) {
return breakpoints; static struct DebugBreakpoint* _lookupBreakpoint(struct DebugBreakpointList* breakpoints, uint32_t address) {
size_t i;
for (i = 0; i < DebugBreakpointListSize(breakpoints); ++i) {
if (DebugBreakpointListGetPointer(breakpoints, i)->address == address) {
return DebugBreakpointListGetPointer(breakpoints, i);
} }
} }
return 0; return 0;
@ -29,7 +33,7 @@ static void _checkBreakpoints(struct ARMDebugger* debugger) {
} else { } else {
instructionLength = WORD_SIZE_THUMB; instructionLength = WORD_SIZE_THUMB;
} }
struct DebugBreakpoint* breakpoint = _lookupBreakpoint(debugger->breakpoints, debugger->cpu->gprs[ARM_PC] - instructionLength); struct DebugBreakpoint* breakpoint = _lookupBreakpoint(&debugger->breakpoints, debugger->cpu->gprs[ARM_PC] - instructionLength);
if (!breakpoint) { if (!breakpoint) {
return; return;
} }
@ -52,11 +56,11 @@ void ARMDebuggerInit(struct ARMCore* cpu, struct ARMComponent* component) {
struct ARMDebugger* debugger = (struct ARMDebugger*) component; struct ARMDebugger* debugger = (struct ARMDebugger*) component;
debugger->cpu = cpu; debugger->cpu = cpu;
debugger->state = DEBUGGER_RUNNING; debugger->state = DEBUGGER_RUNNING;
debugger->breakpoints = 0;
debugger->swBreakpoints = 0;
debugger->originalMemory = cpu->memory; debugger->originalMemory = cpu->memory;
debugger->watchpoints = 0;
debugger->currentBreakpoint = 0; debugger->currentBreakpoint = 0;
DebugBreakpointListInit(&debugger->breakpoints, 0);
DebugBreakpointListInit(&debugger->swBreakpoints, 0);
DebugWatchpointListInit(&debugger->watchpoints, 0);
if (debugger->init) { if (debugger->init) {
debugger->init(debugger); debugger->init(debugger);
} }
@ -65,12 +69,15 @@ void ARMDebuggerInit(struct ARMCore* cpu, struct ARMComponent* component) {
void ARMDebuggerDeinit(struct ARMComponent* component) { void ARMDebuggerDeinit(struct ARMComponent* component) {
struct ARMDebugger* debugger = (struct ARMDebugger*) component; struct ARMDebugger* debugger = (struct ARMDebugger*) component;
debugger->deinit(debugger); debugger->deinit(debugger);
DebugBreakpointListDeinit(&debugger->breakpoints);
DebugBreakpointListDeinit(&debugger->swBreakpoints);
DebugWatchpointListDeinit(&debugger->watchpoints);
} }
void ARMDebuggerRun(struct ARMDebugger* debugger) { void ARMDebuggerRun(struct ARMDebugger* debugger) {
switch (debugger->state) { switch (debugger->state) {
case DEBUGGER_RUNNING: case DEBUGGER_RUNNING:
if (!debugger->breakpoints && !debugger->watchpoints) { if (!DebugBreakpointListSize(&debugger->breakpoints) && !DebugWatchpointListSize(&debugger->watchpoints)) {
ARMRunLoop(debugger->cpu); ARMRunLoop(debugger->cpu);
} else { } else {
ARMRun(debugger->cpu); ARMRun(debugger->cpu);
@ -105,7 +112,7 @@ void ARMDebuggerEnter(struct ARMDebugger* debugger, enum DebuggerEntryReason rea
struct ARMCore* cpu = debugger->cpu; struct ARMCore* cpu = debugger->cpu;
cpu->nextEvent = cpu->cycles; cpu->nextEvent = cpu->cycles;
if (reason == DEBUGGER_ENTER_BREAKPOINT) { if (reason == DEBUGGER_ENTER_BREAKPOINT) {
struct DebugBreakpoint* breakpoint = _lookupBreakpoint(debugger->swBreakpoints, _ARMPCAddress(cpu)); struct DebugBreakpoint* breakpoint = _lookupBreakpoint(&debugger->swBreakpoints, _ARMPCAddress(cpu));
debugger->currentBreakpoint = breakpoint; debugger->currentBreakpoint = breakpoint;
if (breakpoint && breakpoint->isSw) { if (breakpoint && breakpoint->isSw) {
info->address = breakpoint->address; info->address = breakpoint->address;
@ -122,11 +129,9 @@ void ARMDebuggerEnter(struct ARMDebugger* debugger, enum DebuggerEntryReason rea
} }
void ARMDebuggerSetBreakpoint(struct ARMDebugger* debugger, uint32_t address) { void ARMDebuggerSetBreakpoint(struct ARMDebugger* debugger, uint32_t address) {
struct DebugBreakpoint* breakpoint = malloc(sizeof(struct DebugBreakpoint)); struct DebugBreakpoint* breakpoint = DebugBreakpointListAppend(&debugger->breakpoints);
breakpoint->address = address; breakpoint->address = address;
breakpoint->next = debugger->breakpoints;
breakpoint->isSw = false; breakpoint->isSw = false;
debugger->breakpoints = breakpoint;
} }
bool ARMDebuggerSetSoftwareBreakpoint(struct ARMDebugger* debugger, uint32_t address, enum ExecutionMode mode) { bool ARMDebuggerSetSoftwareBreakpoint(struct ARMDebugger* debugger, uint32_t address, enum ExecutionMode mode) {
@ -135,57 +140,44 @@ bool ARMDebuggerSetSoftwareBreakpoint(struct ARMDebugger* debugger, uint32_t add
return false; return false;
} }
struct DebugBreakpoint* breakpoint = malloc(sizeof(struct DebugBreakpoint)); struct DebugBreakpoint* breakpoint = DebugBreakpointListAppend(&debugger->swBreakpoints);
breakpoint->address = address; breakpoint->address = address;
breakpoint->next = debugger->swBreakpoints;
breakpoint->isSw = true; breakpoint->isSw = true;
breakpoint->sw.opcode = opcode; breakpoint->sw.opcode = opcode;
breakpoint->sw.mode = mode; breakpoint->sw.mode = mode;
debugger->swBreakpoints = breakpoint;
return true; return true;
} }
void ARMDebuggerClearBreakpoint(struct ARMDebugger* debugger, uint32_t address) { void ARMDebuggerClearBreakpoint(struct ARMDebugger* debugger, uint32_t address) {
struct DebugBreakpoint** previous = &debugger->breakpoints; struct DebugBreakpointList* breakpoints = &debugger->breakpoints;
struct DebugBreakpoint* breakpoint; size_t i;
struct DebugBreakpoint** next; for (i = 0; i < DebugBreakpointListSize(breakpoints); ++i) {
while ((breakpoint = *previous)) { if (DebugBreakpointListGetPointer(breakpoints, i)->address == address) {
next = &breakpoint->next; DebugBreakpointListShift(breakpoints, i, 1);
if (breakpoint->address == address) {
*previous = *next;
free(breakpoint);
continue;
} }
previous = next;
} }
} }
void ARMDebuggerSetWatchpoint(struct ARMDebugger* debugger, uint32_t address, enum WatchpointType type) { void ARMDebuggerSetWatchpoint(struct ARMDebugger* debugger, uint32_t address, enum WatchpointType type) {
if (!debugger->watchpoints) { if (!DebugWatchpointListSize(&debugger->watchpoints)) {
ARMDebuggerInstallMemoryShim(debugger); ARMDebuggerInstallMemoryShim(debugger);
} }
struct DebugWatchpoint* watchpoint = malloc(sizeof(struct DebugWatchpoint)); struct DebugWatchpoint* watchpoint = DebugWatchpointListAppend(&debugger->watchpoints);
watchpoint->address = address; watchpoint->address = address;
watchpoint->type = type; watchpoint->type = type;
watchpoint->next = debugger->watchpoints;
debugger->watchpoints = watchpoint;
} }
void ARMDebuggerClearWatchpoint(struct ARMDebugger* debugger, uint32_t address) { void ARMDebuggerClearWatchpoint(struct ARMDebugger* debugger, uint32_t address) {
struct DebugWatchpoint** previous = &debugger->watchpoints; struct DebugWatchpointList* watchpoints = &debugger->watchpoints;
struct DebugWatchpoint* watchpoint; size_t i;
struct DebugWatchpoint** next; for (i = 0; i < DebugWatchpointListSize(watchpoints); ++i) {
while ((watchpoint = *previous)) { if (DebugWatchpointListGetPointer(watchpoints, i)->address == address) {
next = &watchpoint->next; DebugWatchpointListShift(watchpoints, i, 1);
if (watchpoint->address == address) {
*previous = *next;
free(watchpoint);
continue;
} }
previous = next;
} }
if (!debugger->watchpoints) { if (!DebugWatchpointListSize(&debugger->watchpoints)) {
ARMDebuggerRemoveMemoryShim(debugger); ARMDebuggerRemoveMemoryShim(debugger);
} }
} }

View File

@ -8,7 +8,8 @@
#include "util/common.h" #include "util/common.h"
#include "arm.h" #include "arm/arm.h"
#include "util/vector.h"
extern const uint32_t ARM_DEBUGGER_ID; extern const uint32_t ARM_DEBUGGER_ID;
@ -20,7 +21,6 @@ enum DebuggerState {
}; };
struct DebugBreakpoint { struct DebugBreakpoint {
struct DebugBreakpoint* next;
uint32_t address; uint32_t address;
bool isSw; bool isSw;
struct { struct {
@ -36,11 +36,13 @@ enum WatchpointType {
}; };
struct DebugWatchpoint { struct DebugWatchpoint {
struct DebugWatchpoint* next;
uint32_t address; uint32_t address;
enum WatchpointType type; enum WatchpointType type;
}; };
DECLARE_VECTOR(DebugBreakpointList, struct DebugBreakpoint);
DECLARE_VECTOR(DebugWatchpointList, struct DebugWatchpoint);
enum DebuggerEntryReason { enum DebuggerEntryReason {
DEBUGGER_ENTER_MANUAL, DEBUGGER_ENTER_MANUAL,
DEBUGGER_ENTER_ATTACHED, DEBUGGER_ENTER_ATTACHED,
@ -75,9 +77,9 @@ struct ARMDebugger {
enum DebuggerState state; enum DebuggerState state;
struct ARMCore* cpu; struct ARMCore* cpu;
struct DebugBreakpoint* breakpoints; struct DebugBreakpointList breakpoints;
struct DebugBreakpoint* swBreakpoints; struct DebugBreakpointList swBreakpoints;
struct DebugWatchpoint* watchpoints; struct DebugWatchpointList watchpoints;
struct ARMMemory originalMemory; struct ARMMemory originalMemory;
struct DebugBreakpoint* currentBreakpoint; struct DebugBreakpoint* currentBreakpoint;

View File

@ -79,9 +79,11 @@ CREATE_SHIM(setActiveRegion, void, (struct ARMCore* cpu, uint32_t address), addr
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, int width) {
--width; --width;
struct DebugWatchpoint* watchpoints; struct DebugWatchpoint* watchpoint;
for (watchpoints = debugger->watchpoints; watchpoints; watchpoints = watchpoints->next) { size_t i;
if (!((watchpoints->address ^ address) & ~width) && watchpoints->type & type) { for (i = 0; i < DebugWatchpointListSize(&debugger->watchpoints); ++i) {
watchpoint = DebugWatchpointListGetPointer(&debugger->watchpoints, i);
if (!((watchpoint->address ^ address) & ~width) && watchpoint->type & type) {
switch (width + 1) { switch (width + 1) {
case 1: case 1:
info->oldValue = debugger->originalMemory.load8(debugger->cpu, address, 0); info->oldValue = debugger->originalMemory.load8(debugger->cpu, address, 0);
@ -94,7 +96,7 @@ static bool _checkWatchpoints(struct ARMDebugger* debugger, uint32_t address, st
break; break;
} }
info->address = address; info->address = address;
info->watchType = watchpoints->type; info->watchType = watchpoint->type;
return true; return true;
} }
} }