-
Notifications
You must be signed in to change notification settings - Fork 8
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
restructure; begin defining loader interface
- Loading branch information
Showing
27 changed files
with
356 additions
and
105 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,21 +1,31 @@ | ||
[package] | ||
name = "fugue" | ||
name = "fugue-core" | ||
version = "0.3.0" | ||
authors = ["Sam Thomas <st@xv.ax>", "Zitai Chen <zitaichen@outlook.com>"] | ||
edition = "2021" | ||
license = "MIT" | ||
description = "A binary analysis framework written in Rust" | ||
homepage = "https://fugue.re" | ||
|
||
[features] | ||
fp = ["fugue-fp"] | ||
state = ["fugue-state"] | ||
|
||
[dependencies] | ||
fugue-arch = { path = "../fugue-arch", version = "0.3" } | ||
fugue-bv = { path = "../fugue-bv", version = "0.3" } | ||
fugue-bytes = { path = "../fugue-bytes", version = "0.3" } | ||
fugue-high = { path = "../fugue-high", version = "0.3" } | ||
fugue-fp = { path = "../fugue-fp", version = "0.3", optional = true } | ||
fugue-ir = { path = "../fugue-ir", version = "0.3" } | ||
fugue-state = { path = "../fugue-state", version = "0.3", optional = true } | ||
anyhow = "1" | ||
bitflags = "2" | ||
fugue-arch = { version = "0.3", path = "../fugue-arch" } | ||
fugue-bv = { version = "0.3", path = "../fugue-bv" } | ||
fugue-bytes = { version = "0.3", path = "../fugue-bytes" } | ||
fugue-ir = { version = "0.3", path = "../fugue-ir" } | ||
gazebo = "0.8" | ||
nom = "7" | ||
memmap2 = "0.9" | ||
object = "0.35" | ||
ouroboros = "0.18" | ||
regex = "1" | ||
rustc-hash = "1.1" | ||
serde = { version = "1", features = ["derive"] } | ||
serde_yaml = "0.9" | ||
static_init = "1" | ||
thiserror = "1" | ||
yaxpeax-arch = { version = "0.2", default-features = false } | ||
yaxpeax-arm = "0.2" | ||
yaxpeax-x86 = "1.2" | ||
uuid = "1" | ||
|
||
[dev-dependencies] | ||
anyhow = "1" | ||
env_logger = "0.10" |
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
use std::borrow::Cow; | ||
|
||
use gazebo::any::ProvidesStaticType; | ||
use uuid::{uuid, Uuid}; | ||
|
||
use super::Attribute; | ||
|
||
#[derive(ProvidesStaticType)] | ||
pub struct CompilerConvention(Cow<'static, str>); | ||
|
||
impl CompilerConvention { | ||
pub fn new(convention: impl Into<Cow<'static, str>>) -> Self { | ||
Self(convention.into()) | ||
} | ||
} | ||
|
||
impl AsRef<str> for CompilerConvention { | ||
fn as_ref(&self) -> &str { | ||
self.0.as_ref() | ||
} | ||
} | ||
|
||
impl<'a> Attribute<'a> for CompilerConvention { | ||
const UUID: Uuid = uuid!("9D5D5EFA-3985-45C5-B803-49217FE3184D"); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
use std::ops::Deref; | ||
|
||
use rustc_hash::FxHashMap; | ||
use uuid::Uuid; | ||
|
||
pub use gazebo::any::{AnyLifetime, ProvidesStaticType}; | ||
|
||
pub mod common; | ||
pub mod platform; | ||
|
||
pub struct Attributes<'a> { | ||
attrs: FxHashMap<Uuid, Box<dyn AnyLifetime<'a>>>, | ||
} | ||
|
||
pub trait Attribute<'a>: AnyLifetime<'a> { | ||
const UUID: Uuid; | ||
} | ||
|
||
impl<'a> Attributes<'a> { | ||
pub fn new() -> Self { | ||
Self { | ||
attrs: FxHashMap::default(), | ||
} | ||
} | ||
|
||
pub fn set_attr<T>(&mut self, value: T) | ||
where | ||
T: Attribute<'a>, | ||
{ | ||
self.attrs.insert(T::UUID, Box::new(value)); | ||
} | ||
|
||
pub fn get_attr<T>(&self) -> Option<&T> | ||
where | ||
T: Attribute<'a>, | ||
{ | ||
self.attrs.get(&T::UUID).and_then(|v| v.downcast_ref()) | ||
} | ||
|
||
pub fn get_attr_as<T, U>(&self) -> Option<&U> | ||
where | ||
T: Attribute<'a> + AsRef<U>, | ||
U: ?Sized, | ||
{ | ||
self.get_attr::<T>().map(T::as_ref) | ||
} | ||
|
||
pub fn get_attr_as_deref<T, U>(&self) -> Option<&U> | ||
where | ||
T: Attribute<'a> + Deref<Target = U>, | ||
U: ?Sized, | ||
{ | ||
self.get_attr::<T>().map(T::deref) | ||
} | ||
|
||
pub fn get_attr_mut<T>(&mut self) -> Option<&mut T> | ||
where | ||
T: Attribute<'a>, | ||
{ | ||
self.attrs.get_mut(&T::UUID).and_then(|v| v.downcast_mut()) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
// pub mod uefi; |
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,11 +1,10 @@ | ||
#[cfg(feature = "fp")] | ||
pub use fugue_fp as fp; | ||
|
||
#[cfg(feature = "state")] | ||
pub use fugue_state as state; | ||
|
||
pub use fugue_arch as arch; | ||
pub use fugue_bv as bv; | ||
pub use fugue_bytes as bytes; | ||
pub use fugue_high as high; | ||
pub use fugue_ir as ir; | ||
pub mod arch; | ||
pub mod attributes; | ||
pub mod eval; | ||
pub mod icfg; | ||
pub mod ir; | ||
pub mod language; | ||
pub mod lifter; | ||
pub mod loader; | ||
pub mod prelude; | ||
pub mod util; |
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,127 @@ | ||
use std::borrow::Cow; | ||
use std::fmt::{Debug, Display}; | ||
use std::ops::Deref; | ||
|
||
use fugue_bytes::Endian; | ||
use fugue_ir::Address; | ||
use thiserror::Error; | ||
|
||
use crate::attributes::common::CompilerConvention; | ||
use crate::attributes::Attribute; | ||
use crate::language::{Language, LanguageBuilder, LanguageBuilderError}; | ||
use crate::util::BytesOrMapping; | ||
|
||
pub mod object; | ||
|
||
pub use self::object::Object; | ||
|
||
#[derive(Debug, Error)] | ||
pub enum LoaderError { | ||
#[error("cannot load object: {0}")] | ||
Format(anyhow::Error), | ||
#[error(transparent)] | ||
Language(#[from] LanguageBuilderError), | ||
} | ||
|
||
impl LoaderError { | ||
pub fn format<E>(e: E) -> Self | ||
where | ||
E: std::error::Error + Send + Sync + 'static, | ||
{ | ||
Self::Format(e.into()) | ||
} | ||
|
||
pub fn format_with<M>(m: M) -> Self | ||
where | ||
M: Debug + Display + Send + Sync + 'static, | ||
{ | ||
Self::Format(anyhow::Error::msg(m)) | ||
} | ||
} | ||
|
||
pub trait Loadable<'a>: Sized { | ||
fn new(data: impl Into<BytesOrMapping<'a>>) -> Result<Self, LoaderError>; | ||
|
||
fn get_attr<T>(&self) -> Option<&T> | ||
where | ||
T: Attribute<'a>; | ||
|
||
fn get_attr_as<'slf, T, U>(&'slf self) -> Option<&'slf U> | ||
where | ||
T: Attribute<'a> + AsRef<U> + 'slf, | ||
U: ?Sized, | ||
{ | ||
self.get_attr::<T>().map(T::as_ref) | ||
} | ||
|
||
fn get_attr_as_deref<'slf, T, U>(&'slf self) -> Option<&'slf U> | ||
where | ||
T: Attribute<'a> + Deref<Target = U> + 'slf, | ||
U: ?Sized, | ||
{ | ||
self.get_attr::<T>().map(T::deref) | ||
} | ||
|
||
fn set_attr<T>(&mut self, attr: T) | ||
where | ||
T: Attribute<'a>; | ||
|
||
fn endian(&self) -> Endian; | ||
|
||
fn language(&self, builder: &LanguageBuilder) -> Result<Language, LoaderError> { | ||
let convention = self | ||
.get_attr_as::<CompilerConvention, _>() | ||
.unwrap_or("default"); | ||
self.language_with(builder, convention) | ||
} | ||
|
||
fn language_with( | ||
&self, | ||
builder: &LanguageBuilder, | ||
convention: impl AsRef<str>, | ||
) -> Result<Language, LoaderError>; | ||
|
||
fn entry(&self) -> Option<Address> { | ||
None | ||
} | ||
|
||
fn segments<'slf>(&'slf self) -> impl Iterator<Item = LoadableSegment<'slf>>; | ||
} | ||
|
||
pub struct LoadableSegment<'a> { | ||
addr: Address, | ||
data: Cow<'a, [u8]>, | ||
} | ||
|
||
impl<'a> From<Vec<u8>> for LoadableSegment<'a> { | ||
fn from(value: Vec<u8>) -> Self { | ||
Self::new(0u32, value) | ||
} | ||
} | ||
|
||
impl<'a> From<&'a [u8]> for LoadableSegment<'a> { | ||
fn from(value: &'a [u8]) -> Self { | ||
Self::new(0u32, value) | ||
} | ||
} | ||
|
||
impl<'a> LoadableSegment<'a> { | ||
pub fn new(addr: impl Into<Address>, data: impl Into<Cow<'a, [u8]>>) -> Self { | ||
Self { | ||
addr: addr.into(), | ||
data: data.into(), | ||
} | ||
} | ||
|
||
pub fn address(&self) -> Address { | ||
self.addr | ||
} | ||
|
||
pub fn data(&self) -> &[u8] { | ||
self.data.as_ref() | ||
} | ||
|
||
pub fn into_parts(self) -> (Address, Cow<'a, [u8]>) { | ||
(self.addr, self.data) | ||
} | ||
} |
Oops, something went wrong.