Merge remote-tracking branch 'refs/remotes/origin/unified' into unified

This commit is contained in:
2025-03-06 01:22:53 +00:00
4 changed files with 33 additions and 16 deletions
+3
View File
@@ -36,6 +36,7 @@ use crate::{
use arch::x86_64::memory::mapping; use arch::x86_64::memory::mapping;
use core::arch::asm; use core::arch::asm;
use limine::BaseRevision; use limine::BaseRevision;
use std::unwind::UNWINDER;
use x86_64::VirtAddr; use x86_64::VirtAddr;
pub mod arch; pub mod arch;
@@ -144,5 +145,7 @@ pub fn boot() -> Result<(), &'static str> {
x86_64::instructions::interrupts::enable(); x86_64::instructions::interrupts::enable();
debugln!("[Success]"); debugln!("[Success]");
UNWINDER.lock(); // Initialises the Unwinder once and only once :fingers_crossed:.
Ok(()) Ok(())
} }
+20
View File
@@ -1,3 +1,23 @@
use core::arch::asm;
use eh_info::ELF;
use spin::{Lazy, Mutex};
use unwinder::{RegisterSet, Unwinder};
pub mod eh_info; pub mod eh_info;
pub mod panic; pub mod panic;
pub mod unwinder; pub mod unwinder;
/// We should initialise on program start.
pub static UNWINDER: Lazy<Mutex<Unwinder>> = Lazy::new(|| {
// Setup stack traces and proper panic handler. TODO: Handle panics
// differently if not initialised.
let eh_frame_ptr = ELF
.get_section_addr(".eh_frame_hdr")
.expect("Could not get `.eh_frame_hdr` address.");
let eh_info = unsafe { eh_info::EhInfo::from_hdr_ptr(eh_frame_ptr) };
let mut registers = RegisterSet::default();
Mutex::new(Unwinder::new(eh_info, registers))
});
+5 -14
View File
@@ -10,7 +10,7 @@ use super::unwinder::Unwinder;
use crate::{ use crate::{
hcf, hcf,
prelude::*, prelude::*,
std::unwind::{eh_info::ELF, unwinder::RegisterSet}, std::unwind::{UNWINDER, eh_info::ELF, unwinder::RegisterSet},
}; };
#[panic_handler] #[panic_handler]
@@ -19,27 +19,18 @@ pub fn panic_handler(info: &PanicInfo<'_>) -> ! {
println!("Kernel panic: {}", info); println!("Kernel panic: {}", info);
serial_println!("Kernel panic: {}", info); serial_println!("Kernel panic: {}", info);
// Setup stack traces and proper panic handler. TODO: Handle panics
// differently if not initialised.
let eh_frame_ptr = ELF
.get_section_addr(".eh_frame_hdr")
.expect("Could not get `.eh_frame_hdr` address.");
let eh_info = unsafe { super::eh_info::EhInfo::from_hdr_ptr(eh_frame_ptr) };
let mut registers = RegisterSet::default();
let mut rip: u64; let mut rip: u64;
let mut rsp: u64; let mut rsp: u64;
unsafe { unsafe {
asm!("lea {0}, [rip]", asm!("lea {0}, [rip]",
"mov {1}, rsp", "mov {1}, rsp",
out(reg) rip, out(reg) rsp); out(reg) rip, out(reg) rsp);
} }
registers.set_pc(rip);
registers.set_stack_ptr(rsp);
let mut unwinder = Unwinder::new(eh_info, registers); let mut unwinder = UNWINDER.lock();
unwinder.regs.set_pc(rip);
unwinder.regs.set_stack_ptr(rsp);
while let Some(call_frame) = unwinder.next().unwrap_or_else(|err| { while let Some(call_frame) = unwinder.next().unwrap_or_else(|err| {
// If an unwind error occurred. // If an unwind error occurred.
eprintln!("{:?}", err); eprintln!("{:?}", err);
+5 -2
View File
@@ -27,7 +27,7 @@ pub struct Unwinder {
unwind_ctx: UnwindContext<usize, StoreOnHeap>, unwind_ctx: UnwindContext<usize, StoreOnHeap>,
/// The current values of ABI/architecture independent registers. There are /// The current values of ABI/architecture independent registers. There are
/// used by DWARF. /// used by DWARF.
regs: RegisterSet, pub regs: RegisterSet,
/// The current CFA address. /// The current CFA address.
cfa: u64, cfa: u64,
/// Is this the first iteration? /// Is this the first iteration?
@@ -112,7 +112,10 @@ impl FallibleIterator for Unwinder {
}; };
// REVIEWME: Must be a nicer way of doing this. // REVIEWME: Must be a nicer way of doing this.
let pc = pc - 1; let Some(pc) = pc.checked_sub(1) else {
// REVIEWME: This should handle underflow now.
return Ok(None);
};
self.regs.set_pc(pc); self.regs.set_pc(pc);