src/debugger/memory-debugger.c (view raw)
1#include "memory-debugger.h"
2
3#include "debugger.h"
4
5#include <string.h>
6
7static int _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 int _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 1;
54 }
55 }
56 return 0;
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}