Merge pull request #11 from philipc/get_symbols
Add File::get_symbols()
This commit is contained in:
commit
8a31cdbff5
66
src/lib.rs
66
src/lib.rs
@ -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(§ion.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()
|
||||
|
25
src/types.rs
25
src/types.rs
@ -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)
|
||||
}
|
||||
}
|
||||
|
@ -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 {
|
||||
|
Loading…
x
Reference in New Issue
Block a user