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