From 142004d7f31ad2eee58dc6c9bdec7bdcc530cf58 Mon Sep 17 00:00:00 2001 From: Rusty Wagner Date: Tue, 10 Dec 2019 16:16:33 -0500 Subject: Immutable type/struct/enum objects, allowing deduplication for reduced memory usage. In C++ API, modifying or creating types, structures, or enumerations should be done with the new TypeBuilder, StructureBuilder, and EnumerationBuilder objects, then converted to a final Type, Structure, or Enumeration object using the Finalize method once the modifications are complete. When modifying structures or enumerations inside existing types, use the WithReplacedStructure or WithReplacedEnumeration methods on the root type object and reregister the type to use the modified object. In Python API, types, structures, and enumerations can be created as in previous versions, but the objects become immutable once they are passed to a method. To modify an existing type, structure, or enumeration, use the mutable_copy() method. When modifying structures or enumerations, replace the modified object in the Type with the with_replaced_structure() or with_replaced_enumeration() methods. --- binaryninjaapi.h | 175 ++++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 162 insertions(+), 13 deletions(-) (limited to 'binaryninjaapi.h') diff --git a/binaryninjaapi.h b/binaryninjaapi.h index 4d9ca8e5..5c11d0b8 100644 --- a/binaryninjaapi.h +++ b/binaryninjaapi.h @@ -2478,20 +2478,13 @@ __attribute__ ((format (printf, 1, 2))) Ref GetEnumeration() const; Ref GetNamedTypeReference() const; Confidence GetScope() const; - void SetScope(const Confidence& scope); Confidence GetAccess() const; - void SetAccess(const Confidence& access); - void SetConst(const Confidence& cnst); - void SetVolatile(const Confidence& vltl); - void SetTypeName(const QualifiedName& name); Confidence GetStackAdjustment() const; QualifiedName GetStructureName() const; uint64_t GetElementCount() const; uint64_t GetOffset() const; - void SetFunctionCanReturn(const Confidence& canReturn); - std::string GetString(Platform* platform = nullptr) const; std::string GetTypeAndName(const QualifiedName& name) const; std::string GetStringBeforeName(Platform* platform = nullptr) const; @@ -2557,6 +2550,114 @@ __attribute__ ((format (printf, 1, 2))) bool IsValue() const { return GetClass() == ValueTypeClass; } bool IsNamedTypeRefer() const { return GetClass() == NamedTypeReferenceClass; } bool IsWideChar() const { return GetClass() == WideCharTypeClass; } + + Ref WithReplacedStructure(Structure* from, Structure* to); + Ref WithReplacedEnumeration(Enumeration* from, Enumeration* to); + Ref WithReplacedNamedTypeReference(NamedTypeReference* from, NamedTypeReference* to); + }; + + class TypeBuilder + { + BNTypeBuilder* m_object; + + public: + TypeBuilder(); + TypeBuilder(BNTypeBuilder* type); + TypeBuilder(const TypeBuilder& type); + TypeBuilder(TypeBuilder&& type); + TypeBuilder(Type* type); + TypeBuilder& operator=(const TypeBuilder& type); + TypeBuilder& operator=(TypeBuilder&& type); + TypeBuilder& operator=(Type* type); + + Ref Finalize(); + + BNTypeClass GetClass() const; + uint64_t GetWidth() const; + size_t GetAlignment() const; + QualifiedName GetTypeName() const; + Confidence IsSigned() const; + Confidence IsConst() const; + Confidence IsVolatile() const; + + Confidence> GetChildType() const; + Confidence> GetCallingConvention() const; + std::vector GetParameters() const; + Confidence HasVariableArguments() const; + Confidence CanReturn() const; + Ref GetStructure() const; + Ref GetEnumeration() const; + Ref GetNamedTypeReference() const; + Confidence GetScope() const; + void SetScope(const Confidence& scope); + Confidence GetAccess() const; + void SetAccess(const Confidence& access); + void SetConst(const Confidence& cnst); + void SetVolatile(const Confidence& vltl); + void SetTypeName(const QualifiedName& name); + Confidence GetStackAdjustment() const; + QualifiedName GetStructureName() const; + + uint64_t GetElementCount() const; + uint64_t GetOffset() const; + + void SetFunctionCanReturn(const Confidence& canReturn); + + std::string GetString(Platform* platform = nullptr) const; + std::string GetTypeAndName(const QualifiedName& name) const; + std::string GetStringBeforeName(Platform* platform = nullptr) const; + std::string GetStringAfterName(Platform* platform = nullptr) const; + + std::vector GetTokens(Platform* platform = nullptr, + uint8_t baseConfidence = BN_FULL_CONFIDENCE) const; + std::vector GetTokensBeforeName(Platform* platform = nullptr, + uint8_t baseConfidence = BN_FULL_CONFIDENCE) const; + std::vector GetTokensAfterName(Platform* platform = nullptr, + uint8_t baseConfidence = BN_FULL_CONFIDENCE) const; + + static TypeBuilder VoidType(); + static TypeBuilder BoolType(); + static TypeBuilder IntegerType(size_t width, const Confidence& sign, const std::string& altName = ""); + static TypeBuilder FloatType(size_t width, const std::string& typeName = ""); + static TypeBuilder StructureType(Structure* strct); + static TypeBuilder NamedType(NamedTypeReference* ref, size_t width = 0, size_t align = 1); + static TypeBuilder NamedType(const QualifiedName& name, Type* type); + static TypeBuilder NamedType(const std::string& id, const QualifiedName& name, Type* type); + static TypeBuilder NamedType(BinaryView* view, const QualifiedName& name); + static TypeBuilder EnumerationType(Architecture* arch, Enumeration* enm, size_t width = 0, bool issigned = false); + static TypeBuilder PointerType(Architecture* arch, const Confidence>& type, + const Confidence& cnst = Confidence(false, 0), + const Confidence& vltl = Confidence(false, 0), BNReferenceType refType = PointerReferenceType); + static TypeBuilder PointerType(size_t width, const Confidence>& type, + const Confidence& cnst = Confidence(false, 0), + const Confidence& vltl = Confidence(false, 0), BNReferenceType refType = PointerReferenceType); + static TypeBuilder ArrayType(const Confidence>& type, uint64_t elem); + static TypeBuilder FunctionType(const Confidence>& returnValue, + const Confidence>& callingConvention, + const std::vector& params, const Confidence& varArg = Confidence(false, 0), + const Confidence& stackAdjust = Confidence(0, 0)); + + bool IsReferenceOfType(BNNamedTypeReferenceClass refType); + bool IsStructReference() { return IsReferenceOfType(StructNamedTypeClass); } + bool IsEnumReference() { return IsReferenceOfType(EnumNamedTypeClass); } + bool IsUnionReference() { return IsReferenceOfType(UnionNamedTypeClass); } + bool IsClassReference() { return IsReferenceOfType(ClassNamedTypeClass); } + bool IsTypedefReference() { return IsReferenceOfType(TypedefNamedTypeClass); } + bool IsStructOrClassReference() { return IsReferenceOfType(StructNamedTypeClass) || IsReferenceOfType(ClassNamedTypeClass); } + + bool IsVoid() const { return GetClass() == VoidTypeClass; } + bool IsBool() const { return GetClass() == BoolTypeClass; } + bool IsInteger() const { return GetClass() == IntegerTypeClass; } + bool IsFloat() const { return GetClass() == FloatTypeClass; } + bool IsStructure() const { return GetClass() == StructureTypeClass; } + bool IsEnumeration() const { return GetClass() == EnumerationTypeClass; } + bool IsPointer() const { return GetClass() == PointerTypeClass; } + bool IsArray() const { return GetClass() == ArrayTypeClass; } + bool IsFunction() const { return GetClass() == FunctionTypeClass; } + bool IsVarArgs() const { return GetClass() == VarArgsTypeClass; } + bool IsValue() const { return GetClass() == ValueTypeClass; } + bool IsNamedTypeRefer() const { return GetClass() == NamedTypeReferenceClass; } + bool IsWideChar() const { return GetClass() == WideCharTypeClass; } }; class NamedTypeReference: public CoreRefCountObject GenerateAutoTypeReference(BNNamedTypeReferenceClass cls, const std::string& source, const QualifiedName& name); @@ -2591,13 +2689,45 @@ __attribute__ ((format (printf, 1, 2))) class Structure: public CoreRefCountObject { public: - Structure(); Structure(BNStructure* s); - Structure(BNStructureType type, bool packed = false); std::vector GetMembers() const; bool GetMemberByName(const std::string& name, StructureMember& result) const; bool GetMemberAtOffset(int64_t offset, StructureMember& result) const; + bool GetMemberAtOffset(int64_t offset, StructureMember& result, size_t& idx) const; + uint64_t GetWidth() const; + size_t GetAlignment() const; + bool IsPacked() const; + bool IsUnion() const; + BNStructureType GetStructureType() const; + + Ref WithReplacedStructure(Structure* from, Structure* to); + Ref WithReplacedEnumeration(Enumeration* from, Enumeration* to); + Ref WithReplacedNamedTypeReference(NamedTypeReference* from, NamedTypeReference* to); + }; + + class StructureBuilder + { + BNStructureBuilder* m_object; + + public: + StructureBuilder(); + StructureBuilder(BNStructureBuilder* s); + StructureBuilder(BNStructureType type, bool packed = false); + StructureBuilder(const StructureBuilder& s); + StructureBuilder(StructureBuilder&& s); + StructureBuilder(Structure* s); + ~StructureBuilder(); + StructureBuilder& operator=(const StructureBuilder& s); + StructureBuilder& operator=(StructureBuilder&& s); + StructureBuilder& operator=(Structure* s); + + Ref Finalize() const; + + std::vector GetMembers() const; + bool GetMemberByName(const std::string& name, StructureMember& result) const; + bool GetMemberAtOffset(int64_t offset, StructureMember& result) const; + bool GetMemberAtOffset(int64_t offset, StructureMember& result, size_t& idx) const; uint64_t GetWidth() const; void SetWidth(size_t width); size_t GetAlignment() const; @@ -2623,10 +2753,29 @@ __attribute__ ((format (printf, 1, 2))) class Enumeration: public CoreRefCountObject { public: - Enumeration(); Enumeration(BNEnumeration* e); std::vector GetMembers() const; + }; + + class EnumerationBuilder + { + BNEnumerationBuilder* m_object; + + public: + EnumerationBuilder(); + EnumerationBuilder(BNEnumerationBuilder* e); + EnumerationBuilder(const EnumerationBuilder& e); + EnumerationBuilder(EnumerationBuilder&& e); + EnumerationBuilder(Enumeration* e); + ~EnumerationBuilder(); + EnumerationBuilder& operator=(const EnumerationBuilder& e); + EnumerationBuilder& operator=(EnumerationBuilder&& e); + EnumerationBuilder& operator=(Enumeration* e); + + Ref Finalize() const; + + std::vector GetMembers() const; void AddMember(const std::string& name); void AddMemberWithValue(const std::string& name, uint64_t value); -- cgit v1.3.1