summaryrefslogtreecommitdiff
path: root/callingconvention.cpp
diff options
context:
space:
mode:
authorRusty Wagner <rusty@vector35.com>2016-01-25 15:16:43 -0500
committerRusty Wagner <rusty.wagner@gmail.com>2016-01-25 23:13:23 -0500
commitad05dd2072917e2487dcd34dbc249b2a0efac589 (patch)
tree0392cd11853a91cbde36c0a8939116a5659fa1d3 /callingconvention.cpp
parentc2b2e11c009fa9b9c6c4a0fbba9210cb997e38ce (diff)
Initial implementation of platform ABI classes
Diffstat (limited to 'callingconvention.cpp')
-rw-r--r--callingconvention.cpp238
1 files changed, 238 insertions, 0 deletions
diff --git a/callingconvention.cpp b/callingconvention.cpp
new file mode 100644
index 00000000..076536c9
--- /dev/null
+++ b/callingconvention.cpp
@@ -0,0 +1,238 @@
+#include "binaryninjaapi.h"
+
+using namespace std;
+using namespace BinaryNinja;
+
+
+CallingConvention::CallingConvention(BNCallingConvention* cc): m_callingConvention(cc)
+{
+}
+
+
+CallingConvention::CallingConvention(Architecture* arch, const string& name)
+{
+ BNCustomCallingConvention cc;
+ cc.context = this;
+ cc.getCallerSavedRegisters = GetCallerSavedRegistersCallback;
+ cc.getIntegerArgumentRegisters = GetIntegerArgumentRegistersCallback;
+ cc.getFloatArgumentRegisters = GetFloatArgumentRegistersCallback;
+ cc.freeRegisterList = FreeRegisterListCallback;
+ cc.areArgumentRegistersSharedIndex = AreArgumentRegistersSharedIndexCallback;
+ cc.isStackReservedForArgumentRegisters = IsStackReservedForArgumentRegistersCallback;
+ cc.getIntegerReturnValueRegister = GetIntegerReturnValueRegisterCallback;
+ cc.getHighIntegerReturnValueRegister = GetHighIntegerReturnValueRegisterCallback;
+ cc.getFloatReturnValueRegister = GetFloatReturnValueRegisterCallback;
+
+ m_callingConvention = BNCreateCallingConvention(arch->GetArchitectureObject(), name.c_str(), &cc);
+}
+
+
+CallingConvention::~CallingConvention()
+{
+ BNFreeCallingConvention(m_callingConvention);
+}
+
+
+uint32_t* CallingConvention::GetCallerSavedRegistersCallback(void* ctxt, size_t* count)
+{
+ CallingConvention* cc = (CallingConvention*)ctxt;
+ vector<uint32_t> regs = cc->GetCallerSavedRegisters();
+ *count = regs.size();
+
+ uint32_t* result = new uint32_t[regs.size()];
+ for (size_t i = 0; i < regs.size(); i++)
+ result[i] = regs[i];
+ return result;
+}
+
+
+uint32_t* CallingConvention::GetIntegerArgumentRegistersCallback(void* ctxt, size_t* count)
+{
+ CallingConvention* cc = (CallingConvention*)ctxt;
+ vector<uint32_t> regs = cc->GetIntegerArgumentRegisters();
+ *count = regs.size();
+
+ uint32_t* result = new uint32_t[regs.size()];
+ for (size_t i = 0; i < regs.size(); i++)
+ result[i] = regs[i];
+ return result;
+}
+
+
+uint32_t* CallingConvention::GetFloatArgumentRegistersCallback(void* ctxt, size_t* count)
+{
+ CallingConvention* cc = (CallingConvention*)ctxt;
+ vector<uint32_t> regs = cc->GetFloatArgumentRegisters();
+ *count = regs.size();
+
+ uint32_t* result = new uint32_t[regs.size()];
+ for (size_t i = 0; i < regs.size(); i++)
+ result[i] = regs[i];
+ return result;
+}
+
+
+void CallingConvention::FreeRegisterListCallback(void*, uint32_t* regs)
+{
+ delete[] regs;
+}
+
+
+bool CallingConvention::AreArgumentRegistersSharedIndexCallback(void* ctxt)
+{
+ CallingConvention* cc = (CallingConvention*)ctxt;
+ return cc->AreArgumentRegistersSharedIndex();
+}
+
+
+bool CallingConvention::IsStackReservedForArgumentRegistersCallback(void* ctxt)
+{
+ CallingConvention* cc = (CallingConvention*)ctxt;
+ return cc->IsStackReservedForArgumentRegisters();
+}
+
+
+uint32_t CallingConvention::GetIntegerReturnValueRegisterCallback(void* ctxt)
+{
+ CallingConvention* cc = (CallingConvention*)ctxt;
+ return cc->GetIntegerReturnValueRegister();
+}
+
+
+uint32_t CallingConvention::GetHighIntegerReturnValueRegisterCallback(void* ctxt)
+{
+ CallingConvention* cc = (CallingConvention*)ctxt;
+ return cc->GetHighIntegerReturnValueRegister();
+}
+
+
+uint32_t CallingConvention::GetFloatReturnValueRegisterCallback(void* ctxt)
+{
+ CallingConvention* cc = (CallingConvention*)ctxt;
+ return cc->GetFloatReturnValueRegister();
+}
+
+
+Ref<Architecture> CallingConvention::GetArchitecture() const
+{
+ return new CoreArchitecture(BNGetCallingConventionArchitecture(m_callingConvention));
+}
+
+
+string CallingConvention::GetName() const
+{
+ char* str = BNGetCallingConventionName(m_callingConvention);
+ string result = str;
+ BNFreeString(str);
+ return result;
+}
+
+
+vector<uint32_t> CallingConvention::GetCallerSavedRegisters()
+{
+ return vector<uint32_t>();
+}
+
+
+vector<uint32_t> CallingConvention::GetIntegerArgumentRegisters()
+{
+ return vector<uint32_t>();
+}
+
+
+vector<uint32_t> CallingConvention::GetFloatArgumentRegisters()
+{
+ return vector<uint32_t>();
+}
+
+
+bool CallingConvention::AreArgumentRegistersSharedIndex()
+{
+ return false;
+}
+
+
+bool CallingConvention::IsStackReservedForArgumentRegisters()
+{
+ return false;
+}
+
+
+uint32_t CallingConvention::GetHighIntegerReturnValueRegister()
+{
+ return BN_INVALID_REGISTER;
+}
+
+
+uint32_t CallingConvention::GetFloatReturnValueRegister()
+{
+ return BN_INVALID_REGISTER;
+}
+
+
+CoreCallingConvention::CoreCallingConvention(BNCallingConvention* cc): CallingConvention(cc)
+{
+}
+
+
+vector<uint32_t> CoreCallingConvention::GetCallerSavedRegisters()
+{
+ size_t count;
+ uint32_t* regs = BNGetCallerSavedRegisters(m_callingConvention, &count);
+ vector<uint32_t> result;
+ result.insert(result.end(), regs, &regs[count]);
+ BNFreeRegisterList(regs);
+ return result;
+}
+
+
+vector<uint32_t> CoreCallingConvention::GetIntegerArgumentRegisters()
+{
+ size_t count;
+ uint32_t* regs = BNGetIntegerArgumentRegisters(m_callingConvention, &count);
+ vector<uint32_t> result;
+ result.insert(result.end(), regs, &regs[count]);
+ BNFreeRegisterList(regs);
+ return result;
+}
+
+
+vector<uint32_t> CoreCallingConvention::GetFloatArgumentRegisters()
+{
+ size_t count;
+ uint32_t* regs = BNGetFloatArgumentRegisters(m_callingConvention, &count);
+ vector<uint32_t> result;
+ result.insert(result.end(), regs, &regs[count]);
+ BNFreeRegisterList(regs);
+ return result;
+}
+
+
+bool CoreCallingConvention::AreArgumentRegistersSharedIndex()
+{
+ return BNAreArgumentRegistersSharedIndex(m_callingConvention);
+}
+
+
+bool CoreCallingConvention::IsStackReservedForArgumentRegisters()
+{
+ return BNIsStackReservedForArgumentRegisters(m_callingConvention);
+}
+
+
+uint32_t CoreCallingConvention::GetIntegerReturnValueRegister()
+{
+ return BNGetIntegerReturnValueRegister(m_callingConvention);
+}
+
+
+uint32_t CoreCallingConvention::GetHighIntegerReturnValueRegister()
+{
+ return BNGetHighIntegerReturnValueRegister(m_callingConvention);
+}
+
+
+uint32_t CoreCallingConvention::GetFloatReturnValueRegister()
+{
+ return BNGetFloatReturnValueRegister(m_callingConvention);
+}