diff options
| author | Rusty Wagner <rusty.wagner@gmail.com> | 2026-02-04 17:23:47 -0500 |
|---|---|---|
| committer | Rusty Wagner <rusty.wagner@gmail.com> | 2026-02-20 16:03:45 -0500 |
| commit | e2e420c91147f2a83cf59b37c973f57e209ef67a (patch) | |
| tree | 841ec88e8ab8100ccb7af8af153e85a7ec7e943a /callingconvention.cpp | |
| parent | 4573354f23da495099983dac4b665988cd837ff5 (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.cpp | 62 |
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, ®s[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, ®s[count]); + BNFreeRegisterList(regs); + return result; +} + + bool CoreCallingConvention::AreArgumentRegistersSharedIndex() { return BNAreArgumentRegistersSharedIndex(m_object); |
