all repos — mgba @ 94c077703d9b56680f6bcaede01734b6a0ed1760

mGBA Game Boy Advance Emulator

src/debugger/memory-debugger.c (view raw)

 1#include "memory-debugger.h"
 2
 3#include "debugger.h"
 4
 5#include <string.h>
 6
 7static bool _checkWatchpoints(struct DebugBreakpoint* watchpoints, uint32_t address, int width);
 8
 9#define FIND_DEBUGGER(DEBUGGER, CPU) \
10	{ \
11		DEBUGGER = 0; \
12		int i; \
13		for (i = 0; i < CPU->numComponents; ++i) { \
14			if (CPU->components[i]->id == ARM_DEBUGGER_ID) { \
15				DEBUGGER = (struct ARMDebugger*) cpu->components[i]; \
16				break; \
17			} \
18		} \
19	}
20
21#define CREATE_SHIM(NAME, RETURN, TYPES, ARGS...) \
22	static RETURN ARMDebuggerShim_ ## NAME TYPES { \
23		struct ARMDebugger* debugger; \
24		FIND_DEBUGGER(debugger, cpu); \
25		return debugger->originalMemory.NAME(cpu, ARGS); \
26	}
27
28#define CREATE_WATCHPOINT_SHIM(NAME, WIDTH, RETURN, TYPES, ARGS...) \
29	static RETURN ARMDebuggerShim_ ## NAME TYPES { \
30		struct ARMDebugger* debugger; \
31		FIND_DEBUGGER(debugger, cpu); \
32		if (_checkWatchpoints(debugger->watchpoints, address, WIDTH)) { \
33			ARMDebuggerEnter(debugger, DEBUGGER_ENTER_WATCHPOINT); \
34		} \
35		return debugger->originalMemory.NAME(cpu, ARGS); \
36	}
37
38CREATE_WATCHPOINT_SHIM(load32, 4, int32_t, (struct ARMCore* cpu, uint32_t address, int* cycleCounter), address, cycleCounter)
39CREATE_WATCHPOINT_SHIM(load16, 2, int16_t, (struct ARMCore* cpu, uint32_t address, int* cycleCounter), address, cycleCounter)
40CREATE_WATCHPOINT_SHIM(loadU16, 2, uint16_t, (struct ARMCore* cpu, uint32_t address, int* cycleCounter), address, cycleCounter)
41CREATE_WATCHPOINT_SHIM(load8, 1, int8_t, (struct ARMCore* cpu, uint32_t address, int* cycleCounter), address, cycleCounter)
42CREATE_WATCHPOINT_SHIM(loadU8, 1, uint8_t, (struct ARMCore* cpu, uint32_t address, int* cycleCounter), address, cycleCounter)
43CREATE_WATCHPOINT_SHIM(store32, 4, void, (struct ARMCore* cpu, uint32_t address, int32_t value, int* cycleCounter), address, value, cycleCounter)
44CREATE_WATCHPOINT_SHIM(store16, 2, void, (struct ARMCore* cpu, uint32_t address, int16_t value, int* cycleCounter), address, value, cycleCounter)
45CREATE_WATCHPOINT_SHIM(store8, 1, void, (struct ARMCore* cpu, uint32_t address, int8_t value, int* cycleCounter), address, value, cycleCounter)
46CREATE_SHIM(waitMultiple, int, (struct ARMCore* cpu, uint32_t startAddress, int count), startAddress, count)
47CREATE_SHIM(setActiveRegion, void, (struct ARMCore* cpu, uint32_t address), address)
48
49static bool _checkWatchpoints(struct DebugBreakpoint* watchpoints, uint32_t address, int width) {
50	width -= 1;
51	for (; watchpoints; watchpoints = watchpoints->next) {
52		if (!((watchpoints->address ^ address) & ~width)) {
53			return true;
54		}
55	}
56	return false;
57}
58
59void ARMDebuggerInstallMemoryShim(struct ARMDebugger* debugger) {
60	debugger->originalMemory = debugger->cpu->memory;
61	debugger->cpu->memory.store32 = ARMDebuggerShim_store32;
62	debugger->cpu->memory.store16 = ARMDebuggerShim_store16;
63	debugger->cpu->memory.store8 = ARMDebuggerShim_store8;
64	debugger->cpu->memory.load32 = ARMDebuggerShim_load32;
65	debugger->cpu->memory.load16 = ARMDebuggerShim_load16;
66	debugger->cpu->memory.loadU16 = ARMDebuggerShim_loadU16;
67	debugger->cpu->memory.load8 = ARMDebuggerShim_load8;
68	debugger->cpu->memory.loadU8 = ARMDebuggerShim_loadU8;
69	debugger->cpu->memory.setActiveRegion = ARMDebuggerShim_setActiveRegion;
70	debugger->cpu->memory.waitMultiple = ARMDebuggerShim_waitMultiple;
71}