summaryrefslogtreecommitdiff
path: root/src/arch/amd64/debugger.c
diff options
context:
space:
mode:
authorFreya Murphy <freya@freyacat.org>2024-02-03 00:50:07 -0500
committerFreya Murphy <freya@freyacat.org>2024-02-03 00:53:58 -0500
commit90a6065691beee52bf5309916fba98f7580d27be (patch)
tree0b5375d20c189f62d394c473d371f7bf7f1d3fc5 /src/arch/amd64/debugger.c
parentimproved debugger, refactored (diff)
downloadcorn-90a6065691beee52bf5309916fba98f7580d27be.tar.gz
corn-90a6065691beee52bf5309916fba98f7580d27be.tar.bz2
corn-90a6065691beee52bf5309916fba98f7580d27be.zip
refactor, new arch dirs, (wip) page alloc on write, hsv screen (convert to userspace later), other fixes
Diffstat (limited to 'src/arch/amd64/debugger.c')
-rw-r--r--src/arch/amd64/debugger.c413
1 files changed, 0 insertions, 413 deletions
diff --git a/src/arch/amd64/debugger.c b/src/arch/amd64/debugger.c
deleted file mode 100644
index a1fa968..0000000
--- a/src/arch/amd64/debugger.c
+++ /dev/null
@@ -1,413 +0,0 @@
-#include <lib.h>
-#include <stddef.h>
-#include <backtrace.h>
-#include <serial.h>
-#include "debugger.h"
-
-struct dr6 {
- uint64_t b0 : 1,
- b1 : 1,
- b2 : 1,
- b3 : 1,
- : 7,
- bld : 1,
- : 1,
- bd : 1,
- bs : 1,
- bt : 1,
- rtm : 1,
- : 47;
-};
-
-struct dr7 {
- uint64_t l0 : 1,
- g0 : 1,
- l1 : 1,
- g1 : 1,
- l2 : 1,
- g2 : 1,
- l3 : 1,
- g3 : 1,
- : 8,
- rw0 : 2,
- len0 : 2,
- rw1 : 2,
- len1 : 2,
- rw2 : 2,
- len2 : 2,
- rw3 : 2,
- len3 : 2,
- : 32;
-};
-
-struct rflags {
- uint64_t cf : 1,
- : 1,
- pf : 1,
- : 1,
- af : 1,
- : 1,
- zf : 1,
- sf : 1,
-
- tf : 1,
- if_ : 1,
- df : 1,
- of : 1,
- iopl : 2,
- nt : 1,
- md : 1,
-
- rf : 1,
- vm : 1,
- ac : 1,
- vif : 1,
- vip : 1,
- id : 1,
- : 42;
-};
-
-struct breakpoint {
- uint64_t addr;
- uint8_t len;
- uint8_t rw;
- uint8_t used;
- uint8_t enable;
- uint8_t instr_len;
-};
-
-static int dbg_steps = 0;
-static int dbg_continue = 0;
-static struct breakpoint bkps[4] = {{0}, {0}, {0}, {0}};
-
-static size_t debugger_read(char *buf, size_t len) {
- char *p = buf;
- size_t result;
- while (p < buf + len - 1) {
- char ch = serial_in();
- switch (ch) {
- case '\r':
- goto end;
- case '\x7f':
- if (p > buf) {
- p--;
- kputs("\x08 \x08");
- }
- break;
- default:
- kputc(ch);
- *p++ = ch;
- }
- }
-end:
- result = p - buf;
- kputc('\n');
- for(; p < buf + len; p++) {
- *p = 0;
- }
- return result;
-}
-
-static void debugger_msg(int cause, struct dr6 dr6) {
- switch (cause) {
- case DEBUG_INT3:
- kputs("dbg: reached int3");
- break;
- case DEBUG_FAULT:
- kputs("dbg: a fault occured");
- break;
- case DEBUG_DBG:
- if (dr6.bs)
- kputs("dbg: finished steps");
- if (dr6.b0)
- kputs("dbg: reached breakpoint 0");
- else if (dr6.b1)
- kputs("dbg: reached breakpoint 1");
- else if (dr6.b2)
- kputs("dbg: reached breakpoint 2");
- else if (dr6.b3)
- kputs("dbg: reached breakpoint 3");
- }
- if (dbg_steps > 0) {
- kprintf(" (%d steps left)", dbg_steps);
- }
- if (dbg_continue > 0) {
- kputs(" (paused continue)");
- }
- kputs("\n");
-}
-
-static void debugger_print_regs(struct isr_regs *state) {
- kprintf("rax: %#016lx (%lu)\n", state->rax, state->rax);
- kprintf("rbx: %#016lx (%lu)\n", state->rbx, state->rbx);
- kprintf("rcx: %#016lx (%lu)\n", state->rcx, state->rcx);
- kprintf("rdx: %#016lx (%lu)\n", state->rdx, state->rdx);
- kprintf("rsi: %#016lx (%lu)\n", state->rsi, state->rsi);
- kprintf("rdi: %#016lx (%lu)\n", state->rdi, state->rdi);
- kprintf("rsp: %#016lx (%lu)\n", state->rsp, state->rsp);
- kprintf("rbp: %#016lx (%lu)\n", state->rbp, state->rbp);
- kprintf("r8 : %#016lx (%lu)\n", state->r8 , state->r8 );
- kprintf("r9 : %#016lx (%lu)\n", state->r9 , state->r9 );
- kprintf("r10: %#016lx (%lu)\n", state->r10, state->r10);
- kprintf("r11: %#016lx (%lu)\n", state->r11, state->r11);
- kprintf("r12: %#016lx (%lu)\n", state->r12, state->r12);
- kprintf("r13: %#016lx (%lu)\n", state->r13, state->r13);
- kprintf("r14: %#016lx (%lu)\n", state->r14, state->r14);
- kprintf("r15: %#016lx (%lu)\n", state->r15, state->r15);
- kputs("---\n");
- kprintf("rip: %#016lx (%lu)\n", state->rip, state->rip);
- kputs("---\n");
- kprintf("rflags: %#016lx (%lu)\n", state->rflags, state->rflags);
- struct rflags *rflags = (struct rflags *)state->rflags;
- kputs("rflags: ");
- if(rflags->cf) kputs("CF ");
- if(rflags->pf) kputs("PF ");
- if(rflags->af) kputs("AF ");
- if(rflags->zf) kputs("ZF ");
- if(rflags->sf) kputs("SF ");
- if(rflags->tf) kputs("TF ");
- if(rflags->if_) kputs("IF ");
- if(rflags->df) kputs("DF ");
- if(rflags->of) kputs("OF ");
- if(rflags->iopl) kputs("IOPL ");
- if(rflags->nt) kputs("NT ");
- if(rflags->md) kputs("MD ");
- if(rflags->rf) kputs("RF ");
- if(rflags->vm) kputs("VM ");
- if(rflags->ac) kputs("AC ");
- if(rflags->vif) kputs("VIF ");
- if(rflags->vip) kputs("VIP ");
- if(rflags->id) kputs("ID ");
- kputs("\n");
-}
-
-#define PROMPT_LEN 60
-
-static int debugger_handle_bkp_cmd(char *msg) {
- if (msg[0] == 'l') {
- // list breakpoints
- for (int i = 0; i < 4; i++) {
- struct breakpoint bkp = bkps[i];
- if(!bkp.used) {
- kprintf("breakpoint %d: unset\n", i);
- continue;
- }
- const char *lenstrs[] = {"1", "2", "8", "4"};
- const char *rwstrs[] = {"x ", "w ", "io", "rw"};
- kprintf(
- "breakpoint %d: %#016lx len=%s trigger=%s instrlen=%01d %s\n",
- i,
- bkp.addr,
- lenstrs[bkp.len],
- rwstrs[bkp.rw],
- bkp.instr_len,
- bkp.enable ? " enabled" : " disabled"
- );
- }
- return 1;
- } else if (msg[0] == 'd') {
- // disable breakpoints
- bkps[0].enable = 0;
- bkps[1].enable = 0;
- bkps[2].enable = 0;
- bkps[3].enable = 0;
- kputs("disabled breakpoints\n");
- return 1;
- } else if (msg[0] == 'c') {
- // clear breakpoints
- bkps[0].used = 0;
- bkps[1].used = 0;
- bkps[2].used = 0;
- bkps[3].used = 0;
- kputs("cleared breakpoints\n");
- return 1;
- } else if (msg[0] <= '0' && msg[0] >= '3') {
- kputs("invalid breakpoint command\n");
- return 1;
- }
- char buf[64];
- int id = msg[0] - '0';
- switch (msg[1]) {
- case 'e':
- bkps[id].enable = bkps[id].used;
- kprintf("enabled breakpoint %d\n", id);
- return 1;
- case 'd':
- bkps[id].enable = 0;
- kprintf("disabled breakpoint %d\n", id);
- return 1;
- case 'c':
- bkps[id].used = 0;
- kprintf("cleared breakpoint %d\n", id);
- return 1;
- case 'a':
- kputs("addr> 0x");
- debugger_read(buf, 64);
- bkps[id].addr = strtoll(buf, NULL, 16);
- kputs("len (1/2/4/8)> ");
- debugger_read(buf, 64);
- switch (buf[0]) {
- case '1': bkps[id].len = 0x0; break;
- case '2': bkps[id].len = 0x1; break;
- case '8': bkps[id].len = 0x2; break;
- case '4': bkps[id].len = 0x3; break;
- default: bkps[id].len = 0x0; break;
- }
- kputs("cond (x/w/io/rw)> ");
- debugger_read(buf, 64);
- switch ((int)buf[0] * 256 + (int)buf[1]) {
- case (int)'x'*256 + (int)0: bkps[id].rw = 0x0; break;
- case (int)'w'*256 + (int)0: bkps[id].rw = 0x1; break;
- case (int)'i'*256 + (int)'o': bkps[id].rw = 0x2; break;
- case (int)'r'*256 + (int)'w': bkps[id].rw = 0x3; break;
- default: bkps[id].len = 0x0; break;
- }
- kputs("instr len (1..15)> ");
- debugger_read(buf, 64);
- bkps[id].instr_len = strtoi(buf, NULL, 10);
- kputs("enable (y/n)> ");
- debugger_read(buf, 64);
- bkps[id].used = 1;
- bkps[id].enable = !(buf[0] == 'n' || buf[0] == 'N');
- kprintf("added breakpoint %d\n", id);
- return 1;
- default:
- kputs("invalid breakpoint command\n");
- return 1;
- }
-}
-
-static void debugger_load_bkps() {
- struct dr7 dr7;
- __asm__ volatile ("mov %%dr7, %0" : "=r"(dr7));
- dr7.g0 = bkps[0].enable & bkps[0].used;
- dr7.g1 = bkps[1].enable & bkps[1].used;
- dr7.g2 = bkps[2].enable & bkps[2].used;
- dr7.g3 = bkps[3].enable & bkps[3].used;
- dr7.l0 = 0;
- dr7.l1 = 0;
- dr7.l2 = 0;
- dr7.l3 = 0;
- dr7.rw0 = bkps[0].rw;
- dr7.rw1 = bkps[1].rw;
- dr7.rw2 = bkps[2].rw;
- dr7.rw3 = bkps[3].rw;
- dr7.len0 = bkps[0].len;
- dr7.len1 = bkps[1].len;
- dr7.len2 = bkps[2].len;
- dr7.len3 = bkps[3].len;
- __asm__ volatile ("mov %0, %%dr7" : : "r"(dr7));
- __asm__ volatile ("mov %0, %%dr0" : : "r"(bkps[0].addr));
- __asm__ volatile ("mov %0, %%dr1" : : "r"(bkps[1].addr));
- __asm__ volatile ("mov %0, %%dr2" : : "r"(bkps[2].addr));
- __asm__ volatile ("mov %0, %%dr3" : : "r"(bkps[3].addr));
-}
-
-static int debugger_prompt(struct isr_regs *state) {
- kputs("dbg> ");
- char buf[64];
- debugger_read(buf, 64);
-
- struct rflags *rflags = (struct rflags *)&state->rflags;
-
- switch (buf[0]) {
- case '\0': // nothing entered
- return 1;
- case 'h': // help
- kputs("see debugger.c for help information\n");
- return 1;
- case 'q': // quit
- return 0;
- case 'c': // continue
- rflags->tf = 1;
- dbg_continue = 1;
- return 0;
- case 'r': // print registers
- debugger_print_regs(state);
- return 1;
- case 'k': // backtrace
- log_backtrace_ex((void *)state->rip, (void *)state->rbp);
- return 1;
- case 's': // step (n)
- rflags->tf = 1;
- dbg_steps = atol(buf + 1) - 1;
- //if (dbg_steps < 0) dbg_steps = 0;
- return 0;
- case 'm': // memory
- {
- kputs("addr> 0x");
- debugger_read(buf, 64);
- uint64_t start = (~0xF) & strtoll(buf, NULL, 16);
-
- kputs("len> 0x");
- debugger_read(buf, 64);
- uint64_t len = (~0xF) & strtoll(buf, NULL, 16);
-
- for (uint64_t a = start; a <= start + len; a += 0x10) {
- kprintf("%08lx: ", a);
- for (uint64_t b = 0; b < 0x10; b++) {
- kprintf("%02x ", *(uint8_t *)(a + b));
- if (b % 0x08 == 7) {
- kputc(' ');
- }
- }
- kputs("|");
- for (uint64_t b = 0; b < 0x10; b++) {
- uint8_t ch = *(uint8_t *)(a + b);
- if (ch < 0x20 || ch >= 0x7f) {
- ch = '.';
- }
- kputc(ch);
- }
- kputs("|\n");
- }
- return 1;
- }
- case 'b': // breakpoints
- {
- int res = debugger_handle_bkp_cmd(buf+1);
- debugger_load_bkps();
- return res;
- }
- default:
- kputs("unknown command\n");
- return 1;
- }
-}
-
-void debugger(struct isr_regs *state, int cause) {
- struct dr6 dr6;
- __asm__ volatile ("mov %%dr6, %0" : "=r"(dr6));
-
- if (!(dr6.b0 || dr6.b1 || dr6.b2 || dr6.b3)) {
- if (dr6.bs && dbg_steps > 0) {
- dbg_steps--;
- return;
- }
-
- if (dr6.bs && dbg_continue) {
- return;
- }
- }
-
- debugger_msg(cause, dr6);
-
- kputs("hi\n");
-
- dbg_steps = 0;
- dbg_continue = 0;
-
- ((struct rflags *)&state->rflags)->tf = 0;
-
- if (dr6.b0) {
- state->rip += bkps[0].instr_len;
- } else if (dr6.b1) {
- state->rip += bkps[1].instr_len;
- } else if (dr6.b2) {
- state->rip += bkps[2].instr_len;
- } else if (dr6.b3) {
- state->rip += bkps[3].instr_len;
- }
-
- while (debugger_prompt(state));
-}