Avoid allocating during panics and infer kernel image size without explicitly storing it

This commit is contained in:
bjorn3
2025-09-14 12:50:43 +02:00
parent 9f71f02532
commit d3b17177b2
4 changed files with 39 additions and 34 deletions
+1 -6
View File
@@ -4,7 +4,7 @@
//! defined in other files inside of the `arch` module
use core::{
slice,
sync::atomic::{AtomicBool, AtomicU32, AtomicUsize, Ordering},
sync::atomic::{AtomicBool, AtomicU32, Ordering},
};
use fdt::Fdt;
@@ -25,8 +25,6 @@ static mut BSS_TEST_ZERO: usize = 0;
/// Test of non-zero values in data.
static mut DATA_TEST_NONZERO: usize = 0xFFFF_FFFF_FFFF_FFFF;
pub static KERNEL_BASE: AtomicUsize = AtomicUsize::new(0);
pub static KERNEL_SIZE: AtomicUsize = AtomicUsize::new(0);
pub static CPU_COUNT: AtomicU32 = AtomicU32::new(0);
pub static AP_READY: AtomicBool = AtomicBool::new(false);
static BSP_READY: AtomicBool = AtomicBool::new(false);
@@ -64,9 +62,6 @@ pub unsafe extern "C" fn kstart(args_ptr: *const KernelArgs) -> ! {
assert_eq!(DATA_TEST_NONZERO, 0xFFFF_FFFF_FFFF_FFFF);
}
KERNEL_BASE.store(args.kernel_base, Ordering::SeqCst);
KERNEL_SIZE.store(args.kernel_size, Ordering::SeqCst);
// Convert env to slice
let env = slice::from_raw_parts(
(crate::PHYS_OFFSET + args.env_base) as *const u8,
-5
View File
@@ -24,8 +24,6 @@ static mut BSS_TEST_ZERO: usize = 0;
/// Test of non-zero values in data.
static mut DATA_TEST_NONZERO: usize = 0xFFFF_FFFF_FFFF_FFFF;
pub static KERNEL_BASE: AtomicUsize = AtomicUsize::new(0);
pub static KERNEL_SIZE: AtomicUsize = AtomicUsize::new(0);
pub static CPU_COUNT: AtomicU32 = AtomicU32::new(0);
pub static BOOT_HART_ID: AtomicUsize = AtomicUsize::new(0);
@@ -81,9 +79,6 @@ pub unsafe extern "C" fn kstart(args_ptr: *const KernelArgs) -> ! {
assert_eq!(DATA_TEST_NONZERO, 0xFFFF_FFFF_FFFF_FFFF);
}
KERNEL_BASE.store(args.kernel_base, Ordering::SeqCst);
KERNEL_SIZE.store(args.kernel_size, Ordering::SeqCst);
let env = slice::from_raw_parts(
(crate::PHYS_OFFSET + args.env_base) as *const u8,
args.env_size,
+1 -7
View File
@@ -5,7 +5,7 @@
use core::{
cell::SyncUnsafeCell,
hint, slice,
sync::atomic::{AtomicBool, AtomicU32, AtomicUsize, Ordering},
sync::atomic::{AtomicBool, AtomicU32, Ordering},
};
#[cfg(feature = "acpi")]
@@ -26,9 +26,6 @@ static BSS_TEST_ZERO: SyncUnsafeCell<usize> = SyncUnsafeCell::new(0);
/// Test of non-zero values in data.
static DATA_TEST_NONZERO: SyncUnsafeCell<usize> = SyncUnsafeCell::new(usize::max_value());
pub static KERNEL_BASE: AtomicUsize = AtomicUsize::new(0);
pub static KERNEL_SIZE: AtomicUsize = AtomicUsize::new(0);
// TODO: This probably shouldn't be an atomic. Only the BSP starts APs.
pub static CPU_COUNT: AtomicU32 = AtomicU32::new(0);
@@ -75,9 +72,6 @@ pub unsafe extern "C" fn kstart(args_ptr: *const KernelArgs) -> ! {
assert_eq!(DATA_TEST_NONZERO.get().read(), usize::max_value());
}
KERNEL_BASE.store(args.kernel_base as usize, Ordering::SeqCst);
KERNEL_SIZE.store(args.kernel_size as usize, Ordering::SeqCst);
// Convert env to slice
let env = slice::from_raw_parts(
(args.env_base as usize + crate::PHYS_OFFSET) as *const u8,
+37 -16
View File
@@ -1,12 +1,16 @@
//! Intrinsics for panic handling
use core::{panic::PanicInfo, slice, sync::atomic::Ordering};
use core::{panic::PanicInfo, slice};
#[cfg(target_pointer_width = "32")]
use object::read::elf::ElfFile32 as ElfFile;
use object::elf::FileHeader32 as FileHeader;
#[cfg(target_pointer_width = "64")]
use object::read::elf::ElfFile64 as ElfFile;
use object::{elf::STT_FUNC, NativeEndian, Object, ObjectSymbol};
use object::elf::FileHeader64 as FileHeader;
use object::{
elf,
read::elf::{FileHeader as _, Sym as _},
NativeEndian,
};
use rmm::VirtualAddress;
use rustc_demangle::demangle;
@@ -14,7 +18,6 @@ use crate::{
arch::{consts::USER_END_OFFSET, interrupt::trace::StackTrace},
context, cpu_id, interrupt,
memory::KernelMapper,
start::KERNEL_SIZE,
syscall,
};
@@ -66,8 +69,25 @@ pub unsafe fn stack_trace() {
let mapper = KernelMapper::lock();
let kernel_ptr = crate::KERNEL_OFFSET as *const u8;
let kernel_slice = slice::from_raw_parts(kernel_ptr, KERNEL_SIZE.load(Ordering::SeqCst));
let obj = ElfFile::<NativeEndian>::parse(kernel_slice).unwrap();
let elf_header: &FileHeader<NativeEndian> = object::pod::from_bytes(slice::from_raw_parts(
kernel_ptr,
size_of::<FileHeader<NativeEndian>>(),
))
.unwrap()
.0;
// This assumes that the linker places .shstrtab as last section. If it
// isn't, that just causes a recursive panic, not UB.
let kernel_size = elf_header.e_shoff(NativeEndian) as usize
+ usize::from(elf_header.e_shnum(NativeEndian))
* usize::from(elf_header.e_shentsize(NativeEndian));
let kernel_slice = slice::from_raw_parts(kernel_ptr, kernel_size);
let symbols = elf_header
.sections(NativeEndian, kernel_slice)
.unwrap()
.symbols(NativeEndian, kernel_slice, elf::SHT_SYMTAB)
.unwrap();
let mut frame = StackTrace::start();
@@ -97,21 +117,22 @@ pub unsafe fn stack_trace() {
println!(" FP {:>016x}: PC {:>016x}", frame_.fp, pc);
for sym in obj.symbols() {
if sym.elf_symbol().st_type() != STT_FUNC {
for sym in symbols.iter() {
if sym.st_type() != elf::STT_FUNC {
continue;
}
if !(pc >= sym.address() as usize && pc < (sym.address() + sym.size()) as usize) {
let sym_addr = sym.st_value.get(NativeEndian) as usize;
if !(pc >= sym_addr && pc < sym_addr + sym.st_size.get(NativeEndian) as usize) {
continue;
}
println!(
" {:>016X}+{:>04X}",
sym.address(),
pc - sym.address() as usize
);
println!(" {:>016X}+{:>04X}", sym_addr, pc - sym_addr);
if let Ok(sym_name) = sym.name() {
if let Some(sym_name) = sym
.name(NativeEndian, symbols.strings())
.ok()
.and_then(|name| core::str::from_utf8(name).ok())
{
println!(" {:#}", demangle(sym_name));
}
}