Skip to content

Commit

Permalink
sketch disassembly API
Browse files Browse the repository at this point in the history
  • Loading branch information
xorpse committed Jun 12, 2024
1 parent 4b65329 commit b59d903
Show file tree
Hide file tree
Showing 2 changed files with 79 additions and 11 deletions.
20 changes: 20 additions & 0 deletions fugue-core/src/icfg/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,26 @@ where
}
}

pub struct FunctionBuilder<'a, 'b, R> where R: ProjectRawView {
builder: &'a mut ICFGBuilder<'b, R>,
}

impl<'a, 'b, R> FunctionBuilder<'a, 'b, R> where R: ProjectRawView {
pub fn new(builder: &'a mut ICFGBuilder<'b, R>) -> Self {
Self { builder }
}

pub fn explore(&mut self, from: impl Into<Address>) { // -> Function
let entry = from.into();
todo!("explore from {entry}")
}

pub fn reset(&mut self) {
// self.blocks.clear();
// self.insns.clear();
}
}

#[cfg(test)]
mod test {
use std::cell::{Cell, RefCell};
Expand Down
70 changes: 59 additions & 11 deletions fugue-core/src/project/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ pub trait ProjectRawView: Sized {
}

pub trait ProjectRawViewReader<'a> {
fn find_region(&self, point: impl Into<Address>) -> Result<LoadedSegment, ProjectRawViewError>;
fn view_bytes(&self, address: impl Into<Address>) -> Result<&[u8], ProjectRawViewError>;
}

Expand Down Expand Up @@ -88,6 +89,15 @@ impl<'a> LoadedSegment<'a> {
}
}

pub fn borrowed_with<'b>(&'b self, data: &'b [u8]) -> LoadedSegment<'b> {
LoadedSegment {
name: Cow::Borrowed(self.name()),
addr: self.addr,
size: self.size,
data: Cow::Borrowed(data),
}
}

pub fn address(&self) -> Address {
self.addr
}
Expand All @@ -105,9 +115,12 @@ impl<'a> LoadedSegment<'a> {
}
}

impl<'a> ProjectRawViewReader<'a> for ProjectRawViewMmapedReader<'a> {
fn view_bytes(&self, address: impl Into<Address>) -> Result<&[u8], ProjectRawViewError> {
let address = address.into();
impl<'a> ProjectRawViewMmapedReader<'a> {
fn find_segment(
&self,
point: impl Into<Address>,
) -> Result<&LoadedSegment<'a>, ProjectRawViewError> {
let address = point.into();

// find the interval that contains this address
let Ok(index) = self.segments.binary_search_by(|segm| {
Expand All @@ -126,19 +139,42 @@ impl<'a> ProjectRawViewReader<'a> for ProjectRawViewMmapedReader<'a> {
));
};

let segm = &self.segments[index].range();
Ok(&self.segments[index])
}
}

impl<'a> ProjectRawViewReader<'a> for ProjectRawViewMmapedReader<'a> {
fn view_bytes(&self, address: impl Into<Address>) -> Result<&[u8], ProjectRawViewError> {
let address = address.into();

let segm = self.find_segment(address)?;
let data = self
.backing
.get(segm.start)
.get(segm.address())
.map_err(ProjectRawViewError::backing)?
.ok_or_else(|| {
ProjectRawViewError::read_with(address, "interval not present in backing")
})?;

let offset = usize::from(address - segm.start);
let offset = usize::from(address - segm.address());

Ok(&data[offset..])
}

fn find_region(&self, point: impl Into<Address>) -> Result<LoadedSegment, ProjectRawViewError> {
let address = point.into();

let segm = self.find_segment(address)?;
let data = self
.backing
.get(segm.address())
.map_err(ProjectRawViewError::backing)?
.ok_or_else(|| {
ProjectRawViewError::read_with(address, "interval not present in backing")
})?;

Ok(segm.borrowed_with(data))
}
}

impl ProjectRawView for ProjectRawViewMmaped {
Expand Down Expand Up @@ -207,18 +243,30 @@ pub struct ProjectRawViewInMemoryReader<'a> {
backing: &'a IntervalMap<Address, LoadedSegment<'static>>,
}

impl<'a> ProjectRawViewInMemoryReader<'a> {
fn find_segment(&self, address: impl Into<Address>) -> Option<&LoadedSegment<'a>> {
let address = address.into();
self.backing.overlap(address).map(|(_, segm)| segm).next()
}
}

impl<'a> ProjectRawViewReader<'a> for ProjectRawViewInMemoryReader<'a> {
fn view_bytes(&self, address: impl Into<Address>) -> Result<&[u8], ProjectRawViewError> {
let address = address.into();
self.backing
.overlap(address)
.next()
.map(|(range, segm)| {
let offset = usize::from(address - range.start);
self.find_segment(address)
.map(|segm| {
let offset = usize::from(address - segm.address());
&segm.data()[offset..]
})
.ok_or_else(|| ProjectRawViewError::read_with(address, "address not mapped"))
}

fn find_region(&self, point: impl Into<Address>) -> Result<LoadedSegment, ProjectRawViewError> {
let address = point.into();
self.find_segment(address)
.map(LoadedSegment::borrowed)
.ok_or_else(|| ProjectRawViewError::read_with(address, "address not mapped"))
}
}

impl ProjectRawView for ProjectRawViewInMemory {
Expand Down

0 comments on commit b59d903

Please sign in to comment.