src/debugger.c (view raw)
1#include "debugger.h"
2
3#include "arm.h"
4
5#include <stdio.h>
6#include <stdarg.h>
7#include <stdlib.h>
8#include <strings.h>
9#include "linenoise.h"
10
11typedef void (DebuggerComamnd)(struct ARMDebugger*);
12
13static void _printStatus(struct ARMDebugger*);
14static void _quit(struct ARMDebugger*);
15
16struct {
17 const char* name;
18 DebuggerComamnd* command;
19} debuggerCommands[] = {
20 { "i", _printStatus },
21 { "info", _printStatus },
22 { "q", _quit },
23 { "quit", _quit },
24 { "status", _printStatus },
25 { 0, 0 }
26};
27
28static inline void _printPSR(union PSR psr) {
29 printf("%08X [%c%c%c%c%c%c%c]\n", psr.packed,
30 psr.n ? 'N' : '-',
31 psr.z ? 'Z' : '-',
32 psr.c ? 'C' : '-',
33 psr.v ? 'V' : '-',
34 psr.i ? 'I' : '-',
35 psr.f ? 'F' : '-',
36 psr.t ? 'T' : '-');
37}
38
39static void _printStatus(struct ARMDebugger* debugger) {
40 int r;
41 for (r = 0; r < 4; ++r) {
42 printf("%08X %08X %08X %08X\n",
43 debugger->cpu->gprs[r << 2],
44 debugger->cpu->gprs[(r << 2) + 1],
45 debugger->cpu->gprs[(r << 2) + 2],
46 debugger->cpu->gprs[(r << 2) + 3]);
47 }
48 _printPSR(debugger->cpu->cpsr);
49}
50
51static void _quit(struct ARMDebugger* debugger) {
52 debugger->state = DEBUGGER_EXITING;
53}
54
55static void _parse(struct ARMDebugger* debugger, const char* line) {
56 char* firstSpace = strchr(line, ' ');
57 size_t cmdLength;
58 if (firstSpace) {
59 cmdLength = line - firstSpace;
60 } else {
61 cmdLength = strlen(line);
62 }
63
64 int i;
65 const char* name;
66 for (i = 0; (name = debuggerCommands[i].name); ++i) {
67 if (strlen(name) != cmdLength) {
68 continue;
69 }
70 if (strncasecmp(name, line, cmdLength) == 0) {
71 debuggerCommands[i].command(debugger);
72 return;
73 }
74 }
75 ARMRun(debugger->cpu);
76 _printStatus(debugger);
77}
78
79void ARMDebuggerInit(struct ARMDebugger* debugger, struct ARMCore* cpu) {
80 debugger->cpu = cpu;
81}
82
83void ARMDebuggerEnter(struct ARMDebugger* debugger) {
84 char* line;
85 _printStatus(debugger);
86 while ((line = linenoise("> "))) {
87 _parse(debugger, line);
88 free(line);
89 switch (debugger->state) {
90 case DEBUGGER_EXITING:
91 return;
92 default:
93 break;
94 }
95 }
96}