src/debugger/debugger.c (view raw)
1#include "debugger.h"
2
3#include "arm.h"
4
5#include "memory-debugger.h"
6
7static void _checkBreakpoints(struct ARMDebugger* debugger) {
8 struct DebugBreakpoint* breakpoint;
9 int instructionLength;
10 enum ExecutionMode mode = debugger->cpu->cpsr.t;
11 if (mode == MODE_ARM) {
12 instructionLength = WORD_SIZE_ARM;
13 } else {
14 instructionLength = WORD_SIZE_THUMB;
15 }
16 for (breakpoint = debugger->breakpoints; breakpoint; breakpoint = breakpoint->next) {
17 if (breakpoint->address + instructionLength == (uint32_t) debugger->cpu->gprs[ARM_PC]) {
18 ARMDebuggerEnter(debugger, DEBUGGER_ENTER_BREAKPOINT);
19 break;
20 }
21 }
22}
23
24void ARMDebuggerInit(struct ARMDebugger* debugger, struct ARMCore* cpu) {
25 debugger->cpu = cpu;
26 debugger->state = DEBUGGER_RUNNING;
27 debugger->breakpoints = 0;
28 debugger->memoryShim.original = cpu->memory;
29 debugger->memoryShim.p = debugger;
30 debugger->memoryShim.watchpoints = 0;
31 if (debugger->init) {
32 debugger->init(debugger);
33 }
34}
35
36void ARMDebuggerDeinit(struct ARMDebugger* debugger) {
37 // TODO: actually call this
38 debugger->deinit(debugger);
39}
40
41void ARMDebuggerRun(struct ARMDebugger* debugger) {
42 if (debugger->state == DEBUGGER_EXITING) {
43 debugger->state = DEBUGGER_RUNNING;
44 }
45 while (debugger->state < DEBUGGER_EXITING) {
46 if (!debugger->breakpoints) {
47 while (debugger->state == DEBUGGER_RUNNING) {
48 ARMRun(debugger->cpu);
49 }
50 } else {
51 while (debugger->state == DEBUGGER_RUNNING) {
52 ARMRun(debugger->cpu);
53 _checkBreakpoints(debugger);
54 }
55 }
56 switch (debugger->state) {
57 case DEBUGGER_RUNNING:
58 break;
59 case DEBUGGER_PAUSED:
60 if (debugger->paused) {
61 debugger->paused(debugger);
62 } else {
63 debugger->state = DEBUGGER_RUNNING;
64 }
65 break;
66 case DEBUGGER_EXITING:
67 case DEBUGGER_SHUTDOWN:
68 return;
69 }
70 }
71}
72
73void ARMDebuggerEnter(struct ARMDebugger* debugger, enum DebuggerEntryReason reason) {
74 debugger->state = DEBUGGER_PAUSED;
75 if (debugger->entered) {
76 debugger->entered(debugger, reason);
77 }
78}
79
80void ARMDebuggerSetBreakpoint(struct ARMDebugger* debugger, uint32_t address) {
81 struct DebugBreakpoint* breakpoint = malloc(sizeof(struct DebugBreakpoint));
82 breakpoint->address = address;
83 breakpoint->next = debugger->breakpoints;
84 debugger->breakpoints = breakpoint;
85}
86
87void ARMDebuggerClearBreakpoint(struct ARMDebugger* debugger, uint32_t address) {
88 struct DebugBreakpoint** previous = &debugger->breakpoints;
89 struct DebugBreakpoint* breakpoint;
90 for (; (breakpoint = *previous); previous = &breakpoint->next) {
91 if (breakpoint->address == address) {
92 *previous = breakpoint->next;
93 free(breakpoint);
94 }
95 }
96}
97
98void ARMDebuggerSetWatchpoint(struct ARMDebugger* debugger, uint32_t address) {
99 if (debugger->cpu->memory != &debugger->memoryShim.d) {
100 ARMDebuggerInstallMemoryShim(debugger);
101 }
102 struct DebugBreakpoint* watchpoint = malloc(sizeof(struct DebugBreakpoint));
103 watchpoint->address = address;
104 watchpoint->next = debugger->memoryShim.watchpoints;
105 debugger->memoryShim.watchpoints = watchpoint;
106}