@@ -10201,21 +10201,95 @@ namespace BinaryNinja {
1020110201 ILReferenceSource source;
1020210202 };
1020310203
10204+ struct ValueLocationComponent
10205+ {
10206+ Variable variable;
10207+ int64_t offset = 0;
10208+ std::optional<uint64_t> size;
10209+ bool indirect = false;
10210+
10211+ ValueLocationComponent() = default;
10212+ ValueLocationComponent(Variable var, int64_t ofs = 0, std::optional<uint64_t> sz = std::nullopt,
10213+ bool indir = false) : variable(var), offset(ofs), size(sz), indirect(indir)
10214+ {}
10215+
10216+ ValueLocationComponent RemapVariables(const std::function<Variable(Variable)>& remap) const;
10217+
10218+ bool operator==(const ValueLocationComponent& component) const;
10219+ bool operator!=(const ValueLocationComponent& component) const;
10220+
10221+ static ValueLocationComponent FromAPIObject(const BNValueLocationComponent* loc);
10222+ BNValueLocationComponent ToAPIObject() const;
10223+ };
10224+
10225+ struct ValueLocation
10226+ {
10227+ std::vector<ValueLocationComponent> components;
10228+
10229+ ValueLocation() {}
10230+ ValueLocation(Variable var) : components {var} {}
10231+ ValueLocation(const std::vector<ValueLocationComponent>& components) : components(components) {}
10232+ ValueLocation(std::vector<ValueLocationComponent>&& components) : components(std::move(components)) {}
10233+
10234+ ValueLocation(BNVariableSourceType type, uint64_t storage) : components {Variable(type, storage)} {}
10235+ ValueLocation(BNVariableSourceType type, uint32_t index, uint64_t storage) :
10236+ components {Variable(type, index, storage)}
10237+ {}
10238+
10239+ std::optional<Variable> GetVariable() const;
10240+ ValueLocation RemapVariables(const std::function<Variable(Variable)>& remap) const;
10241+ void ForEachVariable(const std::function<void(Variable var, bool indirect)>& func) const;
10242+ bool ContainsVariable(Variable var) const;
10243+ bool IsValid() const { return !components.empty(); }
10244+
10245+ bool operator==(const ValueLocation& loc) const;
10246+ bool operator!=(const ValueLocation& loc) const;
10247+
10248+ static ValueLocation FromAPIObject(const BNValueLocation* loc);
10249+ BNValueLocation ToAPIObject() const;
10250+ static void FreeAPIObject(BNValueLocation* loc);
10251+ };
10252+
1020410253 struct FunctionParameter
1020510254 {
1020610255 std::string name;
1020710256 Confidence<Ref<Type>> type;
1020810257 bool defaultLocation;
10209- Variable location;
10258+ ValueLocation location;
1021010259
1021110260 FunctionParameter() = default;
1021210261 FunctionParameter(const std::string& name, Confidence<Ref<Type>> type): name(name), type(type), defaultLocation(true)
1021310262 {}
1021410263
1021510264 FunctionParameter(const std::string& name, const Confidence<Ref<Type>>& type, bool defaultLocation,
10216- const Variable & location):
10265+ const ValueLocation & location) :
1021710266 name(name), type(type), defaultLocation(defaultLocation), location(location)
1021810267 {}
10268+
10269+ static FunctionParameter FromAPIObject(const BNFunctionParameter* param);
10270+ BNFunctionParameter ToAPIObject() const;
10271+ static void FreeAPIObject(BNFunctionParameter* param);
10272+ };
10273+
10274+ struct ReturnValue
10275+ {
10276+ Confidence<Ref<Type>> type;
10277+ bool defaultLocation = true;
10278+ Confidence<ValueLocation> location;
10279+
10280+ ReturnValue(Type* ty) : type(ty) {}
10281+ ReturnValue(Ref<Type> ty) : type(ty) {}
10282+ ReturnValue(const Confidence<Ref<Type>>& ty) : type(ty) {}
10283+ ReturnValue(const Confidence<Ref<Type>>& ty, bool defaultLoc, const Confidence<ValueLocation>& loc) :
10284+ type(ty), defaultLocation(defaultLoc), location(loc) {};
10285+ ReturnValue() = default;
10286+
10287+ bool operator==(const ReturnValue& nt) const;
10288+ bool operator!=(const ReturnValue& nt) const;
10289+
10290+ static ReturnValue FromAPIObject(const BNReturnValue* returnValue);
10291+ BNReturnValue ToAPIObject() const;
10292+ static void FreeAPIObject(BNReturnValue* returnValue);
1021910293 };
1022010294
1022110295 class FieldResolutionInfo : public CoreRefCountObject<BNFieldResolutionInfo, BNNewFieldResolutionInfoReference, BNFreeFieldResolutionInfo>
@@ -10381,6 +10455,22 @@ namespace BinaryNinja {
1038110455 */
1038210456 Confidence<Ref<Type>> GetChildType() const;
1038310457
10458+ /*! Get the return value type and location for this Type if one exists
10459+
10460+ \return The return value type and location
10461+ */
10462+ ReturnValue GetReturnValue() const;
10463+
10464+ /*! Whether the return value is in the default location
10465+ */
10466+ bool IsReturnValueDefaultLocation() const;
10467+
10468+ /*! Get the return value location for this Type
10469+
10470+ \return The return value location
10471+ */
10472+ Confidence<ValueLocation> GetReturnValueLocation() const;
10473+
1038410474 /*! For Function Types, get the calling convention
1038510475
1038610476 \return The CallingConvention
@@ -10595,14 +10685,14 @@ namespace BinaryNinja {
1059510685 auto functionType = Type::FunctionType(retType, cc, params);
1059610686 \endcode
1059710687
10598- \param returnValue Return value Type
10688+ \param returnValue Return value type and location
1059910689 \param callingConvention Calling convention for the function
1060010690 \param params list of FunctionParameter s
1060110691 \param varArg Whether this function has variadic arguments, default false
1060210692 \param stackAdjust Stack adjustment for this function, default 0
1060310693 \return The created function types
1060410694 */
10605- static Ref<Type> FunctionType(const Confidence<Ref<Type>> & returnValue,
10695+ static Ref<Type> FunctionType(const ReturnValue & returnValue,
1060610696 const Confidence<Ref<CallingConvention>>& callingConvention, const std::vector<FunctionParameter>& params,
1060710697 const Confidence<bool>& varArg = Confidence<bool>(false, 0),
1060810698 const Confidence<int64_t>& stackAdjust = Confidence<int64_t>(0, 0));
@@ -10623,23 +10713,21 @@ namespace BinaryNinja {
1062310713 auto functionType = Type::FunctionType(retType, cc, params);
1062410714 \endcode
1062510715
10626- \param returnValue Return value Type
10716+ \param returnValue Return value type and location
1062710717 \param callingConvention Calling convention for the function
1062810718 \param params list of FunctionParameters
1062910719 \param varArg Whether this function has variadic arguments, default false
1063010720 \param stackAdjust Stack adjustment for this function, default 0
10631- \param regStackAdjust Register stack adjustmemt
10632- \param returnRegs Return registers
10721+ \param regStackAdjust Register stack adjustmemt
1063310722 \return The created function types
1063410723 */
10635- static Ref<Type> FunctionType(const Confidence<Ref<Type>> & returnValue,
10724+ static Ref<Type> FunctionType(const ReturnValue & returnValue,
1063610725 const Confidence<Ref<CallingConvention>>& callingConvention,
1063710726 const std::vector<FunctionParameter>& params,
1063810727 const Confidence<bool>& hasVariableArguments,
1063910728 const Confidence<bool>& canReturn,
1064010729 const Confidence<int64_t>& stackAdjust,
1064110730 const std::map<uint32_t, Confidence<int32_t>>& regStackAdjust = std::map<uint32_t, Confidence<int32_t>>(),
10642- const Confidence<std::vector<uint32_t>>& returnRegs = Confidence<std::vector<uint32_t>>(std::vector<uint32_t>(), 0),
1064310731 BNNameType ft = NoNameType,
1064410732 const Confidence<bool>& pure = Confidence<bool>(false, 0));
1064510733 static Ref<Type> VarArgsType();
@@ -10835,6 +10923,9 @@ namespace BinaryNinja {
1083510923 void SetIntegerTypeDisplayType(BNIntegerDisplayType displayType);
1083610924
1083710925 Confidence<Ref<Type>> GetChildType() const;
10926+ ReturnValue GetReturnValue() const;
10927+ bool IsReturnValueDefaultLocation() const;
10928+ Confidence<ValueLocation> GetReturnValueLocation() const;
1083810929 Confidence<Ref<CallingConvention>> GetCallingConvention() const;
1083910930 BNCallingConventionName GetCallingConventionName() const;
1084010931 std::vector<FunctionParameter> GetParameters() const;
@@ -10854,6 +10945,9 @@ namespace BinaryNinja {
1085410945 TypeBuilder& SetConst(const Confidence<bool>& cnst);
1085510946 TypeBuilder& SetVolatile(const Confidence<bool>& vltl);
1085610947 TypeBuilder& SetChildType(const Confidence<Ref<Type>>& child);
10948+ TypeBuilder& SetReturnValue(const ReturnValue& rv);
10949+ TypeBuilder& SetIsReturnValueDefaultLocation(bool defaultLocation);
10950+ TypeBuilder& SetReturnValueLocation(const Confidence<ValueLocation>& location);
1085710951 TypeBuilder& SetCallingConvention(const Confidence<Ref<CallingConvention>>& cc);
1085810952 TypeBuilder& SetCallingConventionName(BNCallingConventionName cc);
1085910953 TypeBuilder& SetSigned(const Confidence<bool>& vltl);
@@ -10929,18 +11023,17 @@ namespace BinaryNinja {
1092911023 const Confidence<bool>& cnst = Confidence<bool>(false, 0),
1093011024 const Confidence<bool>& vltl = Confidence<bool>(false, 0), BNReferenceType refType = PointerReferenceType);
1093111025 static TypeBuilder ArrayType(const Confidence<Ref<Type>>& type, uint64_t elem);
10932- static TypeBuilder FunctionType(const Confidence<Ref<Type>> & returnValue,
11026+ static TypeBuilder FunctionType(const ReturnValue & returnValue,
1093311027 const Confidence<Ref<CallingConvention>>& callingConvention, const std::vector<FunctionParameter>& params,
1093411028 const Confidence<bool>& varArg = Confidence<bool>(false, 0),
1093511029 const Confidence<int64_t>& stackAdjust = Confidence<int64_t>(0, 0));
10936- static TypeBuilder FunctionType(const Confidence<Ref<Type>> & returnValue,
11030+ static TypeBuilder FunctionType(const ReturnValue & returnValue,
1093711031 const Confidence<Ref<CallingConvention>>& callingConvention,
1093811032 const std::vector<FunctionParameter>& params,
1093911033 const Confidence<bool>& hasVariableArguments,
1094011034 const Confidence<bool>& canReturn,
1094111035 const Confidence<int64_t>& stackAdjust,
1094211036 const std::map<uint32_t, Confidence<int32_t>>& regStackAdjust = std::map<uint32_t, Confidence<int32_t>>(),
10943- const Confidence<std::vector<uint32_t>>& returnRegs = Confidence<std::vector<uint32_t>>(std::vector<uint32_t>(), 0),
1094411037 BNNameType ft = NoNameType,
1094511038 const Confidence<bool>& pure = Confidence<bool>(false, 0));
1094611039 static TypeBuilder VarArgsType();
@@ -12792,19 +12885,25 @@ namespace BinaryNinja {
1279212885
1279312886 Ref<Type> GetType() const;
1279412887 Confidence<Ref<Type>> GetReturnType() const;
12888+ ReturnValue GetReturnValue() const;
12889+ bool IsReturnValueDefaultLocation() const;
12890+ Confidence<ValueLocation> GetReturnValueLocation() const;
1279512891 Confidence<std::vector<uint32_t>> GetReturnRegisters() const;
1279612892 Confidence<Ref<CallingConvention>> GetCallingConvention() const;
1279712893 Confidence<std::vector<Variable>> GetParameterVariables() const;
12894+ Confidence<std::vector<ValueLocation>> GetParameterLocations() const;
1279812895 Confidence<bool> HasVariableArguments() const;
1279912896 Confidence<int64_t> GetStackAdjustment() const;
1280012897 std::map<uint32_t, Confidence<int32_t>> GetRegisterStackAdjustments() const;
1280112898 Confidence<std::set<uint32_t>> GetClobberedRegisters() const;
1280212899
1280312900 void SetAutoType(Type* type);
1280412901 void SetAutoReturnType(const Confidence<Ref<Type>>& type);
12805- void SetAutoReturnRegisters(const Confidence<std::vector<uint32_t>>& returnRegs);
12902+ void SetAutoReturnValue(const ReturnValue& rv);
12903+ void SetAutoIsReturnValueDefaultLocation(bool defaultLocation);
12904+ void SetAutoReturnValueLocation(const Confidence<ValueLocation>& location);
1280612905 void SetAutoCallingConvention(const Confidence<Ref<CallingConvention>>& convention);
12807- void SetAutoParameterVariables (const Confidence<std::vector<Variable >>& vars );
12906+ void SetAutoParameterLocations (const Confidence<std::vector<ValueLocation >>& locations );
1280812907 void SetAutoHasVariableArguments(const Confidence<bool>& varArgs);
1280912908 void SetAutoCanReturn(const Confidence<bool>& returns);
1281012909 void SetAutoPure(const Confidence<bool>& pure);
@@ -12814,9 +12913,11 @@ namespace BinaryNinja {
1281412913
1281512914 void SetUserType(Type* type);
1281612915 void SetReturnType(const Confidence<Ref<Type>>& type);
12817- void SetReturnRegisters(const Confidence<std::vector<uint32_t>>& returnRegs);
12916+ void SetReturnValue(const ReturnValue& rv);
12917+ void SetIsReturnValueDefaultLocation(bool defaultLocation);
12918+ void SetReturnValueLocation(const Confidence<ValueLocation>& location);
1281812919 void SetCallingConvention(const Confidence<Ref<CallingConvention>>& convention);
12819- void SetParameterVariables (const Confidence<std::vector<Variable >>& vars );
12920+ void SetParameterLocations (const Confidence<std::vector<ValueLocation >>& locations );
1282012921 void SetHasVariableArguments(const Confidence<bool>& varArgs);
1282112922 void SetCanReturn(const Confidence<bool>& returns);
1282212923 void SetPure(const Confidence<bool>& pure);
@@ -17208,7 +17309,22 @@ namespace BinaryNinja {
1720817309 };
1720917310
1721017311 /*!
17211- \ingroup callingconvention
17312+ \ingroup callingconvention
17313+ */
17314+ struct CallLayout
17315+ {
17316+ std::vector<ValueLocation> parameters;
17317+ std::optional<ValueLocation> returnValue;
17318+ int64_t stackAdjustment = 0;
17319+ std::map<uint32_t, int32_t> registerStackAdjustments;
17320+
17321+ static CallLayout FromAPIObject(BNCallLayout* layout);
17322+ BNCallLayout ToAPIObject() const;
17323+ static void FreeAPIObject(BNCallLayout* layout);
17324+ };
17325+
17326+ /*!
17327+ \ingroup callingconvention
1721217328 */
1721317329 class CallingConvention :
1721417330 public CoreRefCountObject<BNCallingConvention, BNNewCallingConventionReference, BNFreeCallingConvention>
@@ -17246,7 +17362,17 @@ namespace BinaryNinja {
1724617362 static void GetParameterVariableForIncomingVariableCallback(
1724717363 void* ctxt, const BNVariable* var, BNFunction* func, BNVariable* result);
1724817364
17249- public:
17365+ static BNCallLayout GetCallLayoutCallback(void* ctxt, BNReturnValue* returnValue, BNFunctionParameter* params,
17366+ size_t paramCount, bool hasPermittedRegs, uint32_t* permittedRegs, size_t permittedRegCount);
17367+ static void FreeCallLayoutCallback(void* ctxt, BNCallLayout* layout);
17368+ static BNValueLocation GetReturnValueLocationCallback(void* ctxt, BNReturnValue* returnValue);
17369+ static void FreeValueLocationCallback(void* ctxt, BNValueLocation* location);
17370+ static BNValueLocation* GetParameterLocationsCallback(void* ctxt, BNValueLocation* returnValue,
17371+ BNFunctionParameter* params, size_t paramCount, bool hasPermittedRegs, uint32_t* permittedRegs,
17372+ size_t permittedRegCount, size_t* outLocationCount);
17373+ static void FreeParameterLocationsCallback(void* ctxt, BNValueLocation* locations, size_t count);
17374+
17375+ public:
1725017376 Ref<Architecture> GetArchitecture() const;
1725117377 std::string GetName() const;
1725217378
@@ -17272,6 +17398,20 @@ namespace BinaryNinja {
1727217398
1727317399 virtual Variable GetIncomingVariableForParameterVariable(const Variable& var, Function* func);
1727417400 virtual Variable GetParameterVariableForIncomingVariable(const Variable& var, Function* func);
17401+
17402+ virtual CallLayout GetCallLayout(const ReturnValue& returnValue, const std::vector<FunctionParameter>& params,
17403+ const std::optional<std::set<uint32_t>>& permittedRegs = std::nullopt);
17404+ virtual ValueLocation GetReturnValueLocation(const ReturnValue& returnValue);
17405+ virtual std::vector<ValueLocation> GetParameterLocations(const std::optional<ValueLocation>& returnValue,
17406+ const std::vector<FunctionParameter>& params,
17407+ const std::optional<std::set<uint32_t>>& permittedRegs = std::nullopt);
17408+
17409+ CallLayout GetDefaultCallLayout(const ReturnValue& returnValue, const std::vector<FunctionParameter>& params,
17410+ const std::optional<std::set<uint32_t>>& permittedRegs = std::nullopt);
17411+ ValueLocation GetDefaultReturnValueLocation(const ReturnValue& returnValue);
17412+ std::vector<ValueLocation> GetDefaultParameterLocations(const std::optional<ValueLocation>& returnValue,
17413+ const std::vector<FunctionParameter>& params,
17414+ const std::optional<std::set<uint32_t>>& permittedRegs = std::nullopt);
1727517415 };
1727617416
1727717417 /*!
@@ -17304,6 +17444,13 @@ namespace BinaryNinja {
1730417444
1730517445 virtual Variable GetIncomingVariableForParameterVariable(const Variable& var, Function* func) override;
1730617446 virtual Variable GetParameterVariableForIncomingVariable(const Variable& var, Function* func) override;
17447+
17448+ virtual CallLayout GetCallLayout(const ReturnValue& returnValue, const std::vector<FunctionParameter>& params,
17449+ const std::optional<std::set<uint32_t>>& permittedRegs = std::nullopt) override;
17450+ virtual ValueLocation GetReturnValueLocation(const ReturnValue& returnValue) override;
17451+ virtual std::vector<ValueLocation> GetParameterLocations(const std::optional<ValueLocation>& returnValue,
17452+ const std::vector<FunctionParameter>& params,
17453+ const std::optional<std::set<uint32_t>>& permittedRegs = std::nullopt) override;
1730717454 };
1730817455
1730917456 /*!
0 commit comments