CS350 COS
COS
Loading...
Searching...
No Matches
debug.c
Go to the documentation of this file.
1/*
2 * Copyright (c) 2012-2018 Ali Mashtizadeh
3 *
4 * Permission to use, copy, modify, and distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR(S) DISCLAIM ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL AUTHORS BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#include <stdbool.h>
18#include <stdint.h>
19#include <string.h>
20
21#include <sys/kassert.h>
22#include <sys/kdebug.h>
23
24#include "../dev/console.h"
25
26#define DEBUG_MAX_LINE 128
27#define DEBUG_MAX_ARGS 16
28
29void
30Debug_PrintHex(const char *data, size_t length, off_t off, size_t limit)
31{
32 const size_t row_size = 16;
33 bool stop = false;
34
35 size_t row;
36 for (row = 0; !stop; row++) {
37 size_t ix = row * row_size;
38 if (ix >= limit || ix >= length)
39 return;
40
41 kprintf("%08lx ", (uintptr_t)data+ix);
42 size_t col;
43 for (col = 0; col < row_size; col++) {
44 size_t ixc = ix + col;
45 if ((limit != 0 && ixc >= limit) || ixc >= length) {
46 stop = true;
47 for (; col < row_size; col++) {
48 kprintf(" ");
49 }
50 break;
51 }
52 ixc += off;
53
54 kprintf("%02X ", (unsigned char)data[ixc]);
55 }
56 kprintf(" |");
57
58 for (col = 0; col < row_size; col++) {
59 size_t ixc = ix + col;
60 if ((limit != 0 && ixc >= limit) || ixc >= length) {
61 stop = true;
62 for (; col < row_size; col++) {
63 kprintf(" ");
64 }
65 break;
66 }
67 ixc += off;
68
69 unsigned char c = (unsigned char)data[ixc];
70 if (c >= 0x20 && c < 0x7F)
71 kprintf("%c", c);
72 else
73 kprintf(".");
74 }
75 kprintf("|");
76 kprintf("\n");
77 }
78}
79
81Debug_GetValue(uintptr_t addr, int size, bool isSigned)
82{
83 switch (size)
84 {
85 case 1: {
86 uint8_t *val = (uint8_t *)addr;
87 if (isSigned && ((*val & 0x80) == 0x80)) {
88 return (uint64_t)*val | 0xFFFFFFFFFFFFFF00ULL;
89 }
90 return *val;
91 }
92 case 2: {
93 uint16_t *val = (uint16_t *)addr;
94 if (isSigned && ((*val & 0x8000) == 0x8000)) {
95 return (uint64_t)*val | 0xFFFFFFFFFFFF0000ULL;
96 }
97 return *val;
98 }
99 case 4: {
100 uint32_t *val = (uint32_t *)addr;
101 if (isSigned && ((*val & 0x80000000) == 0x80000000)) {
102 return (uint64_t)*val | 0xFFFFFFFF00000000ULL;
103 }
104 return *val;
105 }
106 case 8: {
107 uint64_t *val = (uint64_t *)addr;
108 return *val;
109 }
110 default: {
111 kprintf("Debug_GetValue: Unknown size parameter '%d'\n", size);
112 return (uint64_t)-1;
113 }
114 }
115}
116
117void
118Debug_PrintSymbol(uintptr_t off, int strategy)
119{
120 kprintf("0x%llx", off);
121}
122
124Debug_StrToInt(const char *s)
125{
126 int i = 0;
127 int base = 10;
128 uint64_t val = 0;
129
130 if (s[0] == '0' && s[1] == 'x')
131 {
132 base = 16;
133 i = 2;
134 }
135
136 while (s[i] != '\0') {
137 if (s[i] >= '0' && s[i] <= '9') {
138 val = val * base + (uint64_t)(s[i] - '0');
139 } else if (s[i] >= 'a' && s[i] <= 'f') {
140 if (base != 16)
141 kprintf("Not base 16!\n");
142 val = val * base + (uint64_t)(s[i] - 'a' + 10);
143 } else if (s[i] >= 'A' && s[i] <= 'F') {
144 if (base != 16)
145 kprintf("Not base 16!\n");
146 val = val * base + (uint64_t)(s[i] - 'A' + 10);
147 } else {
148 kprintf("Not a number!\n");
149 }
150 i++;
151 }
152
153 return val;
154}
155
157Debug_SymbolToInt(const char *s)
158{
159 if (*s >= '0' || *s <= '9')
160 return Debug_StrToInt(s);
161
162 kprintf("Unknown symbol '%s'\n");
163 return 0;
164}
165
166#define PHELP(_cmd, _msg) kprintf("%-16s %s\n", _cmd, _msg)
167
170
171static void
172Debug_Help(int argc, const char *argv[])
173{
174 int i;
176 commands /= sizeof(DebugCommand);
178
179 kprintf("Commands:\n");
180 for (i = 0; i < commands; i++)
181 {
182 kprintf("%-16s %s\n", cmds[i].name, cmds[i].description);
183 }
184
185 PHELP("continue", "Continue execution");
186}
187
188REGISTER_DBGCMD(help, "Display the list of commands", Debug_Help);
189
190static void
191Debug_Echo(int argc, const char *argv[])
192{
193 int i;
194
195 for (i = 1; i < argc; i++)
196 {
197 kprintf("%s ", argv[i]);
198 }
199 kprintf("\n");
200}
201
202REGISTER_DBGCMD(echo, "Echo arguments", Debug_Echo);
203
204static void
205Debug_Dump(int argc, const char *argv[])
206{
207 uint64_t off, len;
208
209 if (argc != 3)
210 {
211 kprintf("Dump requires 3 arguments\n");
212 return;
213 }
214
215 off = Debug_SymbolToInt(argv[1]);
216 len = Debug_SymbolToInt(argv[2]);
217 kprintf("Dump 0x%llx 0x%llx\n", off, len);
218 Debug_PrintHex((const char *)off, len, 0, len);
219}
220
221REGISTER_DBGCMD(dump, "Dump a region of memory", Debug_Dump);
222
223static void
224Debug_Disasm(int argc, const char *argv[])
225{
226 uintptr_t off;
227 int len = 1;
228
229 if (argc != 2 && argc != 3) {
230 kprintf("Disasm requires 2 or 3 arguments\n");
231 return;
232 }
233
234 off = Debug_SymbolToInt(argv[1]);
235 if (argc == 3)
236 len = Debug_SymbolToInt(argv[2]);
237 kprintf("Disassembly 0x%llx:\n", off);
238
239 for (; len > 0; len--)
240 {
241 off = db_disasm(off, false);
242 }
243}
244
245REGISTER_DBGCMD(disasm, "Disassemble", Debug_Disasm);
246
247void
249{
250 int argc;
251 char *argv[DEBUG_MAX_ARGS];
252 char *nextArg, *last;
253 char buf[DEBUG_MAX_LINE];
254
255 kprintf("Entered Debugger!\n");
256
257 /*
258 * DebugCommand must be 128 bytes for the Section array to align properly
259 */
260 ASSERT(sizeof(DebugCommand) == 128);
261
262 while (1) {
263 kprintf("kdbg> ");
264
265 // read input
267
268 // parse input
269 nextArg = strtok_r(buf, " \t\r\n", &last);
270 for (argc = 0; argc < DEBUG_MAX_ARGS; argc++) {
271 if (nextArg == NULL)
272 break;
273
274 argv[argc] = nextArg;
275 nextArg = strtok_r(NULL, " \t\r\n", &last);
276 }
277
278 if (strcmp(argv[0], "continue") == 0) {
279 return; // Continue
280 } else {
281 // execute command
282 int i;
284 commands /= sizeof(DebugCommand);
286 bool found = false;
287
288 for (i = 0; i < commands; i++)
289 {
290 if (strcmp(argv[0], cmds[i].name) == 0)
291 {
292 cmds[i].func(argc, (const char **)argv);
293 found = true;
294 }
295 }
296
297 if (strcmp(argv[0], "") == 0)
298 continue;
299
300 if (!found)
301 kprintf("Unknown command '%s'\n", argv[0]);
302 }
303 }
304}
305
void Console_Gets(char *str, size_t n)
Definition: console.c:88
uintptr_t db_disasm(uintptr_t loc, bool altfmt)
Definition: disasm.c:1186
static char buf[4096]
Definition: ethdump.c:10
#define ASSERT(_x)
Definition: kassert.h:8
int kprintf(const char *fmt,...)
Definition: printf.c:210
uint64_t Debug_StrToInt(const char *s)
Definition: debug.c:124
#define REGISTER_DBGCMD(_NAME, _DESC, _FUNC)
Definition: kdebug.h:11
void Debug_Prompt()
Definition: debug.c:248
static void Debug_Help(int argc, const char *argv[])
Definition: debug.c:172
DebugCommand __kdbgcmd_end[]
static void Debug_Dump(int argc, const char *argv[])
Definition: debug.c:205
#define DEBUG_MAX_ARGS
Definition: debug.c:27
static void Debug_Echo(int argc, const char *argv[])
Definition: debug.c:191
uint64_t Debug_SymbolToInt(const char *s)
Definition: debug.c:157
void Debug_PrintSymbol(uintptr_t off, int strategy)
Definition: debug.c:118
static void Debug_Disasm(int argc, const char *argv[])
Definition: debug.c:224
uint64_t Debug_GetValue(uintptr_t addr, int size, bool isSigned)
Definition: debug.c:81
DebugCommand __kdbgcmd_start[]
#define DEBUG_MAX_LINE
Definition: debug.c:26
void Debug_PrintHex(const char *data, size_t length, off_t off, size_t limit)
Definition: debug.c:30
#define PHELP(_cmd, _msg)
Definition: debug.c:166
uint64_t addr
Definition: multiboot.h:1
uint32_t size
Definition: multiboot.h:0
uint64_t len
Definition: multiboot.h:2
static uint16_t base
Definition: sercons.c:37
#define NULL
Definition: stddef.h:6
int strcmp(const char *s1, const char *s2)
Definition: string.c:81
char * strtok_r(char *str, const char *delim, char **last)
Definition: string.c:122
void(* func)(int, const char **)
Definition: kdebug.h:8
int64_t off_t
Definition: types.h:20
unsigned short uint16_t
Definition: types.h:11
unsigned int uint32_t
Definition: types.h:12
uint64_t uintptr_t
Definition: types.h:16
unsigned long uint64_t
Definition: types.h:13
unsigned char uint8_t
Definition: types.h:10