stack trace uses saved registers, aka more useful stacktraces

This commit is contained in:
Zoe
2023-11-25 22:36:06 -06:00
parent b16f2152c2
commit 749ee0a0ba
18 changed files with 132 additions and 35152 deletions

4
.gitignore vendored
View File

@@ -1,6 +1,8 @@
/target /target
/bin /bin
/scripts/*/**
# Bochs # Bochs
bx_enh_dbg.ini bx_enh_dbg.ini
# limine
limine/

4
.gitmodules vendored
View File

@@ -1,4 +0,0 @@
[submodule "limine"]
path = limine
url = https://github.com/limine-bootloader/limine
branch = v5.x-branch-binary

View File

@@ -90,7 +90,7 @@ endif
build-iso: partition-iso build-iso: partition-iso
nm target/${ARCH}-unknown-none/${MODE}/CappuccinOS.elf > scripts/symbols.table nm target/${ARCH}-unknown-none/${MODE}/CappuccinOS.elf > scripts/symbols.table
@if [ ! -d "scripts/rustc_demangle" ]; then \ @if [ ! -d "scripts/rustc_demangle" ]; then \
echo "Cloning repository into scripts/rustc_demangle..."; \ echo "Cloning rustc_demangle.py into scripts/rustc_demangle/..."; \
git clone "https://github.com/juls0730/rustc_demangle.py" "scripts/rustc_demangle"; \ git clone "https://github.com/juls0730/rustc_demangle.py" "scripts/rustc_demangle"; \
else \ else \
echo "Folder scripts/rustc_demangle already exists. Skipping clone."; \ echo "Folder scripts/rustc_demangle already exists. Skipping clone."; \
@@ -106,6 +106,12 @@ build-iso: partition-iso
mcopy -i ${IMAGE_PATH}@@1M -s ${ISO_PATH}/* ::/ mcopy -i ${IMAGE_PATH}@@1M -s ${ISO_PATH}/* ::/
compile-bootloader: compile-bootloader:
@if [ ! -d "limine" ]; then \
echo "Cloning Limine into limine/..."; \
git clone https://github.com/limine-bootloader/limine.git --branch=v5.x-branch-binary --depth=1; \
else \
echo "Folder limine already exists. Skipping clone."; \
fi
make -C limine make -C limine
compile-binaries: compile-binaries:

File diff suppressed because it is too large Load Diff

1
limine

Submodule limine deleted from 7563eb4dbe

1
scripts/.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
rustc_demangle/

View File

@@ -1,2 +1,5 @@
# CappuccinOS/scripts # CappuccinOS/scripts
This folder is responsible for holding all the scripts that are necessary for building CappuccinOS This folder is responsible for holding all the scripts that are necessary for building CappuccinOS
- **demangle-symbols.py**<br/>
This file takes in a symbols file generated by the `nm` program and outputs a symbol file with the symbol names demangled, it uses my library, [rustc_demangle.py](https://github.com/juls0730/rustc_demangle.py) which is a python port of the Rust symbol demangling library [rustc-demangle](https://github.com/rust-lang/rustc-demangle).

Submodule scripts/rustc_demangle deleted from 9c7b8459ec

View File

@@ -1,13 +1,11 @@
#[cfg(any(target_arch = "x86_64"))] #[cfg(any(target_arch = "x86_64"))]
pub use self::imp::*; pub use self::x86_64::*;
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))] #[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
pub use self::x86_common::*; pub use self::x86_common::*;
#[cfg(target_arch = "x86_64")]
mod x86_64;
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))] #[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
mod x86_common; mod x86_common;
#[cfg(target_arch = "x86_64")]
#[path = "x86_64"]
mod imp {
pub mod interrupts;
}

View File

@@ -2,8 +2,46 @@ use super::idt_set_gate;
use crate::libs::util::hcf; use crate::libs::util::hcf;
use crate::{log_error, log_info}; use crate::{log_error, log_info};
#[no_mangle] #[repr(C)]
pub extern "C" fn exception_handler(int: u64, eip: u64, cs: u64, eflags: u64) -> ! { #[derive(Clone, Copy, Debug)]
struct Registers {
// Pushed by wrapper
int: usize,
// Pushed by push_gprs in crate::arch::x86_64
r15: usize,
r14: usize,
r13: usize,
r12: usize,
r11: usize,
r10: usize,
r9: usize,
r8: usize,
rbp: usize,
rdi: usize,
rsi: usize,
rdx: usize,
rcx: usize,
rbx: usize,
rax: usize,
// Pushed by interrupt
rip: usize,
cs: usize,
rflags: usize,
rsp: usize,
ss: usize,
}
extern "C" fn exception_handler(registers: u64) {
crate::println!("{:X?}", registers);
let registers = unsafe { *(registers as *const Registers) };
crate::println!("{:X?}", registers);
let int = registers.int;
match int { match int {
0x00 => { 0x00 => {
log_error!("DIVISION ERROR!"); log_error!("DIVISION ERROR!");
@@ -20,9 +58,6 @@ pub extern "C" fn exception_handler(int: u64, eip: u64, cs: u64, eflags: u64) ->
0x0E => { 0x0E => {
log_error!("PAGE FAULT!"); log_error!("PAGE FAULT!");
} }
0x0F => {
log_error!("IDE");
}
0xFF => { 0xFF => {
log_error!("EXCEPTION!"); log_error!("EXCEPTION!");
} }
@@ -32,100 +67,52 @@ pub extern "C" fn exception_handler(int: u64, eip: u64, cs: u64, eflags: u64) ->
} }
log_info!( log_info!(
"INT: {:x} EIP: {:X}, CS: {:X}, EFLAGS: {:b}", "INT: {:x} RIP: {:X}, CS: {:X}, EFLAGS: {:b}",
int, int,
eip, registers.rip,
cs, registers.cs,
eflags registers.rflags
); );
// unsafe { crate::arch::stack_trace::print_stack_trace(6, registers.rbp as u64);
// core::arch::asm!("cli");
// };
crate::arch::stack_trace::print_stack_trace(6);
hcf();
} }
#[naked] // *macro intensifies*
pub extern "C" fn div_error() { macro_rules! exception_function {
unsafe { ($code:expr, $handler:ident, $recoverable:literal) => {
core::arch::asm!( #[inline(always)]
// WHY DOESN'T PUSH DO THIS CORRECTLY extern "C" fn $handler() {
"mov rdi, 0x00", crate::arch::push_gprs();
"call exception_handler",
"add esp, 4", unsafe {
"iretq", core::arch::asm!(
options(noreturn) "push {0:r}",
); "mov rdi, rsp",
} "call {1}",
"pop {0:r}",
"mov rsp, rdi",
in(reg) $code,
sym exception_handler,
);
};
if $recoverable {
crate::println!("TODO: Recover gracefully ;~;");
hcf();
} else {
hcf();
}
}
};
} }
#[naked] exception_function!(0x00, div_error, true);
pub extern "C" fn invalid_opcode() { exception_function!(0x06, invalid_opcode, true);
unsafe { exception_function!(0x08, double_fault, false);
core::arch::asm!( exception_function!(0x0D, general_protection_fault, true);
"mov rdi, 0x06", // TODO: fix the page fault then gracefully return.
"call exception_handler", exception_function!(0x0E, page_fault, false);
"add esp, 4", exception_function!(0xFF, generic_handler, true);
"iretq",
options(noreturn)
);
}
}
#[naked]
pub extern "C" fn double_fault() {
unsafe {
core::arch::asm!(
"mov rdi, 0x08",
"call exception_handler",
"add esp, 4",
"iretq",
options(noreturn)
);
}
}
#[naked]
pub extern "C" fn general_protection_fault() {
unsafe {
core::arch::asm!(
"mov rdi, 0x0D",
"call exception_handler",
"add esp, 4",
"iretq",
options(noreturn)
);
}
}
#[naked]
pub extern "C" fn page_fault() {
unsafe {
core::arch::asm!(
"mov rdi, 0x0E",
"call exception_handler",
"add esp, 4",
"iretq",
options(noreturn)
);
}
}
#[naked]
pub extern "C" fn generic_handler() {
unsafe {
core::arch::asm!(
"mov rdi, 0xFF",
"call exception_handler",
"add esp, 4",
"iretq",
options(noreturn)
);
}
}
pub fn set_exceptions() { pub fn set_exceptions() {
for i in 0..32 { for i in 0..32 {

View File

@@ -114,7 +114,7 @@ fn idt_init() {
} }
#[naked] #[naked]
pub extern "C" fn syscall() { pub extern "C" fn syscall(func: extern "C" fn()) {
unsafe { unsafe {
core::arch::asm!( core::arch::asm!(
"push rdi", "push rdi",

View File

@@ -1,4 +1,24 @@
pub mod interrupts; pub mod interrupts;
#[path = "../x86_common/mod.rs"] // This inline is detremental to having readable stack traces
pub mod common; #[inline(always)]
pub fn push_gprs() {
unsafe {
core::arch::asm!(
"push rax", "push rbx", "push rcx", "push rdx", "push rsi", "push rdi", "push rbp",
"push r8", "push r9", "push r10", "push r11", "push r12", "push r13", "push r14",
"push r15"
);
}
}
// This inline is detremental to having readable stack traces
#[inline(always)]
pub fn pop_gprs() {
unsafe {
core::arch::asm!(
"pop rax", "pop rbx", "pop rcx", "pop rdx", "pop rsi", "pop rdi", "pop rbp", "pop r8",
"pop r9", "pop r10", "pop r11", "pop r12", "pop r13", "pop r14", "pop r15",
);
}
}

View File

@@ -7,12 +7,8 @@ struct StackFrame {
rip: u64, rip: u64,
} }
pub fn print_stack_trace(max_frames: usize) { pub fn print_stack_trace(max_frames: usize, rbp: u64) {
let mut stackframe: *const StackFrame; let mut stackframe = rbp as *const StackFrame;
unsafe {
core::arch::asm!("mov {0:r}, rbp", out(reg) stackframe);
};
crate::println!("Stack Trace:"); crate::println!("Stack Trace:");
for _frame in 0..max_frames { for _frame in 0..max_frames {

View File

@@ -36,8 +36,6 @@ pub extern "x86-interrupt" fn keyboard_interrupt_handler() {
#[derive(Debug)] #[derive(Debug)]
pub enum KBDError { pub enum KBDError {
TimeoutError,
ParityError,
TestFailed, TestFailed,
} }
@@ -51,25 +49,7 @@ pub fn init() -> Result<(), KBDError> {
outb(KBD_COMMAND_AND_STATUS_PORT, 0xA7); outb(KBD_COMMAND_AND_STATUS_PORT, 0xA7);
outb(KBD_COMMAND_AND_STATUS_PORT, 0xAD); outb(KBD_COMMAND_AND_STATUS_PORT, 0xAD);
outb(KBD_COMMAND_AND_STATUS_PORT, 0xFF); // TODO: Test the controller correctly
let status = inb(KBD_COMMAND_AND_STATUS_PORT);
if status & (1 << 6) != 0 {
return Err(KBDError::TimeoutError);
}
if status & (1 << 7) != 0 {
return Err(KBDError::ParityError);
}
// Test the controller
outb(KBD_COMMAND_AND_STATUS_PORT, 0xAA);
let result = inb(KBD_DATA_PORT);
if result != 0x55 {
crate::println!("Got result: {result}");
return Err(KBDError::TestFailed);
}
idt_set_gate( idt_set_gate(
InterruptIndex::Keyboard.as_u8(), InterruptIndex::Keyboard.as_u8(),

View File

@@ -295,12 +295,10 @@ impl<'a> ATABus {
self.wait_for_drive_ready() self.wait_for_drive_ready()
.map_err(|_| crate::log_error!("Error before issuing Identify command."))?; .map_err(|_| crate::log_error!("Error before issuing Identify command."))?;
for i in 0..(ATA_SECTOR_SIZE / size_of::<u16>()) { for chunk in buffer.chunks_exact_mut(core::mem::size_of::<u16>()) {
let word = inw(self.io_bar + ATADriveDataRegister::Data as u16); let word = inw(self.io_bar + ATADriveDataRegister::Data as u16);
unsafe { chunk.copy_from_slice(&word.to_le_bytes());
*(buffer.as_mut_ptr() as *mut u16).add(i) = word;
};
} }
return Ok(Arc::from(buffer)); return Ok(Arc::from(buffer));

View File

@@ -46,6 +46,11 @@ pub extern "C" fn _start() -> ! {
.label_bytes() .label_bytes()
); );
let asd: u32 = 0xdeadbeef;
unsafe {
*(asd as *mut u64) = 12;
};
usr::shell::init_shell(); usr::shell::init_shell();
hcf(); hcf();

View File

@@ -1,2 +1,3 @@
pub mod shell; pub mod shell;
#[macro_use]
pub mod tty; pub mod tty;

View File

@@ -133,10 +133,6 @@ pub fn handle_key(mut key: Key) {
} }
pub fn prompt() { pub fn prompt() {
unsafe {
core::arch::asm!("div rax, {0:r}", in(reg) 0x00);
};
super::tty::CONSOLE.puts("> "); super::tty::CONSOLE.puts("> ");
} }