Use the object crate for panic backtraces
This increases the kernel image size by about 16kb, but in return significantly simplifies things.
This commit is contained in:
Generated
+10
-23
@@ -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"
|
||||
|
||||
+3
-3
@@ -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"
|
||||
|
||||
-126
@@ -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<Elf<'a>, 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<ElfSymbols<'a>> {
|
||||
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<Self::Item> {
|
||||
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<Self::Item> {
|
||||
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
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -105,9 +105,6 @@ mod debugger;
|
||||
/// Architecture-independent devices
|
||||
mod devices;
|
||||
|
||||
/// ELF file parsing
|
||||
mod elf;
|
||||
|
||||
/// Event handling
|
||||
mod event;
|
||||
|
||||
|
||||
+22
-43
@@ -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::<NativeEndian>::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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user