diff options
| author | Rusty Wagner <rusty.wagner@gmail.com> | 2026-01-23 18:36:13 -0500 |
|---|---|---|
| committer | Rusty Wagner <rusty.wagner@gmail.com> | 2026-05-22 16:30:57 -0400 |
| commit | 217b4a3361cbf62020658f12efb47b8fabb6a24d (patch) | |
| tree | 59d677957d85851dcd3d380f7e3350b709e08628 /callingconvention.cpp | |
| parent | a4a3de2ad363b1bceb28f106e2cc6d811b3370b5 (diff) | |
Initial support for Go and Pascal calling conventions
Diffstat (limited to 'callingconvention.cpp')
| -rw-r--r-- | callingconvention.cpp | 111 |
1 files changed, 111 insertions, 0 deletions
diff --git a/callingconvention.cpp b/callingconvention.cpp index 66b814f1..ec32a5b1 100644 --- a/callingconvention.cpp +++ b/callingconvention.cpp @@ -117,12 +117,15 @@ CallingConvention::CallingConvention(Architecture* arch, const string& name) cc.isArgumentTypeRegisterCompatible = IsArgumentTypeRegisterCompatibleCallback; cc.isNonRegisterArgumentIndirect = IsNonRegisterArgumentIndirectCallback; cc.areStackArgumentsNaturallyAligned = AreStackArgumentsNaturallyAlignedCallback; + cc.areStackArgumentsPushedLeftToRight = AreStackArgumentsPushedLeftToRightCallback; cc.getCallLayout = GetCallLayoutCallback; cc.freeCallLayout = FreeCallLayoutCallback; cc.getReturnValueLocation = GetReturnValueLocationCallback; cc.freeValueLocation = FreeValueLocationCallback; cc.getParameterLocations = GetParameterLocationsCallback; cc.freeParameterLocations = FreeParameterLocationsCallback; + cc.getParameterOrderingForVariables = GetParameterOrderingForVariablesCallback; + cc.freeVariableList = FreeVariableListCallback; cc.getStackAdjustmentForLocations = GetStackAdjustmentForLocationsCallback; cc.getRegisterStackAdjustments = GetRegisterStackAdjustmentsCallback; cc.freeRegisterStackAdjustments = FreeRegisterStackAdjustmentsCallback; @@ -406,6 +409,13 @@ bool CallingConvention::AreStackArgumentsNaturallyAlignedCallback(void* ctxt) } +bool CallingConvention::AreStackArgumentsPushedLeftToRightCallback(void* ctxt) +{ + CallbackRef<CallingConvention> cc(ctxt); + return cc->AreStackArgumentsPushedLeftToRight(); +} + + void CallingConvention::GetCallLayoutCallback(void* ctxt, BNBinaryView* view, BNReturnValue* returnValue, BNFunctionParameter* params, size_t paramCount, bool hasPermittedRegs, uint32_t* permittedRegs, size_t permittedRegCount, BNCallLayout* result) @@ -500,6 +510,33 @@ void CallingConvention::FreeParameterLocationsCallback(void*, BNValueLocation* l } +BNVariable* CallingConvention::GetParameterOrderingForVariablesCallback( + void* ctxt, BNBinaryView* view, BNVariable* vars, BNType** types, size_t paramCount, size_t* outCount) +{ + CallbackRef<CallingConvention> cc(ctxt); + Ref<BinaryView> viewObj; + if (view) + viewObj = new BinaryView(BNNewViewReference(view)); + map<Variable, Ref<Type>> params; + for (size_t i = 0; i < paramCount; i++) + params[vars[i]] = types[i] ? new Type(BNNewTypeReference(types[i])) : nullptr; + + auto outVars = cc->GetParameterOrderingForVariables(viewObj, params); + + *outCount = outVars.size(); + BNVariable* result = new BNVariable[outVars.size()]; + for (size_t i = 0; i < outVars.size(); i++) + result[i] = outVars[i]; + return result; +} + + +void CallingConvention::FreeVariableListCallback(void*, BNVariable* vars, size_t) +{ + delete[] vars; +} + + int64_t CallingConvention::GetStackAdjustmentForLocationsCallback(void* ctxt, BNBinaryView* view, BNValueLocation* returnValue, BNValueLocation* locations, BNType** types, size_t paramCount) { @@ -750,6 +787,12 @@ bool CallingConvention::AreStackArgumentsNaturallyAligned() } +bool CallingConvention::AreStackArgumentsPushedLeftToRight() +{ + return false; +} + + CallLayout CallingConvention::GetCallLayout(BinaryView* view, const ReturnValue& returnValue, const vector<FunctionParameter>& params, const optional<set<uint32_t>>& permittedRegs) { @@ -771,6 +814,13 @@ vector<ValueLocation> CallingConvention::GetParameterLocations(BinaryView* view, } +std::vector<Variable> CallingConvention::GetParameterOrderingForVariables( + BinaryView*, const std::map<Variable, Ref<Type>>& params) +{ + return GetDefaultParameterOrderingForVariables(params); +} + + int64_t CallingConvention::GetStackAdjustmentForLocations(BinaryView*, const std::optional<ValueLocation>& returnValue, const std::vector<ValueLocation>& locations, const std::vector<Ref<Type>>& types) { @@ -881,6 +931,33 @@ vector<ValueLocation> CallingConvention::GetDefaultParameterLocations(BinaryView } +std::vector<Variable> CallingConvention::GetDefaultParameterOrderingForVariables( + const std::map<Variable, Ref<Type>>& params) +{ + BNVariable* vars = new BNVariable[params.size()]; + const BNType** types = new const BNType*[params.size()]; + size_t i = 0; + for (auto it = params.begin(); it != params.end(); ++it, ++i) + { + vars[i] = it->first; + types[i] = it->second.GetPtr() ? it->second->GetObject() : nullptr; + } + + size_t outCount = 0; + auto outVars = BNGetDefaultParameterOrderingForVariables(m_object, vars, types, params.size(), &outCount); + + delete[] vars; + delete[] types; + + vector<Variable> result; + result.reserve(outCount); + for (i = 0; i < outCount; i++) + result.emplace_back(outVars[i]); + BNFreeVariableList(outVars); + return result; +} + + int64_t CallingConvention::GetDefaultStackAdjustmentForLocations(const std::optional<ValueLocation>& returnValue, const std::vector<ValueLocation>& locations, const std::vector<Ref<Type>>& types) { @@ -1145,6 +1222,12 @@ bool CoreCallingConvention::AreStackArgumentsNaturallyAligned() } +bool CoreCallingConvention::AreStackArgumentsPushedLeftToRight() +{ + return BNAreStackArgumentsPushedLeftToRight(m_object); +} + + CallLayout CoreCallingConvention::GetCallLayout(BinaryView* view, const ReturnValue& returnValue, const vector<FunctionParameter>& params, const optional<set<uint32_t>>& permittedRegs) { @@ -1241,6 +1324,34 @@ vector<ValueLocation> CoreCallingConvention::GetParameterLocations(BinaryView* v } +std::vector<Variable> CoreCallingConvention::GetParameterOrderingForVariables( + BinaryView* view, const std::map<Variable, Ref<Type>>& params) +{ + BNVariable* vars = new BNVariable[params.size()]; + const BNType** types = new const BNType*[params.size()]; + size_t i = 0; + for (auto it = params.begin(); it != params.end(); ++it, ++i) + { + vars[i] = it->first; + types[i] = it->second.GetPtr() ? it->second->GetObject() : nullptr; + } + + size_t outCount = 0; + auto outVars = BNGetParameterOrderingForVariables( + m_object, view ? view->GetObject() : nullptr, vars, types, params.size(), &outCount); + + delete[] vars; + delete[] types; + + vector<Variable> result; + result.reserve(outCount); + for (i = 0; i < outCount; i++) + result.emplace_back(outVars[i]); + BNFreeVariableList(outVars); + return result; +} + + int64_t CoreCallingConvention::GetStackAdjustmentForLocations(BinaryView* view, const std::optional<ValueLocation>& returnValue, const std::vector<ValueLocation>& locations, const std::vector<Ref<Type>>& types) |
