summaryrefslogtreecommitdiff
path: root/rust/src
diff options
context:
space:
mode:
authorKyleMiles <krm504@nyu.edu>2021-03-19 23:06:21 +0000
committerKyleMiles <krm504@nyu.edu>2021-07-07 23:27:23 -0400
commit013945b3efa885101db16990311093912775d1c6 (patch)
tree37a8f83c77ad1ed4e40df0ac8bdda541628646b6 /rust/src
parent9dada0ef8d9d50e6ebc5afe97c25f624bb22da51 (diff)
Rust API: Type Improvements
FunctionParameters now hold refs and have a constructor
Diffstat (limited to 'rust/src')
-rw-r--r--rust/src/disassembly.rs2
-rw-r--r--rust/src/types.rs115
2 files changed, 94 insertions, 23 deletions
diff --git a/rust/src/disassembly.rs b/rust/src/disassembly.rs
index e784b1ca..2eb96680 100644
--- a/rust/src/disassembly.rs
+++ b/rust/src/disassembly.rs
@@ -12,6 +12,8 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+// TODO : Combine this with the architecture implementation
+
use binaryninjacore_sys::*;
use crate::string::BnString;
diff --git a/rust/src/types.rs b/rust/src/types.rs
index dd14d556..91bf6972 100644
--- a/rust/src/types.rs
+++ b/rust/src/types.rs
@@ -379,8 +379,10 @@ impl TypeBuilder {
//! For simplicity's sake, that convention isn't followed and you can query the default_int_size from an arch, if you have it, if you need to
unsafe {
+ // TODO : This is _extremely fragile_, we should change the internals of BNCreateEnumerationTypeBuilder instead of doing this
+ let mut fake_arch: BNArchitecture = mem::zeroed();
Self::from_raw(BNCreateEnumerationTypeBuilder(
- ptr::null_mut(),
+ &mut fake_arch,
enumeration.handle,
width,
is_signed,
@@ -724,8 +726,10 @@ impl Type {
//! For simplicity's sake, that convention isn't followed and you can query the default_int_size from an arch, if you have it, if you need to
unsafe {
+ // TODO : This is _extremely fragile_, we should change the internals of BNCreateEnumerationType instead of doing this
+ let mut fake_arch: BNArchitecture = mem::zeroed();
Self::ref_from_raw(BNCreateEnumerationType(
- ptr::null_mut(),
+ &mut fake_arch,
enumeration.handle,
width,
is_signed,
@@ -753,31 +757,69 @@ impl Type {
}
}
- pub fn function<'a, A: Architecture, S: BnStrCompatible + Copy, T: Into<Conf<&'a Type>>>(
+ pub fn function<'a, S: BnStrCompatible + Copy, T: Into<Conf<&'a Type>>>(
return_type: T,
parameters: &[FunctionParameter<S>],
variable_arguments: bool,
- calling_convention: Option<Conf<&CallingConvention<A>>>,
- stack_adjust: Option<Conf<i64>>,
) -> Ref<Self> {
let mut return_type = return_type.into().into();
-
let mut variable_arguments = Conf::new(variable_arguments, max_confidence()).into();
- // TODO : Don't do this? It should be fine
- #[allow(invalid_value)]
- let calling_convention_ref =
- Conf::<&CallingConvention<A>>::new(unsafe { mem::zeroed() }, min_confidence());
- let mut raw_calling_convention: BNCallingConventionWithConfidence = match calling_convention
- {
- Some(calling_convention) => calling_convention.into(),
- None => calling_convention_ref.into(),
- };
+ let mut raw_calling_convention: BNCallingConventionWithConfidence =
+ BNCallingConventionWithConfidence {
+ convention: ptr::null_mut(),
+ confidence: min_confidence(),
+ };
+
+ let mut stack_adjust = Conf::<i64>::new(0, min_confidence()).into();
+ let mut raw_parameters = Vec::<BNFunctionParameter>::with_capacity(parameters.len());
+ for parameter in parameters {
+ // TODO : The core side is fine, but test this function with named parameters to ensure rust doesn't delete the reference
+ let raw_name = parameter.name.as_bytes_with_nul();
+
+ let location = match &parameter.location {
+ Some(location) => location.into_raw(),
+ None => unsafe { mem::zeroed() },
+ };
+
+ raw_parameters.push(BNFunctionParameter {
+ name: raw_name.as_ref().as_ptr() as *mut _,
+ type_: parameter.t.contents.handle,
+ typeConfidence: parameter.t.confidence,
+ defaultLocation: parameter.location.is_none(),
+ location,
+ });
+ }
+
+ unsafe {
+ Self::ref_from_raw(BNCreateFunctionType(
+ &mut return_type,
+ &mut raw_calling_convention,
+ raw_parameters.as_mut_ptr(),
+ raw_parameters.len(),
+ &mut variable_arguments,
+ &mut stack_adjust,
+ ))
+ }
+ }
- let mut stack_adjust = match stack_adjust {
- Some(stack_adjust) => stack_adjust.into(),
- None => Conf::<i64>::new(0, min_confidence()).into(),
- };
+ pub fn function_with_options<
+ 'a,
+ A: Architecture,
+ S: BnStrCompatible + Copy,
+ T: Into<Conf<&'a Type>>,
+ >(
+ return_type: T,
+ parameters: &[FunctionParameter<S>],
+ variable_arguments: bool,
+ calling_convention: Conf<&CallingConvention<A>>,
+ stack_adjust: Conf<i64>,
+ ) -> Ref<Self> {
+ let mut return_type = return_type.into().into();
+ let mut variable_arguments = Conf::new(variable_arguments, max_confidence()).into();
+ let mut raw_calling_convention: BNCallingConventionWithConfidence =
+ calling_convention.into();
+ let mut stack_adjust = stack_adjust.into();
let mut raw_parameters = Vec::<BNFunctionParameter>::with_capacity(parameters.len());
for parameter in parameters {
@@ -808,7 +850,6 @@ impl Type {
&mut stack_adjust,
))
}
- // return Type(core.BNCreateFunctionTypeBuilder(ret_conf, conv_conf, param_buf, len(params), vararg_conf, stack_adjust_conf))
}
pub fn pointer<'a, A: Architecture, T: Into<Conf<&'a Type>>>(arch: &A, t: T) -> Ref<Self> {
@@ -926,13 +967,21 @@ impl ToOwned for Type {
///////////////////////
// FunctionParameter
-pub struct FunctionParameter<'a, S: BnStrCompatible> {
- pub t: Conf<&'a Type>,
+pub struct FunctionParameter<S: BnStrCompatible> {
+ pub t: Conf<Ref<Type>>,
pub name: S,
pub location: Option<Variable>,
}
-// impl<'a, S: BnStrCompatible> FunctionParameter<'a, S> {}
+impl<'a, S: BnStrCompatible> FunctionParameter<S> {
+ pub fn new<T: Into<Conf<Ref<Type>>>>(t: T, name: S, location: Option<Variable>) -> Self {
+ Self {
+ t: t.into(),
+ name,
+ location,
+ }
+ }
+}
//////////////
// Variable
@@ -1156,6 +1205,8 @@ impl ToOwned for Enumeration {
//////////////////////
// StructureBuilder
+pub type StructureType = BNStructureType;
+
#[derive(PartialEq, Eq, Hash)]
pub struct StructureBuilder {
pub(crate) handle: *mut BNStructureBuilder,
@@ -1198,10 +1249,13 @@ impl StructureBuilder {
Self { handle }
}
+ // Chainable terminal
pub fn finalize(&self) -> Ref<Structure> {
Structure::new(self)
}
+ // Chainable builders/setters
+
pub fn set_width<'a>(&'a mut self, width: u64) -> &'a mut Self {
unsafe {
BNSetStructureBuilderWidth(self.handle, width);
@@ -1244,10 +1298,21 @@ impl StructureBuilder {
self
}
+ pub fn set_structure_type<'a>(&'a mut self, t: StructureType) -> &'a Self {
+ unsafe { BNSetStructureBuilderType(self.handle, t) };
+ self
+ }
+
+ // Getters
+
pub fn width(&self) -> u64 {
unsafe { BNGetStructureBuilderWidth(self.handle) }
}
+ pub fn structure_type(&self) -> StructureType {
+ unsafe { BNGetStructureBuilderType(self.handle) }
+ }
+
// TODO : The other methods in the python version (alignment, packed, type, members, remove, replace, etc)
}
@@ -1318,6 +1383,10 @@ impl Structure {
unsafe { BNGetStructureWidth(self.handle) }
}
+ pub fn structure_type(&self) -> StructureType {
+ unsafe { BNGetStructureType(self.handle) }
+ }
+
// TODO : The other methods in the python version (alignment, packed, type, members, remove, replace, etc)
}