summaryrefslogtreecommitdiff
path: root/callingconvention.cpp
diff options
context:
space:
mode:
authorRusty Wagner <rusty.wagner@gmail.com>2026-02-04 17:23:47 -0500
committerRusty Wagner <rusty.wagner@gmail.com>2026-02-20 16:03:45 -0500
commite2e420c91147f2a83cf59b37c973f57e209ef67a (patch)
tree841ec88e8ab8100ccb7af8af153e85a7ec7e943a /callingconvention.cpp
parent4573354f23da495099983dac4b665988cd837ff5 (diff)
Allow calling conventions to specify a list of registers that are required to be considered for heuristic calling convention detection
Diffstat (limited to 'callingconvention.cpp')
-rw-r--r--callingconvention.cpp62
1 files changed, 62 insertions, 0 deletions
diff --git a/callingconvention.cpp b/callingconvention.cpp
index abc93053..b7ee5bbe 100644
--- a/callingconvention.cpp
+++ b/callingconvention.cpp
@@ -39,6 +39,8 @@ CallingConvention::CallingConvention(Architecture* arch, const string& name)
cc.getCalleeSavedRegisters = GetCalleeSavedRegistersCallback;
cc.getIntegerArgumentRegisters = GetIntegerArgumentRegistersCallback;
cc.getFloatArgumentRegisters = GetFloatArgumentRegistersCallback;
+ cc.getRequiredArgumentRegisters = GetRequiredArgumentRegistersCallback;
+ cc.getRequiredClobberedRegisters = GetRequiredClobberedRegistersCallback;
cc.freeRegisterList = FreeRegisterListCallback;
cc.areArgumentRegistersSharedIndex = AreArgumentRegistersSharedIndexCallback;
cc.areArgumentRegistersUsedForVarArgs = AreArgumentRegistersUsedForVarArgsCallback;
@@ -119,6 +121,32 @@ uint32_t* CallingConvention::GetFloatArgumentRegistersCallback(void* ctxt, size_
}
+uint32_t* CallingConvention::GetRequiredArgumentRegistersCallback(void* ctxt, size_t* count)
+{
+ CallbackRef<CallingConvention> cc(ctxt);
+ vector<uint32_t> regs = cc->GetRequiredArgumentRegisters();
+ *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::GetRequiredClobberedRegistersCallback(void* ctxt, size_t* count)
+{
+ CallbackRef<CallingConvention> cc(ctxt);
+ vector<uint32_t> regs = cc->GetRequiredClobberedRegisters();
+ *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, size_t)
{
delete[] regs;
@@ -284,6 +312,18 @@ vector<uint32_t> CallingConvention::GetFloatArgumentRegisters()
}
+vector<uint32_t> CallingConvention::GetRequiredArgumentRegisters()
+{
+ return vector<uint32_t>();
+}
+
+
+vector<uint32_t> CallingConvention::GetRequiredClobberedRegisters()
+{
+ return vector<uint32_t>();
+}
+
+
bool CallingConvention::AreArgumentRegistersSharedIndex()
{
return false;
@@ -417,6 +457,28 @@ vector<uint32_t> CoreCallingConvention::GetFloatArgumentRegisters()
}
+vector<uint32_t> CoreCallingConvention::GetRequiredArgumentRegisters()
+{
+ size_t count;
+ uint32_t* regs = BNGetRequiredArgumentRegisters(m_object, &count);
+ vector<uint32_t> result;
+ result.insert(result.end(), regs, &regs[count]);
+ BNFreeRegisterList(regs);
+ return result;
+}
+
+
+vector<uint32_t> CoreCallingConvention::GetRequiredClobberedRegisters()
+{
+ size_t count;
+ uint32_t* regs = BNGetRequiredClobberedRegisters(m_object, &count);
+ vector<uint32_t> result;
+ result.insert(result.end(), regs, &regs[count]);
+ BNFreeRegisterList(regs);
+ return result;
+}
+
+
bool CoreCallingConvention::AreArgumentRegistersSharedIndex()
{
return BNAreArgumentRegistersSharedIndex(m_object);