Skip to content
Permalink
Browse files

Add symbol lookup (still very WIP)

  • Loading branch information...
jackpot51 committed Jun 14, 2017
1 parent d6354ae commit acab23d1e1fc1779b40caff0e710b352857ca7e8
Showing with 133 additions and 3 deletions.
  1. +1 −1 Cargo.toml
  2. +84 −2 src/elf.rs
  3. +43 −0 src/interrupt/trace.rs
  4. +5 −0 src/start.rs
@@ -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"]

@@ -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);

0 comments on commit acab23d

Please sign in to comment.
You can’t perform that action at this time.