summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRusty Wagner <rusty@vector35.com>2017-01-11 15:42:08 -0500
committerRusty Wagner <rusty@vector35.com>2017-01-11 15:42:08 -0500
commit09a68bdd84d4789626f5c8b8631f61e7a41ca03d (patch)
tree5d294b337d32e4b573c259539417987be125de9b
parentd9455e8b6319ccb766a3a9f274244a54d159e7f4 (diff)
Use named type references for registered types, use qualified names for types
-rw-r--r--architecture.cpp57
-rw-r--r--binaryninjaapi.h62
-rw-r--r--binaryninjacore.h71
-rw-r--r--binaryview.cpp134
-rw-r--r--python/__init__.py290
-rw-r--r--python/generator.cpp46
-rw-r--r--type.cpp111
7 files changed, 533 insertions, 238 deletions
diff --git a/architecture.cpp b/architecture.cpp
index e84b7f78..d0d87df4 100644
--- a/architecture.cpp
+++ b/architecture.cpp
@@ -746,9 +746,8 @@ void Architecture::SetBinaryViewTypeConstant(const string& type, const string& n
bool Architecture::ParseTypesFromSource(const string& source, const string& fileName,
- map<string, Ref<Type>>& types, map<string, Ref<Type>>& variables,
- map<string, Ref<Type>>& functions, string& errors,
- const vector<string>& includeDirs)
+ map<vector<string>, Ref<Type>>& types, map<vector<string>, Ref<Type>>& variables,
+ map<vector<string>, Ref<Type>>& functions, string& errors, const vector<string>& includeDirs)
{
BNTypeParserResult result;
char* errorStr;
@@ -762,26 +761,41 @@ bool Architecture::ParseTypesFromSource(const string& source, const string& file
functions.clear();
bool ok = BNParseTypesFromSource(m_object, source.c_str(), fileName.c_str(), &result,
- &errorStr, includeDirList, includeDirs.size());
+ &errorStr, includeDirList, includeDirs.size());
errors = errorStr;
BNFreeString(errorStr);
if (!ok)
return false;
for (size_t i = 0; i < result.typeCount; i++)
- types[result.types[i].name] = new Type(BNNewTypeReference(result.types[i].type));
+ {
+ vector<string> name;
+ for (size_t j = 0; j < result.types[i].nameCount; j++)
+ name.push_back(result.types[i].name[j]);
+ types[name] = new Type(BNNewTypeReference(result.types[i].type));
+ }
for (size_t i = 0; i < result.variableCount; i++)
- types[result.variables[i].name] = new Type(BNNewTypeReference(result.variables[i].type));
+ {
+ vector<string> name;
+ for (size_t j = 0; j < result.variables[i].nameCount; j++)
+ name.push_back(result.variables[i].name[j]);
+ types[name] = new Type(BNNewTypeReference(result.variables[i].type));
+ }
for (size_t i = 0; i < result.functionCount; i++)
- types[result.functions[i].name] = new Type(BNNewTypeReference(result.functions[i].type));
+ {
+ vector<string> name;
+ for (size_t j = 0; j < result.functions[i].nameCount; j++)
+ name.push_back(result.functions[i].name[j]);
+ types[name] = new Type(BNNewTypeReference(result.functions[i].type));
+ }
BNFreeTypeParserResult(&result);
return true;
}
-bool Architecture::ParseTypesFromSourceFile(const string& fileName, map<string, Ref<Type>>& types,
- map<string, Ref<Type>>& variables, map<string, Ref<Type>>& functions,
- string& errors, const vector<string>& includeDirs)
+bool Architecture::ParseTypesFromSourceFile(const string& fileName, map<vector<string>, Ref<Type>>& types,
+ map<vector<string>, Ref<Type>>& variables, map<vector<string>, Ref<Type>>& functions,
+ string& errors, const vector<string>& includeDirs)
{
BNTypeParserResult result;
char* errorStr;
@@ -795,18 +809,33 @@ bool Architecture::ParseTypesFromSourceFile(const string& fileName, map<string,
functions.clear();
bool ok = BNParseTypesFromSourceFile(m_object, fileName.c_str(), &result, &errorStr,
- includeDirList, includeDirs.size());
+ includeDirList, includeDirs.size());
errors = errorStr;
BNFreeString(errorStr);
if (!ok)
return false;
for (size_t i = 0; i < result.typeCount; i++)
- types[result.types[i].name] = new Type(BNNewTypeReference(result.types[i].type));
+ {
+ vector<string> name;
+ for (size_t j = 0; j < result.types[i].nameCount; j++)
+ name.push_back(result.types[i].name[j]);
+ types[name] = new Type(BNNewTypeReference(result.types[i].type));
+ }
for (size_t i = 0; i < result.variableCount; i++)
- variables[result.variables[i].name] = new Type(BNNewTypeReference(result.variables[i].type));
+ {
+ vector<string> name;
+ for (size_t j = 0; j < result.variables[i].nameCount; j++)
+ name.push_back(result.variables[i].name[j]);
+ variables[name] = new Type(BNNewTypeReference(result.variables[i].type));
+ }
for (size_t i = 0; i < result.functionCount; i++)
- functions[result.functions[i].name] = new Type(BNNewTypeReference(result.functions[i].type));
+ {
+ vector<string> name;
+ for (size_t j = 0; j < result.functions[i].nameCount; j++)
+ name.push_back(result.functions[i].name[j]);
+ functions[name] = new Type(BNNewTypeReference(result.functions[i].type));
+ }
BNFreeTypeParserResult(&result);
return true;
}
diff --git a/binaryninjaapi.h b/binaryninjaapi.h
index 58f901ab..15c86a58 100644
--- a/binaryninjaapi.h
+++ b/binaryninjaapi.h
@@ -590,8 +590,8 @@ namespace BinaryNinja
static void DataVariableUpdatedCallback(void* ctxt, BNBinaryView* data, BNDataVariable* var);
static void StringFoundCallback(void* ctxt, BNBinaryView* data, BNStringType type, uint64_t offset, size_t len);
static void StringRemovedCallback(void* ctxt, BNBinaryView* data, BNStringType type, uint64_t offset, size_t len);
- static void TypeDefinedCallback(void* ctxt, BNBinaryView* data, const char* name, BNType* type);
- static void TypeUndefinedCallback(void* ctxt, BNBinaryView* data, const char* name, BNType* type);
+ static void TypeDefinedCallback(void* ctxt, BNBinaryView* data, const char** name, size_t nameCount, BNType* type);
+ static void TypeUndefinedCallback(void* ctxt, BNBinaryView* data, const char** name, size_t nameCount, BNType* type);
public:
BinaryDataNotification();
@@ -610,8 +610,8 @@ namespace BinaryNinja
virtual void OnDataVariableUpdated(BinaryView* view, const DataVariable& var) { (void)view; (void)var; }
virtual void OnStringFound(BinaryView* data, BNStringType type, uint64_t offset, size_t len) { (void)data; (void)type; (void)offset; (void)len; }
virtual void OnStringRemoved(BinaryView* data, BNStringType type, uint64_t offset, size_t len) { (void)data; (void)type; (void)offset; (void)len; }
- virtual void OnTypeDefined(BinaryView* data, const std::string& name, Type* type) { (void)data; (void)name; (void)type; }
- virtual void OnTypeUndefined(BinaryView* data, const std::string& name, Type* type) { (void)data; (void)name; (void)type; }
+ virtual void OnTypeDefined(BinaryView* data, const std::vector<std::string>& name, Type* type) { (void)data; (void)name; (void)type; }
+ virtual void OnTypeUndefined(BinaryView* data, const std::vector<std::string>& name, Type* type) { (void)data; (void)name; (void)type; }
};
class FileAccessor
@@ -755,7 +755,7 @@ namespace BinaryNinja
uint64_t align, entrySize;
};
- struct NameAndType;
+ struct QualifiedNameAndType;
/*! BinaryView is the base class for creating views on binary data (e.g. ELF, PE, Mach-O).
BinaryView should be subclassed to create a new BinaryView
@@ -977,15 +977,21 @@ namespace BinaryNinja
std::vector<LinearDisassemblyLine> GetNextLinearDisassemblyLines(LinearDisassemblyPosition& pos,
DisassemblySettings* settings);
- bool ParseTypeString(const std::string& text, NameAndType& result, std::string& errors);
+ bool ParseTypeString(const std::string& text, QualifiedNameAndType& result, std::string& errors);
- std::map<std::string, Ref<Type>> GetTypes();
+ std::map<std::vector<std::string>, Ref<Type>> GetTypes();
Ref<Type> GetTypeByName(const std::string& name);
+ Ref<Type> GetTypeByName(const std::vector<std::string>& name);
bool IsTypeAutoDefined(const std::string& name);
+ bool IsTypeAutoDefined(const std::vector<std::string>& name);
void DefineType(const std::string& name, Ref<Type> type);
+ void DefineType(const std::vector<std::string>& name, Ref<Type> type);
void DefineUserType(const std::string& name, Ref<Type> type);
+ void DefineUserType(const std::vector<std::string>& name, Ref<Type> type);
void UndefineType(const std::string& name);
+ void UndefineType(const std::vector<std::string>& name);
void UndefineUserType(const std::string& name);
+ void UndefineUserType(const std::vector<std::string>& name);
bool FindNextData(uint64_t start, const DataBuffer& data, uint64_t& result, BNFindFlag flags = NoFindFlags);
@@ -1435,13 +1441,15 @@ namespace BinaryNinja
void SetBinaryViewTypeConstant(const std::string& type, const std::string& name, uint64_t value);
bool ParseTypesFromSource(const std::string& source, const std::string& fileName,
- std::map<std::string, Ref<Type>>& types, std::map<std::string, Ref<Type>>& variables,
- std::map<std::string, Ref<Type>>& functions, std::string& errors,
- const std::vector<std::string>& includeDirs = std::vector<std::string>());
- bool ParseTypesFromSourceFile(const std::string& fileName, std::map<std::string, Ref<Type>>& types,
- std::map<std::string, Ref<Type>>& variables,
- std::map<std::string, Ref<Type>>& functions, std::string& errors,
- const std::vector<std::string>& includeDirs = std::vector<std::string>());
+ std::map<std::vector<std::string>, Ref<Type>>& types,
+ std::map<std::vector<std::string>, Ref<Type>>& variables,
+ std::map<std::vector<std::string>, Ref<Type>>& functions, std::string& errors,
+ const std::vector<std::string>& includeDirs = std::vector<std::string>());
+ bool ParseTypesFromSourceFile(const std::string& fileName,
+ std::map<std::vector<std::string>, Ref<Type>>& types,
+ std::map<std::vector<std::string>, Ref<Type>>& variables,
+ std::map<std::vector<std::string>, Ref<Type>>& functions, std::string& errors,
+ const std::vector<std::string>& includeDirs = std::vector<std::string>());
void RegisterCallingConvention(CallingConvention* cc);
std::vector<Ref<CallingConvention>> GetCallingConventions();
@@ -1504,7 +1512,7 @@ namespace BinaryNinja
};
class Structure;
- class UnknownType;
+ class NamedTypeReference;
class Enumeration;
struct NameAndType
@@ -1513,6 +1521,12 @@ namespace BinaryNinja
Ref<Type> type;
};
+ struct QualifiedNameAndType
+ {
+ std::vector<std::string> name;
+ Ref<Type> type;
+ };
+
class Type: public CoreRefCountObject<BNType, BNNewTypeReference, BNFreeType>
{
public:
@@ -1532,7 +1546,7 @@ namespace BinaryNinja
bool CanReturn() const;
Ref<Structure> GetStructure() const;
Ref<Enumeration> GetEnumeration() const;
- Ref<UnknownType> GetUnknownType() const;
+ Ref<NamedTypeReference> GetNamedTypeReference() const;
uint64_t GetElementCount() const;
@@ -1554,7 +1568,8 @@ namespace BinaryNinja
static Ref<Type> IntegerType(size_t width, bool sign, const std::string& altName = "");
static Ref<Type> FloatType(size_t width, const std::string& typeName = "");
static Ref<Type> StructureType(Structure* strct);
- static Ref<Type> UnknownNamedType(UnknownType* unknwn);
+ static Ref<Type> NamedType(NamedTypeReference* ref, size_t width = 0, size_t align = 1);
+ static Ref<Type> NamedType(const std::vector<std::string>& name, Type* type);
static Ref<Type> EnumerationType(Architecture* arch, Enumeration* enm, size_t width = 0, bool issigned = false);
static Ref<Type> PointerType(Architecture* arch, Type* type, bool cnst = false, bool vltl = false,
BNReferenceType refType = PointerReferenceType);
@@ -1565,10 +1580,14 @@ namespace BinaryNinja
static std::string GetQualifiedName(const std::vector<std::string>& names);
};
- class UnknownType: public CoreRefCountObject<BNUnknownType, BNNewUnknownTypeReference, BNFreeUnknownType>
+ class NamedTypeReference: public CoreRefCountObject<BNNamedTypeReference, BNNewNamedTypeReference,
+ BNFreeNamedTypeReference>
{
public:
- UnknownType(BNUnknownType* s, std::vector<std::string> name = {});
+ NamedTypeReference(BNNamedTypeReference* nt);
+ NamedTypeReference(BNNamedTypeReferenceClass cls, const std::vector<std::string>& name = {});
+ BNNamedTypeReferenceClass GetTypeClass() const;
+ void SetTypeClass(BNNamedTypeReferenceClass cls);
std::vector<std::string> GetName() const;
void SetName(const std::vector<std::string>& name);
};
@@ -1586,8 +1605,6 @@ namespace BinaryNinja
Structure();
Structure(BNStructure* s);
- std::vector<std::string> GetName() const;
- void SetName(const std::vector<std::string>& name);
std::vector<StructureMember> GetMembers() const;
uint64_t GetWidth() const;
void SetWidth(size_t width);
@@ -1616,9 +1633,6 @@ namespace BinaryNinja
public:
Enumeration(BNEnumeration* e);
- std::vector<std::string> GetName() const;
- void SetName(const std::vector<std::string>& name);
-
std::vector<EnumerationMember> GetMembers() const;
void AddMember(const std::string& name);
diff --git a/binaryninjacore.h b/binaryninjacore.h
index b29a67a2..26f37536 100644
--- a/binaryninjacore.h
+++ b/binaryninjacore.h
@@ -94,7 +94,7 @@ extern "C"
struct BNLowLevelILFunction;
struct BNType;
struct BNStructure;
- struct BNUnknownType;
+ struct BNNamedTypeReference;
struct BNEnumeration;
struct BNCallingConvention;
struct BNPlatform;
@@ -371,7 +371,17 @@ extern "C"
FunctionTypeClass = 8,
VarArgsTypeClass = 9,
ValueTypeClass = 10,
- UnknownTypeClass = 11
+ NamedTypeReferenceClass = 11
+ };
+
+ enum BNNamedTypeReferenceClass
+ {
+ UnknownNamedTypeClass = 0,
+ TypedefNamedTypeClass = 1,
+ ClassNamedTypeClass = 2,
+ StructNamedTypeClass = 3,
+ UnionNamedTypeClass = 4,
+ EnumNamedTypeClass = 5
};
enum BNStructureType
@@ -635,8 +645,8 @@ extern "C"
void (*dataVariableUpdated)(void* ctxt, BNBinaryView* view, BNDataVariable* var);
void (*stringFound)(void* ctxt, BNBinaryView* view, BNStringType type, uint64_t offset, size_t len);
void (*stringRemoved)(void* ctxt, BNBinaryView* view, BNStringType type, uint64_t offset, size_t len);
- void (*typeDefined)(void* ctxt, BNBinaryView* view, const char* name, BNType* type);
- void (*typeUndefined)(void* ctxt, BNBinaryView* view, const char* name, BNType* type);
+ void (*typeDefined)(void* ctxt, BNBinaryView* view, const char** name, size_t nameCount, BNType* type);
+ void (*typeUndefined)(void* ctxt, BNBinaryView* view, const char** name, size_t nameCount, BNType* type);
};
struct BNFileAccessor
@@ -842,6 +852,13 @@ extern "C"
BNType* type;
};
+ struct BNQualifiedNameAndType
+ {
+ char** name;
+ size_t nameCount;
+ BNType* type;
+ };
+
struct BNStructureMember
{
BNType* type;
@@ -864,9 +881,9 @@ extern "C"
struct BNTypeParserResult
{
- BNNameAndType* types;
- BNNameAndType* variables;
- BNNameAndType* functions;
+ BNQualifiedNameAndType* types;
+ BNQualifiedNameAndType* variables;
+ BNQualifiedNameAndType* functions;
size_t typeCount, variableCount, functionCount;
};
@@ -1776,17 +1793,19 @@ extern "C"
BINARYNINJACOREAPI void BNFreeDataVariables(BNDataVariable* vars, size_t count);
BINARYNINJACOREAPI bool BNGetDataVariableAtAddress(BNBinaryView* view, uint64_t addr, BNDataVariable* var);
- BINARYNINJACOREAPI bool BNParseTypeString(BNBinaryView* view, const char* text, BNNameAndType* result, char** errors);
+ BINARYNINJACOREAPI bool BNParseTypeString(BNBinaryView* view, const char* text,
+ BNQualifiedNameAndType* result, char** errors);
BINARYNINJACOREAPI void BNFreeNameAndType(BNNameAndType* obj);
+ BINARYNINJACOREAPI void BNFreeQualifiedNameAndType(BNQualifiedNameAndType* obj);
- BINARYNINJACOREAPI BNNameAndType* BNGetAnalysisTypeList(BNBinaryView* view, size_t* count);
- BINARYNINJACOREAPI void BNFreeTypeList(BNNameAndType* types, size_t count);
- BINARYNINJACOREAPI BNType* BNGetAnalysisTypeByName(BNBinaryView* view, const char* name);
- BINARYNINJACOREAPI bool BNIsAnalysisTypeAutoDefined(BNBinaryView* view, const char* name);
- BINARYNINJACOREAPI void BNDefineAnalysisType(BNBinaryView* view, const char* name, BNType* type);
- BINARYNINJACOREAPI void BNDefineUserAnalysisType(BNBinaryView* view, const char* name, BNType* type);
- BINARYNINJACOREAPI void BNUndefineAnalysisType(BNBinaryView* view, const char* name);
- BINARYNINJACOREAPI void BNUndefineUserAnalysisType(BNBinaryView* view, const char* name);
+ BINARYNINJACOREAPI BNQualifiedNameAndType* BNGetAnalysisTypeList(BNBinaryView* view, size_t* count);
+ BINARYNINJACOREAPI void BNFreeTypeList(BNQualifiedNameAndType* types, size_t count);
+ BINARYNINJACOREAPI BNType* BNGetAnalysisTypeByName(BNBinaryView* view, const char** name, size_t nameCount);
+ BINARYNINJACOREAPI bool BNIsAnalysisTypeAutoDefined(BNBinaryView* view, const char** name, size_t nameCount);
+ BINARYNINJACOREAPI void BNDefineAnalysisType(BNBinaryView* view, const char** name, size_t nameCount, BNType* type);
+ BINARYNINJACOREAPI void BNDefineUserAnalysisType(BNBinaryView* view, const char** name, size_t nameCount, BNType* type);
+ BINARYNINJACOREAPI void BNUndefineAnalysisType(BNBinaryView* view, const char** name, size_t nameCount);
+ BINARYNINJACOREAPI void BNUndefineUserAnalysisType(BNBinaryView* view, const char** name, size_t nameCount);
BINARYNINJACOREAPI void BNReanalyzeAllFunctions(BNBinaryView* view);
BINARYNINJACOREAPI void BNReanalyzeFunction(BNFunction* func);
@@ -1968,6 +1987,7 @@ extern "C"
BINARYNINJACOREAPI bool BNFunctionTypeCanReturn(BNType* type);
BINARYNINJACOREAPI BNStructure* BNGetTypeStructure(BNType* type);
BINARYNINJACOREAPI BNEnumeration* BNGetTypeEnumeration(BNType* type);
+ BINARYNINJACOREAPI BNNamedTypeReference* BNGetTypeNamedTypeReference(BNType* type);
BINARYNINJACOREAPI uint64_t BNGetTypeElementCount(BNType* type);
BINARYNINJACOREAPI void BNSetFunctionCanReturn(BNType* type, bool canReturn);
@@ -1979,19 +1999,20 @@ extern "C"
BINARYNINJACOREAPI BNInstructionTextToken* BNGetTypeTokensAfterName(BNType* type, size_t* count);
BINARYNINJACOREAPI void BNFreeTokenList(BNInstructionTextToken* tokens, size_t count);
- BINARYNINJACOREAPI BNType* BNCreateUnknownNamedType(BNUnknownType* ut);
- BINARYNINJACOREAPI BNUnknownType* BNCreateUnknownType(void);
- BINARYNINJACOREAPI void BNSetUnknownTypeName(BNUnknownType* ut, const char** name, size_t size);
- BINARYNINJACOREAPI char** BNGetUnknownTypeName(BNUnknownType* ut, size_t* size);
- BINARYNINJACOREAPI void BNFreeUnknownType(BNUnknownType* ut);
- BINARYNINJACOREAPI BNUnknownType* BNNewUnknownTypeReference(BNUnknownType* ut);
+ BINARYNINJACOREAPI BNType* BNCreateNamedTypeReference(BNNamedTypeReference* nt, size_t width, size_t align);
+ BINARYNINJACOREAPI BNType* BNCreateNamedTypeReferenceFromType(const char** name, size_t nameCount, BNType* type);
+ BINARYNINJACOREAPI BNNamedTypeReference* BNCreateNamedType(void);
+ BINARYNINJACOREAPI void BNSetTypeReferenceClass(BNNamedTypeReference* nt, BNNamedTypeReferenceClass cls);
+ BINARYNINJACOREAPI BNNamedTypeReferenceClass BNGetTypeReferenceClass(BNNamedTypeReference* nt);
+ BINARYNINJACOREAPI void BNSetTypeReferenceName(BNNamedTypeReference* nt, const char** name, size_t size);
+ BINARYNINJACOREAPI char** BNGetTypeReferenceName(BNNamedTypeReference* nt, size_t* size);
+ BINARYNINJACOREAPI void BNFreeNamedTypeReference(BNNamedTypeReference* nt);
+ BINARYNINJACOREAPI BNNamedTypeReference* BNNewNamedTypeReference(BNNamedTypeReference* nt);
BINARYNINJACOREAPI BNStructure* BNCreateStructure(void);
BINARYNINJACOREAPI BNStructure* BNNewStructureReference(BNStructure* s);
BINARYNINJACOREAPI void BNFreeStructure(BNStructure* s);
- BINARYNINJACOREAPI char** BNGetStructureName(BNStructure* s, size_t* size);
- BINARYNINJACOREAPI void BNSetStructureName(BNStructure* s, const char** names, size_t size);
BINARYNINJACOREAPI BNStructureMember* BNGetStructureMembers(BNStructure* s, size_t* count);
BINARYNINJACOREAPI void BNFreeStructureMemberList(BNStructureMember* members, size_t count);
BINARYNINJACOREAPI uint64_t BNGetStructureWidth(BNStructure* s);
@@ -2012,8 +2033,6 @@ extern "C"
BINARYNINJACOREAPI BNEnumeration* BNNewEnumerationReference(BNEnumeration* e);
BINARYNINJACOREAPI void BNFreeEnumeration(BNEnumeration* e);
- BINARYNINJACOREAPI char** BNGetEnumerationName(BNEnumeration* e, size_t* size);
- BINARYNINJACOREAPI void BNSetEnumerationName(BNEnumeration* e, const char** name, size_t size);
BINARYNINJACOREAPI BNEnumerationMember* BNGetEnumerationMembers(BNEnumeration* e, size_t* count);
BINARYNINJACOREAPI void BNFreeEnumerationMemberList(BNEnumerationMember* members, size_t count);
diff --git a/binaryview.cpp b/binaryview.cpp
index 154dfcf5..9fdd5748 100644
--- a/binaryview.cpp
+++ b/binaryview.cpp
@@ -129,21 +129,29 @@ void BinaryDataNotification::StringRemovedCallback(void* ctxt, BNBinaryView* obj
}
-void BinaryDataNotification::TypeDefinedCallback(void* ctxt, BNBinaryView* data, const char* name, BNType* type)
+void BinaryDataNotification::TypeDefinedCallback(void* ctxt, BNBinaryView* data, const char** name, size_t nameCount,
+ BNType* type)
{
BinaryDataNotification* notify = (BinaryDataNotification*)ctxt;
Ref<BinaryView> view = new BinaryView(BNNewViewReference(data));
Ref<Type> typeObj = new Type(BNNewTypeReference(type));
- notify->OnTypeDefined(view, name, typeObj);
+ vector<string> nameList;
+ for (size_t i = 0; i < nameCount; i++)
+ nameList.push_back(name[i]);
+ notify->OnTypeDefined(view, nameList, typeObj);
}
-void BinaryDataNotification::TypeUndefinedCallback(void* ctxt, BNBinaryView* data, const char* name, BNType* type)
+void BinaryDataNotification::TypeUndefinedCallback(void* ctxt, BNBinaryView* data, const char** name, size_t nameCount,
+ BNType* type)
{
BinaryDataNotification* notify = (BinaryDataNotification*)ctxt;
Ref<BinaryView> view = new BinaryView(BNNewViewReference(data));
Ref<Type> typeObj = new Type(BNNewTypeReference(type));
- notify->OnTypeUndefined(view, name, typeObj);
+ vector<string> nameList;
+ for (size_t i = 0; i < nameCount; i++)
+ nameList.push_back(name[i]);
+ notify->OnTypeUndefined(view, nameList, typeObj);
}
@@ -1447,9 +1455,9 @@ vector<LinearDisassemblyLine> BinaryView::GetNextLinearDisassemblyLines(LinearDi
}
-bool BinaryView::ParseTypeString(const string& text, NameAndType& result, string& errors)
+bool BinaryView::ParseTypeString(const string& text, QualifiedNameAndType& result, string& errors)
{
- BNNameAndType nt;
+ BNQualifiedNameAndType nt;
char* errorStr;
if (!BNParseTypeString(m_object, text.c_str(), &nt, &errorStr))
@@ -1459,22 +1467,28 @@ bool BinaryView::ParseTypeString(const string& text, NameAndType& result, string
return false;
}
- result.name = nt.name;
- result.type = new Type(nt.type);
+ for (size_t i = 0; i < nt.nameCount; i++)
+ result.name.push_back(nt.name[i]);
+ result.type = new Type(BNNewTypeReference(nt.type));
errors = "";
- BNFreeString(nt.name);
+ BNFreeQualifiedNameAndType(&nt);
return true;
}
-map<string, Ref<Type>> BinaryView::GetTypes()
+map<vector<string>, Ref<Type>> BinaryView::GetTypes()
{
size_t count;
- BNNameAndType* types = BNGetAnalysisTypeList(m_object, &count);
+ BNQualifiedNameAndType* types = BNGetAnalysisTypeList(m_object, &count);
- map<string, Ref<Type>> result;
+ map<vector<string>, Ref<Type>> result;
for (size_t i = 0; i < count; i++)
- result[types[i].name] = new Type(BNNewTypeReference(types[i].type));
+ {
+ vector<string> name;
+ for (size_t j = 0; j < types[i].nameCount; j++)
+ name.push_back(types[i].name[j]);
+ result[name] = new Type(BNNewTypeReference(types[i].type));
+ }
BNFreeTypeList(types, count);
return result;
@@ -1483,40 +1497,112 @@ map<string, Ref<Type>> BinaryView::GetTypes()
Ref<Type> BinaryView::GetTypeByName(const string& name)
{
- BNType* type = BNGetAnalysisTypeByName(m_object, name.c_str());
+ const char* nameStr = name.c_str();
+ BNType* type = BNGetAnalysisTypeByName(m_object, &nameStr, 1);
+ if (!type)
+ return nullptr;
+ return new Type(type);
+}
+
+
+Ref<Type> BinaryView::GetTypeByName(const vector<string>& name)
+{
+ const char** nameList = new const char*[name.size()];
+ for (size_t i = 0; i < name.size(); i++)
+ nameList[i] = name[i].c_str();
+
+ BNType* type = BNGetAnalysisTypeByName(m_object, nameList, name.size());
+ delete[] nameList;
+
if (!type)
return nullptr;
return new Type(type);
}
-bool BinaryView::IsTypeAutoDefined(const std::string& name)
+bool BinaryView::IsTypeAutoDefined(const string& name)
+{
+ const char* nameStr = name.c_str();
+ return BNIsAnalysisTypeAutoDefined(m_object, &nameStr, 1);
+}
+
+
+bool BinaryView::IsTypeAutoDefined(const vector<string>& name)
+{
+ const char** nameList = new const char*[name.size()];
+ for (size_t i = 0; i < name.size(); i++)
+ nameList[i] = name[i].c_str();
+ bool result = BNIsAnalysisTypeAutoDefined(m_object, nameList, name.size());
+ delete[] nameList;
+ return result;
+}
+
+
+void BinaryView::DefineType(const string& name, Ref<Type> type)
+{
+ const char* nameStr = name.c_str();
+ BNDefineAnalysisType(m_object, &nameStr, 1, type->GetObject());
+}
+
+
+void BinaryView::DefineType(const vector<string>& name, Ref<Type> type)
+{
+ const char** nameList = new const char*[name.size()];
+ for (size_t i = 0; i < name.size(); i++)
+ nameList[i] = name[i].c_str();
+ BNDefineAnalysisType(m_object, nameList, name.size(), type->GetObject());
+ delete[] nameList;
+}
+
+
+void BinaryView::DefineUserType(const string& name, Ref<Type> type)
+{
+ const char* nameStr = name.c_str();
+ BNDefineUserAnalysisType(m_object, &nameStr, 1, type->GetObject());
+}
+
+
+void BinaryView::DefineUserType(const vector<string>& name, Ref<Type> type)
{
- return BNIsAnalysisTypeAutoDefined(m_object, name.c_str());
+ const char** nameList = new const char*[name.size()];
+ for (size_t i = 0; i < name.size(); i++)
+ nameList[i] = name[i].c_str();
+ BNDefineUserAnalysisType(m_object, nameList, name.size(), type->GetObject());
+ delete[] nameList;
}
-void BinaryView::DefineType(const std::string& name, Ref<Type> type)
+void BinaryView::UndefineType(const string& name)
{
- BNDefineAnalysisType(m_object, name.c_str(), type->GetObject());
+ const char* nameStr = name.c_str();
+ BNUndefineAnalysisType(m_object, &nameStr, 1);
}
-void BinaryView::DefineUserType(const std::string& name, Ref<Type> type)
+void BinaryView::UndefineType(const vector<string>& name)
{
- BNDefineUserAnalysisType(m_object, name.c_str(), type->GetObject());
+ const char** nameList = new const char*[name.size()];
+ for (size_t i = 0; i < name.size(); i++)
+ nameList[i] = name[i].c_str();
+ BNUndefineAnalysisType(m_object, nameList, name.size());
+ delete[] nameList;
}
-void BinaryView::UndefineType(const std::string& name)
+void BinaryView::UndefineUserType(const string& name)
{
- BNUndefineAnalysisType(m_object, name.c_str());
+ const char* nameStr = name.c_str();
+ BNUndefineUserAnalysisType(m_object, &nameStr, 1);
}
-void BinaryView::UndefineUserType(const std::string& name)
+void BinaryView::UndefineUserType(const vector<string>& name)
{
- BNUndefineUserAnalysisType(m_object, name.c_str());
+ const char** nameList = new const char*[name.size()];
+ for (size_t i = 0; i < name.size(); i++)
+ nameList[i] = name[i].c_str();
+ BNUndefineUserAnalysisType(m_object, nameList, name.size());
+ delete[] nameList;
}
diff --git a/python/__init__.py b/python/__init__.py
index cc138009..b5ced583 100644
--- a/python/__init__.py
+++ b/python/__init__.py
@@ -660,6 +660,70 @@ class StringReference(object):
def __repr__(self):
return "<%s: %#x, len %#x>" % (self.type, self.start, self.length)
+class QualifiedName(object):
+ def __init__(self, name = []):
+ if isinstance(name, str):
+ self.name = [name]
+ else:
+ self.name = name
+
+ def __str__(self):
+ return "::".join(self.name)
+
+ def __repr__(self):
+ return repr(str(self))
+
+ def __len__(self):
+ return len(self.name)
+
+ def __hash__(self):
+ return hash(str(self))
+
+ def __eq__(self, other):
+ if isinstance(other, str):
+ return str(self) == other
+ elif isinstance(other, list):
+ return self.name == other
+ elif isinstance(other, QualifiedName):
+ return self.name == other.name
+ return False
+
+ def __ne__(self, other):
+ return not (self == other)
+
+ def __lt__(self, other):
+ if isinstance(other, QualifiedName):
+ return self.name < other.name
+ return False
+
+ def __le__(self, other):
+ if isinstance(other, QualifiedName):
+ return self.name <= other.name
+ return False
+
+ def __gt__(self, other):
+ if isinstance(other, QualifiedName):
+ return self.name > other.name
+ return False
+
+ def __ge__(self, other):
+ if isinstance(other, QualifiedName):
+ return self.name >= other.name
+ return False
+
+ def __cmp__(self, other):
+ if self == other:
+ return 0
+ if self < other:
+ return -1
+ return 1
+
+ def __getitem__(self, key):
+ return self.name[key]
+
+ def __iter__(self):
+ return iter(self.name)
+
class BinaryDataNotificationCallbacks(object):
def __init__(self, view, notify):
self.view = view
@@ -761,15 +825,21 @@ class BinaryDataNotificationCallbacks(object):
except:
log_error(traceback.format_exc())
- def _type_defined(self, ctxt, name, type_obj):
+ def _type_defined(self, ctxt, name, name_count, type_obj):
try:
- self.notify.type_defined(self.view, name, Type(core.BNNewTypeReference(type_obj)))
+ name_list = []
+ for i in xrange(0, name_count):
+ name_list.append(name[i])
+ self.notify.type_defined(self.view, QualifiedName(name_list), Type(core.BNNewTypeReference(type_obj)))
except:
log_error(traceback.format_exc())
- def _type_undefined(self, ctxt, name, type_obj):
+ def _type_undefined(self, ctxt, name, name_count, type_obj):
try:
- self.notify.type_undefined(self.view, name, Type(core.BNNewTypeReference(type_obj)))
+ name_list = []
+ for i in xrange(0, name_count):
+ name_list.append(name[i])
+ self.notify.type_undefined(self.view, QualifiedName(name_list), Type(core.BNNewTypeReference(type_obj)))
except:
log_error(traceback.format_exc())
@@ -1394,7 +1464,10 @@ class BinaryView(object):
type_list = core.BNGetAnalysisTypeList(self.handle, count)
result = {}
for i in xrange(0, count.value):
- result[type_list[i].name] = Type(core.BNNewTypeReference(type_list[i].type))
+ name = []
+ for j in xrange(0, type_list[i].nameCount):
+ name.append(type_list[i].name[j])
+ result[QualifiedName(name)] = Type(core.BNNewTypeReference(type_list[i].type))
core.BNFreeTypeList(type_list, count.value)
return result
@@ -3350,30 +3423,33 @@ class BinaryView(object):
``parse_type_string`` converts `C-style` string into a :py:Class:`Type`.
:param str text: `C-style` string of type to create
- :return: A tuple of a :py:Class:`Type` and string type name
- :rtype: tuple(Type, str)
+ :return: A tuple of a :py:Class:`Type` and type name
+ :rtype: tuple(Type, QualifiedName)
:Example:
>>> bv.parse_type_string("int foo")
(<type: int32_t>, 'foo')
>>>
"""
- result = core.BNNameAndType()
+ result = core.BNQualifiedNameAndType()
errors = ctypes.c_char_p()
if not core.BNParseTypeString(self.handle, text, result, errors):
error_str = errors.value
core.BNFreeString(ctypes.cast(errors, ctypes.POINTER(ctypes.c_byte)))
raise SyntaxError, error_str
type_obj = Type(core.BNNewTypeReference(result.type))
- name = result.name
- core.BNFreeNameAndType(result)
+ name = []
+ for i in xrange(0, result.nameCount):
+ name.append(result.name[i])
+ name = QualifiedName(name)
+ core.BNFreeQualifiedNameAndType(result)
return type_obj, name
def get_type_by_name(self, name):
"""
``get_type_by_name`` returns the defined type whose name corresponds with the provided ``name``
- :param str name: Type name to lookup
+ :param QualifiedName name: Type name to lookup
:return: A :py:Class:`Type` or None if the type does not exist
:rtype: Type or None
:Example:
@@ -3384,7 +3460,12 @@ class BinaryView(object):
<type: int32_t>
>>>
"""
- obj = core.BNGetAnalysisTypeByName(self.handle, name)
+ if isinstance(name, str):
+ name = [name]
+ name_list = (ctypes.c_char_p * len(name))()
+ for i in xrange(0, len(name)):
+ name_list[i] = name[i]
+ obj = core.BNGetAnalysisTypeByName(self.handle, name_list, len(name))
if not obj:
return None
return Type(obj)
@@ -3394,7 +3475,7 @@ class BinaryView(object):
``is_type_auto_defined`` queries the user type list of name. If name is not in the *user* type list then the name
is considered an *auto* type.
- :param str name: Name of type to query
+ :param QualifiedName name: Name of type to query
:return: True if the type is not a *user* type. False if the type is a *user* type.
:Example:
>>> bv.is_type_auto_defined("foo")
@@ -3404,14 +3485,19 @@ class BinaryView(object):
False
>>>
"""
- return core.BNIsAnalysisTypeAutoDefined(self.handle, name)
+ if isinstance(name, str):
+ name = [name]
+ name_list = (ctypes.c_char_p * len(name))()
+ for i in xrange(0, len(name)):
+ name_list[i] = name[i]
+ return core.BNIsAnalysisTypeAutoDefined(self.handle, name_list, len(name))
def define_type(self, name, type_obj):
"""
``define_type`` registers a :py:Class:`Type` ``type_obj`` of the given ``name`` in the global list of types for
the current :py:Class:`BinaryView`.
- :param str name: Name of the type to be registered
+ :param QualifiedName name: Name of the type to be registered
:param Type type_obj: Type object to be registered
:rtype: None
:Example:
@@ -3421,14 +3507,19 @@ class BinaryView(object):
>>> bv.get_type_by_name(name)
<type: int32_t>
"""
- core.BNDefineAnalysisType(self.handle, name, type_obj.handle)
+ if isinstance(name, str):
+ name = [name]
+ name_list = (ctypes.c_char_p * len(name))()
+ for i in xrange(0, len(name)):
+ name_list[i] = name[i]
+ core.BNDefineAnalysisType(self.handle, name_list, len(name), type_obj.handle)
def define_user_type(self, name, type_obj):
"""
``define_user_type`` registers a :py:Class:`Type` ``type_obj`` of the given ``name`` in the global list of user
types for the current :py:Class:`BinaryView`.
- :param str name: Name of the user type to be registered
+ :param QualifiedName name: Name of the user type to be registered
:param Type type_obj: Type object to be registered
:rtype: None
:Example:
@@ -3438,13 +3529,18 @@ class BinaryView(object):
>>> bv.get_type_by_name(name)
<type: int32_t>
"""
- core.BNDefineUserAnalysisType(self.handle, name, type_obj.handle)
+ if isinstance(name, str):
+ name = [name]
+ name_list = (ctypes.c_char_p * len(name))()
+ for i in xrange(0, len(name)):
+ name_list[i] = name[i]
+ core.BNDefineUserAnalysisType(self.handle, name_list, len(name), type_obj.handle)
def undefine_type(self, name):
"""
``undefine_type`` removes a :py:Class:`Type` from the global list of types for the current :py:Class:`BinaryView`
- :param str name: Name of type to be undefined
+ :param QualifiedName name: Name of type to be undefined
:rtype: None
:Example:
@@ -3456,14 +3552,19 @@ class BinaryView(object):
>>> bv.get_type_by_name(name)
>>>
"""
- core.BNUndefineAnalysisType(self.handle, name)
+ if isinstance(name, str):
+ name = [name]
+ name_list = (ctypes.c_char_p * len(name))()
+ for i in xrange(0, len(name)):
+ name_list[i] = name[i]
+ core.BNUndefineAnalysisType(self.handle, name_list, len(name))
def undefine_user_type(self, name):
"""
``undefine_user_type`` removes a :py:Class:`Type` from the global list of user types for the current
:py:Class:`BinaryView`
- :param str name: Name of user type to be undefined
+ :param QualifiedName name: Name of user type to be undefined
:rtype: None
:Example:
@@ -3475,7 +3576,12 @@ class BinaryView(object):
>>> bv.get_type_by_name(name)
>>>
"""
- core.BNUndefineUserAnalysisType(self.handle, name)
+ if isinstance(name, str):
+ name = [name]
+ name_list = (ctypes.c_char_p * len(name))()
+ for i in xrange(0, len(name)):
+ name_list[i] = name[i]
+ core.BNUndefineUserAnalysisType(self.handle, name_list, len(name))
def find_next_data(self, start, data, flags = 0):
"""
@@ -4314,6 +4420,14 @@ class Type(object):
return Enumeration(result)
@property
+ def named_type_reference(self):
+ """Reference to a named type (read-only)"""
+ result = core.BNGetTypeNamedTypeReference(self.handle)
+ if result is None:
+ return None
+ return NamedTypeReference(result)
+
+ @property
def count(self):
"""Type count (read-only)"""
return core.BNGetTypeElementCount(self.handle)
@@ -4351,12 +4465,19 @@ class Type(object):
return Type(core.BNCreateStructureType(structure_type.handle))
@classmethod
- def unknown_type(self, unknown_type):
- return Type(core.BNCreateUnknownType(unknown_type.handle))
+ def named_type(self, named_type, width = 0, align = 1):
+ return Type(core.BNCreateNamedTypeReference(named_type.handle, width, align))
@classmethod
- def unknown_type(self, s):
- return Type(core.BNCreateUnknownType(s.handle))
+ def named_type_from_type(self, name, t):
+ if isinstance(name, str):
+ name = [name]
+ name_list = (ctypes.c_char_p * len(name))()
+ for i in xrange(0, len(name)):
+ name_list[i] = name[i]
+ if t is not None:
+ t = t.handle
+ return Type(core.BNCreateNamedTypeReferenceFromType(name_list, len(name), t))
@classmethod
def enumeration_type(self, arch, e, width = None):
@@ -4394,28 +4515,60 @@ class Type(object):
raise AttributeError, "attribute '%s' is read only" % name
-class UnknownType(object):
- def __init__(self, handle = None):
+class NamedTypeReference(object):
+ def __init__(self, type_class = core.UnknownNamedTypeClass, name = None, handle = None):
if handle is None:
- self.handle = core.BNCreateUnknownType()
+ self.handle = core.BNCreateNamedType()
+ core.BNSetTypeReferenceClass(self.handle, type_class)
+ if name is not None:
+ if isinstance(name, str):
+ name = [name]
+ name_list = (ctypes.c_char_p * len(name))()
+ for i in xrange(0, len(name)):
+ name_list[i] = name[i]
+ core.BNSetTypeReferenceName(self.handle, name_list, len(name))
else:
self.handle = handle
def __del__(self):
- core.BNFreeUnknownType(self.handle)
+ core.BNFreeNamedTypeReference(self.handle)
+
+ @property
+ def type_class(self):
+ return core.BNGetTypeReferenceClass(self.handle)
+
+ @type_class.setter
+ def type_class(self, value):
+ core.BNSetTypeReferenceClass(self.handle, value)
@property
def name(self):
count = ctypes.c_ulonglong()
- nameList = core.BNGetUnknownTypeName(self.handle, count)
+ nameList = core.BNGetTypeReferenceName(self.handle, count)
result = []
for i in xrange(count.value):
result.append(nameList[i])
- return get_qualified_name(result)
+ return QualifiedName(result)
@name.setter
def name(self, value):
- core.BNSetUnknownTypeName(self.handle, value)
+ if isinstance(value, str):
+ value = [value]
+ name_list = (ctypes.c_char_p * len(value))()
+ for i in xrange(0, len(value)):
+ name_list[i] = value[i]
+ core.BNSetTypeReferenceName(self.handle, name_list, len(value))
+
+ def __repr__(self):
+ if self.type_class == core.TypedefNamedTypeClass:
+ return "<named type: typedef %s>" % str(self.name)
+ if self.type_class == core.StructNamedTypeClass:
+ return "<named type: struct %s>" % str(self.name)
+ if self.type_class == core.UnionNamedTypeClass:
+ return "<named type: union %s>" % str(self.name)
+ if self.type_class == core.EnumNamedTypeClass:
+ return "<named type: enum %s>" % str(self.name)
+ return "<named type: unknown %s>" % str(self.name)
class StructureMember(object):
@@ -4441,19 +4594,6 @@ class Structure(object):
core.BNFreeStructure(self.handle)
@property
- def name(self):
- count = ctypes.c_ulonglong()
- nameList = core.BNGetStructureName(self.handle, count)
- result = []
- for i in xrange(count.value):
- result.append(nameList[i])
- return get_qualified_name(result)
-
- @name.setter
- def name(self, value):
- core.BNSetStructureName(self.handle, value)
-
- @property
def members(self):
"""Structure member list (read-only)"""
count = ctypes.c_ulonglong()
@@ -4539,14 +4679,6 @@ class Enumeration(object):
core.BNFreeEnumeration(self.handle)
@property
- def name(self):
- return core.BNGetEnumerationName(self.handle)
-
- @name.setter
- def name(self, value):
- core.BNSetEnumerationName(self.handle, value)
-
- @property
def members(self):
"""Enumeration member list (read-only)"""
count = ctypes.c_ulonglong()
@@ -7423,8 +7555,8 @@ class Architecture(object):
:param str source: source string to be parsed
:param str filename: optional source filename
:param list(str) include_dirs: optional list of string filename include directories
- :return: a tuple of py:class:`TypeParserResult` and error string
- :rtype: tuple(TypeParserResult,str)
+ :return: py:class:`TypeParserResult` (a SyntaxError is thrown on parse error)
+ :rtype: TypeParserResult
:Example:
>>> arch.parse_types_from_source('int foo;\\nint bar(int x);\\nstruct bas{int x,y;};\\n')
@@ -7444,18 +7576,27 @@ class Architecture(object):
error_str = errors.value
core.BNFreeString(ctypes.cast(errors, ctypes.POINTER(ctypes.c_byte)))
if not result:
- return (None, error_str)
+ raise SyntaxError, error_str
types = {}
variables = {}
functions = {}
for i in xrange(0, parse.typeCount):
- types[parse.types[i].name] = Type(core.BNNewTypeReference(parse.types[i].type))
+ name = []
+ for j in xrange(0, parse.types[i].nameCount):
+ name.append(parse.types[i].name[j])
+ types[QualifiedName(name)] = Type(core.BNNewTypeReference(parse.types[i].type))
for i in xrange(0, parse.variableCount):
- variables[parse.variables[i].name] = Type(core.BNNewTypeReference(parse.variables[i].type))
+ name = []
+ for j in xrange(0, parse.variables[i].nameCount):
+ name.append(parse.variables[i].name[j])
+ variables[QualifiedName(name)] = Type(core.BNNewTypeReference(parse.variables[i].type))
for i in xrange(0, parse.functionCount):
- functions[parse.functions[i].name] = Type(core.BNNewTypeReference(parse.functions[i].type))
- BNFreeTypeParserResult(parse)
- return (TypeParserResult(types, variables, functions), error_str)
+ name = []
+ for j in xrange(0, parse.functions[i].nameCount):
+ name.append(parse.functions[i].name[j])
+ functions[QualifiedName(name)] = Type(core.BNNewTypeReference(parse.functions[i].type))
+ core.BNFreeTypeParserResult(parse)
+ return TypeParserResult(types, variables, functions)
def parse_types_from_source_file(self, filename, include_dirs = []):
"""
@@ -7464,8 +7605,8 @@ class Architecture(object):
:param str filename: filename of file to be parsed
:param list(str) include_dirs: optional list of string filename include directories
- :return: a tuple of py:class:`TypeParserResult` and error string
- :rtype: tuple(TypeParserResult, str)
+ :return: py:class:`TypeParserResult` (a SyntaxError is thrown on parse error)
+ :rtype: TypeParserResult
:Example:
>>> file = "/Users/binja/tmp.c"
@@ -7485,18 +7626,27 @@ class Architecture(object):
error_str = errors.value
core.BNFreeString(ctypes.cast(errors, ctypes.POINTER(ctypes.c_byte)))
if not result:
- return (None, error_str)
+ raise SyntaxError, error_str
types = {}
variables = {}
functions = {}
for i in xrange(0, parse.typeCount):
- types[parse.types[i].name] = Type(core.BNNewTypeReference(parse.types[i].type))
+ name = []
+ for j in xrange(0, parse.types[i].nameCount):
+ name.append(parse.types[i].name[j])
+ types[QualifiedName(name)] = Type(core.BNNewTypeReference(parse.types[i].type))
for i in xrange(0, parse.variableCount):
- variables[parse.variables[i].name] = Type(core.BNNewTypeReference(parse.variables[i].type))
+ name = []
+ for j in xrange(0, parse.variables[i].nameCount):
+ name.append(parse.variables[i].name[j])
+ variables[QualifiedName(name)] = Type(core.BNNewTypeReference(parse.variables[i].type))
for i in xrange(0, parse.functionCount):
- functions[parse.functions[i].name] = Type(core.BNNewTypeReference(parse.functions[i].type))
- BNFreeTypeParserResult(parse)
- return (TypeParserResult(types, variables, functions), error_str)
+ name = []
+ for j in xrange(0, parse.functions[i].nameCount):
+ name.append(parse.functions[i].name[j])
+ functions[QualifiedName(name)] = Type(core.BNNewTypeReference(parse.functions[i].type))
+ core.BNFreeTypeParserResult(parse)
+ return TypeParserResult(types, variables, functions)
def register_calling_convention(self, cc):
"""
diff --git a/python/generator.cpp b/python/generator.cpp
index 08485315..4c313fdd 100644
--- a/python/generator.cpp
+++ b/python/generator.cpp
@@ -97,11 +97,8 @@ void OutputType(FILE* out, Type* type, bool isReturnType = false, bool isCallbac
else
fprintf(out, "ctypes.c_double");
break;
- case StructureTypeClass:
- fprintf(out, "%s", type->GetQualifiedName(type->GetStructure()->GetName()).c_str());
- break;
- case EnumerationTypeClass:
- fprintf(out, "%s", type->GetQualifiedName(type->GetEnumeration()->GetName()).c_str());
+ case NamedTypeReferenceClass:
+ fprintf(out, "%s", type->GetQualifiedName(type->GetNamedTypeReference()->GetName()).c_str());
break;
case PointerTypeClass:
if (isCallback || (type->GetChildType()->GetClass() == VoidTypeClass))
@@ -156,7 +153,7 @@ int main(int argc, char* argv[])
Architecture::Register(new GeneratorArchitecture());
// Parse API header to get type and function information
- map<string, Ref<Type>> types, vars, funcs;
+ map<vector<string>, Ref<Type>> types, vars, funcs;
string errors;
bool ok = Architecture::GetByName("generator")->ParseTypesFromSourceFile(argv[1], types, vars, funcs, errors);
fprintf(stderr, "%s", errors.c_str());
@@ -187,21 +184,25 @@ int main(int argc, char* argv[])
map<string, int64_t> enumMembers;
for (auto& i : types)
{
+ string name;
+ if (i.first.size() != 1)
+ continue;
+ name = i.first[0];
if (i.second->GetClass() == StructureTypeClass)
{
- fprintf(out, "class %s(ctypes.Structure):\n", i.first.c_str());
+ fprintf(out, "class %s(ctypes.Structure):\n", name.c_str());
fprintf(out, " pass\n");
}
else if (i.second->GetClass() == EnumerationTypeClass)
{
- fprintf(out, "%s = ctypes.c_int\n", i.first.c_str());
+ fprintf(out, "%s = ctypes.c_int\n", name.c_str());
for (auto& j : i.second->GetEnumeration()->GetMembers())
fprintf(out, "%s = %" PRId64 "\n", j.name.c_str(), j.value);
- fprintf(out, "%s_names = {\n", i.first.c_str());
+ fprintf(out, "%s_names = {\n", name.c_str());
for (auto& j : i.second->GetEnumeration()->GetMembers())
fprintf(out, " %" PRId64 ": \"%s\",\n", j.value, j.name.c_str());
fprintf(out, "}\n");
- fprintf(out, "%s_by_name = {\n", i.first.c_str());
+ fprintf(out, "%s_by_name = {\n", name.c_str());
for (auto& j : i.second->GetEnumeration()->GetMembers())
fprintf(out, " \"%s\": %" PRId64 ",\n", j.name.c_str(), j.value);
fprintf(out, "}\n");
@@ -211,7 +212,7 @@ int main(int argc, char* argv[])
else if ((i.second->GetClass() == BoolTypeClass) || (i.second->GetClass() == IntegerTypeClass) ||
(i.second->GetClass() == FloatTypeClass) || (i.second->GetClass() == ArrayTypeClass))
{
- fprintf(out, "%s = ", i.first.c_str());
+ fprintf(out, "%s = ", name.c_str());
OutputType(out, i.second);
fprintf(out, "\n");
}
@@ -225,9 +226,13 @@ int main(int argc, char* argv[])
fprintf(out, "\n# Structure definitions\n");
for (auto& i : types)
{
+ string name;
+ if (i.first.size() != 1)
+ continue;
+ name = i.first[0];
if ((i.second->GetClass() == StructureTypeClass) && (i.second->GetStructure()->GetMembers().size() != 0))
{
- fprintf(out, "%s._fields_ = [\n", i.first.c_str());
+ fprintf(out, "%s._fields_ = [\n", name.c_str());
for (auto& j : i.second->GetStructure()->GetMembers())
{
fprintf(out, " (\"%s\", ", j.name.c_str());
@@ -241,6 +246,11 @@ int main(int argc, char* argv[])
fprintf(out, "\n# Function definitions\n");
for (auto& i : funcs)
{
+ string name;
+ if (i.first.size() != 1)
+ continue;
+ name = i.first[0];
+
// Check for a string result, these will be automatically wrapped to free the string
// memory and return a Python string
bool stringResult = (i.second->GetChildType()->GetClass() == PointerTypeClass) &&
@@ -249,7 +259,7 @@ int main(int argc, char* argv[])
// Pointer returns will be automatically wrapped to return None on null pointer
bool pointerResult = (i.second->GetChildType()->GetClass() == PointerTypeClass);
bool callbackConvention = false;
- if (i.first == "BNAllocString")
+ if (name == "BNAllocString")
{
// Don't perform automatic wrapping of string allocation, and return a void
// pointer so that callback functions (which is the only valid use of BNAllocString)
@@ -258,11 +268,11 @@ int main(int argc, char* argv[])
callbackConvention = true;
}
- string funcName = i.first;
+ string funcName = name;
if (stringResult || pointerResult)
funcName = string("_") + funcName;
- fprintf(out, "%s = core.%s\n", funcName.c_str(), i.first.c_str());
+ fprintf(out, "%s = core.%s\n", funcName.c_str(), name.c_str());
fprintf(out, "%s.restype = ", funcName.c_str());
OutputType(out, i.second->GetChildType(), true, callbackConvention);
fprintf(out, "\n");
@@ -272,7 +282,7 @@ int main(int argc, char* argv[])
for (auto& j : i.second->GetParameters())
{
fprintf(out, " ");
- if (i.first == "BNFreeString")
+ if (name == "BNFreeString")
{
// BNFreeString expects a pointer to a string allocated by the core, so do not use
// a c_char_p here, as that would be allocated by the Python runtime. This can
@@ -291,7 +301,7 @@ int main(int argc, char* argv[])
if (stringResult)
{
// Emit wrapper to get Python string and free native memory
- fprintf(out, "def %s(*args):\n", i.first.c_str());
+ fprintf(out, "def %s(*args):\n", name.c_str());
fprintf(out, " result = %s(*args)\n", funcName.c_str());
fprintf(out, " string = ctypes.cast(result, ctypes.c_char_p).value\n");
fprintf(out, " BNFreeString(result)\n");
@@ -300,7 +310,7 @@ int main(int argc, char* argv[])
else if (pointerResult)
{
// Emit wrapper to return None on null pointer
- fprintf(out, "def %s(*args):\n", i.first.c_str());
+ fprintf(out, "def %s(*args):\n", name.c_str());
fprintf(out, " result = %s(*args)\n", funcName.c_str());
fprintf(out, " if not result:\n");
fprintf(out, " return None\n");
diff --git a/type.cpp b/type.cpp
index c8cfdc33..0571f743 100644
--- a/type.cpp
+++ b/type.cpp
@@ -133,6 +133,15 @@ Ref<Enumeration> Type::GetEnumeration() const
}
+Ref<NamedTypeReference> Type::GetNamedTypeReference() const
+{
+ BNNamedTypeReference* ref = BNGetTypeNamedTypeReference(m_object);
+ if (ref)
+ return new NamedTypeReference(ref);
+ return nullptr;
+}
+
+
uint64_t Type::GetElementCount() const
{
return BNGetTypeElementCount(m_object);
@@ -307,9 +316,21 @@ Ref<Type> Type::StructureType(Structure* strct)
}
-Ref<Type> Type::UnknownNamedType(UnknownType* unknwn)
+Ref<Type> Type::NamedType(NamedTypeReference* ref, size_t width, size_t align)
{
- return new Type(BNCreateUnknownNamedType(unknwn->GetObject()));
+ return new Type(BNCreateNamedTypeReference(ref->GetObject(), width, align));
+}
+
+
+Ref<Type> Type::NamedType(const vector<string>& name, Type* type)
+{
+ const char** nameList = new const char*[name.size()];
+ for (size_t i = 0; i < name.size(); i++)
+ nameList[i] = name[i].c_str();
+ Type* result = new Type(BNCreateNamedTypeReferenceFromType(nameList, name.size(),
+ type ? type->GetObject() : nullptr));
+ delete[] nameList;
+ return result;
}
@@ -355,35 +376,54 @@ void Type::SetFunctionCanReturn(bool canReturn)
}
-UnknownType::UnknownType(BNUnknownType* ut, vector<string> names)
+NamedTypeReference::NamedTypeReference(BNNamedTypeReference* nt)
+{
+ m_object = nt;
+}
+
+
+NamedTypeReference::NamedTypeReference(BNNamedTypeReferenceClass cls, const vector<string>& names)
{
- m_object = ut;
+ m_object = BNCreateNamedType();
+ BNSetTypeReferenceClass(m_object, cls);
const char ** nameList = new const char*[names.size()];
for (size_t i = 0; i < names.size(); i++)
{
nameList[i] = names[i].c_str();
}
- BNSetUnknownTypeName(ut, nameList, names.size());
+ BNSetTypeReferenceName(m_object, nameList, names.size());
delete [] nameList;
}
-void UnknownType::SetName(const vector<string>& names)
+void NamedTypeReference::SetTypeClass(BNNamedTypeReferenceClass cls)
+{
+ BNSetTypeReferenceClass(m_object, cls);
+}
+
+
+BNNamedTypeReferenceClass NamedTypeReference::GetTypeClass() const
+{
+ return BNGetTypeReferenceClass(m_object);
+}
+
+
+void NamedTypeReference::SetName(const vector<string>& names)
{
const char ** nameList = new const char*[names.size()];
for (size_t i = 0; i < names.size(); i++)
{
nameList[i] = names[i].c_str();
}
- BNSetUnknownTypeName(m_object, nameList, names.size());
+ BNSetTypeReferenceName(m_object, nameList, names.size());
delete [] nameList;
}
-vector<string> UnknownType::GetName() const
+vector<string> NamedTypeReference::GetName() const
{
size_t size;
- char** name = BNGetUnknownTypeName(m_object, &size);
+ char** name = BNGetTypeReferenceName(m_object, &size);
vector<string> result;
for (size_t i = 0; i < size; i++)
{
@@ -407,33 +447,6 @@ Structure::Structure(BNStructure* s)
}
-vector<string> Structure::GetName() const
-{
- size_t size;
- char** name = BNGetStructureName(m_object, &size);
- vector<string> result;
- for (size_t i = 0; i < size; i++)
- {
- result.push_back(name[i]);
- BNFreeString(name[i]);
- }
- delete [] name;
- return result;
-}
-
-
-void Structure::SetName(const vector<string>& names)
-{
- const char ** nameList = new const char*[names.size()];
- for (size_t i = 0; i < names.size(); i++)
- {
- nameList[i] = names[i].c_str();
- }
- BNSetStructureName(m_object, nameList, names.size());
- delete [] nameList;
-}
-
-
vector<StructureMember> Structure::GetMembers() const
{
size_t count;
@@ -532,32 +545,6 @@ Enumeration::Enumeration(BNEnumeration* e)
}
-vector<string> Enumeration::GetName() const
-{
- vector<string> result;
- size_t size;
- char** name = BNGetEnumerationName(m_object, &size);
- for (size_t i = 0; i < size; i++)
- {
- result.push_back(name[i]);
- BNFreeString(name[i]);
- }
- delete [] name;
- return result;
-}
-
-void Enumeration::SetName(const vector<string>& names)
-{
- const char **const nameList = new const char*[names.size()];
- for (size_t i = 0; i < names.size(); i++)
- {
- nameList[i] = names[i].c_str();
- }
- BNSetEnumerationName(m_object, nameList, names.size());
- delete [] nameList;
-}
-
-
vector<EnumerationMember> Enumeration::GetMembers() const
{
size_t count;