use error::*;
use il;
use memory;
use std::fmt;
use types::Architecture;
mod elf;
mod json;
pub use self::elf::*;
pub use self::json::*;
#[derive(Clone, Debug, PartialEq)]
pub struct FunctionEntry {
address: u64,
name: Option<String>
}
impl FunctionEntry {
pub fn new(address: u64, name: Option<String>) -> FunctionEntry {
FunctionEntry {
address: address,
name: name
}
}
pub fn address(&self) -> u64 {
self.address
}
pub fn name(&self) -> &Option<String> {
&self.name
}
}
impl fmt::Display for FunctionEntry {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self.name {
Some(ref name) => write!(f, "{} -> {:X}", name, self.address),
None => write!(f, "{:X}", self.address)
}
}
}
pub trait Loader: Clone {
fn memory(&self) -> Result<memory::backing::Memory>;
fn function_entries(&self) -> Result<Vec<FunctionEntry>>;
fn program_entry(&self) -> u64;
fn architecture(&self) -> Result<Architecture>;
fn function(&self, address: u64) -> Result<il::Function> {
let translator = self.architecture()?.translator();
let memory = self.memory()?;
Ok(translator.translate_function(&memory, address)?)
}
fn program(&self) -> Result<il::Program> {
let translator = self.architecture()?.translator();
let memory = self.memory()?;
let mut program = il::Program::new();
for function_entry in self.function_entries()? {
let address = function_entry.address();
if memory.permissions(address)
.map_or(false, |p|
p.contains(memory::MemoryPermissions::EXECUTE)) {
let mut function = translator.translate_function(&memory, address)?;
function.set_name(function_entry.name().clone());
program.add_function(function);
}
}
Ok(program)
}
}