src/debugger/memory-debugger.c (view raw)
1#include "memory-debugger.h"
2
3#include "debugger.h"
4
5#include <string.h>
6
7static void ARMDebuggerShim_store32(struct ARMMemory*, uint32_t address, int32_t value, int* cycleCounter);
8static void ARMDebuggerShim_store16(struct ARMMemory*, uint32_t address, int16_t value, int* cycleCounter);
9static void ARMDebuggerShim_store8(struct ARMMemory*, uint32_t address, int8_t value, int* cycleCounter);
10static void ARMDebuggerShim_setActiveRegion(struct ARMMemory* memory, uint32_t address);
11
12#define CREATE_SHIM(NAME, RETURN, TYPES, ARGS...) \
13 static RETURN ARMDebuggerShim_ ## NAME TYPES { \
14 struct DebugMemoryShim* debugMemory = (struct DebugMemoryShim*) memory; \
15 return debugMemory->original->NAME(debugMemory->original, ARGS); \
16 }
17
18CREATE_SHIM(load32, int32_t, (struct ARMMemory* memory, uint32_t address, int* cycleCounter), address, cycleCounter)
19CREATE_SHIM(load16, int16_t, (struct ARMMemory* memory, uint32_t address, int* cycleCounter), address, cycleCounter)
20CREATE_SHIM(loadU16, uint16_t, (struct ARMMemory* memory, uint32_t address, int* cycleCounter), address, cycleCounter)
21CREATE_SHIM(load8, int8_t, (struct ARMMemory* memory, uint32_t address, int* cycleCounter), address, cycleCounter)
22CREATE_SHIM(loadU8, uint8_t, (struct ARMMemory* memory, uint32_t address, int* cycleCounter), address, cycleCounter)
23CREATE_SHIM(waitMultiple, int, (struct ARMMemory* memory, uint32_t startAddress, int count), startAddress, count)
24
25static int _checkWatchpoints(struct DebugBreakpoint* watchpoints, uint32_t address, int width) {
26 width -= 1;
27 for (; watchpoints; watchpoints = watchpoints->next) {
28 if (!((watchpoints->address ^ address) & ~width)) {
29 return 1;
30 }
31 }
32 return 0;
33}
34
35void ARMDebuggerInstallMemoryShim(struct ARMDebugger* debugger) {
36 debugger->memoryShim.original = debugger->cpu->memory;
37 memcpy(&debugger->memoryShim.d, debugger->cpu->memory, sizeof(struct ARMMemory));
38 debugger->memoryShim.d.store32 = ARMDebuggerShim_store32;
39 debugger->memoryShim.d.store16 = ARMDebuggerShim_store16;
40 debugger->memoryShim.d.store8 = ARMDebuggerShim_store8;
41 debugger->memoryShim.d.load32 = ARMDebuggerShim_load32;
42 debugger->memoryShim.d.load16 = ARMDebuggerShim_load16;
43 debugger->memoryShim.d.loadU16 = ARMDebuggerShim_loadU16;
44 debugger->memoryShim.d.load8 = ARMDebuggerShim_load8;
45 debugger->memoryShim.d.loadU8 = ARMDebuggerShim_loadU8;
46 debugger->memoryShim.d.setActiveRegion = ARMDebuggerShim_setActiveRegion;
47 debugger->memoryShim.d.waitMultiple = ARMDebuggerShim_waitMultiple;
48 debugger->cpu->memory = &debugger->memoryShim.d;
49}
50
51int32_t ARMDebuggerLoad32(struct ARMMemory* memory, uint32_t address, int* cycleCounter) {
52 struct DebugMemoryShim* debugMemory = (struct DebugMemoryShim*) memory;
53 return debugMemory->original->load32(debugMemory->original, address, cycleCounter);
54}
55
56int16_t ARMDebuggerLoad16(struct ARMMemory* memory, uint32_t address, int* cycleCounter) {
57 struct DebugMemoryShim* debugMemory = (struct DebugMemoryShim*) memory;
58 return debugMemory->original->load16(debugMemory->original, address, cycleCounter);
59}
60
61uint16_t ARMDebuggerLoadU16(struct ARMMemory* memory, uint32_t address, int* cycleCounter) {
62 struct DebugMemoryShim* debugMemory = (struct DebugMemoryShim*) memory;
63 return debugMemory->original->loadU16(debugMemory->original, address, cycleCounter);
64}
65
66int8_t ARMDebuggerLoad8(struct ARMMemory* memory, uint32_t address, int* cycleCounter) {
67 struct DebugMemoryShim* debugMemory = (struct DebugMemoryShim*) memory;
68 return debugMemory->original->load8(debugMemory->original, address, cycleCounter);
69}
70
71uint8_t ARMDebuggerLoadU8(struct ARMMemory* memory, uint32_t address, int* cycleCounter) {
72 struct DebugMemoryShim* debugMemory = (struct DebugMemoryShim*) memory;
73 return debugMemory->original->loadU8(debugMemory->original, address, cycleCounter);
74}
75
76void ARMDebuggerShim_store32(struct ARMMemory* memory, uint32_t address, int32_t value, int* cycleCounter) {
77 struct DebugMemoryShim* debugMemory = (struct DebugMemoryShim*) memory;
78 if (_checkWatchpoints(debugMemory->watchpoints, address, 4)) {
79 ARMDebuggerEnter(debugMemory->p, DEBUGGER_ENTER_WATCHPOINT);
80 }
81 debugMemory->original->store32(debugMemory->original, address, value, cycleCounter);
82}
83
84void ARMDebuggerShim_store16(struct ARMMemory* memory, uint32_t address, int16_t value, int* cycleCounter) {
85 struct DebugMemoryShim* debugMemory = (struct DebugMemoryShim*) memory;
86 if (_checkWatchpoints(debugMemory->watchpoints, address, 2)) {
87 ARMDebuggerEnter(debugMemory->p, DEBUGGER_ENTER_WATCHPOINT);
88 }
89 debugMemory->original->store16(debugMemory->original, address, value, cycleCounter);
90}
91
92void ARMDebuggerShim_store8(struct ARMMemory* memory, uint32_t address, int8_t value, int* cycleCounter) {
93 struct DebugMemoryShim* debugMemory = (struct DebugMemoryShim*) memory;
94 if (_checkWatchpoints(debugMemory->watchpoints, address, 1)) {
95 ARMDebuggerEnter(debugMemory->p, DEBUGGER_ENTER_WATCHPOINT);
96 }
97 debugMemory->original->store8(debugMemory->original, address, value, cycleCounter);
98}
99
100void ARMDebuggerShim_setActiveRegion(struct ARMMemory* memory, uint32_t address) {
101 struct DebugMemoryShim* debugMemory = (struct DebugMemoryShim*) memory;
102 debugMemory->original->setActiveRegion(debugMemory->original, address);
103 memory->activeRegion = debugMemory->original->activeRegion;
104 memory->activeMask = debugMemory->original->activeMask;
105 memory->activePrefetchCycles32 = debugMemory->original->activePrefetchCycles32;
106 memory->activePrefetchCycles16 = debugMemory->original->activePrefetchCycles16;
107 memory->activeNonseqCycles32 = debugMemory->original->activeNonseqCycles32;
108 memory->activeNonseqCycles16 = debugMemory->original->activeNonseqCycles16;
109}