Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New standard proposal #5498

Closed
wants to merge 33 commits into from
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
17985a3
change `TypeBuilder` to the new standard
rbran May 29, 2024
4146df2
change `Type` to the new standard
rbran May 29, 2024
37b7cb9
change `BnString` to the new standard
rbran May 29, 2024
4bae1fd
change `FunctionParameter` to the new standard
rbran May 29, 2024
3e18469
change `NamedTypedVariable` to the new standard
rbran May 29, 2024
3d87df2
change `EnumerationBuilder` to the new standard
rbran May 29, 2024
ed8884d
change `Enumeration` to the new standard
rbran May 29, 2024
ec15b1b
change `StructureBuilder` to the new standard
rbran May 29, 2024
1e43870
change `Structure` to the new standard
rbran May 29, 2024
865ae40
change `StructureMember` to the new standard
rbran May 29, 2024
a019f2f
convert Vec into Array
rbran May 29, 2024
d44c3ed
change `NamedTypeReference` to the new standard
rbran May 29, 2024
bd54936
change `BaseStructure` to the new standard
rbran May 29, 2024
f5ab5ea
change `QualifiedName` to the new standard
rbran May 29, 2024
073de86
change `QualifiedNameAndType` to the new standard
rbran May 29, 2024
7af09f9
change `QualifiedName` to the new standard
rbran May 29, 2024
456a05d
change `NameAndType` to the new standard
rbran May 29, 2024
0fcc1fa
change `DataVariable` to the new standard
rbran May 29, 2024
3788dc5
change `DataVariableAndName` to the new standard
rbran May 29, 2024
747b750
create `DataVariableAndNameAndDebugParser` to the new standard
rbran May 29, 2024
09acf14
change `InheritedStructureMember` to the new standard
rbran May 30, 2024
8a36bd3
change `QualifiedName` to the new standard
rbran May 30, 2024
dae5412
change `RegisterValue` to the new standard
rbran May 30, 2024
dc96bff
change `Architecture` to the new standard
rbran May 30, 2024
818e335
fix mem leak at `Platform::parse_types_from_source`
rbran May 30, 2024
75e6d1d
don't consume the parameter at
rbran May 30, 2024
25f3dc5
Revert "change `Architecture` to the new standard"
rbran May 30, 2024
f7ca88b
fix examples
rbran May 30, 2024
44c0d31
change `StackVariableReference` to the new standard
rbran May 31, 2024
03148eb
change `IndirectBranchInfo` to the new standard
rbran May 31, 2024
0c9ecbe
change `BNConstantReference` to the new standard
rbran May 31, 2024
37f168e
change `UserVariableValue` to the new standard
rbran May 31, 2024
5c8e823
fix doc
rbran Jun 4, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 4 additions & 17 deletions rust/src/callingconvention.rs
Original file line number Diff line number Diff line change
Expand Up @@ -434,7 +434,7 @@ impl<A: Architecture> CallingConvention<A> {

pub fn name(&self) -> BnString {
unsafe {
BnString::from_raw(NonNull::new(BNGetCallingConventionName(self.handle)).unwrap())
BnString::from_raw(ptr::NonNull::new(BNGetCallingConventionName(self.handle)).unwrap())
}
}

Expand All @@ -443,22 +443,9 @@ impl<A: Architecture> CallingConvention<A> {
params: &[FunctionParameter],
permitted_registers: Option<&[A::Register]>,
) -> Vec<Variable> {
let mut bn_params: Vec<BNFunctionParameter> = vec![];
let name_strings = params.iter().map(|parameter| &parameter.name);

for (parameter, raw_name) in params.iter().zip(name_strings) {
let location = match &parameter.location {
Some(location) => location.raw(),
None => unsafe { mem::zeroed() },
};
bn_params.push(BNFunctionParameter {
name: BnString::new(raw_name).into_raw(),
type_: parameter.t.contents.as_raw(),
typeConfidence: parameter.t.confidence,
defaultLocation: parameter.location.is_none(),
location,
});
}
// SAFETY: FunctionParameter and BNFunctionParameter are transparent,
// so this can be safelly transmuted
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

safelly -> safely

let bn_params: &[BNFunctionParameter] = unsafe { mem::transmute(params) };

let mut count: usize = 0;
let vars: *mut BNVariable = if let Some(permitted_args) = permitted_registers {
Expand Down
136 changes: 67 additions & 69 deletions rust/src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ use std::{
ffi::CStr,
fmt::{self, Debug, Display, Formatter},
hash::{Hash, Hasher},
iter::{zip, IntoIterator},
iter::IntoIterator,
mem::{self, ManuallyDrop},
ops::Range,
os::raw::c_char,
Expand Down Expand Up @@ -1029,24 +1029,9 @@ impl Type {
};

let mut stack_adjust = Conf::<i64>::new(0, min_confidence()).into();
let mut raw_parameters = Vec::<BNFunctionParameter>::with_capacity(parameters.len());
let mut parameter_name_references = Vec::with_capacity(parameters.len());
for parameter in parameters {
let raw_name = parameter.name.as_str().into_bytes_with_nul();
let location = match &parameter.location {
Some(location) => location.raw(),
None => unsafe { mem::zeroed() },
};

raw_parameters.push(BNFunctionParameter {
name: raw_name.as_slice().as_ptr() as *mut _,
type_: parameter.t.contents.as_raw(),
typeConfidence: parameter.t.confidence,
defaultLocation: parameter.location.is_none(),
location,
});
parameter_name_references.push(raw_name);
}
// SAFETY: FunctionParameter and BNFunctionParameter are transparent,
// so this can be safelly transmuted
let raw_parameters: &[BNFunctionParameter] = unsafe { mem::transmute(parameters) };
let reg_stack_adjust_regs = ptr::null_mut();
let reg_stack_adjust_values = ptr::null_mut();

Expand All @@ -1060,7 +1045,7 @@ impl Type {
let result = BNNewTypeReference(BNCreateFunctionType(
&mut return_type,
&mut raw_calling_convention,
raw_parameters.as_mut_ptr(),
raw_parameters.as_ptr() as *mut BNFunctionParameter,
raw_parameters.len(),
&mut variable_arguments,
&mut can_return,
Expand Down Expand Up @@ -1096,29 +1081,14 @@ impl Type {
calling_convention.into().into();
let mut stack_adjust = stack_adjust.into();

let mut raw_parameters = Vec::<BNFunctionParameter>::with_capacity(parameters.len());
let mut parameter_name_references = Vec::with_capacity(parameters.len());
let mut name_ptrs = vec![];
for parameter in parameters {
name_ptrs.push(parameter.name.clone());
name_ptrs.push(parameter.name().clone());
}

for (name, parameter) in zip(name_ptrs, parameters) {
let raw_name = name.as_str().into_bytes_with_nul();
let location = match &parameter.location {
Some(location) => location.raw(),
None => unsafe { mem::zeroed() },
};

raw_parameters.push(BNFunctionParameter {
name: raw_name.as_slice().as_ptr() as *mut _,
type_: parameter.t.contents.as_raw(),
typeConfidence: parameter.t.confidence,
defaultLocation: parameter.location.is_none(),
location,
});
parameter_name_references.push(raw_name);
}
// SAFETY: FunctionParameter and BNFunctionParameter are transparent,
// so this can be safelly transmuted
let raw_parameters: &[BNFunctionParameter] = unsafe { mem::transmute(parameters) };

// TODO: Update type signature and include these (will be a breaking change)
let reg_stack_adjust_regs = ptr::null_mut();
Expand All @@ -1134,7 +1104,7 @@ impl Type {
let result = BNCreateFunctionType(
&mut return_type,
&mut raw_calling_convention,
raw_parameters.as_mut_ptr(),
raw_parameters.as_ptr() as *mut BNFunctionParameter,
raw_parameters.len(),
&mut variable_arguments,
&mut can_return,
Expand Down Expand Up @@ -1333,56 +1303,84 @@ impl Drop for Type {
///////////////////////
// FunctionParameter

#[repr(C)]
#[derive(Clone, Debug)]
pub struct FunctionParameter {
pub t: Conf<Type>,
pub name: String,
pub location: Option<Variable>,
name: Option<BnString>,
pub t: Type,
type_confidence: u8,
default_location: bool,
location: Variable,
}

impl FunctionParameter {
pub fn new<T: Into<Conf<Type>>>(t: T, name: String, location: Option<Variable>) -> Self {
pub fn new<S: BnStrCompatible, T: Into<Conf<Type>>>(
t: T,
name: S,
location: Option<Variable>,
) -> Self {
let t = t.into();
let dummy_var: Variable =
Variable::new(BNVariableSourceType::StackVariableSourceType, 0, 0);
Self {
t: t.into(),
name,
location,
name: Some(BnString::new(name)),
t: t.contents,
type_confidence: t.confidence,
default_location: location.is_some(),
location: location.unwrap_or(dummy_var),
}
}

pub(crate) fn from_raw(member: BNFunctionParameter) -> Self {
let name = if member.name.is_null() {
if member.location.type_ == BNVariableSourceType::RegisterVariableSourceType {
format!("reg_{}", member.location.storage)
} else if member.location.type_ == BNVariableSourceType::StackVariableSourceType {
format!("arg_{}", member.location.storage)
} else {
String::new()
}
pub(crate) unsafe fn from_raw(member: BNFunctionParameter) -> Self {
let name = NonNull::new(member.name).map(|name| unsafe { BnString::from_raw(name) });

let location = if member.defaultLocation {
// dummy value
Variable::new(BNVariableSourceType::StackVariableSourceType, 0, 0)
} else {
unsafe { CStr::from_ptr(member.name) }
.to_str()
.unwrap()
.to_owned()
unsafe { Variable::from_raw(member.location) }
};

Self {
t: Conf::new(
unsafe { Type::from_raw(NonNull::new(BNNewTypeReference(member.type_)).unwrap()) },
member.typeConfidence,
),
t: unsafe { Type::from_raw(NonNull::new(BNNewTypeReference(member.type_)).unwrap()) },
type_confidence: member.typeConfidence,
name,
location: if member.defaultLocation {
None
} else {
Some(unsafe { Variable::from_raw(member.location) })
},
default_location: member.defaultLocation,
location,
}
}

pub fn location(&self) -> Option<Variable> {
(!self.default_location).then_some(self.location)
}

pub fn name(&self) -> Cow<str> {
if let Some(name) = &self.name {
Cow::Borrowed(name.as_str())
} else {
match self.location() {
Some(Variable {
t: BNVariableSourceType::RegisterVariableSourceType,
..
}) => Cow::Owned(format!("reg_{}", self.location.storage)),
Some(Variable {
t: BNVariableSourceType::StackVariableSourceType,
..
}) => Cow::Owned(format!("arg_{}", self.location.storage)),
Some(Variable {
t: BNVariableSourceType::FlagVariableSourceType,
..
})
| None => Cow::Borrowed(""),
}
}
}
}

//////////////
// Variable

#[repr(C)]
#[derive(Clone, Copy, Debug, Hash, Eq, PartialEq)]
pub struct Variable {
pub t: BNVariableSourceType,
Expand Down