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