From 90a6065691beee52bf5309916fba98f7580d27be Mon Sep 17 00:00:00 2001 From: Freya Murphy Date: Sat, 3 Feb 2024 00:50:07 -0500 Subject: refactor, new arch dirs, (wip) page alloc on write, hsv screen (convert to userspace later), other fixes --- src/arch/amd64/debugger.c | 413 ---------------------------------------------- 1 file changed, 413 deletions(-) delete mode 100644 src/arch/amd64/debugger.c (limited to 'src/arch/amd64/debugger.c') 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 -#include -#include -#include -#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)); -} -- cgit v1.2.3-freya