summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authortrimill <trimill@trimillxyz.org>2024-02-03 00:37:02 -0500
committertrimill <trimill@trimillxyz.org>2024-02-03 00:45:47 -0500
commit6d7a563d368241cb074cb356dd2fafa8c6d7115a (patch)
tree1046e13cc4580d3b75a614652cbdd3ab941e7da2
parentpretty colors (diff)
downloadcorn-6d7a563d368241cb074cb356dd2fafa8c6d7115a.tar.gz
corn-6d7a563d368241cb074cb356dd2fafa8c6d7115a.tar.bz2
corn-6d7a563d368241cb074cb356dd2fafa8c6d7115a.zip
improved debugger, refactored
-rw-r--r--include/panic.h12
-rw-r--r--src/arch/amd64/acpi.c3
-rw-r--r--src/arch/amd64/backtrace.c14
-rw-r--r--src/arch/amd64/debugger.c342
-rw-r--r--src/arch/amd64/fb.c1
-rw-r--r--src/arch/amd64/idt.c85
-rw-r--r--src/arch/amd64/panic.c17
-rw-r--r--src/kmain.c2
-rw-r--r--src/print.c8
9 files changed, 276 insertions, 208 deletions
diff --git a/include/panic.h b/include/panic.h
index d7f612c..08b7561 100644
--- a/include/panic.h
+++ b/include/panic.h
@@ -3,11 +3,11 @@
#define _PANIC_STR(x) _PANIC_STR2(x)
#define _PANIC_STR2(x) #x
-#define panic(msg, ...) _panic_impl(_PANIC_STR(__LINE__), __FILE__, msg, ## __VA_ARGS__)
-#define kassert(val, msg, ...) do { if (!(val)) { panic(msg, ## __VA_ARGS__); } } while(0)
+#define panic(...) _panic_impl(_PANIC_STR(__LINE__), __FILE__, __VA_ARGS__)
+#define kassert(val, ...) do { if (!(val)) { panic(__VA_ARGS__); } } while(0)
-__attribute__((noreturn,format(printf, 3, 4)))
-void _panic_impl(char *line, char *file, char *msg, ...);
+__attribute__((format(printf, 3, 4)))
+_Noreturn void _panic_impl(char *line, char *file, char *format, ...);
-__attribute__((noreturn,format(printf, 3, 4)))
-void _panic_interrupt(void *ip, void *bp, char *msg, ...);
+__attribute__((format(printf, 3, 4)))
+_Noreturn void panic_interrupt(void *ip, void *bp, char *format, ...);
diff --git a/src/arch/amd64/acpi.c b/src/arch/amd64/acpi.c
index d476ac8..e262a99 100644
--- a/src/arch/amd64/acpi.c
+++ b/src/arch/amd64/acpi.c
@@ -6,7 +6,6 @@
#include "bindings.h"
#include "memory.h"
-#include "serial.h"
/* global state, idk a better way rn */
struct acpi_state state;
@@ -208,7 +207,7 @@ static void *acpi_find_table_rsdt(struct rsdt *rsdt, const char *identifier, int
memcpy(buf, h->signature, 4);
buf[4] = '\n';
buf[5] = '\0';
- serial_out_str(buf);
+ kputs(buf);
if (!strncmp(h->signature, identifier, ident_len))
return (void *)h;
}
diff --git a/src/arch/amd64/backtrace.c b/src/arch/amd64/backtrace.c
index a5e8ffd..9e1c9d7 100644
--- a/src/arch/amd64/backtrace.c
+++ b/src/arch/amd64/backtrace.c
@@ -1,6 +1,5 @@
#include <backtrace.h>
#include <lib.h>
-#include "serial.h"
struct stackframe {
struct stackframe *rbp;
@@ -36,17 +35,10 @@ void log_backtrace() {
void log_backtrace_ex(void *ip, void *bp) {
struct stackframe *frame = bp;
- char buf[20];
- serial_out_str("Stack trace:\n");
- ultoa((size_t)ip, buf, 16);
- serial_out_str(" 0x");
- serial_out_str(buf);
- serial_out_str("\n");
+ kputs("Stack trace:\n");
+ kprintf(" %#lx\n", (size_t)ip);
while (frame) {
- ultoa((size_t)frame->rip, buf, 16);
- serial_out_str(" 0x");
- serial_out_str(buf);
- serial_out_str("\n");
+ kprintf(" %#lx\n", (size_t)frame->rip);
frame = frame->rbp;
}
diff --git a/src/arch/amd64/debugger.c b/src/arch/amd64/debugger.c
index 2356e4a..a1fa968 100644
--- a/src/arch/amd64/debugger.c
+++ b/src/arch/amd64/debugger.c
@@ -1,7 +1,7 @@
#include <lib.h>
#include <stddef.h>
-#include <serial.h>
#include <backtrace.h>
+#include <serial.h>
#include "debugger.h"
struct dr6 {
@@ -73,183 +73,217 @@ struct breakpoint {
uint8_t rw;
uint8_t used;
uint8_t enable;
+ uint8_t instr_len;
};
-static size_t dbg_steps = 0;
+static int dbg_steps = 0;
static int dbg_continue = 0;
static struct breakpoint bkps[4] = {{0}, {0}, {0}, {0}};
-static void dbg_putc(char c) {
- serial_out(c);
-}
-
-static void dbg_puts(char *msg) {
- serial_out_str(msg);
-}
-
-static char dbg_getc() {
- return serial_in();
+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) {
- char buf[24];
switch (cause) {
case DEBUG_INT3:
- dbg_puts("dbg: reached int3");
+ kputs("dbg: reached int3");
break;
case DEBUG_FAULT:
- dbg_puts("dbg: a fault occured");
+ kputs("dbg: a fault occured");
break;
case DEBUG_DBG:
if (dr6.bs)
- dbg_puts("dbg: finished steps");
- else if (dr6.b0)
- dbg_puts("dbg: reached breakpoint 0");
+ kputs("dbg: finished steps");
+ if (dr6.b0)
+ kputs("dbg: reached breakpoint 0");
else if (dr6.b1)
- dbg_puts("dbg: reached breakpoint 1");
+ kputs("dbg: reached breakpoint 1");
else if (dr6.b2)
- dbg_puts("dbg: reached breakpoint 2");
+ kputs("dbg: reached breakpoint 2");
else if (dr6.b3)
- dbg_puts("dbg: reached breakpoint 3");
+ kputs("dbg: reached breakpoint 3");
}
if (dbg_steps > 0) {
- ultoa(dbg_steps, buf, 10);
- dbg_puts(" (");
- dbg_puts(buf);
- dbg_puts(" steps left)");
+ kprintf(" (%d steps left)", dbg_steps);
}
if (dbg_continue > 0) {
- dbg_puts(" (paused continue)");
- }
- dbg_puts("\n");
-}
-
-static void debugger_print_reg(char *name, uint64_t val) {
- char buf[24];
- char *end;
- dbg_puts(name);
- dbg_puts(": 0x");
-
- end = ultoa(val, buf, 16);
- for (int i = 0; i < 16 - (end - buf); i++) {
- dbg_putc('0');
+ kputs(" (paused continue)");
}
- dbg_puts(buf);
-
- dbg_puts(" (");
- end = ultoa(val, buf, 10);
- dbg_puts(buf);
- dbg_puts(")\n");
+ kputs("\n");
}
static void debugger_print_regs(struct isr_regs *state) {
- debugger_print_reg("rax", state->rax);
- debugger_print_reg("rbx", state->rbx);
- debugger_print_reg("rcx", state->rcx);
- debugger_print_reg("rdx", state->rdx);
- debugger_print_reg("rsi", state->rsi);
- debugger_print_reg("rdi", state->rdi);
- debugger_print_reg("rsp", state->rsp);
- debugger_print_reg("rbp", state->rbp);
- debugger_print_reg("r8 ", state->r8 );
- debugger_print_reg("r9 ", state->r9 );
- debugger_print_reg("r10", state->r10);
- debugger_print_reg("r11", state->r11);
- debugger_print_reg("r12", state->r12);
- debugger_print_reg("r13", state->r13);
- debugger_print_reg("r14", state->r14);
- debugger_print_reg("r15", state->r15);
- dbg_puts("---\n");
- debugger_print_reg("rip", state->rip);
- dbg_puts("---\n");
- debugger_print_reg("rflags", state->rflags);
+ 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;
- dbg_puts("rflags: ");
- if(rflags->cf) dbg_puts("CF ");
- if(rflags->pf) dbg_puts("PF ");
- if(rflags->af) dbg_puts("AF ");
- if(rflags->zf) dbg_puts("ZF ");
- if(rflags->sf) dbg_puts("SF ");
- if(rflags->tf) dbg_puts("TF ");
- if(rflags->if_) dbg_puts("IF ");
- if(rflags->df) dbg_puts("DF ");
- if(rflags->of) dbg_puts("OF ");
- if(rflags->iopl) dbg_puts("IOPL ");
- if(rflags->nt) dbg_puts("NT ");
- if(rflags->md) dbg_puts("MD ");
- if(rflags->rf) dbg_puts("RF ");
- if(rflags->vm) dbg_puts("VM ");
- if(rflags->ac) dbg_puts("AC ");
- if(rflags->vif) dbg_puts("VIF ");
- if(rflags->vip) dbg_puts("VIP ");
- if(rflags->id) dbg_puts("ID ");
- dbg_putc('\n');
+ 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 *buf) {
- if (buf[0] == 'l') {
+static int debugger_handle_bkp_cmd(char *msg) {
+ if (msg[0] == 'l') {
// list breakpoints
- char buf[20];
for (int i = 0; i < 4; i++) {
- dbg_puts("breakpoint ");
- dbg_putc('0' + i);
- dbg_puts(": ");
struct breakpoint bkp = bkps[i];
if(!bkp.used) {
- dbg_puts("unset\n");
+ kprintf("breakpoint %d: unset\n", i);
continue;
}
- dbg_puts(" 0x");
- ultoa(bkp.addr, buf, 16);
- dbg_puts(buf);
- dbg_puts(" len=");
- switch (bkp.len) {
- case 0x0: dbg_putc('1'); break;
- case 0x1: dbg_putc('2'); break;
- case 0x2: dbg_putc('8'); break;
- case 0x3: dbg_putc('4'); break;
- }
- dbg_puts(" trigger=");
- switch (bkp.rw) {
- case 0x0: dbg_puts("x "); break;
- case 0x1: dbg_puts("w "); break;
- case 0x2: dbg_puts("io"); break;
- case 0x3: dbg_puts("rw"); break;
- }
- dbg_puts(bkp.enable ? " enabled" : " disabled");
+ 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 (buf[0] == 'd') {
+ } 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 (buf[0] == 'c') {
+ } 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;
- } else if (buf[0] <= '0' && buf[0] >= '3') {
- dbg_puts("invalid breakpoint command\n");
+ 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;
}
- // TODO set breakpoints
- 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[0].used;
- dr7.g2 = bkps[2].enable & bkps[0].used;
- dr7.g3 = bkps[3].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;
@@ -263,19 +297,16 @@ static void debugger_load_bkps() {
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) {
- char buf[PROMPT_LEN];
- char *p = buf;
- dbg_puts("dbg> ");
- while ((*p = dbg_getc()) != '\r' && p < buf + PROMPT_LEN - 1) {
- dbg_putc(*p++);
- }
- dbg_putc('\n');
- for(; p < buf + PROMPT_LEN; p++) {
- *p = 0;
- }
+ kputs("dbg> ");
+ char buf[64];
+ debugger_read(buf, 64);
struct rflags *rflags = (struct rflags *)&state->rflags;
@@ -283,7 +314,7 @@ static int debugger_prompt(struct isr_regs *state) {
case '\0': // nothing entered
return 1;
case 'h': // help
- dbg_puts("see debugger.c for help information\n");
+ kputs("see debugger.c for help information\n");
return 1;
case 'q': // quit
return 0;
@@ -302,6 +333,36 @@ static int debugger_prompt(struct isr_regs *state) {
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);
@@ -309,7 +370,7 @@ static int debugger_prompt(struct isr_regs *state) {
return res;
}
default:
- dbg_puts("unknown command\n");
+ kputs("unknown command\n");
return 1;
}
}
@@ -318,9 +379,7 @@ 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) {
-
- } else {
+ if (!(dr6.b0 || dr6.b1 || dr6.b2 || dr6.b3)) {
if (dr6.bs && dbg_steps > 0) {
dbg_steps--;
return;
@@ -333,11 +392,22 @@ void debugger(struct isr_regs *state, int cause) {
debugger_msg(cause, dr6);
+ kputs("hi\n");
+
dbg_steps = 0;
dbg_continue = 0;
- struct rflags *rflags = (struct rflags *)&state->rflags;
- rflags->tf = 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));
}
diff --git a/src/arch/amd64/fb.c b/src/arch/amd64/fb.c
index 8484f29..8560166 100644
--- a/src/arch/amd64/fb.c
+++ b/src/arch/amd64/fb.c
@@ -1,6 +1,5 @@
#include <lib.h>
#include <memory.h>
-#include <serial.h>
#include <stdint.h>
#include <panic.h>
#include <pci.h>
diff --git a/src/arch/amd64/idt.c b/src/arch/amd64/idt.c
index a2ee2a7..d33c795 100644
--- a/src/arch/amd64/idt.c
+++ b/src/arch/amd64/idt.c
@@ -1,7 +1,6 @@
#include <stdint.h>
#include <stddef.h>
#include <lib.h>
-#include <serial.h>
#include <panic.h>
#include "debugger.h"
@@ -74,48 +73,48 @@ void idt_init(void) {
// Intel manual vol 3 ch 6.3.1
char *EXCEPTIONS[] = {
- "0x00 Division Error",
- "0x01 Debug",
- "0x02 NMI",
- "0x03 Breakpoint",
- "0x04 Overflow",
- "0x05 BOUND Range Exceeded",
- "0x06 Invalid Opcode",
- "0x07 Device Not Available",
- "0x08 Double Fault",
- "0x09 Coprocessor Segment Overrun",
- "0x0A Invalid TSS",
- "0x0B Segment Not Present",
- "0x0C Stack-Segment Fault",
- "0x0D General Protection Fault",
- "0x0E Page Fault",
- "0x0F Reserved",
- "0x10 x87 Floating-Point Error",
- "0x11 Alignment Check",
- "0x12 Machine Check",
- "0x13 SIMD Floaing-Point Exception",
- "0x14 Virtualization Exception",
- "0x15 Control Protection Exception",
- "0x16 Reserved",
- "0x17 Reserved",
- "0x18 Reserved",
- "0x19 Reserved",
- "0x1A Reserved",
- "0x1B Reserved",
- "0x1C Hypervisor Injection Exception",
- "0x1D VMM Communication Exception",
- "0x1E Security Exception",
- "0x1F Reserved",
+ "Division Error",
+ "Debug",
+ "NMI",
+ "Breakpoint",
+ "Overflow",
+ "BOUND Range Exceeded",
+ "Invalid Opcode",
+ "Device Not Available",
+ "Double Fault",
+ "Coprocessor Segment Overrun",
+ "Invalid TSS",
+ "Segment Not Present",
+ "Stack-Segment Fault",
+ "General Protection Fault",
+ "Page Fault",
+ "Reserved",
+ "x87 Floating-Point Error",
+ "Alignment Check",
+ "Machine Check",
+ "SIMD Floaing-Point Exception",
+ "Virtualization Exception",
+ "Control Protection Exception",
+ "Reserved",
+ "Reserved",
+ "Reserved",
+ "Reserved",
+ "Reserved",
+ "Reserved",
+ "Hypervisor Injection Exception",
+ "VMM Communication Exception",
+ "Security Exception",
+ "Reserved",
};
void idt_exception_handler(uint64_t exception, uint64_t code, struct isr_regs *state) {
- // breakpoint interrupt
- if (exception == 0x03) {
- debugger(state, DEBUG_INT3);
- return;
- } else if (exception == 0x01) {
+ switch (exception) {
+ case 0x01: // debug
debugger(state, DEBUG_DBG);
return;
+ case 0x03: // breakpoint
+ debugger(state, DEBUG_INT3);
+ return;
}
char custom[64];
@@ -124,12 +123,12 @@ void idt_exception_handler(uint64_t exception, uint64_t code, struct isr_regs *s
// page faults store the offending address in cr2
if (exception == 0x0E) {
strcat(custom, "\nPage fault address: 0x");
- void *addr;
- __asm__ volatile ("mov %%cr2, %0" : "=r"(addr));
- ultoa((size_t)addr, custom + 23, 16);
+ uint64_t cr2;
+ __asm__ volatile ("mov %%cr2, %0" : "=r"(cr2));
+ ultoa((size_t)cr2, custom + 23, 16);
}
- _panic_interrupt(
+ panic_interrupt(
(void *)state->rip,
(void *)state->rbp,
"Exception %s\nError code 0x%lu%s",
@@ -149,7 +148,7 @@ void idt_pic_timer(void) {
// print a message once we know the timer works
// but avoid spamming the logs
if (counter == 3) {
- serial_out_str("pic timer!\n");
+ kputs("pic timer!\n");
}
if (counter <= 3) {
counter++;
diff --git a/src/arch/amd64/panic.c b/src/arch/amd64/panic.c
index fa750bc..6c35727 100644
--- a/src/arch/amd64/panic.c
+++ b/src/arch/amd64/panic.c
@@ -1,31 +1,34 @@
#include <panic.h>
#include <backtrace.h>
#include <stdarg.h>
+
#include <lib.h>
#include "bindings.h"
-void _panic_impl(char *line, char *file, char *format, ...) {
+_Noreturn void _panic_impl(char *line, char *file, char *format, ...) {
cli();
va_list list;
- va_start(list, msg);
+ va_start(list, format);
kprintf("\n\n!!! PANIC !!!\n");
kprintf("In file %s at line %s:\n", file, line);
kvprintf(format, list);
kprintf("\n\n");
+
log_backtrace();
while (1) {
halt();
}
}
-void _panic_interrupt(void *ip, void *bp, char *format, ...) {
- cli();
+_Noreturn void panic_interrupt(void *ip, void *bp, char *msg, ...) {
va_list list;
va_start(list, msg);
- kprintf("\n\n!!! PANIC !!!\n");
- kvprintf(format, list);
- kprintf("\n\n");
+ cli();
+ kputs("\n\n!!! PANIC !!!\n");
+ kvprintf(msg, list);
+ kputs("\n\n");
+
log_backtrace_ex(ip, bp);
while (1) {
halt();
diff --git a/src/kmain.c b/src/kmain.c
index bc1d225..7ae9d01 100644
--- a/src/kmain.c
+++ b/src/kmain.c
@@ -2,7 +2,6 @@
#include <acpi.h>
#include <memory.h>
#include <lib.h>
-#include <serial.h>
#include <fb.h>
#include <shim.h>
#include <panic.h>
@@ -20,6 +19,7 @@ void kmain(struct boot_info *info) {
*(char *)(0xB8000 + 0x144) = 'h';
*(char *)(0xB8000 + 0x146) = 'i';
+
while (1) {
__asm__("hlt;");
// loop so we dont halt
diff --git a/src/print.c b/src/print.c
index 712df30..4adfcf7 100644
--- a/src/print.c
+++ b/src/print.c
@@ -344,7 +344,7 @@ static void print_unum(
bool space_pre = (flag & FLG_LEFT_ALIGN) || !(flag & FLG_ZERO);
- if (!space_pre && radix == 16 && flag & FLG_ALTERNATE) {
+ if (!space_pre && radix == 16 && (flag & FLG_ALTERNATE)) {
char x = base + ('x' - 'a');
serial_out('0');
serial_out(x);
@@ -371,6 +371,12 @@ static void print_unum(
if (flag & FLG_ZERO)
zero_padded = true;
}
+
+ if (space_pre && radix == 16 && (flag & FLG_ALTERNATE)) {
+ char x = base + ('x' - 'a');
+ serial_out('0');
+ serial_out(x);
+ }
if (space_pre && radix == 16 && flag & FLG_ALTERNATE) {
char x = base + ('x' - 'a');