Avoid allocating during panics and infer kernel image size without explicitly storing it
This commit is contained in:
@@ -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,
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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
@@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user