all repos — mgba @ e30674d05301e40ad386fd4ed32341a8bb533d95

mGBA Game Boy Advance Emulator

Debugger: Convert breakpoints and watchpoints from linked-lists to vectors
Jeffrey Pfau jeffrey@endrift.com
Tue, 12 Jan 2016 18:07:04 -0800
commit

e30674d05301e40ad386fd4ed32341a8bb533d95

parent

16ba5bd05ff423ba9bc98cb7615140b01ff49bd2

4 files changed, 48 insertions(+), 51 deletions(-)

jump to
M CHANGESCHANGES

@@ -58,6 +58,7 @@ - 3DS: Update to new ctrulib API

- GBA RR: Add preliminary SRAM support for VBM loading - GBA RR: Add support for resets in movies - 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) Bugfixes:
M src/debugger/debugger.csrc/debugger/debugger.c

@@ -12,10 +12,14 @@ #include "memory-debugger.h"

const uint32_t ARM_DEBUGGER_ID = 0xDEADBEEF; -static struct DebugBreakpoint* _lookupBreakpoint(struct DebugBreakpoint* breakpoints, uint32_t address) { - for (; breakpoints; breakpoints = breakpoints->next) { - if (breakpoints->address == address) { - return breakpoints; +DEFINE_VECTOR(DebugBreakpointList, struct DebugBreakpoint); +DEFINE_VECTOR(DebugWatchpointList, struct DebugWatchpoint); + +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;

@@ -29,7 +33,7 @@ instructionLength = WORD_SIZE_ARM;

} else { 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) { return; }

@@ -52,11 +56,11 @@ void ARMDebuggerInit(struct ARMCore* cpu, struct ARMComponent* component) {

struct ARMDebugger* debugger = (struct ARMDebugger*) component; debugger->cpu = cpu; debugger->state = DEBUGGER_RUNNING; - debugger->breakpoints = 0; - debugger->swBreakpoints = 0; debugger->originalMemory = cpu->memory; - debugger->watchpoints = 0; debugger->currentBreakpoint = 0; + DebugBreakpointListInit(&debugger->breakpoints, 0); + DebugBreakpointListInit(&debugger->swBreakpoints, 0); + DebugWatchpointListInit(&debugger->watchpoints, 0); if (debugger->init) { debugger->init(debugger); }

@@ -65,12 +69,15 @@

void ARMDebuggerDeinit(struct ARMComponent* component) { struct ARMDebugger* debugger = (struct ARMDebugger*) component; debugger->deinit(debugger); + DebugBreakpointListDeinit(&debugger->breakpoints); + DebugBreakpointListDeinit(&debugger->swBreakpoints); + DebugWatchpointListDeinit(&debugger->watchpoints); } void ARMDebuggerRun(struct ARMDebugger* debugger) { switch (debugger->state) { case DEBUGGER_RUNNING: - if (!debugger->breakpoints && !debugger->watchpoints) { + if (!DebugBreakpointListSize(&debugger->breakpoints) && !DebugWatchpointListSize(&debugger->watchpoints)) { ARMRunLoop(debugger->cpu); } else { ARMRun(debugger->cpu);

@@ -105,7 +112,7 @@ debugger->state = DEBUGGER_PAUSED;

struct ARMCore* cpu = debugger->cpu; cpu->nextEvent = cpu->cycles; if (reason == DEBUGGER_ENTER_BREAKPOINT) { - struct DebugBreakpoint* breakpoint = _lookupBreakpoint(debugger->swBreakpoints, _ARMPCAddress(cpu)); + struct DebugBreakpoint* breakpoint = _lookupBreakpoint(&debugger->swBreakpoints, _ARMPCAddress(cpu)); debugger->currentBreakpoint = breakpoint; if (breakpoint && breakpoint->isSw) { info->address = breakpoint->address;

@@ -122,11 +129,9 @@ }

} 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->next = debugger->breakpoints; breakpoint->isSw = false; - debugger->breakpoints = breakpoint; } bool ARMDebuggerSetSoftwareBreakpoint(struct ARMDebugger* debugger, uint32_t address, enum ExecutionMode mode) {

@@ -135,57 +140,44 @@ if (!debugger->setSoftwareBreakpoint || !debugger->setSoftwareBreakpoint(debugger, address, mode, &opcode)) {

return false; } - struct DebugBreakpoint* breakpoint = malloc(sizeof(struct DebugBreakpoint)); + struct DebugBreakpoint* breakpoint = DebugBreakpointListAppend(&debugger->swBreakpoints); breakpoint->address = address; - breakpoint->next = debugger->swBreakpoints; breakpoint->isSw = true; breakpoint->sw.opcode = opcode; breakpoint->sw.mode = mode; - debugger->swBreakpoints = breakpoint; return true; } void ARMDebuggerClearBreakpoint(struct ARMDebugger* debugger, uint32_t address) { - struct DebugBreakpoint** previous = &debugger->breakpoints; - struct DebugBreakpoint* breakpoint; - struct DebugBreakpoint** next; - while ((breakpoint = *previous)) { - next = &breakpoint->next; - if (breakpoint->address == address) { - *previous = *next; - free(breakpoint); - continue; + struct DebugBreakpointList* breakpoints = &debugger->breakpoints; + size_t i; + for (i = 0; i < DebugBreakpointListSize(breakpoints); ++i) { + if (DebugBreakpointListGetPointer(breakpoints, i)->address == address) { + DebugBreakpointListShift(breakpoints, i, 1); } - previous = next; } + } void ARMDebuggerSetWatchpoint(struct ARMDebugger* debugger, uint32_t address, enum WatchpointType type) { - if (!debugger->watchpoints) { + if (!DebugWatchpointListSize(&debugger->watchpoints)) { ARMDebuggerInstallMemoryShim(debugger); } - struct DebugWatchpoint* watchpoint = malloc(sizeof(struct DebugWatchpoint)); + struct DebugWatchpoint* watchpoint = DebugWatchpointListAppend(&debugger->watchpoints); watchpoint->address = address; watchpoint->type = type; - watchpoint->next = debugger->watchpoints; - debugger->watchpoints = watchpoint; } void ARMDebuggerClearWatchpoint(struct ARMDebugger* debugger, uint32_t address) { - struct DebugWatchpoint** previous = &debugger->watchpoints; - struct DebugWatchpoint* watchpoint; - struct DebugWatchpoint** next; - while ((watchpoint = *previous)) { - next = &watchpoint->next; - if (watchpoint->address == address) { - *previous = *next; - free(watchpoint); - continue; + struct DebugWatchpointList* watchpoints = &debugger->watchpoints; + size_t i; + for (i = 0; i < DebugWatchpointListSize(watchpoints); ++i) { + if (DebugWatchpointListGetPointer(watchpoints, i)->address == address) { + DebugWatchpointListShift(watchpoints, i, 1); } - previous = next; } - if (!debugger->watchpoints) { + if (!DebugWatchpointListSize(&debugger->watchpoints)) { ARMDebuggerRemoveMemoryShim(debugger); } }
M src/debugger/debugger.hsrc/debugger/debugger.h

@@ -8,7 +8,8 @@ #define DEBUGGER_H

#include "util/common.h" -#include "arm.h" +#include "arm/arm.h" +#include "util/vector.h" extern const uint32_t ARM_DEBUGGER_ID;

@@ -20,7 +21,6 @@ DEBUGGER_SHUTDOWN

}; struct DebugBreakpoint { - struct DebugBreakpoint* next; uint32_t address; bool isSw; struct {

@@ -36,11 +36,13 @@ WATCHPOINT_RW = WATCHPOINT_WRITE | WATCHPOINT_READ

}; struct DebugWatchpoint { - struct DebugWatchpoint* next; uint32_t address; enum WatchpointType type; }; +DECLARE_VECTOR(DebugBreakpointList, struct DebugBreakpoint); +DECLARE_VECTOR(DebugWatchpointList, struct DebugWatchpoint); + enum DebuggerEntryReason { DEBUGGER_ENTER_MANUAL, DEBUGGER_ENTER_ATTACHED,

@@ -75,9 +77,9 @@ struct ARMComponent d;

enum DebuggerState state; struct ARMCore* cpu; - struct DebugBreakpoint* breakpoints; - struct DebugBreakpoint* swBreakpoints; - struct DebugWatchpoint* watchpoints; + struct DebugBreakpointList breakpoints; + struct DebugBreakpointList swBreakpoints; + struct DebugWatchpointList watchpoints; struct ARMMemory originalMemory; struct DebugBreakpoint* currentBreakpoint;
M src/debugger/memory-debugger.csrc/debugger/memory-debugger.c

@@ -79,9 +79,11 @@ 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) { --width; - struct DebugWatchpoint* watchpoints; - for (watchpoints = debugger->watchpoints; watchpoints; watchpoints = watchpoints->next) { - if (!((watchpoints->address ^ address) & ~width) && watchpoints->type & type) { + struct DebugWatchpoint* watchpoint; + size_t i; + for (i = 0; i < DebugWatchpointListSize(&debugger->watchpoints); ++i) { + watchpoint = DebugWatchpointListGetPointer(&debugger->watchpoints, i); + if (!((watchpoint->address ^ address) & ~width) && watchpoint->type & type) { switch (width + 1) { case 1: info->oldValue = debugger->originalMemory.load8(debugger->cpu, address, 0);

@@ -94,7 +96,7 @@ info->oldValue = debugger->originalMemory.load32(debugger->cpu, address, 0);

break; } info->address = address; - info->watchType = watchpoints->type; + info->watchType = watchpoint->type; return true; } }