From 30bbafdfa4cdf0fa621b3e78dcad459e2265dc60 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Sat, 13 Sep 2025 20:55:39 +0200 Subject: [PATCH] Use the object crate for panic backtraces This increases the kernel image size by about 16kb, but in return significantly simplifies things. --- Cargo.lock | 33 ++++---------- Cargo.toml | 6 +-- src/elf.rs | 126 --------------------------------------------------- src/main.rs | 3 -- src/panic.rs | 65 +++++++++----------------- 5 files changed, 35 insertions(+), 198 deletions(-) delete mode 100644 src/elf.rs diff --git a/Cargo.lock b/Cargo.lock index 5609b27518..eae15d5548 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -82,16 +82,6 @@ name = "fdt" version = "0.2.0-alpha1" source = "git+https://github.com/repnop/fdt.git?rev=2fb1409edd1877c714a0aa36b6a7c5351004be54#2fb1409edd1877c714a0aa36b6a7c5351004be54" -[[package]] -name = "goblin" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d20fd25aa456527ce4f544271ae4fea65d2eda4a6561ea56f39fb3ee4f7e3884" -dependencies = [ - "plain", - "scroll", -] - [[package]] name = "hashbrown" version = "0.14.5" @@ -127,10 +117,10 @@ dependencies = [ "byteorder", "cc", "fdt", - "goblin", "hashbrown 0.14.5", "indexmap", "linked_list_allocator 0.9.1", + "object", "raw-cpuid", "redox-path", "redox_syscall", @@ -180,18 +170,21 @@ version = "2.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32a282da65faaf38286cf3be983213fcf1d2e2a58700e808f83f4ea9a4804bc0" +[[package]] +name = "object" +version = "0.37.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff76201f031d8863c38aa7f905eca4f53abbfa15f609db4277d44cd8938f33fe" +dependencies = [ + "memchr", +] + [[package]] name = "once_cell" version = "1.21.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" -[[package]] -name = "plain" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4596b6d070b27117e987119b4dac604f3c58cfb0b191112e24771b2faeac1a6" - [[package]] name = "proc-macro2" version = "1.0.95" @@ -273,12 +266,6 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" -[[package]] -name = "scroll" -version = "0.10.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fda28d4b4830b807a8b43f7b0e6b5df875311b3e7621d84577188c175b6ec1ec" - [[package]] name = "serde" version = "1.0.219" diff --git a/Cargo.toml b/Cargo.toml index 0de9d62b1a..648dfbc555 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -25,10 +25,10 @@ slab = { version = "0.4", default-features = false } # TODO: Remove indexmap = { version = "2.5.0", default-features = false } -[dependencies.goblin] -version = "0.2.1" +[dependencies.object] +version = "0.37.1" default-features = false -features = ["elf32", "elf64"] +features = ["read_core", "elf"] [dependencies.rustc-demangle] version = "0.1.16" diff --git a/src/elf.rs b/src/elf.rs deleted file mode 100644 index 95db91ae62..0000000000 --- a/src/elf.rs +++ /dev/null @@ -1,126 +0,0 @@ -//! ELF executables - -use alloc::string::String; - -use goblin::elf::section_header::SHT_SYMTAB; - -#[cfg(target_arch = "x86")] -pub use goblin::elf32::{header, program_header, section_header, sym}; - -#[cfg(any( - target_arch = "aarch64", - target_arch = "riscv64", - target_arch = "x86_64" -))] -pub use goblin::elf64::{header, section_header, sym}; - -/// An ELF executable -pub struct Elf<'a> { - pub data: &'a [u8], - header: &'a header::Header, -} - -impl<'a> Elf<'a> { - /// Create a ELF executable from data - pub fn from(data: &'a [u8]) -> Result, String> { - if data.len() < header::SIZEOF_EHDR { - Err(format!( - "Elf: Not enough data: {} < {}", - data.len(), - header::SIZEOF_EHDR - )) - } else if &data[..header::SELFMAG] != header::ELFMAG { - Err(format!( - "Elf: Invalid magic: {:?} != {:?}", - &data[..header::SELFMAG], - header::ELFMAG - )) - } else if data.get(header::EI_CLASS) != Some(&header::ELFCLASS) { - Err(format!( - "Elf: Invalid architecture: {:?} != {:?}", - data.get(header::EI_CLASS), - header::ELFCLASS - )) - } else { - Ok(Elf { - data, - header: unsafe { &*(data.as_ptr() as usize as *const header::Header) }, - }) - } - } - - pub fn sections(&'a self) -> ElfSections<'a> { - ElfSections { - data: self.data, - header: self.header, - i: 0, - } - } - - pub fn symbols(&'a self) -> Option> { - let mut symtab_opt = None; - for section in self.sections() { - if section.sh_type == SHT_SYMTAB { - symtab_opt = Some(section); - break; - } - } - - if let Some(symtab) = symtab_opt { - Some(ElfSymbols { - data: self.data, - symtab, - i: 0, - }) - } else { - None - } - } -} - -pub struct ElfSections<'a> { - data: &'a [u8], - header: &'a header::Header, - i: usize, -} - -impl<'a> Iterator for ElfSections<'a> { - type Item = &'a section_header::SectionHeader; - fn next(&mut self) -> Option { - if self.i < self.header.e_shnum as usize { - let item = unsafe { - &*((self.data.as_ptr() as usize - + self.header.e_shoff as usize - + self.i * self.header.e_shentsize as usize) - as *const section_header::SectionHeader) - }; - self.i += 1; - Some(item) - } else { - None - } - } -} - -pub struct ElfSymbols<'a> { - data: &'a [u8], - symtab: &'a section_header::SectionHeader, - i: usize, -} - -impl<'a> Iterator for ElfSymbols<'a> { - type Item = &'a sym::Sym; - fn next(&mut self) -> Option { - if self.i < (self.symtab.sh_size as usize) / sym::SIZEOF_SYM { - let item = unsafe { - &*((self.data.as_ptr() as usize - + self.symtab.sh_offset as usize - + self.i * sym::SIZEOF_SYM) as *const sym::Sym) - }; - self.i += 1; - Some(item) - } else { - None - } - } -} diff --git a/src/main.rs b/src/main.rs index dcdf71255e..97b6f6dc65 100644 --- a/src/main.rs +++ b/src/main.rs @@ -105,9 +105,6 @@ mod debugger; /// Architecture-independent devices mod devices; -/// ELF file parsing -mod elf; - /// Event handling mod event; diff --git a/src/panic.rs b/src/panic.rs index eddc0f0ea7..14e8c7d7dd 100644 --- a/src/panic.rs +++ b/src/panic.rs @@ -1,15 +1,18 @@ //! Intrinsics for panic handling -use core::{panic::PanicInfo, slice, str, sync::atomic::Ordering}; -use goblin::elf::sym; +use core::{panic::PanicInfo, slice, sync::atomic::Ordering}; + +#[cfg(target_pointer_width = "32")] +use object::read::elf::ElfFile32 as ElfFile; +#[cfg(target_pointer_width = "64")] +use object::read::elf::ElfFile64 as ElfFile; +use object::{elf::STT_FUNC, NativeEndian, Object, ObjectSymbol}; use rmm::VirtualAddress; use rustc_demangle::demangle; use crate::{ arch::{consts::USER_END_OFFSET, interrupt::trace::StackTrace}, - context, cpu_id, - elf::Elf, - interrupt, + context, cpu_id, interrupt, memory::KernelMapper, start::KERNEL_SIZE, syscall, @@ -104,47 +107,23 @@ pub unsafe fn symbol_trace(addr: usize) { let kernel_ptr = crate::KERNEL_OFFSET as *const u8; let kernel_slice = slice::from_raw_parts(kernel_ptr, KERNEL_SIZE.load(Ordering::SeqCst)); - if let Ok(elf) = Elf::from(kernel_slice) { - let mut strtab_opt = None; - for section in elf.sections() { - if section.sh_type == ::goblin::elf::section_header::SHT_STRTAB { - strtab_opt = Some(section); - break; - } + let obj = ElfFile::::parse(kernel_slice).unwrap(); + for sym in obj.symbols() { + if sym.elf_symbol().st_type() != STT_FUNC { + continue; + } + if !(addr >= sym.address() as usize && addr < (sym.address() + sym.size()) as usize) { + continue; } - if let Some(symbols) = elf.symbols() { - for sym in symbols { - if sym::st_type(sym.st_info) == sym::STT_FUNC - && addr >= sym.st_value as usize - && addr < (sym.st_value + sym.st_size) as usize - { - println!( - " {:>016X}+{:>04X}", - sym.st_value, - addr - sym.st_value as usize - ); + println!( + " {:>016X}+{:>04X}", + sym.address(), + addr - sym.address() as usize + ); - if let Some(strtab) = strtab_opt { - let start = strtab.sh_offset as usize + sym.st_name as usize; - let mut end = start; - while end < elf.data.len() { - let b = elf.data[end]; - end += 1; - if b == 0 { - break; - } - } - - if end > start { - let sym_slice = &elf.data[start..end - 1]; - if let Ok(sym_name) = str::from_utf8(sym_slice) { - println!(" {:#}", demangle(sym_name)); - } - } - } - } - } + if let Ok(sym_name) = sym.name() { + println!(" {:#}", demangle(sym_name)); } } }