Merge pull request #11 from philipc/get_symbols

Add File::get_symbols()
This commit is contained in:
Christopher Cole 2016-07-06 09:02:12 -07:00 committed by GitHub
commit 8a31cdbff5
3 changed files with 64 additions and 29 deletions

View File

@ -16,20 +16,6 @@ pub struct File {
pub sections: Vec<Section>,
}
pub trait ReadExact {
fn read_exactly(&mut self, len: u64) -> io::Result<Vec<u8>>;
}
impl<T> ReadExact for T
where T: io::Read
{
fn read_exactly(&mut self, len: u64) -> io::Result<Vec<u8>> {
let mut buf = Vec::with_capacity(len as usize);
let mut chunk = self.take(len);
try!(chunk.read_to_end(&mut buf));
return Ok(buf);
}
}
impl std::fmt::Debug for File {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
write!(f, "{:?} {:?} {:?}", self.ehdr, self.phdrs, self.sections)
@ -231,7 +217,9 @@ impl File {
let off = elf_f.sections[s_i].shdr.offset;
let size = elf_f.sections[s_i].shdr.size;
try!(io_file.seek(io::SeekFrom::Start(off)));
elf_f.sections[s_i].data = try!(io_file.read_exactly(size));
let mut data = vec![0; size as usize];
try!(io_file.read_exact(&mut data));
elf_f.sections[s_i].data = data;
s_i += 1;
}
@ -251,6 +239,54 @@ impl File {
Ok(elf_f)
}
pub fn get_symbols(&self, section: &Section) -> Result<Vec<types::Symbol>, ParseError> {
let mut symbols = Vec::new();
if section.shdr.shtype == types::SHT_SYMTAB || section.shdr.shtype == types::SHT_DYNSYM {
let link = &self.sections[section.shdr.link as usize].data;
let mut io_section = io::Cursor::new(&section.data);
while (io_section.position() as usize) < section.data.len() {
try!(self.parse_symbol(&mut io_section, &mut symbols, link));
}
}
Ok(symbols)
}
fn parse_symbol(&self, io_section: &mut Read, symbols: &mut Vec<types::Symbol>, link: &[u8]) -> Result<(), ParseError> {
let name: u32;
let value: u64;
let size: u64;
let shndx: u16;
let mut info = [0u8];
let mut other = [0u8];
if self.ehdr.class == types::ELFCLASS32 {
name = try!(read_u32!(self, io_section));
value = try!(read_u32!(self, io_section)) as u64;
size = try!(read_u32!(self, io_section)) as u64;
try!(io_section.read_exact(&mut info));
try!(io_section.read_exact(&mut other));
shndx = try!(read_u16!(self, io_section));
} else {
name = try!(read_u32!(self, io_section));
try!(io_section.read_exact(&mut info));
try!(io_section.read_exact(&mut other));
shndx = try!(read_u16!(self, io_section));
value = try!(read_u64!(self, io_section));
size = try!(read_u64!(self, io_section));
}
symbols.push(types::Symbol {
name: try!(utils::get_string(link, name as usize)),
value: value,
size: size,
shndx: shndx,
symtype: types::SymbolType(info[0] & 0xf),
bind: types::SymbolBind(info[0] >> 4),
vis: types::SymbolVis(other[0] & 0x3),
});
Ok(())
}
pub fn get_section<T: AsRef<str>>(&self, name: T) -> Option<&Section> {
self.sections
.iter()

View File

@ -785,20 +785,19 @@ pub struct Symbol {
pub value: u64,
/// Symbol size
pub size: u64,
info: u8,
other: u8,
/// Section index
pub shndx: u16,
/// Symbol type
pub symtype: SymbolType,
/// Symbol binding
pub bind: SymbolBind,
/// Symbol visibility
pub vis: SymbolVis,
}
impl Symbol {
pub fn sym_type(&self) -> SymbolType {
SymbolType(self.info & 0xf)
}
pub fn sym_bind(&self) -> SymbolBind {
SymbolBind(self.info >> 4)
}
pub fn sym_vis(&self) -> SymbolVis {
SymbolVis(self.other & 0x3)
impl fmt::Display for Symbol {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "Symbol: Value: {:#010x} Size: {:#06x} Type: {} Bind: {} Vis: {} Section: {} Name: {}",
self.value, self.size, self.symtype, self.bind, self.vis, self.shndx, self.name)
}
}

View File

@ -38,7 +38,7 @@ macro_rules! read_u64 {
}
use std;
pub fn get_string(data: &Vec<u8>, start: usize) -> Result<String, std::string::FromUtf8Error> {
pub fn get_string(data: &[u8], start: usize) -> Result<String, std::string::FromUtf8Error> {
let mut end: usize = 0;
for i in start..data.len() {
if data[i] == 0u8 {