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
24static void ARMDebuggerInit(struct ARMCore*, struct ARMComponent*);
25static void ARMDebuggerDeinit(struct ARMComponent*);
26
27void ARMDebuggerCreate(struct ARMDebugger* debugger) {
28 debugger->d.init = ARMDebuggerInit;
29 debugger->d.deinit = ARMDebuggerDeinit;
30}
31
32void ARMDebuggerInit(struct ARMCore* cpu, struct ARMComponent* component) {
33 struct ARMDebugger* debugger = (struct ARMDebugger*) component;
34 debugger->cpu = cpu;
35 debugger->state = DEBUGGER_RUNNING;
36 debugger->breakpoints = 0;
37 debugger->memoryShim.original = cpu->memory;
38 debugger->memoryShim.p = debugger;
39 debugger->memoryShim.watchpoints = 0;
40 if (debugger->init) {
41 debugger->init(debugger);
42 }
43}
44
45void ARMDebuggerDeinit(struct ARMComponent* component) {
46 struct ARMDebugger* debugger = (struct ARMDebugger*) component;
47 debugger->deinit(debugger);
48}
49
50void ARMDebuggerRun(struct ARMDebugger* debugger) {
51 if (debugger->state == DEBUGGER_EXITING) {
52 debugger->state = DEBUGGER_RUNNING;
53 }
54 while (debugger->state < DEBUGGER_EXITING) {
55 if (!debugger->breakpoints) {
56 while (debugger->state == DEBUGGER_RUNNING) {
57 ARMRun(debugger->cpu);
58 }
59 } else {
60 while (debugger->state == DEBUGGER_RUNNING) {
61 ARMRun(debugger->cpu);
62 _checkBreakpoints(debugger);
63 }
64 }
65 switch (debugger->state) {
66 case DEBUGGER_RUNNING:
67 break;
68 case DEBUGGER_PAUSED:
69 if (debugger->paused) {
70 debugger->paused(debugger);
71 } else {
72 debugger->state = DEBUGGER_RUNNING;
73 }
74 break;
75 case DEBUGGER_EXITING:
76 case DEBUGGER_SHUTDOWN:
77 return;
78 }
79 }
80}
81
82void ARMDebuggerEnter(struct ARMDebugger* debugger, enum DebuggerEntryReason reason) {
83 debugger->state = DEBUGGER_PAUSED;
84 if (debugger->entered) {
85 debugger->entered(debugger, reason);
86 }
87}
88
89void ARMDebuggerSetBreakpoint(struct ARMDebugger* debugger, uint32_t address) {
90 struct DebugBreakpoint* breakpoint = malloc(sizeof(struct DebugBreakpoint));
91 breakpoint->address = address;
92 breakpoint->next = debugger->breakpoints;
93 debugger->breakpoints = breakpoint;
94}
95
96void ARMDebuggerClearBreakpoint(struct ARMDebugger* debugger, uint32_t address) {
97 struct DebugBreakpoint** previous = &debugger->breakpoints;
98 struct DebugBreakpoint* breakpoint;
99 for (; (breakpoint = *previous); previous = &breakpoint->next) {
100 if (breakpoint->address == address) {
101 *previous = breakpoint->next;
102 free(breakpoint);
103 }
104 }
105}
106
107void ARMDebuggerSetWatchpoint(struct ARMDebugger* debugger, uint32_t address) {
108 // FIXME: Make watchpoints work again
109 struct DebugBreakpoint* watchpoint = malloc(sizeof(struct DebugBreakpoint));
110 watchpoint->address = address;
111 watchpoint->next = debugger->memoryShim.watchpoints;
112 debugger->memoryShim.watchpoints = watchpoint;
113}