stack trace uses saved registers, aka more useful stacktraces
This commit is contained in:
4
.gitignore
vendored
4
.gitignore
vendored
@@ -1,6 +1,8 @@
|
|||||||
/target
|
/target
|
||||||
/bin
|
/bin
|
||||||
/scripts/*/**
|
|
||||||
|
|
||||||
# Bochs
|
# Bochs
|
||||||
bx_enh_dbg.ini
|
bx_enh_dbg.ini
|
||||||
|
|
||||||
|
# limine
|
||||||
|
limine/
|
||||||
4
.gitmodules
vendored
4
.gitmodules
vendored
@@ -1,4 +0,0 @@
|
|||||||
[submodule "limine"]
|
|
||||||
path = limine
|
|
||||||
url = https://github.com/limine-bootloader/limine
|
|
||||||
branch = v5.x-branch-binary
|
|
||||||
8
Makefile
8
Makefile
@@ -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:
|
||||||
|
|||||||
35007
disassembly.txt
35007
disassembly.txt
File diff suppressed because it is too large
Load Diff
1
limine
1
limine
Submodule limine deleted from 7563eb4dbe
1
scripts/.gitignore
vendored
Normal file
1
scripts/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
rustc_demangle/
|
||||||
@@ -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
@@ -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;
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -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 {
|
||||||
|
|||||||
@@ -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",
|
||||||
|
|||||||
@@ -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",
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -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 {
|
||||||
|
|||||||
@@ -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(),
|
||||||
|
|||||||
@@ -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));
|
||||||
|
|||||||
@@ -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();
|
||||||
|
|||||||
@@ -1,2 +1,3 @@
|
|||||||
pub mod shell;
|
pub mod shell;
|
||||||
|
#[macro_use]
|
||||||
pub mod tty;
|
pub mod tty;
|
||||||
|
|||||||
@@ -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("> ");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user