From 8d621c51b2797fda7b1dc22243dde611cfc04f68 Mon Sep 17 00:00:00 2001 From: Rusty Wagner Date: Tue, 23 Dec 2025 13:12:02 -0700 Subject: Refactor calling conventions to support correct representation of structures --- rust/src/function.rs | 121 ++++++++++++++++++++++++++++++++++----------------- 1 file changed, 80 insertions(+), 41 deletions(-) (limited to 'rust/src/function.rs') diff --git a/rust/src/function.rs b/rust/src/function.rs index 320382de..6a62946f 100644 --- a/rust/src/function.rs +++ b/rust/src/function.rs @@ -21,6 +21,7 @@ use crate::{ calling_convention::CoreCallingConvention, component::Component, disassembly::{DisassemblySettings, DisassemblyTextLine}, + ffi::slice_from_raw_parts, flowgraph::FlowGraph, medium_level_il::FunctionGraphType, platform::Platform, @@ -28,7 +29,7 @@ use crate::{ string::*, symbol::{Binding, Symbol}, tags::{Tag, TagReference, TagType}, - types::{IntegerDisplayType, QualifiedName, Type}, + types::{IntegerDisplayType, QualifiedName, ReturnValue, Type, ValueLocation}, }; use crate::{data_buffer::DataBuffer, disassembly::InstructionTextToken, rc::*}; pub use binaryninjacore_sys::BNAnalysisSkipReason as AnalysisSkipReason; @@ -657,6 +658,11 @@ impl Function { Conf::>::from_owned_raw(raw_return_type) } + pub fn return_value(&self) -> ReturnValue { + let raw_return_value = unsafe { BNGetFunctionReturnValue(self.handle) }; + ReturnValue::from_owned_core_raw(raw_return_value) + } + pub fn set_auto_return_type<'a, C>(&self, return_type: C) where C: Into>, @@ -665,6 +671,22 @@ impl Function { unsafe { BNSetAutoFunctionReturnType(self.handle, &mut raw_return_type) } } + pub fn set_auto_is_return_value_default_location(&self, is_default: bool) { + unsafe { BNSetAutoIsFunctionReturnValueDefaultLocation(self.handle, is_default) } + } + + pub fn set_auto_return_value_location(&self, location: impl Into>) { + let mut raw_location = Conf::::into_rust_raw(location.into()); + unsafe { BNSetAutoFunctionReturnValueLocation(self.handle, &mut raw_location) }; + Conf::::free_rust_raw(raw_location); + } + + pub fn set_auto_return_value(&self, return_value: impl Into) { + let mut raw_return_value = ReturnValue::into_rust_raw(return_value.into()); + unsafe { BNSetAutoFunctionReturnValue(self.handle, &mut raw_return_value) } + ReturnValue::free_rust_raw(raw_return_value); + } + pub fn set_user_return_type<'a, C>(&self, return_type: C) where C: Into>, @@ -673,6 +695,22 @@ impl Function { unsafe { BNSetUserFunctionReturnType(self.handle, &mut raw_return_type) } } + pub fn set_user_is_return_value_default_location(&self, is_default: bool) { + unsafe { BNSetUserIsFunctionReturnValueDefaultLocation(self.handle, is_default) } + } + + pub fn set_user_return_value_location(&self, location: impl Into>) { + let mut raw_location = Conf::::into_rust_raw(location.into()); + unsafe { BNSetUserFunctionReturnValueLocation(self.handle, &mut raw_location) }; + Conf::::free_rust_raw(raw_location); + } + + pub fn set_user_return_value(&self, return_value: impl Into) { + let mut raw_return_value = ReturnValue::into_rust_raw(return_value.into()); + unsafe { BNSetUserFunctionReturnValue(self.handle, &mut raw_return_value) } + ReturnValue::free_rust_raw(raw_return_value); + } + pub fn function_type(&self) -> Ref { unsafe { Type::ref_from_raw(BNGetFunctionType(self.handle)) } } @@ -1017,38 +1055,65 @@ impl Function { } } - pub fn set_user_parameter_variables(&self, values: I, confidence: u8) + pub fn parameter_locations(&self) -> Conf> { + unsafe { + let mut raw_locations = BNGetFunctionParameterLocations(self.handle); + let raw_location_list = + slice_from_raw_parts(raw_locations.locations, raw_locations.count); + let locations: Vec = raw_location_list + .iter() + .map(ValueLocation::from_raw) + .collect(); + let confidence = raw_locations.confidence; + BNFreeParameterLocations(&mut raw_locations); + Conf::new(locations, confidence) + } + } + + pub fn set_user_parameter_locations(&self, values: I, confidence: u8) where - I: IntoIterator, + I: IntoIterator, { - let vars: Vec = values.into_iter().map(Into::into).collect(); + let locations: Vec = values + .into_iter() + .map(|location| ValueLocation::into_rust_raw(&location.into())) + .collect(); unsafe { - BNSetUserFunctionParameterVariables( + BNSetUserFunctionParameterLocations( self.handle, - &mut BNParameterVariablesWithConfidence { - vars: vars.as_ptr() as *mut _, - count: vars.len(), + &mut BNValueLocationListWithConfidence { + locations: locations.as_ptr() as *mut _, + count: locations.len(), confidence, }, ) } + locations + .into_iter() + .for_each(|location| ValueLocation::free_rust_raw(location.into())); } - pub fn set_auto_parameter_variables(&self, values: I, confidence: u8) + pub fn set_auto_parameter_locations(&self, values: I, confidence: u8) where - I: IntoIterator, + I: IntoIterator, { - let vars: Vec = values.into_iter().map(Into::into).collect(); + let locations: Vec = values + .into_iter() + .map(|location| ValueLocation::into_rust_raw(&location.into())) + .collect(); unsafe { - BNSetAutoFunctionParameterVariables( + BNSetAutoFunctionParameterLocations( self.handle, - &mut BNParameterVariablesWithConfidence { - vars: vars.as_ptr() as *mut _, - count: vars.len(), + &mut BNValueLocationListWithConfidence { + locations: locations.as_ptr() as *mut _, + count: locations.len(), confidence, }, ) } + locations + .into_iter() + .for_each(|location| ValueLocation::free_rust_raw(location.into())); } pub fn parameter_at( @@ -2536,32 +2601,6 @@ impl Function { Conf::new(regs, result.confidence) } - pub fn set_user_return_registers(&self, values: I, confidence: u8) - where - I: IntoIterator, - { - let mut regs: Box<[u32]> = values.into_iter().map(|reg| reg.id().0).collect(); - let mut regs = BNRegisterSetWithConfidence { - regs: regs.as_mut_ptr(), - count: regs.len(), - confidence, - }; - unsafe { BNSetUserFunctionReturnRegisters(self.handle, &mut regs) } - } - - pub fn set_auto_return_registers(&self, values: I, confidence: u8) - where - I: IntoIterator, - { - let mut regs: Box<[u32]> = values.into_iter().map(|reg| reg.id().0).collect(); - let mut regs = BNRegisterSetWithConfidence { - regs: regs.as_mut_ptr(), - count: regs.len(), - confidence, - }; - unsafe { BNSetAutoFunctionReturnRegisters(self.handle, &mut regs) } - } - /// Flow graph of unresolved stack adjustments pub fn unresolved_stack_adjustment_graph(&self) -> Option> { let graph = unsafe { BNGetUnresolvedStackAdjustmentGraph(self.handle) }; -- cgit v1.3.1