From cb02af3bdac0798a82ecb128e46cdee30d347e8a Mon Sep 17 00:00:00 2001 From: Michael Krasnitski Date: Sun, 12 Jan 2025 15:10:18 -0500 Subject: [PATCH 1/2] Fix clippy lints --- rust/build.rs | 2 +- rust/clippy.toml | 1 + rust/src/architecture.rs | 26 +++++++++++++--------- rust/src/basicblock.rs | 2 +- rust/src/binaryview.rs | 2 +- rust/src/component.rs | 6 ++--- rust/src/databuffer.rs | 2 +- rust/src/demangle.rs | 7 ++---- rust/src/disassembly.rs | 2 +- rust/src/enterprise.rs | 47 +++++++++++++++++---------------------- rust/src/flowgraph.rs | 4 ++-- rust/src/lib.rs | 2 +- rust/src/llil/function.rs | 20 ++++++++--------- rust/src/project.rs | 2 +- rust/src/section.rs | 2 +- rust/src/settings.rs | 4 ---- rust/src/typearchive.rs | 2 +- rust/src/typecontainer.rs | 2 +- rust/src/typeparser.rs | 6 ++--- rust/src/typeprinter.rs | 8 ++----- rust/src/types.rs | 2 +- rust/src/variable.rs | 6 +++-- rust/src/workflow.rs | 20 ++++------------- 23 files changed, 79 insertions(+), 98 deletions(-) create mode 100644 rust/clippy.toml diff --git a/rust/build.rs b/rust/build.rs index 18983aee9..46b518e00 100644 --- a/rust/build.rs +++ b/rust/build.rs @@ -5,7 +5,7 @@ fn main() { let _ = std::fs::create_dir("target/doc"); let _ = std::fs::copy("../docs/img/favicon.ico", "target/doc/favicon.ico"); let _ = std::fs::copy( - "under_construction.png", + "assets/under_construction.png", "target/doc/under_construction.png", ); let _ = std::fs::copy("../docs/img/logo.png", "target/doc/logo.png"); diff --git a/rust/clippy.toml b/rust/clippy.toml new file mode 100644 index 000000000..ba34bf464 --- /dev/null +++ b/rust/clippy.toml @@ -0,0 +1 @@ +too-many-arguments-threshold = 8 diff --git a/rust/src/architecture.rs b/rust/src/architecture.rs index 588901248..e7493a696 100644 --- a/rust/src/architecture.rs +++ b/rust/src/architecture.rs @@ -200,14 +200,20 @@ impl From for InstructionInfo { fn from(value: BNInstructionInfo) -> Self { // TODO: This is quite ugly, but we destructure the branch info so this will have to do. let mut branch_info = [None; NUM_BRANCH_INFO]; - for i in 0..value.branchCount.min(NUM_BRANCH_INFO) { - let branch_target = value.branchTarget[i]; - branch_info[i] = Some(BranchInfo { - kind: match value.branchType[i] { - BNBranchType::UnconditionalBranch => BranchKind::Unconditional(branch_target), - BNBranchType::FalseBranch => BranchKind::False(branch_target), - BNBranchType::TrueBranch => BranchKind::True(branch_target), - BNBranchType::CallDestination => BranchKind::Call(branch_target), + for (i, slot) in branch_info + .iter_mut() + .enumerate() + .take(value.branchCount.min(NUM_BRANCH_INFO)) + { + let target = value.branchTarget[i]; + let kind = value.branchType[i]; + let arch = value.branchArch[i]; + *slot = Some(BranchInfo { + kind: match kind { + BNBranchType::UnconditionalBranch => BranchKind::Unconditional(target), + BNBranchType::FalseBranch => BranchKind::False(target), + BNBranchType::TrueBranch => BranchKind::True(target), + BNBranchType::CallDestination => BranchKind::Call(target), BNBranchType::FunctionReturn => BranchKind::FunctionReturn, BNBranchType::SystemCall => BranchKind::SystemCall, BNBranchType::IndirectBranch => BranchKind::Indirect, @@ -215,10 +221,10 @@ impl From for InstructionInfo { BNBranchType::UnresolvedBranch => BranchKind::Unresolved, BNBranchType::UserDefinedBranch => BranchKind::UserDefined, }, - arch: if value.branchArch[i].is_null() { + arch: if arch.is_null() { None } else { - Some(unsafe { CoreArchitecture::from_raw(value.branchArch[i]) }) + Some(unsafe { CoreArchitecture::from_raw(arch) }) }, }); } diff --git a/rust/src/basicblock.rs b/rust/src/basicblock.rs index 56ff0abeb..96406fd11 100644 --- a/rust/src/basicblock.rs +++ b/rust/src/basicblock.rs @@ -240,7 +240,7 @@ impl BasicBlock { // TODO iterated dominance frontier } -impl<'a, C: BlockContext> IntoIterator for &'a BasicBlock { +impl IntoIterator for &BasicBlock { type Item = C::Instruction; type IntoIter = C::Iter; diff --git a/rust/src/binaryview.rs b/rust/src/binaryview.rs index 47987f139..7f3d727fa 100644 --- a/rust/src/binaryview.rs +++ b/rust/src/binaryview.rs @@ -669,7 +669,7 @@ pub trait BinaryViewExt: BinaryViewBase { let name_array = unsafe { Array::::new(result_names, result_count, ()) }; id_array .into_iter() - .zip(name_array.into_iter()) + .zip(&name_array) .map(|(id, name)| (id.to_owned(), name)) .collect() } diff --git a/rust/src/component.rs b/rust/src/component.rs index 7ed514509..5a03fb417 100644 --- a/rust/src/component.rs +++ b/rust/src/component.rs @@ -146,13 +146,13 @@ impl Component { } /// Original name set for this component - + /// /// :note: The `.display_name` property should be used for `bv.get_component_by_path()` lookups. - + /// /// This can differ from the .display_name property if one of its sibling components has the same .original_name; In that /// case, .name will be an automatically generated unique name (e.g. "MyComponentName (1)") while .original_name will /// remain what was originally set (e.g. "MyComponentName") - + /// /// If this component has a duplicate name and is moved to a component where none of its siblings share its name, /// .name will return the original "MyComponentName" pub fn name(&self) -> BnString { diff --git a/rust/src/databuffer.rs b/rust/src/databuffer.rs index 3bc833b23..5b4d6515a 100644 --- a/rust/src/databuffer.rs +++ b/rust/src/databuffer.rs @@ -172,7 +172,7 @@ impl DataBuffer { impl Default for DataBuffer { fn default() -> Self { - Self(unsafe { BNCreateDataBuffer([].as_ptr() as *const c_void, 0) }) + Self(unsafe { BNCreateDataBuffer([].as_ptr(), 0) }) } } diff --git a/rust/src/demangle.rs b/rust/src/demangle.rs index 831157b28..9598426d6 100644 --- a/rust/src/demangle.rs +++ b/rust/src/demangle.rs @@ -304,10 +304,7 @@ impl Demangler { }) } - extern "C" fn cb_free_var_name(_ctxt: *mut c_void, name: *mut BNQualifiedName) - where - C: CustomDemangler, - { + extern "C" fn cb_free_var_name(_ctxt: *mut c_void, name: *mut BNQualifiedName) { ffi_wrap!("CustomDemangler::cb_free_var_name", unsafe { // TODO: What is the point of this free callback? // TODO: The core can just call BNFreeQualifiedName. @@ -323,7 +320,7 @@ impl Demangler { context: ctxt as *mut c_void, isMangledString: Some(cb_is_mangled_string::), demangle: Some(cb_demangle::), - freeVarName: Some(cb_free_var_name::), + freeVarName: Some(cb_free_var_name), }; unsafe { diff --git a/rust/src/disassembly.rs b/rust/src/disassembly.rs index 2a4db4f68..5d42347be 100644 --- a/rust/src/disassembly.rs +++ b/rust/src/disassembly.rs @@ -285,7 +285,7 @@ impl From for BNInstructionTextToken { let kind_value = value.kind.try_value().unwrap_or(0); let operand = value.kind.try_operand().unwrap_or(0); let size = value.kind.try_size().unwrap_or(0); - let type_names = value.kind.try_type_names().unwrap_or(vec![]); + let type_names = value.kind.try_type_names().unwrap_or_default(); Self { type_: value.kind.into(), // Expected to be freed with `InstructionTextToken::free_raw`. diff --git a/rust/src/enterprise.rs b/rust/src/enterprise.rs index adb1a32a6..449b478b2 100644 --- a/rust/src/enterprise.rs +++ b/rust/src/enterprise.rs @@ -20,10 +20,8 @@ pub fn checkout_license(duration: Duration) -> Result<(), EnterpriseCheckoutErro return Ok(()); } - if !is_server_initialized() { - if !initialize_server() && is_server_floating_license() { - return Err(EnterpriseCheckoutError(server_last_error().to_string())); - } + if !is_server_initialized() && !initialize_server() && is_server_floating_license() { + return Err(EnterpriseCheckoutError(server_last_error().to_string())); } if is_server_floating_license() { @@ -31,33 +29,30 @@ pub fn checkout_license(duration: Duration) -> Result<(), EnterpriseCheckoutErro return Err(EnterpriseCheckoutError(server_last_error().to_string())); } - if !is_server_authenticated() { - if !authenticate_server_with_method("Keychain", false) { - let Some(username) = std::env::var("BN_ENTERPRISE_USERNAME").ok() else { - return Err(EnterpriseCheckoutError("BN_ENTERPRISE_USERNAME not set when attempting to authenticate with credentials".to_string())); - }; - let Some(password) = std::env::var("BN_ENTERPRISE_PASSWORD").ok() else { - return Err(EnterpriseCheckoutError("BN_ENTERPRISE_PASSWORD not set when attempting to authenticate with credentials".to_string())); - }; - if !authenticate_server_with_credentials(username, password, true) { - let failed_message = "Could not checkout a license: Not authenticated. Try one of the following: \n \ - - Log in and check out a license for an extended time\n \ - - Set BN_ENTERPRISE_USERNAME and BN_ENTERPRISE_PASSWORD environment variables\n \ - - Use binaryninja::enterprise::{authenticate_server_with_method OR authenticate_server_with_credentials} in your code"; - return Err(EnterpriseCheckoutError(failed_message.to_string())); - } + if !is_server_authenticated() && !authenticate_server_with_method("Keychain", false) { + let Some(username) = std::env::var("BN_ENTERPRISE_USERNAME").ok() else { + return Err(EnterpriseCheckoutError("BN_ENTERPRISE_USERNAME not set when attempting to authenticate with credentials".to_string())); + }; + let Some(password) = std::env::var("BN_ENTERPRISE_PASSWORD").ok() else { + return Err(EnterpriseCheckoutError("BN_ENTERPRISE_PASSWORD not set when attempting to authenticate with credentials".to_string())); + }; + if !authenticate_server_with_credentials(username, password, true) { + let failed_message = "Could not checkout a license: Not authenticated. Try one of the following: \n \ + - Log in and check out a license for an extended time\n \ + - Set BN_ENTERPRISE_USERNAME and BN_ENTERPRISE_PASSWORD environment variables\n \ + - Use binaryninja::enterprise::{authenticate_server_with_method OR authenticate_server_with_credentials} in your code"; + return Err(EnterpriseCheckoutError(failed_message.to_string())); } } } - if !is_server_license_still_activated() - || (!is_server_floating_license() && crate::license_expiration_time() < SystemTime::now()) + if (!is_server_license_still_activated() + || (!is_server_floating_license() && crate::license_expiration_time() < SystemTime::now())) + && !update_server_license(duration) { - if !update_server_license(duration) { - return Err(EnterpriseCheckoutError( - "Failed to refresh expired license".to_string(), - )); - } + return Err(EnterpriseCheckoutError( + "Failed to refresh expired license".to_string(), + )); } Ok(()) diff --git a/rust/src/flowgraph.rs b/rust/src/flowgraph.rs index 0d490e577..9db271541 100644 --- a/rust/src/flowgraph.rs +++ b/rust/src/flowgraph.rs @@ -91,7 +91,7 @@ impl<'a> FlowGraphNode<'a> { } } -unsafe impl<'a> RefCountable for FlowGraphNode<'a> { +unsafe impl RefCountable for FlowGraphNode<'_> { unsafe fn inc_ref(handle: &Self) -> Ref { Ref::new(Self { handle: BNNewFlowGraphNodeReference(handle.handle), @@ -104,7 +104,7 @@ unsafe impl<'a> RefCountable for FlowGraphNode<'a> { } } -impl<'a> ToOwned for FlowGraphNode<'a> { +impl ToOwned for FlowGraphNode<'_> { type Owned = Ref; fn to_owned(&self) -> Self::Owned { diff --git a/rust/src/lib.rs b/rust/src/lib.rs index b29d857a0..167430865 100644 --- a/rust/src/lib.rs +++ b/rust/src/lib.rs @@ -210,7 +210,7 @@ unsafe extern "C" fn cb_progress_func bool>( if ctxt.is_null() { return true; } - let closure: &mut F = std::mem::transmute(ctxt); + let closure = &mut *(ctxt as *mut F); closure(progress, total) } diff --git a/rust/src/llil/function.rs b/rust/src/llil/function.rs index cd1f8e39c..b2121cafc 100644 --- a/rust/src/llil/function.rs +++ b/rust/src/llil/function.rs @@ -63,9 +63,9 @@ pub struct LowLevelILFunction, } -impl<'func, A, M, F> LowLevelILFunction +impl LowLevelILFunction where - A: 'func + Architecture, + A: Architecture, M: FunctionMutability, F: FunctionForm, { @@ -137,9 +137,9 @@ where // LLIL basic blocks are not available until the function object // is finalized, so ensure we can't try requesting basic blocks // during lifting -impl<'func, A, F> LowLevelILFunction +impl LowLevelILFunction where - A: 'func + Architecture, + A: Architecture, F: FunctionForm, { pub fn basic_blocks(&self) -> Array>> { @@ -176,9 +176,9 @@ impl LowLevelILFunction> { } } -impl<'func, A, M, F> ToOwned for LowLevelILFunction +impl ToOwned for LowLevelILFunction where - A: 'func + Architecture, + A: Architecture, M: FunctionMutability, F: FunctionForm, { @@ -189,9 +189,9 @@ where } } -unsafe impl<'func, A, M, F> RefCountable for LowLevelILFunction +unsafe impl RefCountable for LowLevelILFunction where - A: 'func + Architecture, + A: Architecture, M: FunctionMutability, F: FunctionForm, { @@ -210,9 +210,9 @@ where } } -impl<'func, A, M, F> fmt::Debug for LowLevelILFunction +impl fmt::Debug for LowLevelILFunction where - A: 'func + Architecture, + A: Architecture, M: FunctionMutability, F: FunctionForm, { diff --git a/rust/src/project.rs b/rust/src/project.rs index 12eac228a..d52e594c0 100644 --- a/rust/src/project.rs +++ b/rust/src/project.rs @@ -1107,7 +1107,7 @@ unsafe extern "C" fn cb_progress_func bool>( if ctxt.is_null() { return true; } - let closure: &mut F = mem::transmute(ctxt); + let closure = &mut *(ctxt as *mut F); closure(progress, total) } diff --git a/rust/src/section.rs b/rust/src/section.rs index cf66c3f99..7df3d014d 100644 --- a/rust/src/section.rs +++ b/rust/src/section.rs @@ -273,7 +273,7 @@ impl SectionBuilder { let len = self.range.end.wrapping_sub(start); unsafe { - let nul_str = std::ffi::CStr::from_bytes_with_nul_unchecked(b"\x00").as_ptr(); + let nul_str = c"".as_ptr(); let name_ptr = name.as_ref().as_ptr() as *mut _; let ty_ptr = ty.map_or(nul_str, |s| s.as_ref().as_ptr() as *mut _); let linked_section_ptr = diff --git a/rust/src/settings.rs b/rust/src/settings.rs index 0c9fd7877..f37a5a348 100644 --- a/rust/src/settings.rs +++ b/rust/src/settings.rs @@ -50,10 +50,6 @@ impl Settings { } } - pub fn default() -> Ref { - Self::new("default") - } - pub fn set_resource_id(&self, resource_id: S) { let resource_id = resource_id.into_bytes_with_nul(); unsafe { BNSettingsSetResourceId(self.handle, resource_id.as_ref().as_ptr() as *mut _) }; diff --git a/rust/src/typearchive.rs b/rust/src/typearchive.rs index 4a0640fb4..3697daafb 100644 --- a/rust/src/typearchive.rs +++ b/rust/src/typearchive.rs @@ -402,7 +402,7 @@ impl TypeArchive { } /// Get a list of all types' names and ids in the archive at a current snapshot - + /// /// * `snapshot` - Snapshot id to search for types pub fn get_type_names_and_ids( &self, diff --git a/rust/src/typecontainer.rs b/rust/src/typecontainer.rs index bd71b177f..da2192862 100644 --- a/rust/src/typecontainer.rs +++ b/rust/src/typecontainer.rs @@ -341,7 +341,7 @@ impl TypeContainer { /// Parse an entire block of source into types, variables, and functions, with /// knowledge of the types in the Type Container. - + /// /// * `source` - Source code to parse /// * `file_name` - Name of the file containing the source (optional: exists on disk) /// * `options` - String arguments to pass as options, e.g. command line arguments diff --git a/rust/src/typeparser.rs b/rust/src/typeparser.rs index 111ad9df8..e83366c82 100644 --- a/rust/src/typeparser.rs +++ b/rust/src/typeparser.rs @@ -376,9 +376,9 @@ impl From for TypeParserResult { let raw_functions = unsafe { std::slice::from_raw_parts(value.functions, value.functionCount) }; let result = TypeParserResult { - types: raw_types.iter().map(|t| ParsedType::from(t)).collect(), - variables: raw_variables.iter().map(|t| ParsedType::from(t)).collect(), - functions: raw_functions.iter().map(|t| ParsedType::from(t)).collect(), + types: raw_types.iter().map(ParsedType::from).collect(), + variables: raw_variables.iter().map(ParsedType::from).collect(), + functions: raw_functions.iter().map(ParsedType::from).collect(), }; // SAFETY: `value` must be a properly initialized BNTypeParserResult. unsafe { BNFreeTypeParserResult(&mut value) }; diff --git a/rust/src/typeprinter.rs b/rust/src/typeprinter.rs index ffbd0d06e..2f6e6ca0f 100644 --- a/rust/src/typeprinter.rs +++ b/rust/src/typeprinter.rs @@ -339,12 +339,8 @@ impl CoreTypePrinter { impl Default for CoreTypePrinter { fn default() -> Self { // TODO: Remove this entirely, there is no "default", its view specific lets not make this some defined behavior. - let default_settings = crate::settings::Settings::default(); - let name = default_settings.get_string( - std::ffi::CStr::from_bytes_with_nul(b"analysis.types.printerName\x00").unwrap(), - None, - None, - ); + let default_settings = crate::settings::Settings::new("default"); + let name = default_settings.get_string("analysis.types.printerName", None, None); Self::printer_by_name(name).unwrap() } } diff --git a/rust/src/types.rs b/rust/src/types.rs index e27ddf73f..8b441c7b1 100644 --- a/rust/src/types.rs +++ b/rust/src/types.rs @@ -1109,7 +1109,7 @@ unsafe impl CoreArrayProviderInner for (&str, Variable, &Type) { ) -> (&'a str, Variable, &'a Type) { let name = CStr::from_ptr(raw.name).to_str().unwrap(); let var = Variable::from(raw.var); - let var_type = std::mem::transmute(&raw.type_); + let var_type = &*(raw.type_ as *mut Type); (name, var, var_type) } } diff --git a/rust/src/variable.rs b/rust/src/variable.rs index 93f2e4f9d..5a88584db 100644 --- a/rust/src/variable.rs +++ b/rust/src/variable.rs @@ -771,8 +771,10 @@ impl From for PossibleValueSet { // TODO: Anything requiring core allocation is missing! impl From for BNPossibleValueSet { fn from(value: PossibleValueSet) -> Self { - let mut raw = BNPossibleValueSet::default(); - raw.state = value.value_type(); + let mut raw = BNPossibleValueSet { + state: value.value_type(), + ..Default::default() + }; match value { PossibleValueSet::UndeterminedValue => {} PossibleValueSet::EntryValue { reg } => { diff --git a/rust/src/workflow.rs b/rust/src/workflow.rs index 236e0cb73..f8042ccc7 100644 --- a/rust/src/workflow.rs +++ b/rust/src/workflow.rs @@ -192,7 +192,7 @@ impl Activity { ctxt: *mut c_void, analysis: *mut BNAnalysisContext, ) { - let ctxt: &mut F = core::mem::transmute(ctxt); + let ctxt = &mut *(ctxt as *mut F); if let Some(analysis) = NonNull::new(analysis) { ctxt(&AnalysisContext::from_raw(analysis)) } @@ -567,29 +567,17 @@ impl Workflow { /// Not yet implemented. pub fn show_metrics(&self) { - unsafe { - BNWorkflowShowReport( - self.handle.as_ptr(), - b"metrics\x00".as_ptr() as *const c_char, - ) - } + unsafe { BNWorkflowShowReport(self.handle.as_ptr(), c"metrics".as_ptr()) } } /// Show the Workflow topology in the UI. pub fn show_topology(&self) { - unsafe { - BNWorkflowShowReport( - self.handle.as_ptr(), - b"topology\x00".as_ptr() as *const c_char, - ) - } + unsafe { BNWorkflowShowReport(self.handle.as_ptr(), c"topology".as_ptr()) } } /// Not yet implemented. pub fn show_trace(&self) { - unsafe { - BNWorkflowShowReport(self.handle.as_ptr(), b"trace\x00".as_ptr() as *const c_char) - } + unsafe { BNWorkflowShowReport(self.handle.as_ptr(), c"trace".as_ptr()) } } } From f8dcae5266435e04db801a99a11c35053fb612b4 Mon Sep 17 00:00:00 2001 From: Michael Krasnitski Date: Sun, 12 Jan 2025 15:10:37 -0500 Subject: [PATCH 2/2] Un-alias RegisterViewType --- rust/src/function.rs | 2 +- rust/src/hlil/instruction.rs | 5 +- rust/src/mlil/instruction.rs | 5 +- rust/src/variable.rs | 135 +++++++++++++++++++++++++++++------ 4 files changed, 117 insertions(+), 30 deletions(-) diff --git a/rust/src/function.rs b/rust/src/function.rs index 61f0df4b0..371e80d67 100644 --- a/rust/src/function.rs +++ b/rust/src/function.rs @@ -1320,7 +1320,7 @@ impl Function { // TODO: Adjust `BuiltinType`? let mut builtin_type = BuiltinType::BuiltinNone; let buffer = DataBuffer::from_raw(unsafe { - BNGetConstantData(self.handle, state, value, size, &mut builtin_type) + BNGetConstantData(self.handle, state.into(), value, size, &mut builtin_type) }); (buffer, builtin_type) } diff --git a/rust/src/hlil/instruction.rs b/rust/src/hlil/instruction.rs index 664faf3c3..7c6923e8b 100644 --- a/rust/src/hlil/instruction.rs +++ b/rust/src/hlil/instruction.rs @@ -751,10 +751,7 @@ impl HighLevelILInstruction { constant_data: ConstantData::new( self.function.get_function(), RegisterValue { - // TODO: Replace with a From for RegisterValueType. - // TODO: We might also want to change the type of `op.constant_data_kind` - // TODO: To RegisterValueType and do the conversion when creating instruction. - state: unsafe { std::mem::transmute(op.constant_data_kind) }, + state: op.constant_data_kind.into(), value: op.constant_data_value, offset: 0, size: op.size, diff --git a/rust/src/mlil/instruction.rs b/rust/src/mlil/instruction.rs index c55ec8cb8..68f2269d0 100644 --- a/rust/src/mlil/instruction.rs +++ b/rust/src/mlil/instruction.rs @@ -750,10 +750,7 @@ impl MediumLevelILInstruction { constant_data: ConstantData::new( self.function.get_function(), RegisterValue { - // TODO: Replace with a From for RegisterValueType. - // TODO: We might also want to change the type of `op.constant_data_kind` - // TODO: To RegisterValueType and do the conversion when creating instruction. - state: unsafe { std::mem::transmute(op.constant_data_kind) }, + state: op.constant_data_kind.into(), value: op.constant_data_value, offset: 0, size: op.size, diff --git a/rust/src/variable.rs b/rust/src/variable.rs index 5a88584db..3416c368e 100644 --- a/rust/src/variable.rs +++ b/rust/src/variable.rs @@ -15,7 +15,6 @@ use binaryninjacore_sys::{ use std::collections::HashSet; pub type VariableSourceType = BNVariableSourceType; -pub type RegisterValueType = BNRegisterValueType; #[derive(Debug, Clone, Hash, PartialEq, Eq)] pub struct DataVariable { @@ -514,7 +513,7 @@ impl RegisterValue { impl From for RegisterValue { fn from(value: BNRegisterValue) -> Self { Self { - state: value.state, + state: value.state.into(), value: value.value, offset: value.offset, size: value.size, @@ -525,7 +524,7 @@ impl From for RegisterValue { impl From for BNRegisterValue { fn from(value: RegisterValue) -> Self { Self { - state: value.state, + state: value.state.into(), value: value.value, offset: value.offset, size: value.size, @@ -533,6 +532,100 @@ impl From for BNRegisterValue { } } +#[derive(Clone, Copy, Debug, Hash, Eq, PartialEq)] +pub enum RegisterValueType { + UndeterminedValue = 0, + EntryValue = 1, + ConstantValue = 2, + ConstantPointerValue = 3, + ExternalPointerValue = 4, + StackFrameOffset = 5, + ReturnAddressValue = 6, + ImportedAddressValue = 7, + SignedRangeValue = 8, + UnsignedRangeValue = 9, + LookupTableValue = 10, + InSetOfValues = 11, + NotInSetOfValues = 12, + ConstantDataValue = 32768, + ConstantDataZeroExtendValue = 32769, + ConstantDataSignExtendValue = 32770, + ConstantDataAggregateValue = 32771, +} + +impl From for RegisterValueType { + fn from(value: u32) -> Self { + match value { + 0 => Self::UndeterminedValue, + 1 => Self::EntryValue, + 2 => Self::ConstantValue, + 3 => Self::ConstantPointerValue, + 4 => Self::ExternalPointerValue, + 5 => Self::StackFrameOffset, + 6 => Self::ReturnAddressValue, + 7 => Self::ImportedAddressValue, + 8 => Self::SignedRangeValue, + 9 => Self::UnsignedRangeValue, + 10 => Self::LookupTableValue, + 11 => Self::InSetOfValues, + 12 => Self::NotInSetOfValues, + 32768 => Self::ConstantDataValue, + 32769 => Self::ConstantDataZeroExtendValue, + 32770 => Self::ConstantDataSignExtendValue, + 32771 => Self::ConstantDataAggregateValue, + _ => unreachable!(), + } + } +} + +impl From for RegisterValueType { + fn from(value: BNRegisterValueType) -> Self { + match value { + BNRegisterValueType::UndeterminedValue => Self::UndeterminedValue, + BNRegisterValueType::EntryValue => Self::EntryValue, + BNRegisterValueType::ConstantValue => Self::ConstantValue, + BNRegisterValueType::ConstantPointerValue => Self::ConstantPointerValue, + BNRegisterValueType::ExternalPointerValue => Self::ExternalPointerValue, + BNRegisterValueType::StackFrameOffset => Self::StackFrameOffset, + BNRegisterValueType::ReturnAddressValue => Self::ReturnAddressValue, + BNRegisterValueType::ImportedAddressValue => Self::ImportedAddressValue, + BNRegisterValueType::SignedRangeValue => Self::SignedRangeValue, + BNRegisterValueType::UnsignedRangeValue => Self::UnsignedRangeValue, + BNRegisterValueType::LookupTableValue => Self::LookupTableValue, + BNRegisterValueType::InSetOfValues => Self::InSetOfValues, + BNRegisterValueType::NotInSetOfValues => Self::NotInSetOfValues, + BNRegisterValueType::ConstantDataValue => Self::ConstantDataValue, + BNRegisterValueType::ConstantDataZeroExtendValue => Self::ConstantDataZeroExtendValue, + BNRegisterValueType::ConstantDataSignExtendValue => Self::ConstantDataSignExtendValue, + BNRegisterValueType::ConstantDataAggregateValue => Self::ConstantDataAggregateValue, + } + } +} + +impl From for BNRegisterValueType { + fn from(value: RegisterValueType) -> Self { + match value { + RegisterValueType::UndeterminedValue => Self::UndeterminedValue, + RegisterValueType::EntryValue => Self::EntryValue, + RegisterValueType::ConstantValue => Self::ConstantValue, + RegisterValueType::ConstantPointerValue => Self::ConstantPointerValue, + RegisterValueType::ExternalPointerValue => Self::ExternalPointerValue, + RegisterValueType::StackFrameOffset => Self::StackFrameOffset, + RegisterValueType::ReturnAddressValue => Self::ReturnAddressValue, + RegisterValueType::ImportedAddressValue => Self::ImportedAddressValue, + RegisterValueType::SignedRangeValue => Self::SignedRangeValue, + RegisterValueType::UnsignedRangeValue => Self::UnsignedRangeValue, + RegisterValueType::LookupTableValue => Self::LookupTableValue, + RegisterValueType::InSetOfValues => Self::InSetOfValues, + RegisterValueType::NotInSetOfValues => Self::NotInSetOfValues, + RegisterValueType::ConstantDataValue => Self::ConstantDataValue, + RegisterValueType::ConstantDataZeroExtendValue => Self::ConstantDataZeroExtendValue, + RegisterValueType::ConstantDataSignExtendValue => Self::ConstantDataSignExtendValue, + RegisterValueType::ConstantDataAggregateValue => Self::ConstantDataAggregateValue, + } + } +} + #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] pub struct ValueRange { pub start: T, @@ -703,64 +796,64 @@ impl PossibleValueSet { impl From for PossibleValueSet { fn from(value: BNPossibleValueSet) -> Self { match value.state { - RegisterValueType::UndeterminedValue => Self::UndeterminedValue, - RegisterValueType::EntryValue => Self::EntryValue { reg: value.value }, - RegisterValueType::ConstantValue => Self::ConstantValue { value: value.value }, - RegisterValueType::ConstantPointerValue => { + BNRegisterValueType::UndeterminedValue => Self::UndeterminedValue, + BNRegisterValueType::EntryValue => Self::EntryValue { reg: value.value }, + BNRegisterValueType::ConstantValue => Self::ConstantValue { value: value.value }, + BNRegisterValueType::ConstantPointerValue => { Self::ConstantPointerValue { value: value.value } } - RegisterValueType::ExternalPointerValue => Self::ExternalPointerValue { + BNRegisterValueType::ExternalPointerValue => Self::ExternalPointerValue { value: value.value, offset: value.offset, }, - RegisterValueType::StackFrameOffset => Self::StackFrameOffset { value: value.value }, - RegisterValueType::ReturnAddressValue => Self::ReturnAddressValue, - RegisterValueType::ImportedAddressValue => Self::ImportedAddressValue, - RegisterValueType::SignedRangeValue => { + BNRegisterValueType::StackFrameOffset => Self::StackFrameOffset { value: value.value }, + BNRegisterValueType::ReturnAddressValue => Self::ReturnAddressValue, + BNRegisterValueType::ImportedAddressValue => Self::ImportedAddressValue, + BNRegisterValueType::SignedRangeValue => { let raw_ranges = unsafe { std::slice::from_raw_parts(value.ranges, value.count) }; Self::SignedRangeValue { value: value.value, ranges: raw_ranges.iter().map(|&r| r.into()).collect(), } } - RegisterValueType::UnsignedRangeValue => { + BNRegisterValueType::UnsignedRangeValue => { let raw_ranges = unsafe { std::slice::from_raw_parts(value.ranges, value.count) }; Self::UnsignedRangeValue { value: value.value, ranges: raw_ranges.iter().map(|&r| r.into()).collect(), } } - RegisterValueType::LookupTableValue => { + BNRegisterValueType::LookupTableValue => { let raw_entries = unsafe { std::slice::from_raw_parts(value.table, value.count) }; Self::LookupTableValue { table: raw_entries.iter().map(|&r| r.into()).collect(), } } - RegisterValueType::InSetOfValues => { + BNRegisterValueType::InSetOfValues => { let raw_values = unsafe { std::slice::from_raw_parts(value.valueSet, value.count) }; Self::InSetOfValues { values: raw_values.iter().copied().collect(), } } - RegisterValueType::NotInSetOfValues => { + BNRegisterValueType::NotInSetOfValues => { let raw_values = unsafe { std::slice::from_raw_parts(value.valueSet, value.count) }; Self::NotInSetOfValues { values: raw_values.iter().copied().collect(), } } - RegisterValueType::ConstantDataValue => Self::ConstantDataValue { + BNRegisterValueType::ConstantDataValue => Self::ConstantDataValue { value: value.value, size: value.size, }, - RegisterValueType::ConstantDataZeroExtendValue => Self::ConstantDataZeroExtendValue { + BNRegisterValueType::ConstantDataZeroExtendValue => Self::ConstantDataZeroExtendValue { value: value.value, size: value.size, }, - RegisterValueType::ConstantDataSignExtendValue => Self::ConstantDataSignExtendValue { + BNRegisterValueType::ConstantDataSignExtendValue => Self::ConstantDataSignExtendValue { value: value.value, size: value.size, }, - RegisterValueType::ConstantDataAggregateValue => Self::ConstantDataAggregateValue { + BNRegisterValueType::ConstantDataAggregateValue => Self::ConstantDataAggregateValue { value: value.value, size: value.size, }, @@ -772,7 +865,7 @@ impl From for PossibleValueSet { impl From for BNPossibleValueSet { fn from(value: PossibleValueSet) -> Self { let mut raw = BNPossibleValueSet { - state: value.value_type(), + state: value.value_type().into(), ..Default::default() }; match value {