Add symbol lookup (still very WIP)
This commit is contained in:
@@ -16,7 +16,7 @@ raw-cpuid = { git = "https://github.com/gz/rust-cpuid", branch = "master" }
|
||||
redox_syscall = "0.1"
|
||||
|
||||
[dependencies.goblin]
|
||||
version = "0.0.8"
|
||||
version = "0.0.10"
|
||||
default-features = false
|
||||
features = ["elf32", "elf64"]
|
||||
|
||||
|
||||
86
src/elf.rs
86
src/elf.rs
@@ -4,11 +4,13 @@ use collections::String;
|
||||
|
||||
use core::str;
|
||||
|
||||
use goblin::elf::section_header::SHT_SYMTAB;
|
||||
|
||||
#[cfg(target_arch = "x86")]
|
||||
pub use goblin::elf32::{header, program_header};
|
||||
pub use goblin::elf32::{header, program_header, section_header, sym};
|
||||
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
pub use goblin::elf64::{header, program_header};
|
||||
pub use goblin::elf64::{header, program_header, section_header, sym};
|
||||
|
||||
/// An ELF executable
|
||||
pub struct Elf<'a> {
|
||||
@@ -33,6 +35,14 @@ impl<'a> Elf<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn sections(&'a self) -> ElfSections<'a> {
|
||||
ElfSections {
|
||||
data: self.data,
|
||||
header: self.header,
|
||||
i: 0
|
||||
}
|
||||
}
|
||||
|
||||
pub fn segments(&'a self) -> ElfSegments<'a> {
|
||||
ElfSegments {
|
||||
data: self.data,
|
||||
@@ -41,12 +51,58 @@ impl<'a> Elf<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
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,
|
||||
header: self.header,
|
||||
symtab: symtab,
|
||||
i: 0
|
||||
})
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
/// Get the entry field of the header
|
||||
pub fn entry(&self) -> usize {
|
||||
self.header.e_entry as usize
|
||||
}
|
||||
}
|
||||
|
||||
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 ElfSegments<'a> {
|
||||
data: &'a [u8],
|
||||
header: &'a header::Header,
|
||||
@@ -71,3 +127,29 @@ impl<'a> Iterator for ElfSegments<'a> {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct ElfSymbols<'a> {
|
||||
data: &'a [u8],
|
||||
header: &'a header::Header,
|
||||
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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,6 +22,7 @@ pub unsafe fn stack_trace() {
|
||||
}
|
||||
println!(" {:>016X}: {:>016X}", rbp, rip);
|
||||
rbp = *(rbp as *const usize);
|
||||
symbol_trace(rip);
|
||||
} else {
|
||||
println!(" {:>016X}: GUARD PAGE", rbp);
|
||||
break;
|
||||
@@ -31,3 +32,45 @@ pub unsafe fn stack_trace() {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
pub unsafe fn symbol_trace(addr: usize) {
|
||||
use core::slice;
|
||||
use core::sync::atomic::Ordering;
|
||||
|
||||
use elf::Elf;
|
||||
use start::{KERNEL_BASE, KERNEL_SIZE};
|
||||
|
||||
let kernel_ptr = (KERNEL_BASE.load(Ordering::SeqCst) + ::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;
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(symbols) = elf.symbols() {
|
||||
for sym in symbols {
|
||||
if 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);
|
||||
|
||||
if let Some(strtab) = strtab_opt {
|
||||
print!(" ");
|
||||
|
||||
for &b in elf.data[strtab.sh_offset as usize + sym.st_name as usize ..].iter() {
|
||||
if b == 0 {
|
||||
break;
|
||||
}
|
||||
print!("{}", b as char);
|
||||
}
|
||||
|
||||
println!("");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,6 +26,8 @@ static mut TBSS_TEST_ZERO: usize = 0;
|
||||
#[thread_local]
|
||||
static mut TDATA_TEST_NONZERO: usize = 0xFFFFFFFFFFFFFFFF;
|
||||
|
||||
pub static KERNEL_BASE: AtomicUsize = ATOMIC_USIZE_INIT;
|
||||
pub static KERNEL_SIZE: AtomicUsize = ATOMIC_USIZE_INIT;
|
||||
pub static CPU_COUNT: AtomicUsize = ATOMIC_USIZE_INIT;
|
||||
pub static AP_READY: AtomicBool = ATOMIC_BOOL_INIT;
|
||||
static BSP_READY: AtomicBool = ATOMIC_BOOL_INIT;
|
||||
@@ -47,6 +49,9 @@ pub unsafe extern fn kstart(kernel_base: usize, kernel_size: usize, stack_base:
|
||||
assert_eq!(DATA_TEST_NONZERO, 0xFFFFFFFFFFFFFFFF);
|
||||
}
|
||||
|
||||
KERNEL_BASE.store(kernel_base, Ordering::SeqCst);
|
||||
KERNEL_SIZE.store(kernel_size, Ordering::SeqCst);
|
||||
|
||||
println!("Kernel: {:X}:{:X}", kernel_base, kernel_base + kernel_size);
|
||||
println!("Stack: {:X}:{:X}", stack_base, stack_base + stack_size);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user