Skip to content

Commit

Permalink
Merge branch 'name-and-type-transparent' of github.com:rbran/binaryni…
Browse files Browse the repository at this point in the history
…nja-api into dev
  • Loading branch information
rssor committed May 1, 2024
2 parents e0fb875 + 562fbfa commit 6b268f8
Show file tree
Hide file tree
Showing 6 changed files with 129 additions and 59 deletions.
8 changes: 4 additions & 4 deletions rust/examples/dwarf/dwarf_export/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -551,23 +551,23 @@ fn export_data_vars(
dwarf.unit.get_mut(var_die_uid).set(
gimli::DW_AT_name,
AttributeValue::String(
format!("data_{:x}", data_variable.address)
format!("data_{:x}", data_variable.address())
.as_bytes()
.to_vec(),
),
);
}

let mut variable_location = Expression::new();
variable_location.op_addr(Address::Constant(data_variable.address));
variable_location.op_addr(Address::Constant(data_variable.address()));
dwarf.unit.get_mut(var_die_uid).set(
gimli::DW_AT_location,
AttributeValue::Exprloc(variable_location),
);

if let Some(target_die_uid) = export_type(
format!("{}", data_variable.t.contents),
data_variable.t.contents.as_ref(),
format!("{}", data_variable.t()),
data_variable.t(),
bv,
defined_types,
dwarf,
Expand Down
6 changes: 3 additions & 3 deletions rust/examples/dwarf/shared/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -88,11 +88,11 @@ pub fn create_section_reader<'a, Endian: 'a + Endianity>(
if let Some(data_var) = view
.data_variables()
.iter()
.find(|var| var.address == symbol.address())
.find(|var| var.address() == symbol.address())
{
// TODO : This should eventually be wrapped by some DataView sorta thingy thing, like how python does it
let data_type = data_var.type_with_confidence().contents;
let data = view.read_vec(data_var.address, data_type.width() as usize);
let data_type = data_var.t();
let data = view.read_vec(data_var.address(), data_type.width() as usize);
let element_type = data_type.element_type().unwrap().contents;

if let Some(current_section_header) = data
Expand Down
8 changes: 4 additions & 4 deletions rust/src/architecture.rs
Original file line number Diff line number Diff line change
Expand Up @@ -313,7 +313,7 @@ pub trait Intrinsic: Sized + Clone + Copy {
fn id(&self) -> u32;

/// Reeturns the list of the input names and types for this intrinsic.
fn inputs(&self) -> Vec<NameAndType<String>>;
fn inputs(&self) -> Vec<Ref<NameAndType>>;

/// Returns the list of the output types for this intrinsic.
fn outputs(&self) -> Vec<Conf<Ref<Type>>>;
Expand Down Expand Up @@ -650,7 +650,7 @@ impl Intrinsic for UnusedIntrinsic {
fn id(&self) -> u32 {
unreachable!()
}
fn inputs(&self) -> Vec<NameAndType<String>> {
fn inputs(&self) -> Vec<Ref<NameAndType>> {
unreachable!()
}
fn outputs(&self) -> Vec<Conf<Ref<Type>>> {
Expand Down Expand Up @@ -992,7 +992,7 @@ impl Intrinsic for crate::architecture::CoreIntrinsic {
self.1
}

fn inputs(&self) -> Vec<NameAndType<String>> {
fn inputs(&self) -> Vec<Ref<NameAndType>> {
let mut count: usize = 0;

unsafe {
Expand Down Expand Up @@ -2423,7 +2423,7 @@ where
let inputs = intrinsic.inputs();
let mut res = Vec::with_capacity(inputs.len());
for input in inputs {
res.push(input.into_raw());
res.push(unsafe { Ref::into_raw(input) }.into_raw());
}

unsafe {
Expand Down
16 changes: 12 additions & 4 deletions rust/src/binaryview.rs
Original file line number Diff line number Diff line change
Expand Up @@ -574,16 +574,24 @@ pub trait BinaryViewExt: BinaryViewBase {
}
}

fn define_auto_data_var(&self, dv: DataVariable) {
fn define_auto_data_var(&self, dv: &DataVariable) {
unsafe {
BNDefineDataVariable(self.as_ref().handle, dv.address, &mut dv.t.into());
BNDefineDataVariable(
self.as_ref().handle,
dv.address(),
&mut dv.type_with_confidence().into(),
);
}
}

/// You likely would also like to call [`Self::define_user_symbol`] to bind this data variable with a name
fn define_user_data_var(&self, dv: DataVariable) {
fn define_user_data_var(&self, dv: &DataVariable) {
unsafe {
BNDefineUserDataVariable(self.as_ref().handle, dv.address, &mut dv.t.into());
BNDefineUserDataVariable(
self.as_ref().handle,
dv.address(),
&mut dv.type_with_confidence().into(),
);
}
}

Expand Down
12 changes: 6 additions & 6 deletions rust/src/debuginfo.rs
Original file line number Diff line number Diff line change
Expand Up @@ -376,7 +376,7 @@ impl DebugInfo {
}

/// Returns a generator of all types provided by a named DebugInfoParser
pub fn types_by_name<S: BnStrCompatible>(&self, parser_name: S) -> Vec<NameAndType<String>> {
pub fn types_by_name<S: BnStrCompatible>(&self, parser_name: S) -> Vec<Ref<NameAndType>> {
let parser_name = parser_name.into_bytes_with_nul();

let mut count: usize = 0;
Expand All @@ -387,10 +387,10 @@ impl DebugInfo {
&mut count,
)
};
let result: Vec<NameAndType<String>> = unsafe {
let result: Vec<Ref<NameAndType>> = unsafe {
slice::from_raw_parts_mut(debug_types_ptr, count)
.iter()
.map(NameAndType::<String>::from_raw)
.map(NameAndType::from_raw)
.collect()
};

Expand All @@ -399,13 +399,13 @@ impl DebugInfo {
}

/// A generator of all types provided by DebugInfoParsers
pub fn types(&self) -> Vec<NameAndType<String>> {
pub fn types(&self) -> Vec<Ref<NameAndType>> {
let mut count: usize = 0;
let debug_types_ptr = unsafe { BNGetDebugTypes(self.handle, ptr::null_mut(), &mut count) };
let result: Vec<NameAndType<String>> = unsafe {
let result: Vec<Ref<NameAndType>> = unsafe {
slice::from_raw_parts_mut(debug_types_ptr, count)
.iter()
.map(NameAndType::<String>::from_raw)
.map(NameAndType::from_raw)
.collect()
};

Expand Down
138 changes: 100 additions & 38 deletions rust/src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ pub type MemberScope = BNMemberScope;
////////////////
// Confidence

/// Compatible with the `BNType*WithConfidence` types
pub struct Conf<T> {
pub contents: T,
pub confidence: u8,
Expand Down Expand Up @@ -698,6 +699,7 @@ impl Drop for TypeBuilder {
//////////
// Type

#[repr(transparent)]
pub struct Type {
pub(crate) handle: *mut BNType,
}
Expand Down Expand Up @@ -2447,13 +2449,11 @@ unsafe impl CoreArrayWrapper for QualifiedNameTypeAndId {
//////////////////////////
// NameAndType

pub struct NameAndType<S: BnStrCompatible> {
pub name: S,
pub t: Conf<Ref<Type>>,
}
#[repr(transparent)]
pub struct NameAndType(pub(crate) BNNameAndType);

impl NameAndType<String> {
pub(crate) fn from_raw(raw: &BNNameAndType) -> Self {
impl NameAndType {
pub(crate) fn from_raw(raw: &BNNameAndType) -> Ref<Self> {
Self::new(
raw_to_string(raw.name).unwrap(),
unsafe { &Type::ref_from_raw(raw.type_) },
Expand All @@ -2462,43 +2462,73 @@ impl NameAndType<String> {
}
}

impl<S: BnStrCompatible> NameAndType<S> {
pub fn new(name: S, t: &Ref<Type>, confidence: u8) -> Self {
Self {
name,
t: Conf::new(t.clone(), confidence),
impl NameAndType {
pub fn new<S: BnStrCompatible>(name: S, t: &Type, confidence: u8) -> Ref<Self> {
unsafe {
Ref::new(Self(BNNameAndType {
name: BNAllocString(name.into_bytes_with_nul().as_ref().as_ptr() as *mut _),
type_: Ref::into_raw(t.to_owned()).handle,
typeConfidence: confidence,
}))
}
}

pub(crate) fn into_raw(self) -> BNNameAndType {
let t = self.t.clone();
let res = BNNameAndType {
name: BnString::new(self.name).into_raw(),
type_: t.contents.handle,
typeConfidence: self.t.confidence,
};
mem::forget(t);
res
self.0
}

pub fn type_with_confidence(&self) -> Conf<Ref<Type>> {
self.t.clone()
pub fn name(&self) -> &str {
let c_str = unsafe { CStr::from_ptr(self.0.name) };
c_str.to_str().unwrap()
}

pub fn t(&self) -> &Type {
unsafe { mem::transmute::<_, &Type>(&self.0.type_) }
}

pub fn type_with_confidence(&self) -> Conf<&Type> {
Conf::new(self.t(), self.0.typeConfidence)
}
}

impl ToOwned for NameAndType {
type Owned = Ref<Self>;

fn to_owned(&self) -> Self::Owned {
unsafe { RefCountable::inc_ref(self) }
}
}

unsafe impl RefCountable for NameAndType {
unsafe fn inc_ref(handle: &Self) -> Ref<Self> {
Self::new(
CStr::from_ptr(handle.0.name),
handle.t(),
handle.type_with_confidence().confidence,
)
}

unsafe fn dec_ref(handle: &Self) {
unsafe {
BNFreeString(handle.0.name);
RefCountable::dec_ref(handle.t());
}
}
}

impl<S: BnStrCompatible> CoreArrayProvider for NameAndType<S> {
impl CoreArrayProvider for NameAndType {
type Raw = BNNameAndType;
type Context = ();
}

unsafe impl<S: BnStrCompatible> CoreOwnedArrayProvider for NameAndType<S> {
unsafe impl CoreOwnedArrayProvider for NameAndType {
unsafe fn free(raw: *mut Self::Raw, count: usize, _context: &Self::Context) {
BNFreeNameAndTypeList(raw, count);
}
}

unsafe impl<S: BnStrCompatible> CoreArrayWrapper for NameAndType<S> {
type Wrapped<'a> = &'a NameAndType<S> where S: 'a;
unsafe impl CoreArrayWrapper for NameAndType {
type Wrapped<'a> = &'a NameAndType;

unsafe fn wrap_raw<'a>(raw: &'a Self::Raw, _context: &'a Self::Context) -> Self::Wrapped<'a> {
mem::transmute(raw)
Expand All @@ -2508,29 +2538,61 @@ unsafe impl<S: BnStrCompatible> CoreArrayWrapper for NameAndType<S> {
//////////////////
// DataVariable

pub struct DataVariable {
pub address: u64,
pub t: Conf<Ref<Type>>,
pub auto_discovered: bool,
}
#[repr(transparent)]
pub struct DataVariable(pub(crate) BNDataVariable);

// impl DataVariable {
// pub(crate) fn from_raw(var: &BNDataVariable) -> Self {
// Self {
// address: var.address,
// t: Conf::new(unsafe { Type::ref_from_raw(var.type_) }, var.typeConfidence),
// auto_discovered: var.autoDiscovered,
// }
// let var = DataVariable(*var);
// Self(BNDataVariable {
// type_: unsafe { Ref::into_raw(var.t().to_owned()).handle },
// ..var.0
// })
// }
// }

impl DataVariable {
pub fn type_with_confidence(&self) -> Conf<Ref<Type>> {
Conf::new(self.t.contents.clone(), self.t.confidence)
pub fn address(&self) -> u64 {
self.0.address
}

pub fn auto_discovered(&self) -> bool {
self.0.autoDiscovered
}

pub fn t(&self) -> &Type {
unsafe { mem::transmute(&self.0.type_) }
}

pub fn type_with_confidence(&self) -> Conf<&Type> {
Conf::new(self.t(), self.0.typeConfidence)
}

pub fn symbol(&self, bv: &BinaryView) -> Option<Ref<Symbol>> {
bv.symbol_by_address(self.address).ok()
bv.symbol_by_address(self.0.address).ok()
}
}

impl ToOwned for DataVariable {
type Owned = Ref<Self>;

fn to_owned(&self) -> Self::Owned {
unsafe { RefCountable::inc_ref(self) }
}
}

unsafe impl RefCountable for DataVariable {
unsafe fn inc_ref(handle: &Self) -> Ref<Self> {
unsafe {
Ref::new(Self(BNDataVariable {
type_: Ref::into_raw(handle.t().to_owned()).handle,
..handle.0
}))
}
}

unsafe fn dec_ref(handle: &Self) {
unsafe { BNFreeType(handle.0.type_) }
}
}

Expand Down

0 comments on commit 6b268f8

Please sign in to comment.