From e2e420c91147f2a83cf59b37c973f57e209ef67a Mon Sep 17 00:00:00 2001 From: Rusty Wagner Date: Wed, 4 Feb 2026 17:23:47 -0500 Subject: Allow calling conventions to specify a list of registers that are required to be considered for heuristic calling convention detection --- callingconvention.cpp | 62 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) (limited to 'callingconvention.cpp') 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 cc(ctxt); + vector 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 cc(ctxt); + vector 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 CallingConvention::GetFloatArgumentRegisters() } +vector CallingConvention::GetRequiredArgumentRegisters() +{ + return vector(); +} + + +vector CallingConvention::GetRequiredClobberedRegisters() +{ + return vector(); +} + + bool CallingConvention::AreArgumentRegistersSharedIndex() { return false; @@ -417,6 +457,28 @@ vector CoreCallingConvention::GetFloatArgumentRegisters() } +vector CoreCallingConvention::GetRequiredArgumentRegisters() +{ + size_t count; + uint32_t* regs = BNGetRequiredArgumentRegisters(m_object, &count); + vector result; + result.insert(result.end(), regs, ®s[count]); + BNFreeRegisterList(regs); + return result; +} + + +vector CoreCallingConvention::GetRequiredClobberedRegisters() +{ + size_t count; + uint32_t* regs = BNGetRequiredClobberedRegisters(m_object, &count); + vector result; + result.insert(result.end(), regs, ®s[count]); + BNFreeRegisterList(regs); + return result; +} + + bool CoreCallingConvention::AreArgumentRegistersSharedIndex() { return BNAreArgumentRegistersSharedIndex(m_object); -- cgit v1.3.1