@@ -12,7 +12,8 @@ use binaryninjacore_sys::{
1212 BNFreeVariableList , BNFreeVariableNameAndTypeList , BNFromVariableIdentifier ,
1313 BNIndirectBranchInfo , BNLookupTableEntry , BNMergedVariable , BNPossibleValueSet ,
1414 BNRegisterValue , BNRegisterValueType , BNStackVariableReference , BNToVariableIdentifier ,
15- BNUserVariableValue , BNValueRange , BNVariable , BNVariableNameAndType , BNVariableSourceType ,
15+ BNTypeWithConfidence , BNUserVariableValue , BNValueRange , BNVariable , BNVariableNameAndType ,
16+ BNVariableSourceType ,
1617} ;
1718use std:: collections:: HashSet ;
1819
@@ -238,7 +239,9 @@ impl UserVariableValue {
238239 var : value. variable . into ( ) ,
239240 defSite : value. def_site . into ( ) ,
240241 after : value. after ,
241- value : PossibleValueSet :: into_raw ( value. value ) ,
242+ // TODO: This returns a rust allocated value, we should at some point provide allocators for the
243+ // TODO: internal state of BNPossibleValueSet, so we can store rust created object in core objects.
244+ value : PossibleValueSet :: into_rust_raw ( value. value ) ,
242245 }
243246 }
244247}
@@ -590,6 +593,28 @@ impl LookupTableEntry {
590593 to : value. toValue ,
591594 }
592595 }
596+
597+ pub ( crate ) fn from_owned_raw ( value : BNLookupTableEntry ) -> Self {
598+ let owned = Self :: from_raw ( & value) ;
599+ Self :: free_raw ( value) ;
600+ owned
601+ }
602+
603+ pub ( crate ) fn into_raw ( value : Self ) -> BNLookupTableEntry {
604+ let from_values: Box < [ i64 ] > = value. from . into_iter ( ) . collect ( ) ;
605+ let from_values_len = from_values. len ( ) ;
606+ BNLookupTableEntry {
607+ // Freed in [`Self::free_raw`]
608+ fromValues : Box :: leak ( from_values) . as_mut_ptr ( ) ,
609+ fromCount : from_values_len,
610+ toValue : value. to ,
611+ }
612+ }
613+
614+ pub ( crate ) fn free_raw ( value : BNLookupTableEntry ) {
615+ let raw_from = unsafe { std:: slice:: from_raw_parts_mut ( value. fromValues , value. fromCount ) } ;
616+ let boxed_from = unsafe { Box :: from_raw ( raw_from) } ;
617+ }
593618}
594619
595620#[ derive( Debug , Clone , PartialEq , Eq ) ]
@@ -724,15 +749,14 @@ impl PossibleValueSet {
724749 }
725750 }
726751
727- /// Take ownership over an "owned" core allocated value. Do not call this for a rust allocated value.
728- pub ( crate ) fn from_owned_raw ( mut value : BNPossibleValueSet ) -> Self {
752+ /// Take ownership over an "owned" ** core allocated** value. Do not call this for a rust allocated value.
753+ pub ( crate ) fn from_owned_core_raw ( mut value : BNPossibleValueSet ) -> Self {
729754 let owned = Self :: from_raw ( & value) ;
730- // TODO: This entire function is a little wonky.
731- Self :: free_raw ( & mut value) ;
755+ Self :: free_core_raw ( & mut value) ;
732756 owned
733757 }
734758
735- pub ( crate ) fn into_raw ( value : Self ) -> BNPossibleValueSet {
759+ pub ( crate ) fn into_rust_raw ( value : Self ) -> BNPossibleValueSet {
736760 let mut raw = BNPossibleValueSet {
737761 state : value. value_type ( ) ,
738762 ..Default :: default ( )
@@ -758,31 +782,39 @@ impl PossibleValueSet {
758782 PossibleValueSet :: ReturnAddressValue => { }
759783 PossibleValueSet :: ImportedAddressValue => { }
760784 PossibleValueSet :: SignedRangeValue { value, ranges } => {
785+ let boxed_raw_ranges: Box < [ BNValueRange ] > =
786+ ranges. into_iter ( ) . map ( BNValueRange :: from) . collect ( ) ;
761787 raw. value = value;
762- // TODO: raw.ranges
763- // TODO: requires core allocation and freeing .
764- // TODO: See `BNFreePossibleValueSet` for why this sucks.
788+ raw . count = boxed_raw_ranges . len ( ) ;
789+ // NOTE: We are allocating this in rust, meaning core MUST NOT free this .
790+ raw . ranges = Box :: leak ( boxed_raw_ranges ) . as_mut_ptr ( ) ;
765791 }
766792 PossibleValueSet :: UnsignedRangeValue { value, ranges } => {
793+ let boxed_raw_ranges: Box < [ BNValueRange ] > =
794+ ranges. into_iter ( ) . map ( BNValueRange :: from) . collect ( ) ;
767795 raw. value = value;
768- // TODO: raw.ranges
769- // TODO: requires core allocation and freeing .
770- // TODO: See `BNFreePossibleValueSet` for why this sucks.
796+ raw . count = boxed_raw_ranges . len ( ) ;
797+ // NOTE: We are allocating this in rust, meaning core MUST NOT free this .
798+ raw . ranges = Box :: leak ( boxed_raw_ranges ) . as_mut_ptr ( ) ;
771799 }
772800 PossibleValueSet :: LookupTableValue { table } => {
773- // TODO: raw.table
774- // TODO: requires core allocation and freeing.
775- // TODO: See `BNFreePossibleValueSet` for why this sucks.
801+ let boxed_raw_entries: Box < [ BNLookupTableEntry ] > =
802+ table. into_iter ( ) . map ( LookupTableEntry :: into_raw) . collect ( ) ;
803+ raw. count = boxed_raw_entries. len ( ) ;
804+ // NOTE: We are allocating this in rust, meaning core MUST NOT free this.
805+ raw. table = Box :: leak ( boxed_raw_entries) . as_mut_ptr ( ) ;
776806 }
777807 PossibleValueSet :: InSetOfValues { values } => {
778- // TODO: raw.valueSet
779- // TODO: requires core allocation and freeing.
780- // TODO: See `BNFreePossibleValueSet` for why this sucks.
808+ let boxed_raw_values: Box < [ i64 ] > = values. into_iter ( ) . collect ( ) ;
809+ raw. count = boxed_raw_values. len ( ) ;
810+ // NOTE: We are allocating this in rust, meaning core MUST NOT free this.
811+ raw. valueSet = Box :: leak ( boxed_raw_values) . as_mut_ptr ( ) ;
781812 }
782813 PossibleValueSet :: NotInSetOfValues { values } => {
783- // TODO: raw.valueSet
784- // TODO: requires core allocation and freeing.
785- // TODO: See `BNFreePossibleValueSet` for why this sucks.
814+ let boxed_raw_values: Box < [ i64 ] > = values. into_iter ( ) . collect ( ) ;
815+ raw. count = boxed_raw_values. len ( ) ;
816+ // NOTE: We are allocating this in rust, meaning core MUST NOT free this.
817+ raw. valueSet = Box :: leak ( boxed_raw_values) . as_mut_ptr ( ) ;
786818 }
787819 PossibleValueSet :: ConstantDataValue { value, size } => {
788820 raw. value = value;
@@ -804,14 +836,28 @@ impl PossibleValueSet {
804836 raw
805837 }
806838
807- /// Free a CORE ALLOCATED possible value set. Do not use this with [Self::into_raw ] values.
808- pub ( crate ) fn free_raw ( value : & mut BNPossibleValueSet ) {
839+ /// Free a CORE ALLOCATED possible value set. Do not use this with [Self::into_rust_raw ] values.
840+ pub ( crate ) fn free_core_raw ( value : & mut BNPossibleValueSet ) {
809841 unsafe { BNFreePossibleValueSet ( value) }
810842 }
811843
812844 /// Free a RUST ALLOCATED possible value set. Do not use this with CORE ALLOCATED values.
813- pub ( crate ) fn free_owned_raw ( value : BNPossibleValueSet ) {
814- // TODO: Once we fill out allocation of the possible value set then we should fill this out as well.
845+ pub ( crate ) fn free_rust_raw ( value : BNPossibleValueSet ) {
846+ // Free the range list
847+ if !value. ranges . is_null ( ) {
848+ let raw_ranges = unsafe { std:: slice:: from_raw_parts_mut ( value. ranges , value. count ) } ;
849+ let boxed_ranges = unsafe { Box :: from_raw ( raw_ranges) } ;
850+ }
851+
852+ if !value. table . is_null ( ) {
853+ unsafe { LookupTableEntry :: free_raw ( * value. table ) } ;
854+ }
855+
856+ if !value. valueSet . is_null ( ) {
857+ let raw_value_set =
858+ unsafe { std:: slice:: from_raw_parts_mut ( value. valueSet , value. count ) } ;
859+ let boxed_value_set = unsafe { Box :: from_raw ( raw_value_set) } ;
860+ }
815861 }
816862
817863 pub fn value_type ( & self ) -> RegisterValueType {
0 commit comments