diff options
| author | Glenn Smith <glenn@vector35.com> | 2023-07-06 13:40:52 -0400 |
|---|---|---|
| committer | Glenn Smith <glenn@vector35.com> | 2023-07-07 17:42:18 -0400 |
| commit | 7598688466960427890036590239565364310171 (patch) | |
| tree | 1c8680da5ef239926c9dbd78345c4083aed95aba | |
| parent | 94e476e947cf4cb0734fbd0563286e8443c75b96 (diff) | |
Expose function "pure" flag to api and typesystem
| -rw-r--r-- | binaryninjaapi.h | 22 | ||||
| -rw-r--r-- | binaryninjacore.h | 10 | ||||
| -rw-r--r-- | function.cpp | 25 | ||||
| -rw-r--r-- | python/debuginfo.py | 2 | ||||
| -rw-r--r-- | python/function.py | 25 | ||||
| -rw-r--r-- | python/types.py | 30 | ||||
| -rw-r--r-- | rust/src/types.rs | 28 | ||||
| -rw-r--r-- | type.cpp | 54 |
8 files changed, 181 insertions, 15 deletions
diff --git a/binaryninjaapi.h b/binaryninjaapi.h index a06d4bf7..ef47dc23 100644 --- a/binaryninjaapi.h +++ b/binaryninjaapi.h @@ -7272,6 +7272,12 @@ namespace BinaryNinja { */ Confidence<bool> CanReturn() const; + /*! For Function Types, whether a function is pure (has no observable side-effects) + + \return Whether the function is pure + */ + Confidence<bool> IsPure() const; + /*! For Structure Types, the underlying Structure \return The underlying structure @@ -7472,7 +7478,8 @@ namespace BinaryNinja { const Confidence<int64_t>& stackAdjust, const std::map<uint32_t, Confidence<int32_t>>& regStackAdjust = std::map<uint32_t, Confidence<int32_t>>(), const Confidence<std::vector<uint32_t>>& returnRegs = Confidence<std::vector<uint32_t>>(std::vector<uint32_t>(), 0), - BNNameType ft = NoNameType); + BNNameType ft = NoNameType, + const Confidence<bool>& pure = Confidence<bool>(false, 0)); static std::string GenerateAutoTypeId(const std::string& source, const QualifiedName& name); static std::string GenerateAutoDemangledTypeId(const QualifiedName& name); @@ -7661,6 +7668,7 @@ namespace BinaryNinja { std::vector<FunctionParameter> GetParameters() const; Confidence<bool> HasVariableArguments() const; Confidence<bool> CanReturn() const; + Confidence<bool> IsPure() const; Ref<Structure> GetStructure() const; Ref<Enumeration> GetEnumeration() const; Ref<NamedTypeReference> GetNamedTypeReference() const; @@ -7683,6 +7691,7 @@ namespace BinaryNinja { TypeBuilder& SetOffset(uint64_t offset); TypeBuilder& SetFunctionCanReturn(const Confidence<bool>& canReturn); + TypeBuilder& SetPure(const Confidence<bool>& pure); TypeBuilder& SetParameters(const std::vector<FunctionParameter>& params); std::string GetString(Platform* platform = nullptr) const; @@ -7736,7 +7745,8 @@ namespace BinaryNinja { const Confidence<int64_t>& stackAdjust, const std::map<uint32_t, Confidence<int32_t>>& regStackAdjust = std::map<uint32_t, Confidence<int32_t>>(), const Confidence<std::vector<uint32_t>>& returnRegs = Confidence<std::vector<uint32_t>>(std::vector<uint32_t>(), 0), - BNNameType ft = NoNameType); + BNNameType ft = NoNameType, + const Confidence<bool>& pure = Confidence<bool>(false, 0)); bool IsReferenceOfType(BNNamedTypeReferenceClass refType); bool IsStructReference() { return IsReferenceOfType(StructNamedTypeClass); } @@ -8959,6 +8969,12 @@ namespace BinaryNinja { */ Confidence<bool> CanReturn() const; + /*! Whether this function is pure + + \return Whether this function is pure + */ + Confidence<bool> IsPure() const; + /*! Whether this function has an explicitly defined type \return Whether this function has an explicitly defined type @@ -9233,6 +9249,7 @@ namespace BinaryNinja { void SetAutoParameterVariables(const Confidence<std::vector<Variable>>& vars); void SetAutoHasVariableArguments(const Confidence<bool>& varArgs); void SetAutoCanReturn(const Confidence<bool>& returns); + void SetAutoPure(const Confidence<bool>& pure); void SetAutoStackAdjustment(const Confidence<int64_t>& stackAdjust); void SetAutoRegisterStackAdjustments(const std::map<uint32_t, Confidence<int32_t>>& regStackAdjust); void SetAutoClobberedRegisters(const Confidence<std::set<uint32_t>>& clobbered); @@ -9244,6 +9261,7 @@ namespace BinaryNinja { void SetParameterVariables(const Confidence<std::vector<Variable>>& vars); void SetHasVariableArguments(const Confidence<bool>& varArgs); void SetCanReturn(const Confidence<bool>& returns); + void SetPure(const Confidence<bool>& pure); void SetStackAdjustment(const Confidence<int64_t>& stackAdjust); void SetRegisterStackAdjustments(const std::map<uint32_t, Confidence<int32_t>>& regStackAdjust); void SetClobberedRegisters(const Confidence<std::set<uint32_t>>& clobbered); diff --git a/binaryninjacore.h b/binaryninjacore.h index 485d7860..dd5840fd 100644 --- a/binaryninjacore.h +++ b/binaryninjacore.h @@ -3792,6 +3792,7 @@ extern "C" BINARYNINJACOREAPI bool BNWasFunctionAutomaticallyDiscovered(BNFunction* func); BINARYNINJACOREAPI bool BNFunctionHasUserAnnotations(BNFunction* func); BINARYNINJACOREAPI BNBoolWithConfidence BNCanFunctionReturn(BNFunction* func); + BINARYNINJACOREAPI BNBoolWithConfidence BNIsFunctionPure(BNFunction* func); BINARYNINJACOREAPI void BNSetFunctionAutoType(BNFunction* func, BNType* type); BINARYNINJACOREAPI void BNSetFunctionUserType(BNFunction* func, BNType* type); BINARYNINJACOREAPI bool BNFunctionHasUserType(BNFunction* func); @@ -3913,6 +3914,7 @@ extern "C" BNFunction* func, BNParameterVariablesWithConfidence* vars); BINARYNINJACOREAPI void BNSetAutoFunctionHasVariableArguments(BNFunction* func, BNBoolWithConfidence* varArgs); BINARYNINJACOREAPI void BNSetAutoFunctionCanReturn(BNFunction* func, BNBoolWithConfidence* returns); + BINARYNINJACOREAPI void BNSetAutoFunctionPure(BNFunction* func, BNBoolWithConfidence* pure); BINARYNINJACOREAPI void BNSetAutoFunctionStackAdjustment(BNFunction* func, BNOffsetWithConfidence* stackAdjust); BINARYNINJACOREAPI void BNSetAutoFunctionRegisterStackAdjustments( BNFunction* func, BNRegisterStackAdjustment* adjustments, size_t count); @@ -3926,6 +3928,7 @@ extern "C" BNFunction* func, BNParameterVariablesWithConfidence* vars); BINARYNINJACOREAPI void BNSetUserFunctionHasVariableArguments(BNFunction* func, BNBoolWithConfidence* varArgs); BINARYNINJACOREAPI void BNSetUserFunctionCanReturn(BNFunction* func, BNBoolWithConfidence* returns); + BINARYNINJACOREAPI void BNSetUserFunctionPure(BNFunction* func, BNBoolWithConfidence* pure); BINARYNINJACOREAPI void BNSetUserFunctionStackAdjustment(BNFunction* func, BNOffsetWithConfidence* stackAdjust); BINARYNINJACOREAPI void BNSetUserFunctionRegisterStackAdjustments( BNFunction* func, BNRegisterStackAdjustment* adjustments, size_t count); @@ -5331,7 +5334,7 @@ extern "C" BNFunctionParameter* params, size_t paramCount, BNBoolWithConfidence* varArg, BNBoolWithConfidence* canReturn, BNOffsetWithConfidence* stackAdjust, uint32_t* regStackAdjustRegs, BNOffsetWithConfidence* regStackAdjustValues, size_t regStackAdjustCount, - BNRegisterSetWithConfidence* returnRegs, BNNameType ft); + BNRegisterSetWithConfidence* returnRegs, BNNameType ft, BNBoolWithConfidence* pure); BINARYNINJACOREAPI BNType* BNNewTypeReference(BNType* type); BINARYNINJACOREAPI BNType* BNDuplicateType(BNType* type); BINARYNINJACOREAPI char* BNGetTypeAndName(BNType* type, BNQualifiedName* name, BNTokenEscapingType escaping); @@ -5361,7 +5364,7 @@ extern "C" BNFunctionParameter* params, size_t paramCount, BNBoolWithConfidence* varArg, BNBoolWithConfidence* canReturn, BNOffsetWithConfidence* stackAdjust, uint32_t* regStackAdjustRegs, BNOffsetWithConfidence* regStackAdjustValues, size_t regStackAdjustCount, - BNRegisterSetWithConfidence* returnRegs, BNNameType ft); + BNRegisterSetWithConfidence* returnRegs, BNNameType ft, BNBoolWithConfidence* pure); BINARYNINJACOREAPI BNType* BNFinalizeTypeBuilder(BNTypeBuilder* type); BINARYNINJACOREAPI BNTypeBuilder* BNDuplicateTypeBuilder(BNTypeBuilder* type); BINARYNINJACOREAPI char* BNGetTypeBuilderTypeAndName(BNTypeBuilder* type, BNQualifiedName* name); @@ -5383,6 +5386,7 @@ extern "C" BINARYNINJACOREAPI void BNFreeTypeParameterList(BNFunctionParameter* types, size_t count); BINARYNINJACOREAPI BNBoolWithConfidence BNTypeHasVariableArguments(BNType* type); BINARYNINJACOREAPI BNBoolWithConfidence BNFunctionTypeCanReturn(BNType* type); + BINARYNINJACOREAPI BNBoolWithConfidence BNIsTypePure(BNType* type); BINARYNINJACOREAPI BNStructure* BNGetTypeStructure(BNType* type); BINARYNINJACOREAPI BNEnumeration* BNGetTypeEnumeration(BNType* type); BINARYNINJACOREAPI BNNamedTypeReference* BNGetTypeNamedTypeReference(BNType* type); @@ -5432,6 +5436,7 @@ extern "C" BINARYNINJACOREAPI BNFunctionParameter* BNGetTypeBuilderParameters(BNTypeBuilder* type, size_t* count); BINARYNINJACOREAPI BNBoolWithConfidence BNTypeBuilderHasVariableArguments(BNTypeBuilder* type); BINARYNINJACOREAPI BNBoolWithConfidence BNFunctionTypeBuilderCanReturn(BNTypeBuilder* type); + BINARYNINJACOREAPI BNBoolWithConfidence BNIsTypeBuilderPure(BNTypeBuilder* type); BINARYNINJACOREAPI BNStructure* BNGetTypeBuilderStructure(BNTypeBuilder* type); BINARYNINJACOREAPI BNEnumeration* BNGetTypeBuilderEnumeration(BNTypeBuilder* type); BINARYNINJACOREAPI BNNamedTypeReference* BNGetTypeBuilderNamedTypeReference(BNTypeBuilder* type); @@ -5440,6 +5445,7 @@ extern "C" BINARYNINJACOREAPI uint64_t BNGetTypeBuilderOffset(BNTypeBuilder* type); BINARYNINJACOREAPI void BNSetTypeBuilderOffset(BNTypeBuilder* type, uint64_t offset); BINARYNINJACOREAPI void BNSetFunctionTypeBuilderCanReturn(BNTypeBuilder* type, BNBoolWithConfidence* canReturn); + BINARYNINJACOREAPI void BNSetTypeBuilderPure(BNTypeBuilder* type, BNBoolWithConfidence* pure); BINARYNINJACOREAPI void BNSetFunctionTypeBuilderParameters( BNTypeBuilder* type, BNFunctionParameter* params, size_t paramCount); BINARYNINJACOREAPI void BNTypeBuilderSetConst(BNTypeBuilder* type, BNBoolWithConfidence* cnst); diff --git a/function.cpp b/function.cpp index c9314968..298148b6 100644 --- a/function.cpp +++ b/function.cpp @@ -233,6 +233,13 @@ Confidence<bool> Function::CanReturn() const } +Confidence<bool> Function::IsPure() const +{ + BNBoolWithConfidence bc = BNIsFunctionPure(m_object); + return Confidence<bool>(bc.value, bc.confidence); +} + + bool Function::HasExplicitlyDefinedType() const { return BNFunctionHasExplicitlyDefinedType(m_object); @@ -1005,6 +1012,15 @@ void Function::SetAutoCanReturn(const Confidence<bool>& returns) } +void Function::SetAutoPure(const Confidence<bool>& pure) +{ + BNBoolWithConfidence bc; + bc.value = pure.GetValue(); + bc.confidence = pure.GetConfidence(); + BNSetAutoFunctionPure(m_object, &bc); +} + + void Function::SetAutoStackAdjustment(const Confidence<int64_t>& stackAdjust) { BNOffsetWithConfidence oc; @@ -1125,6 +1141,15 @@ void Function::SetCanReturn(const Confidence<bool>& returns) } +void Function::SetPure(const Confidence<bool>& pure) +{ + BNBoolWithConfidence bc; + bc.value = pure.GetValue(); + bc.confidence = pure.GetConfidence(); + BNSetUserFunctionPure(m_object, &bc); +} + + void Function::SetStackAdjustment(const Confidence<int64_t>& stackAdjust) { BNOffsetWithConfidence oc; diff --git a/python/debuginfo.py b/python/debuginfo.py index 6e179ab8..d95657c6 100644 --- a/python/debuginfo.py +++ b/python/debuginfo.py @@ -325,7 +325,7 @@ class DebugInfo(object): for i in range(0, count.value): if functions[i].type: - function_type = _types.Type(core.BNNewTypeReference(functions[i].type)) + function_type = _types.Type.create(core.BNNewTypeReference(functions[i].type)) else: function_type = None diff --git a/python/function.py b/python/function.py index 42e5ea44..97655e41 100644 --- a/python/function.py +++ b/python/function.py @@ -546,6 +546,22 @@ class Function: core.BNSetUserFunctionCanReturn(self.handle, bc) @property + def is_pure(self) -> 'types.BoolWithConfidence': + """Whether function is pure""" + result = core.BNIsFunctionPure(self.handle) + return types.BoolWithConfidence(result.value, confidence=result.confidence) + + @is_pure.setter + def is_pure(self, value: 'types.BoolWithConfidence') -> None: + bc = core.BNBoolWithConfidence() + bc.value = bool(value) + if hasattr(value, 'confidence'): + bc.confidence = value.confidence + else: + bc.confidence = core.max_confidence + core.BNSetUserFunctionPure(self.handle, bc) + + @property @deprecation.deprecated(deprecated_in="3.4.4049", details="Use Function.has_explicitly_defined_type instead.") def explicitly_defined_type(self) -> bool: """Whether function has explicitly defined types (read-only)""" @@ -2592,6 +2608,15 @@ class Function: bc.confidence = core.max_confidence core.BNSetAutoFunctionCanReturn(self.handle, bc) + def set_auto_pure(self, value: Union[bool, 'types.BoolWithConfidence']) -> None: + bc = core.BNBoolWithConfidence() + bc.value = bool(value) + if isinstance(value, types.BoolWithConfidence): + bc.confidence = value.confidence + else: + bc.confidence = core.max_confidence + core.BNSetAutoFunctionPure(self.handle, bc) + def set_auto_stack_adjustment(self, value: Union[int, 'types.OffsetWithConfidence']) -> None: oc = core.BNOffsetWithConfidence() oc.value = int(value) diff --git a/python/types.py b/python/types.py index 52426474..94b90527 100644 --- a/python/types.py +++ b/python/types.py @@ -981,7 +981,8 @@ class FunctionBuilder(TypeBuilder): platform: Optional['_platform.Platform'] = None, confidence: int = core.max_confidence, can_return: Optional[BoolWithConfidence] = None, reg_stack_adjust: Optional[Dict['architecture.RegisterName', OffsetWithConfidenceType]] = None, return_regs: Optional[Union['RegisterSet', List['architecture.RegisterType']]] = None, - name_type: 'NameType' = NameType.NoNameType + name_type: 'NameType' = NameType.NoNameType, + pure: Optional[BoolWithConfidence] = None ) -> 'FunctionBuilder': param_buf = FunctionBuilder._to_core_struct(params) if return_type is None: @@ -1029,6 +1030,11 @@ class FunctionBuilder(TypeBuilder): else: can_return_conf = BoolWithConfidence.get_core_struct(can_return, core.max_confidence) + if pure is None: + pure_conf = BoolWithConfidence.get_core_struct(False, 0) + else: + pure_conf = BoolWithConfidence.get_core_struct(pure, core.max_confidence) + if stack_adjust is None: stack_adjust_conf = OffsetWithConfidence.get_core_struct(0, 0) else: @@ -1038,7 +1044,7 @@ class FunctionBuilder(TypeBuilder): handle = core.BNCreateFunctionTypeBuilder( ret_conf, conv_conf, param_buf, len(params), vararg_conf, can_return_conf, stack_adjust_conf, reg_stack_adjust_regs, reg_stack_adjust_values, len(reg_stack_adjust), - return_regs_set, name_type + return_regs_set, name_type, pure_conf ) assert handle is not None, "BNCreateFunctionTypeBuilder returned None" return cls(handle, platform, confidence) @@ -1075,6 +1081,14 @@ class FunctionBuilder(TypeBuilder): core.BNSetFunctionTypeBuilderCanReturn(self._handle, BoolWithConfidence.get_core_struct(value)) @property + def pure(self) -> BoolWithConfidence: + return BoolWithConfidence.from_core_struct(core.BNIsTypeBuilderPure(self._handle)) + + @pure.setter + def pure(self, value: BoolWithConfidenceType) -> None: + core.BNSetTypeBuilderPure(self._handle, BoolWithConfidence.get_core_struct(value)) + + @property def stack_adjust(self) -> OffsetWithConfidence: return OffsetWithConfidence.from_core_struct(core.BNGetTypeBuilderStackAdjustment(self._handle)) @@ -2742,7 +2756,8 @@ class FunctionType(Type): confidence: int = core.max_confidence, can_return: Union[BoolWithConfidence, bool] = True, reg_stack_adjust: Optional[Dict['architecture.RegisterName', OffsetWithConfidenceType]] = None, return_regs: Optional[Union['RegisterSet', List['architecture.RegisterType']]] = None, - name_type: 'NameType' = NameType.NoNameType + name_type: 'NameType' = NameType.NoNameType, + pure: Union[BoolWithConfidence, bool] = False ) -> 'FunctionType': if ret is None: ret = VoidType.create() @@ -2792,12 +2807,13 @@ class FunctionType(Type): return_regs_set[i] = platform.arch.get_reg_index(reg) _can_return = BoolWithConfidence.get_core_struct(can_return) + _pure = BoolWithConfidence.get_core_struct(pure) if params is None: params = [] func_type = core.BNCreateFunctionType( ret_conf, conv_conf, param_buf, len(params), _variable_arguments, _can_return, _stack_adjust, reg_stack_adjust_regs, reg_stack_adjust_values, len(reg_stack_adjust), - return_regs_set, name_type + return_regs_set, name_type, _pure ) assert func_type is not None, f"core.BNCreateFunctionType returned None {ret_conf} {conv_conf} {param_buf} {_variable_arguments} {_stack_adjust}" @@ -2865,6 +2881,12 @@ class FunctionType(Type): return BoolWithConfidence(result.value, confidence=result.confidence) @property + def pure(self) -> BoolWithConfidence: + """Whether type is pure""" + result = core.BNIsTypePure(self._handle) + return BoolWithConfidence(result.value, confidence=result.confidence) + + @property def children(self) -> List[Type]: return [self.return_value, *[param.type for param in self.parameters]] diff --git a/rust/src/types.rs b/rust/src/types.rs index c899b474..717972b9 100644 --- a/rust/src/types.rs +++ b/rust/src/types.rs @@ -323,6 +323,18 @@ impl TypeBuilder { // Settable properties + pub fn set_can_return<T: Into<Conf<bool>>>(&self, value: T) -> &Self { + let mut bool_with_confidence = value.into().into(); + unsafe { BNSetFunctionTypeBuilderCanReturn(self.handle, &mut bool_with_confidence) }; + self + } + + pub fn set_pure<T: Into<Conf<bool>>>(&self, value: T) -> &Self { + let mut bool_with_confidence = value.into().into(); + unsafe { BNSetTypeBuilderPure(self.handle, &mut bool_with_confidence) }; + self + } + pub fn set_const<T: Into<Conf<bool>>>(&self, value: T) -> &Self { let mut bool_with_confidence = value.into().into(); unsafe { BNTypeBuilderSetConst(self.handle, &mut bool_with_confidence) }; @@ -426,6 +438,14 @@ impl TypeBuilder { unsafe { BNTypeBuilderHasVariableArguments(self.handle).into() } } + pub fn can_return(&self) -> Conf<bool> { + unsafe { BNFunctionTypeBuilderCanReturn(self.handle).into() } + } + + pub fn pure(&self) -> Conf<bool> { + unsafe { BNIsTypeBuilderPure(self.handle).into() } + } + pub fn get_structure(&self) -> Result<Ref<Structure>> { let result = unsafe { BNGetTypeBuilderStructure(self.handle) }; if result.is_null() { @@ -794,6 +814,10 @@ impl Type { unsafe { BNFunctionTypeCanReturn(self.handle).into() } } + pub fn pure(&self) -> Conf<bool> { + unsafe { BNIsTypePure(self.handle).into() } + } + pub fn get_structure(&self) -> Result<Ref<Structure>> { let result = unsafe { BNGetTypeStructure(self.handle) }; if result.is_null() { @@ -969,6 +993,7 @@ impl Type { let mut return_type = return_type.into().into(); let mut variable_arguments = Conf::new(variable_arguments, max_confidence()).into(); let mut can_return = Conf::new(true, min_confidence()).into(); + let mut pure = Conf::new(false, min_confidence()).into(); let mut raw_calling_convention: BNCallingConventionWithConfidence = BNCallingConventionWithConfidence { @@ -1018,6 +1043,7 @@ impl Type { 0, &mut return_regs, BNNameType::NoNameType, + &mut pure, ))) } } @@ -1038,6 +1064,7 @@ impl Type { let mut return_type = return_type.into().into(); let mut variable_arguments = Conf::new(variable_arguments, max_confidence()).into(); let mut can_return = Conf::new(true, min_confidence()).into(); + let mut pure = Conf::new(false, min_confidence()).into(); let mut raw_calling_convention: BNCallingConventionWithConfidence = calling_convention.into().into(); let mut stack_adjust = stack_adjust.into(); @@ -1090,6 +1117,7 @@ impl Type { 0, &mut return_regs, BNNameType::NoNameType, + &mut pure, )) } } @@ -635,6 +635,13 @@ Confidence<bool> Type::CanReturn() const } +Confidence<bool> Type::IsPure() const +{ + BNBoolWithConfidence result = BNIsTypePure(m_object); + return Confidence<bool>(result.value, result.confidence); +} + + Ref<Structure> Type::GetStructure() const { BNStructure* s = BNGetTypeStructure(m_object); @@ -936,9 +943,13 @@ Ref<Type> Type::FunctionType(const Confidence<Ref<Type>>& returnValue, returnRegsConf.count = 0; returnRegsConf.confidence = 0; + BNBoolWithConfidence pureConf; + pureConf.value = false; + pureConf.confidence = 0; + Type* type = new Type(BNCreateFunctionType( &returnValueConf, &callingConventionConf, paramArray, params.size(), &varArgConf, - &canReturnConf, &stackAdjustConf, nullptr, nullptr, 0, &returnRegsConf, NoNameType)); + &canReturnConf, &stackAdjustConf, nullptr, nullptr, 0, &returnRegsConf, NoNameType, &pureConf)); delete[] paramArray; return type; } @@ -952,7 +963,8 @@ Ref<Type> Type::FunctionType(const Confidence<Ref<Type>>& returnValue, const Confidence<int64_t>& stackAdjust, const std::map<uint32_t, Confidence<int32_t>>& regStackAdjust, const Confidence<std::vector<uint32_t>>& returnRegs, - BNNameType ft) + BNNameType ft, + const Confidence<bool>& pure) { BNTypeWithConfidence returnValueConf; returnValueConf.type = returnValue->GetObject(); @@ -1004,10 +1016,14 @@ Ref<Type> Type::FunctionType(const Confidence<Ref<Type>>& returnValue, returnRegsConf.count = returnRegs->size(); returnRegsConf.confidence = returnRegs.GetConfidence(); + BNBoolWithConfidence pureConf; + pureConf.value = pure.GetValue(); + pureConf.confidence = pure.GetConfidence(); + Type* type = new Type(BNCreateFunctionType( &returnValueConf, &callingConventionConf, paramArray, params.size(), &varArgConf, &canReturnConf, &stackAdjustConf, regStackAdjustRegs.data(), - regStackAdjustValues.data(), regStackAdjust.size(), &returnRegsConf, NoNameType)); + regStackAdjustValues.data(), regStackAdjust.size(), &returnRegsConf, NoNameType, &pureConf)); delete[] paramArray; return type; } @@ -1432,6 +1448,13 @@ Confidence<bool> TypeBuilder::CanReturn() const } +Confidence<bool> TypeBuilder::IsPure() const +{ + BNBoolWithConfidence result = BNIsTypeBuilderPure(m_object); + return Confidence<bool>(result.value, result.confidence); +} + + Ref<Structure> TypeBuilder::GetStructure() const { BNStructure* s = BNGetTypeBuilderStructure(m_object); @@ -1772,9 +1795,13 @@ TypeBuilder TypeBuilder::FunctionType(const Confidence<Ref<Type>>& returnValue, returnRegsConf.count = 0; returnRegsConf.confidence = 0; + BNBoolWithConfidence pureConf; + pureConf.value = false; + pureConf.confidence = 0; + TypeBuilder type(BNCreateFunctionTypeBuilder( &returnValueConf, &callingConventionConf, paramArray, paramCount, &varArgConf, - &canReturnConf, &stackAdjustConf, nullptr, nullptr, 0, &returnRegsConf, NoNameType)); + &canReturnConf, &stackAdjustConf, nullptr, nullptr, 0, &returnRegsConf, NoNameType, &pureConf)); delete[] paramArray; return type; } @@ -1788,7 +1815,8 @@ TypeBuilder TypeBuilder::FunctionType(const Confidence<Ref<Type>>& returnValue, const Confidence<int64_t>& stackAdjust, const std::map<uint32_t, Confidence<int32_t>>& regStackAdjust, const Confidence<std::vector<uint32_t>>& returnRegs, - BNNameType ft) + BNNameType ft, + const Confidence<bool>& pure) { BNTypeWithConfidence returnValueConf; returnValueConf.type = returnValue->GetObject(); @@ -1840,10 +1868,14 @@ TypeBuilder TypeBuilder::FunctionType(const Confidence<Ref<Type>>& returnValue, returnRegsConf.count = returnRegs->size(); returnRegsConf.confidence = returnRegs.GetConfidence(); + BNBoolWithConfidence pureConf; + pureConf.value = pure.GetValue(); + pureConf.confidence = pure.GetConfidence(); + TypeBuilder type(BNCreateFunctionTypeBuilder( &returnValueConf, &callingConventionConf, paramArray, params.size(), &varArgConf, &canReturnConf, &stackAdjustConf, regStackAdjustRegs.data(), - regStackAdjustValues.data(), regStackAdjust.size(), &returnRegsConf, NoNameType)); + regStackAdjustValues.data(), regStackAdjust.size(), &returnRegsConf, NoNameType, &pureConf)); delete[] paramArray; return type; } @@ -1859,6 +1891,16 @@ TypeBuilder& TypeBuilder::SetFunctionCanReturn(const Confidence<bool>& canReturn } +TypeBuilder& TypeBuilder::SetPure(const Confidence<bool>& pure) +{ + BNBoolWithConfidence bc; + bc.value = pure.GetValue(); + bc.confidence = pure.GetConfidence(); + BNSetTypeBuilderPure(m_object, &bc); + return *this; +} + + TypeBuilder& TypeBuilder::SetParameters(const std::vector<FunctionParameter>& params) { size_t paramCount = 0; |
