summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRusty Wagner <rusty@vector35.com>2015-07-10 01:03:30 -0400
committerRusty Wagner <rusty@vector35.com>2015-07-10 01:03:30 -0400
commit680179d22dee90938666b9e5b2033bcb6c48c7d2 (patch)
treed3ddd65f0bada990efa2d2f794e9066979414a72
parent5e539bf3e497a9781037fcddf6be6a51e551fce4 (diff)
Initial implementation of low level IL
-rw-r--r--api.pro1
-rw-r--r--architecture.cpp104
-rw-r--r--binaryninjaapi.h117
-rw-r--r--function.cpp22
-rw-r--r--functiongraph.cpp4
-rw-r--r--lowlevelil.cpp453
6 files changed, 697 insertions, 4 deletions
diff --git a/api.pro b/api.pro
index 57eb935c..52f63afc 100644
--- a/api.pro
+++ b/api.pro
@@ -27,6 +27,7 @@ SOURCES += \
functiongraphblock.cpp \
log.cpp \
tempfile.cpp \
+ lowlevelil.cpp \
../core/json/jsoncpp.cpp
HEADERS += binaryninjaapi.h
diff --git a/architecture.cpp b/architecture.cpp
index da18e9c1..83e577b6 100644
--- a/architecture.cpp
+++ b/architecture.cpp
@@ -1,3 +1,6 @@
+#define _CRT_SECURE_NO_WARNINGS
+#include <stdio.h>
+#include <inttypes.h>
#include "binaryninjaapi.h"
using namespace BinaryNinja;
@@ -102,6 +105,39 @@ void Architecture::FreeInstructionTextCallback(BNInstructionTextToken* tokens, s
}
+bool Architecture::GetInstructionLowLevelILCallback(void* ctxt, const uint8_t* data, uint64_t addr,
+ size_t* len, BNLowLevelILFunction* il)
+{
+ Architecture* arch = (Architecture*)ctxt;
+ LowLevelILFunction func(BNNewLowLevelILFunctionReference(il));
+ return arch->GetInstructionLowLevelIL(data, addr, *len, func);
+}
+
+
+char* Architecture::GetRegisterNameCallback(void* ctxt, uint32_t reg)
+{
+ Architecture* arch = (Architecture*)ctxt;
+ string result = arch->GetRegisterName(reg);
+ return BNAllocString(result.c_str());
+}
+
+
+char* Architecture::GetFlagNameCallback(void* ctxt, uint32_t flag)
+{
+ Architecture* arch = (Architecture*)ctxt;
+ string result = arch->GetFlagName(flag);
+ return BNAllocString(result.c_str());
+}
+
+
+char* Architecture::GetFlagWriteTypeNameCallback(void* ctxt, uint32_t flags)
+{
+ Architecture* arch = (Architecture*)ctxt;
+ string result = arch->GetFlagWriteTypeName(flags);
+ return BNAllocString(result.c_str());
+}
+
+
bool Architecture::AssembleCallback(void* ctxt, const char* code, uint64_t addr, BNDataBuffer* result, char** errors)
{
Architecture* arch = (Architecture*)ctxt;
@@ -187,6 +223,10 @@ void Architecture::Register(Architecture* arch)
callbacks.getInstructionInfo = GetInstructionInfoCallback;
callbacks.getInstructionText = GetInstructionTextCallback;
callbacks.freeInstructionText = FreeInstructionTextCallback;
+ callbacks.getInstructionLowLevelIL = GetInstructionLowLevelILCallback;
+ callbacks.getRegisterName = GetRegisterNameCallback;
+ callbacks.getFlagName = GetFlagNameCallback;
+ callbacks.getFlagWriteTypeName = GetFlagWriteTypeNameCallback;
callbacks.assemble = AssembleCallback;
callbacks.isNeverBranchPatchAvailable = IsNeverBranchPatchAvailableCallback;
callbacks.isAlwaysBranchPatchAvailable = IsAlwaysBranchPatchAvailableCallback;
@@ -234,6 +274,37 @@ string Architecture::GetName() const
}
+bool Architecture::GetInstructionLowLevelIL(const uint8_t*, uint64_t, size_t&, LowLevelILFunction& il)
+{
+ il.AddInstruction(il.Unimplemented());
+ return false;
+}
+
+
+string Architecture::GetRegisterName(uint32_t reg)
+{
+ char regStr[32];
+ sprintf(regStr, "r%" PRIu32, reg);
+ return regStr;
+}
+
+
+string Architecture::GetFlagName(uint32_t flag)
+{
+ char flagStr[32];
+ sprintf(flagStr, "flag%" PRIu32, flag);
+ return flagStr;
+}
+
+
+string Architecture::GetFlagWriteTypeName(uint32_t flags)
+{
+ char flagStr[32];
+ sprintf(flagStr, "update%" PRIu32, flags);
+ return flagStr;
+}
+
+
bool Architecture::Assemble(const std::string&, uint64_t, DataBuffer&, std::string& errors)
{
errors = "Architecture does not implement an assembler.\n";
@@ -333,6 +404,39 @@ bool CoreArchitecture::GetInstructionText(const uint8_t* data, uint64_t addr, si
}
+bool CoreArchitecture::GetInstructionLowLevelIL(const uint8_t* data, uint64_t addr, size_t& len, LowLevelILFunction& il)
+{
+ return BNGetInstructionLowLevelIL(m_arch, data, addr, &len, il.GetFunctionObject());
+}
+
+
+string CoreArchitecture::GetRegisterName(uint32_t reg)
+{
+ char* name = BNGetArchitectureRegisterName(m_arch, reg);
+ string result = name;
+ BNFreeString(name);
+ return result;
+}
+
+
+string CoreArchitecture::GetFlagName(uint32_t flag)
+{
+ char* name = BNGetArchitectureFlagName(m_arch, flag);
+ string result = name;
+ BNFreeString(name);
+ return result;
+}
+
+
+string CoreArchitecture::GetFlagWriteTypeName(uint32_t flags)
+{
+ char* name = BNGetArchitectureFlagWriteTypeName(m_arch, flags);
+ string result = name;
+ BNFreeString(name);
+ return result;
+}
+
+
bool CoreArchitecture::Assemble(const string& code, uint64_t addr, DataBuffer& result, string& errors)
{
char* errorStr = nullptr;
diff --git a/binaryninjaapi.h b/binaryninjaapi.h
index 0b9f91bb..971c900e 100644
--- a/binaryninjaapi.h
+++ b/binaryninjaapi.h
@@ -789,6 +789,8 @@ namespace BinaryNinja
InstructionTextToken(BNInstructionTextTokenType type, const std::string& text, uint64_t value = 0);
};
+ class LowLevelILFunction;
+
class Architecture: public RefCountObject
{
protected:
@@ -804,6 +806,11 @@ namespace BinaryNinja
static bool GetInstructionTextCallback(void* ctxt, const uint8_t* data, uint64_t addr,
size_t* len, BNInstructionTextToken** result, size_t* count);
static void FreeInstructionTextCallback(BNInstructionTextToken* tokens, size_t count);
+ static bool GetInstructionLowLevelILCallback(void* ctxt, const uint8_t* data, uint64_t addr,
+ size_t* len, BNLowLevelILFunction* il);
+ static char* GetRegisterNameCallback(void* ctxt, uint32_t reg);
+ static char* GetFlagNameCallback(void* ctxt, uint32_t flag);
+ static char* GetFlagWriteTypeNameCallback(void* ctxt, uint32_t flags);
static bool AssembleCallback(void* ctxt, const char* code, uint64_t addr, BNDataBuffer* result, char** errors);
static bool IsNeverBranchPatchAvailableCallback(void* ctxt, const uint8_t* data, uint64_t addr, size_t len);
@@ -835,6 +842,11 @@ namespace BinaryNinja
virtual bool GetInstructionText(const uint8_t* data, uint64_t addr, size_t& len,
std::vector<InstructionTextToken>& result) = 0;
+ virtual bool GetInstructionLowLevelIL(const uint8_t* data, uint64_t addr, size_t& len, LowLevelILFunction& il);
+ virtual std::string GetRegisterName(uint32_t reg);
+ virtual std::string GetFlagName(uint32_t flag);
+ virtual std::string GetFlagWriteTypeName(uint32_t flags);
+
virtual bool Assemble(const std::string& code, uint64_t addr, DataBuffer& result, std::string& errors);
virtual bool IsNeverBranchPatchAvailable(const uint8_t* data, uint64_t addr, size_t len);
@@ -858,6 +870,10 @@ namespace BinaryNinja
virtual bool GetInstructionInfo(const uint8_t* data, uint64_t addr, size_t maxLen, InstructionInfo& result) override;
virtual bool GetInstructionText(const uint8_t* data, uint64_t addr, size_t& len,
std::vector<InstructionTextToken>& result) override;
+ virtual bool GetInstructionLowLevelIL(const uint8_t* data, uint64_t addr, size_t& len, LowLevelILFunction& il) override;
+ virtual std::string GetRegisterName(uint32_t reg) override;
+ virtual std::string GetFlagName(uint32_t flag) override;
+ virtual std::string GetFlagWriteTypeName(uint32_t flags) override;
virtual bool Assemble(const std::string& code, uint64_t addr, DataBuffer& result, std::string& errors) override;
virtual bool IsNeverBranchPatchAvailable(const uint8_t* data, uint64_t addr, size_t len) override;
@@ -920,6 +936,9 @@ namespace BinaryNinja
std::vector<Ref<BasicBlock>> GetBasicBlocks() const;
void MarkRecentUse();
+ Ref<LowLevelILFunction> GetLowLevelIL() const;
+ std::vector<Ref<BasicBlock>> GetLowLevelILBasicBlocks() const;
+
Ref<FunctionGraph> CreateFunctionGraph();
};
@@ -981,7 +1000,7 @@ namespace BinaryNinja
size_t GetMaximumSymbolWidth() const;
void SetMaximumSymbolWidth(size_t width);
- void StartLayout();
+ void StartLayout(BNFunctionGraphType = NormalFunctionGraph);
bool IsLayoutComplete();
void OnComplete(const std::function<void()>& func);
void Abort();
@@ -992,4 +1011,100 @@ namespace BinaryNinja
int GetHeight() const;
std::vector<Ref<FunctionGraphBlock>> GetBlocksInRegion(int left, int top, int right, int bottom);
};
+
+ struct LowLevelILLabel: public BNLowLevelILLabel
+ {
+ LowLevelILLabel();
+ };
+
+ class LowLevelILFunction: public RefCountObject
+ {
+ BNLowLevelILFunction* m_func;
+
+ public:
+ LowLevelILFunction();
+ LowLevelILFunction(BNLowLevelILFunction* func);
+ ~LowLevelILFunction();
+
+ BNLowLevelILFunction* GetFunctionObject() const { return m_func; }
+
+ uint64_t GetCurrentAddress() const;
+ void SetCurrentAddress(uint64_t addr);
+
+ size_t AddExpr(BNLowLevelILOperation operation, size_t size, uint32_t flags,
+ uint64_t a = 0, uint64_t b = 0, uint64_t c = 0, uint64_t d = 0);
+ size_t AddInstruction(size_t expr);
+
+ size_t Nop();
+ size_t SetRegister(size_t size, uint32_t reg, uint64_t val);
+ size_t SetRegisterSplit(size_t size, uint32_t high, uint32_t low, uint64_t val);
+ size_t SetFlag(uint32_t flag, uint64_t val);
+ size_t Load(size_t size, uint64_t addr);
+ size_t Store(size_t size, uint64_t addr, uint64_t val);
+ size_t Push(size_t size, uint64_t val);
+ size_t Pop(size_t size);
+ size_t Register(size_t size, uint32_t reg);
+ size_t Const(size_t size, uint64_t val);
+ size_t Flag(uint32_t reg);
+ size_t Add(size_t size, uint64_t a, uint64_t b, uint32_t flags = 0);
+ size_t AddCarry(size_t size, uint64_t a, uint64_t b, uint32_t flags = 0);
+ size_t Sub(size_t size, uint64_t a, uint64_t b, uint32_t flags = 0);
+ size_t SubBorrow(size_t size, uint64_t a, uint64_t b, uint32_t flags = 0);
+ size_t And(size_t size, uint64_t a, uint64_t b, uint32_t flags = 0);
+ size_t Or(size_t size, uint64_t a, uint64_t b, uint32_t flags = 0);
+ size_t Xor(size_t size, uint64_t a, uint64_t b, uint32_t flags = 0);
+ size_t ShiftLeft(size_t size, uint64_t a, uint64_t b, uint32_t flags = 0);
+ size_t LogicalShiftRight(size_t size, uint64_t a, uint64_t b, uint32_t flags = 0);
+ size_t ArithShiftRight(size_t size, uint64_t a, uint64_t b, uint32_t flags = 0);
+ size_t RotateLeft(size_t size, uint64_t a, uint64_t b, uint32_t flags = 0);
+ size_t RotateLeftCarry(size_t size, uint64_t a, uint64_t b, uint32_t flags = 0);
+ size_t RotateRight(size_t size, uint64_t a, uint64_t b, uint32_t flags = 0);
+ size_t RotateRightCarry(size_t size, uint64_t a, uint64_t b, uint32_t flags = 0);
+ size_t Mult(size_t size, uint64_t a, uint64_t b, uint32_t flags = 0);
+ size_t MultDoublePrecUnsigned(size_t size, uint64_t a, uint64_t b, uint32_t flags = 0);
+ size_t MultDoublePrecSigned(size_t size, uint64_t a, uint64_t b, uint32_t flags = 0);
+ size_t DivUnsigned(size_t size, uint64_t a, uint64_t b, uint32_t flags = 0);
+ size_t DivDoublePrecUnsigned(size_t size, uint64_t high, uint64_t low, uint64_t div, uint32_t flags = 0);
+ size_t DivSigned(size_t size, uint64_t a, uint64_t b, uint32_t flags = 0);
+ size_t DivDoublePrecSigned(size_t size, uint64_t high, uint64_t low, uint64_t div, uint32_t flags = 0);
+ size_t ModUnsigned(size_t size, uint64_t a, uint64_t b, uint32_t flags = 0);
+ size_t ModDoublePrecUnsigned(size_t size, uint64_t high, uint64_t low, uint64_t div, uint32_t flags = 0);
+ size_t ModSigned(size_t size, uint64_t a, uint64_t b, uint32_t flags = 0);
+ size_t ModDoublePrecSigned(size_t size, uint64_t high, uint64_t low, uint64_t div, uint32_t flags = 0);
+ size_t Neg(size_t size, uint64_t a, uint32_t flags = 0);
+ size_t Not(size_t size, uint64_t a, uint32_t flags = 0);
+ size_t SignExtend(size_t size, uint64_t a);
+ size_t ZeroExtend(size_t size, uint64_t a);
+ size_t Jump(uint64_t dest);
+ size_t Call(uint64_t dest);
+ size_t Return(size_t dest);
+ size_t FlagCondition(BNLowLevelILFlagCondition cond);
+ size_t CompareEqual(size_t size, uint64_t a, uint64_t b);
+ size_t CompareNotEqual(size_t size, uint64_t a, uint64_t b);
+ size_t CompareSignedLessThan(size_t size, uint64_t a, uint64_t b);
+ size_t CompareUnsignedLessThan(size_t size, uint64_t a, uint64_t b);
+ size_t CompareSignedLessEqual(size_t size, uint64_t a, uint64_t b);
+ size_t CompareUnsignedLessEqual(size_t size, uint64_t a, uint64_t b);
+ size_t CompareSignedGreaterEqual(size_t size, uint64_t a, uint64_t b);
+ size_t CompareUnsignedGreaterEqual(size_t size, uint64_t a, uint64_t b);
+ size_t CompareSignedGreaterThan(size_t size, uint64_t a, uint64_t b);
+ size_t CompareUnsignedGreaterThan(size_t size, uint64_t a, uint64_t b);
+ size_t SystemCall();
+ size_t Undefined();
+ size_t Unimplemented();
+ size_t UnimplementedMemoryRef(size_t size, uint64_t addr);
+
+ size_t Goto(BNLowLevelILLabel& label);
+ size_t If(uint64_t operand, BNLowLevelILLabel& t, BNLowLevelILLabel& f);
+ void MarkLabel(BNLowLevelILLabel& label);
+
+ BNLowLevelILInstruction operator[](size_t i) const;
+ size_t GetIndexForInstruction(size_t i) const;
+ size_t GetInstructionCount() const;
+
+ void AddLabelForAddress(Architecture* arch, uint64_t addr);
+ BNLowLevelILLabel* GetLabelForAddress(Architecture* arch, uint64_t addr);
+
+ void Finalize();
+ };
}
diff --git a/function.cpp b/function.cpp
index 2219ba57..6e0a221d 100644
--- a/function.cpp
+++ b/function.cpp
@@ -29,7 +29,7 @@ uint64_t Function::GetStart() const
Ref<Symbol> Function::GetSymbol() const
{
- return new Symbol(BNNewSymbolReference(BNGetFunctionSymbol(m_func)));
+ return new Symbol(BNGetFunctionSymbol(m_func));
}
@@ -53,6 +53,26 @@ void Function::MarkRecentUse()
}
+Ref<LowLevelILFunction> Function::GetLowLevelIL() const
+{
+ return new LowLevelILFunction(BNGetFunctionLowLevelIL(m_func));
+}
+
+
+vector<Ref<BasicBlock>> Function::GetLowLevelILBasicBlocks() const
+{
+ size_t count;
+ BNBasicBlock** blocks = BNGetFunctionLowLevelILBasicBlockList(m_func, &count);
+
+ vector<Ref<BasicBlock>> result;
+ for (size_t i = 0; i < count; i++)
+ result.push_back(new BasicBlock(BNNewBasicBlockReference(blocks[i])));
+
+ BNFreeBasicBlockList(blocks, count);
+ return result;
+}
+
+
Ref<FunctionGraph> Function::CreateFunctionGraph()
{
BNFunctionGraph* graph = BNCreateFunctionGraph(m_func);
diff --git a/functiongraph.cpp b/functiongraph.cpp
index d6f9a85a..1ebd149f 100644
--- a/functiongraph.cpp
+++ b/functiongraph.cpp
@@ -62,9 +62,9 @@ void FunctionGraph::SetMaximumSymbolWidth(size_t width)
}
-void FunctionGraph::StartLayout()
+void FunctionGraph::StartLayout(BNFunctionGraphType type)
{
- BNStartFunctionGraphLayout(m_graph);
+ BNStartFunctionGraphLayout(m_graph, type);
}
diff --git a/lowlevelil.cpp b/lowlevelil.cpp
new file mode 100644
index 00000000..23988004
--- /dev/null
+++ b/lowlevelil.cpp
@@ -0,0 +1,453 @@
+#include "binaryninjaapi.h"
+
+using namespace BinaryNinja;
+
+
+LowLevelILLabel::LowLevelILLabel()
+{
+ BNLowLevelILInitLabel(this);
+}
+
+
+LowLevelILFunction::LowLevelILFunction()
+{
+ m_func = BNCreateLowLevelILFunction();
+}
+
+
+LowLevelILFunction::LowLevelILFunction(BNLowLevelILFunction* func): m_func(func)
+{
+}
+
+
+LowLevelILFunction::~LowLevelILFunction()
+{
+ BNFreeLowLevelILFunction(m_func);
+}
+
+
+uint64_t LowLevelILFunction::GetCurrentAddress() const
+{
+ return BNLowLevelILGetCurrentAddress(m_func);
+}
+
+
+void LowLevelILFunction::SetCurrentAddress(uint64_t addr)
+{
+ BNLowLevelILSetCurrentAddress(m_func, addr);
+}
+
+
+size_t LowLevelILFunction::AddExpr(BNLowLevelILOperation operation, size_t size, uint32_t flags,
+ uint64_t a, uint64_t b, uint64_t c, uint64_t d)
+{
+ return BNLowLevelILAddExpr(m_func, operation, size, flags, a, b, c, d);
+}
+
+
+size_t LowLevelILFunction::AddInstruction(size_t expr)
+{
+ return BNLowLevelILAddInstruction(m_func, expr);
+}
+
+
+size_t LowLevelILFunction::Nop()
+{
+ return AddExpr(LLIL_NOP, 0, 0);
+}
+
+
+size_t LowLevelILFunction::SetRegister(size_t size, uint32_t reg, uint64_t val)
+{
+ return AddExpr(LLIL_SET_REG, size, 0, reg, val);
+}
+
+
+size_t LowLevelILFunction::SetRegisterSplit(size_t size, uint32_t high, uint32_t low, uint64_t val)
+{
+ return AddExpr(LLIL_SET_REG_SPLIT, size, 0, high, low, val);
+}
+
+
+size_t LowLevelILFunction::SetFlag(uint32_t flag, uint64_t val)
+{
+ return AddExpr(LLIL_SET_FLAG, 0, 0, flag, val);
+}
+
+
+size_t LowLevelILFunction::Load(size_t size, uint64_t addr)
+{
+ return AddExpr(LLIL_LOAD, size, 0, addr);
+}
+
+
+size_t LowLevelILFunction::Store(size_t size, uint64_t addr, uint64_t val)
+{
+ return AddExpr(LLIL_STORE, size, 0, addr, val);
+}
+
+
+size_t LowLevelILFunction::Push(size_t size, uint64_t val)
+{
+ return AddExpr(LLIL_PUSH, size, 0, val);
+}
+
+
+size_t LowLevelILFunction::Pop(size_t size)
+{
+ return AddExpr(LLIL_POP, size, 0);
+}
+
+
+size_t LowLevelILFunction::Register(size_t size, uint32_t reg)
+{
+ return AddExpr(LLIL_REG, size, 0, reg);
+}
+
+
+size_t LowLevelILFunction::Const(size_t size, uint64_t val)
+{
+ return AddExpr(LLIL_CONST, size, 0, val);
+}
+
+
+size_t LowLevelILFunction::Flag(uint32_t reg)
+{
+ return AddExpr(LLIL_FLAG, 0, 0, reg);
+}
+
+
+size_t LowLevelILFunction::Add(size_t size, uint64_t a, uint64_t b, uint32_t flags)
+{
+ return AddExpr(LLIL_ADD, size, flags, a, b);
+}
+
+
+size_t LowLevelILFunction::AddCarry(size_t size, uint64_t a, uint64_t b, uint32_t flags)
+{
+ return AddExpr(LLIL_ADC, size, flags, a, b);
+}
+
+
+size_t LowLevelILFunction::Sub(size_t size, uint64_t a, uint64_t b, uint32_t flags)
+{
+ return AddExpr(LLIL_SUB, size, flags, a, b);
+}
+
+
+size_t LowLevelILFunction::SubBorrow(size_t size, uint64_t a, uint64_t b, uint32_t flags)
+{
+ return AddExpr(LLIL_SBB, size, flags, a, b);
+}
+
+
+size_t LowLevelILFunction::And(size_t size, uint64_t a, uint64_t b, uint32_t flags)
+{
+ return AddExpr(LLIL_AND, size, flags, a, b);
+}
+
+
+size_t LowLevelILFunction::Or(size_t size, uint64_t a, uint64_t b, uint32_t flags)
+{
+ return AddExpr(LLIL_OR, size, flags, a, b);
+}
+
+
+size_t LowLevelILFunction::Xor(size_t size, uint64_t a, uint64_t b, uint32_t flags)
+{
+ return AddExpr(LLIL_XOR, size, flags, a, b);
+}
+
+
+size_t LowLevelILFunction::ShiftLeft(size_t size, uint64_t a, uint64_t b, uint32_t flags)
+{
+ return AddExpr(LLIL_LSL, size, flags, a, b);
+}
+
+
+size_t LowLevelILFunction::LogicalShiftRight(size_t size, uint64_t a, uint64_t b, uint32_t flags)
+{
+ return AddExpr(LLIL_LSR, size, flags, a, b);
+}
+
+
+size_t LowLevelILFunction::ArithShiftRight(size_t size, uint64_t a, uint64_t b, uint32_t flags)
+{
+ return AddExpr(LLIL_ASR, size, flags, a, b);
+}
+
+
+size_t LowLevelILFunction::RotateLeft(size_t size, uint64_t a, uint64_t b, uint32_t flags)
+{
+ return AddExpr(LLIL_ROL, size, flags, a, b);
+}
+
+
+size_t LowLevelILFunction::RotateLeftCarry(size_t size, uint64_t a, uint64_t b, uint32_t flags)
+{
+ return AddExpr(LLIL_RLC, size, flags, a, b);
+}
+
+
+size_t LowLevelILFunction::RotateRight(size_t size, uint64_t a, uint64_t b, uint32_t flags)
+{
+ return AddExpr(LLIL_ROR, size, flags, a, b);
+}
+
+
+size_t LowLevelILFunction::RotateRightCarry(size_t size, uint64_t a, uint64_t b, uint32_t flags)
+{
+ return AddExpr(LLIL_RRC, size, flags, a, b);
+}
+
+
+size_t LowLevelILFunction::Mult(size_t size, uint64_t a, uint64_t b, uint32_t flags)
+{
+ return AddExpr(LLIL_MUL, size, flags, a, b);
+}
+
+
+size_t LowLevelILFunction::MultDoublePrecUnsigned(size_t size, uint64_t a, uint64_t b, uint32_t flags)
+{
+ return AddExpr(LLIL_MULU_DP, size, flags, a, b);
+}
+
+
+size_t LowLevelILFunction::MultDoublePrecSigned(size_t size, uint64_t a, uint64_t b, uint32_t flags)
+{
+ return AddExpr(LLIL_MULS_DP, size, flags, a, b);
+}
+
+
+size_t LowLevelILFunction::DivUnsigned(size_t size, uint64_t a, uint64_t b, uint32_t flags)
+{
+ return AddExpr(LLIL_DIVU, size, flags, a, b);
+}
+
+
+size_t LowLevelILFunction::DivDoublePrecUnsigned(size_t size, uint64_t high, uint64_t low, uint64_t div, uint32_t flags)
+{
+ return AddExpr(LLIL_DIVU_DP, size, flags, high, low, div);
+}
+
+
+size_t LowLevelILFunction::DivSigned(size_t size, uint64_t a, uint64_t b, uint32_t flags)
+{
+ return AddExpr(LLIL_DIVS, size, flags, a, b);
+}
+
+
+size_t LowLevelILFunction::DivDoublePrecSigned(size_t size, uint64_t high, uint64_t low, uint64_t div, uint32_t flags)
+{
+ return AddExpr(LLIL_DIVS_DP, size, flags, high, low, div);
+}
+
+
+size_t LowLevelILFunction::ModUnsigned(size_t size, uint64_t a, uint64_t b, uint32_t flags)
+{
+ return AddExpr(LLIL_MODU, size, flags, a, b);
+}
+
+
+size_t LowLevelILFunction::ModDoublePrecUnsigned(size_t size, uint64_t high, uint64_t low, uint64_t div, uint32_t flags)
+{
+ return AddExpr(LLIL_MODU_DP, size, flags, high, low, div);
+}
+
+
+size_t LowLevelILFunction::ModSigned(size_t size, uint64_t a, uint64_t b, uint32_t flags)
+{
+ return AddExpr(LLIL_MODS, size, flags, a, b);
+}
+
+
+size_t LowLevelILFunction::ModDoublePrecSigned(size_t size, uint64_t high, uint64_t low, uint64_t div, uint32_t flags)
+{
+ return AddExpr(LLIL_MODS_DP, size, flags, high, low, div);
+}
+
+
+size_t LowLevelILFunction::Neg(size_t size, uint64_t a, uint32_t flags)
+{
+ return AddExpr(LLIL_NEG, size, flags, a);
+}
+
+
+size_t LowLevelILFunction::Not(size_t size, uint64_t a, uint32_t flags)
+{
+ return AddExpr(LLIL_NOT, size, flags, a);
+}
+
+
+size_t LowLevelILFunction::SignExtend(size_t size, uint64_t a)
+{
+ return AddExpr(LLIL_SX, size, 0, a);
+}
+
+
+size_t LowLevelILFunction::ZeroExtend(size_t size, uint64_t a)
+{
+ return AddExpr(LLIL_ZX, size, 0, a);
+}
+
+
+size_t LowLevelILFunction::Jump(uint64_t dest)
+{
+ return AddExpr(LLIL_JUMP, 0, 0, dest);
+}
+
+
+size_t LowLevelILFunction::Call(uint64_t dest)
+{
+ return AddExpr(LLIL_CALL, 0, 0, dest);
+}
+
+
+size_t LowLevelILFunction::Return(size_t dest)
+{
+ return AddExpr(LLIL_RET, 0, 0, dest);
+}
+
+
+size_t LowLevelILFunction::FlagCondition(BNLowLevelILFlagCondition cond)
+{
+ return AddExpr(LLIL_FLAG_COND, 0, 0, (uint64_t)cond);
+}
+
+
+size_t LowLevelILFunction::CompareEqual(size_t size, uint64_t a, uint64_t b)
+{
+ return AddExpr(LLIL_CMP_E, size, 0, a, b);
+}
+
+
+size_t LowLevelILFunction::CompareNotEqual(size_t size, uint64_t a, uint64_t b)
+{
+ return AddExpr(LLIL_CMP_NE, size, 0, a, b);
+}
+
+
+size_t LowLevelILFunction::CompareSignedLessThan(size_t size, uint64_t a, uint64_t b)
+{
+ return AddExpr(LLIL_CMP_SLT, size, 0, a, b);
+}
+
+
+size_t LowLevelILFunction::CompareUnsignedLessThan(size_t size, uint64_t a, uint64_t b)
+{
+ return AddExpr(LLIL_CMP_ULT, size, 0, a, b);
+}
+
+
+size_t LowLevelILFunction::CompareSignedLessEqual(size_t size, uint64_t a, uint64_t b)
+{
+ return AddExpr(LLIL_CMP_SLE, size, 0, a, b);
+}
+
+
+size_t LowLevelILFunction::CompareUnsignedLessEqual(size_t size, uint64_t a, uint64_t b)
+{
+ return AddExpr(LLIL_CMP_ULE, size, 0, a, b);
+}
+
+
+size_t LowLevelILFunction::CompareSignedGreaterEqual(size_t size, uint64_t a, uint64_t b)
+{
+ return AddExpr(LLIL_CMP_SGE, size, 0, a, b);
+}
+
+
+size_t LowLevelILFunction::CompareUnsignedGreaterEqual(size_t size, uint64_t a, uint64_t b)
+{
+ return AddExpr(LLIL_CMP_UGE, size, 0, a, b);
+}
+
+
+size_t LowLevelILFunction::CompareSignedGreaterThan(size_t size, uint64_t a, uint64_t b)
+{
+ return AddExpr(LLIL_CMP_SGT, size, 0, a, b);
+}
+
+
+size_t LowLevelILFunction::CompareUnsignedGreaterThan(size_t size, uint64_t a, uint64_t b)
+{
+ return AddExpr(LLIL_CMP_UGT, size, 0, a, b);
+}
+
+
+size_t LowLevelILFunction::SystemCall()
+{
+ return AddExpr(LLIL_SYSCALL, 0, 0);
+}
+
+
+size_t LowLevelILFunction::Undefined()
+{
+ return AddExpr(LLIL_UNDEF, 0, 0);
+}
+
+
+size_t LowLevelILFunction::Unimplemented()
+{
+ return AddExpr(LLIL_UNIMPL, 0, 0);
+}
+
+
+size_t LowLevelILFunction::UnimplementedMemoryRef(size_t size, uint64_t addr)
+{
+ return AddExpr(LLIL_UNIMPL_MEM, size, 0, addr);
+}
+
+
+size_t LowLevelILFunction::Goto(BNLowLevelILLabel& label)
+{
+ return BNLowLevelILGoto(m_func, &label);
+}
+
+
+size_t LowLevelILFunction::If(uint64_t operand, BNLowLevelILLabel& t, BNLowLevelILLabel& f)
+{
+ return BNLowLevelILIf(m_func, operand, &t, &f);
+}
+
+
+void LowLevelILFunction::MarkLabel(BNLowLevelILLabel& label)
+{
+ BNLowLevelILMarkLabel(m_func, &label);
+}
+
+
+BNLowLevelILInstruction LowLevelILFunction::operator[](size_t i) const
+{
+ return BNGetLowLevelILByIndex(m_func, i);
+}
+
+
+size_t LowLevelILFunction::GetIndexForInstruction(size_t i) const
+{
+ return BNGetLowLevelILIndexForInstruction(m_func, i);
+}
+
+
+size_t LowLevelILFunction::GetInstructionCount() const
+{
+ return BNGetLowLevelILInstructionCount(m_func);
+}
+
+
+void LowLevelILFunction::AddLabelForAddress(Architecture* arch, uint64_t addr)
+{
+ BNAddLowLevelILLabelForAddress(m_func, arch->GetArchitectureObject(), addr);
+}
+
+
+BNLowLevelILLabel* LowLevelILFunction::GetLabelForAddress(Architecture* arch, uint64_t addr)
+{
+ return BNGetLowLevelILLabelForAddress(m_func, arch->GetArchitectureObject(), addr);
+}
+
+
+void LowLevelILFunction::Finalize()
+{
+ BNFinalizeLowLevelILFunction(m_func);
+}