Skip to content
Snippets Groups Projects
Commit acab23d1 authored by Jeremy Soller's avatar Jeremy Soller
Browse files

Add symbol lookup (still very WIP)

parent d6354aeb
No related branches found
No related tags found
No related merge requests found
...@@ -16,7 +16,7 @@ raw-cpuid = { git = "https://github.com/gz/rust-cpuid", branch = "master" } ...@@ -16,7 +16,7 @@ raw-cpuid = { git = "https://github.com/gz/rust-cpuid", branch = "master" }
redox_syscall = "0.1" redox_syscall = "0.1"
[dependencies.goblin] [dependencies.goblin]
version = "0.0.8" version = "0.0.10"
default-features = false default-features = false
features = ["elf32", "elf64"] features = ["elf32", "elf64"]
......
...@@ -4,11 +4,13 @@ use collections::String; ...@@ -4,11 +4,13 @@ use collections::String;
use core::str; use core::str;
use goblin::elf::section_header::SHT_SYMTAB;
#[cfg(target_arch = "x86")] #[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")] #[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 /// An ELF executable
pub struct Elf<'a> { pub struct Elf<'a> {
...@@ -33,6 +35,14 @@ impl<'a> 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> { pub fn segments(&'a self) -> ElfSegments<'a> {
ElfSegments { ElfSegments {
data: self.data, data: self.data,
...@@ -41,12 +51,58 @@ impl<'a> Elf<'a> { ...@@ -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 /// Get the entry field of the header
pub fn entry(&self) -> usize { pub fn entry(&self) -> usize {
self.header.e_entry as 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> { pub struct ElfSegments<'a> {
data: &'a [u8], data: &'a [u8],
header: &'a header::Header, header: &'a header::Header,
...@@ -71,3 +127,29 @@ impl<'a> Iterator for ElfSegments<'a> { ...@@ -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() { ...@@ -22,6 +22,7 @@ pub unsafe fn stack_trace() {
} }
println!(" {:>016X}: {:>016X}", rbp, rip); println!(" {:>016X}: {:>016X}", rbp, rip);
rbp = *(rbp as *const usize); rbp = *(rbp as *const usize);
symbol_trace(rip);
} else { } else {
println!(" {:>016X}: GUARD PAGE", rbp); println!(" {:>016X}: GUARD PAGE", rbp);
break; break;
...@@ -31,3 +32,45 @@ pub unsafe fn stack_trace() { ...@@ -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; ...@@ -26,6 +26,8 @@ static mut TBSS_TEST_ZERO: usize = 0;
#[thread_local] #[thread_local]
static mut TDATA_TEST_NONZERO: usize = 0xFFFFFFFFFFFFFFFF; 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 CPU_COUNT: AtomicUsize = ATOMIC_USIZE_INIT;
pub static AP_READY: AtomicBool = ATOMIC_BOOL_INIT; pub static AP_READY: AtomicBool = ATOMIC_BOOL_INIT;
static BSP_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: ...@@ -47,6 +49,9 @@ pub unsafe extern fn kstart(kernel_base: usize, kernel_size: usize, stack_base:
assert_eq!(DATA_TEST_NONZERO, 0xFFFFFFFFFFFFFFFF); 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!("Kernel: {:X}:{:X}", kernel_base, kernel_base + kernel_size);
println!("Stack: {:X}:{:X}", stack_base, stack_base + stack_size); println!("Stack: {:X}:{:X}", stack_base, stack_base + stack_size);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment