@@ -9414,6 +9414,21 @@ namespace BinaryNinja {
94149414 std::set<ArchAndAddr>& GetHaltedDisassemblyAddresses();
94159415 std::map<ArchAndAddr, ArchAndAddr>& GetInlinedUnresolvedIndirectBranches();
94169416
9417+ bool SetFunctionArchContextRaw(void* p);
9418+ void* GetFunctionArchContextRaw() const { return m_context->functionArchContext; }
9419+
9420+ template <class ArchT>
9421+ bool SetFunctionArchContext(const ArchT* arch, typename ArchT::FunctionArchContext* context)
9422+ {
9423+ return arch->SetFunctionArchContext(*this, context);
9424+ }
9425+
9426+ template <class ArchT>
9427+ typename ArchT::FunctionArchContext* GetFunctionArchContext(const ArchT* arch)
9428+ {
9429+ return arch->GetFunctionArchContext(*this);
9430+ }
9431+
94179432 void AddTempOutgoingReference(Function* targetFunc);
94189433
94199434 Ref<BasicBlock> CreateBasicBlock(Architecture* arch, uint64_t start);
@@ -9436,6 +9451,7 @@ namespace BinaryNinja {
94369451 std::map<ArchAndAddr, std::set<ArchAndAddr>> m_autoIndirectBranches;
94379452 std::set<uint64_t> m_inlinedCalls;
94389453 bool* m_containsInlinedFunctions;
9454+ void* m_functionArchContext;
94399455
94409456 public:
94419457 BNFunctionLifterContext* m_context;
@@ -9451,6 +9467,12 @@ namespace BinaryNinja {
94519467 std::map<ArchAndAddr, std::set<ArchAndAddr>>& GetAutoIndirectBranches();
94529468 std::set<uint64_t>& GetInlinedCalls();
94539469 void SetContainsInlinedFunctions(bool value);
9470+ void* GetFunctionArchContextRaw() const { return m_functionArchContext; }
9471+ template <class ArchT>
9472+ typename ArchT::FunctionArchContext* GetFunctionArchContext(const ArchT* arch)
9473+ {
9474+ return arch->GetFunctionArchContext(*this);
9475+ }
94549476
94559477 void CheckForInlinedCall(BasicBlock* block, size_t instrCountBefore, size_t instrCountAfter, uint64_t prevAddr,
94569478 uint64_t addr, const uint8_t* opcode, size_t len,
@@ -9484,11 +9506,14 @@ namespace BinaryNinja {
94849506 void* ctxt, const uint8_t* data, uint64_t addr, size_t maxLen, BNInstructionInfo* result);
94859507 static bool GetInstructionTextCallback(void* ctxt, const uint8_t* data, uint64_t addr, size_t* len,
94869508 BNInstructionTextToken** result, size_t* count);
9509+ static bool GetInstructionTextWithContextCallback(void* ctxt, const uint8_t* data, uint64_t addr, size_t* len,
9510+ void* context, BNInstructionTextToken** result, size_t* count);
94879511 static void FreeInstructionTextCallback(BNInstructionTextToken* tokens, size_t count);
94889512 static bool GetInstructionLowLevelILCallback(
94899513 void* ctxt, const uint8_t* data, uint64_t addr, size_t* len, BNLowLevelILFunction* il);
94909514 static void AnalyzeBasicBlocksCallback(void *ctxt, BNFunction* function, BNBasicBlockAnalysisContext* context);
94919515 static bool LiftFunctionCallback(void* ctxt, BNLowLevelILFunction* function, BNFunctionLifterContext* context);
9516+ static void FreeFunctionArchContextCallback(void* ctxt, void* context);
94929517 static char* GetRegisterNameCallback(void* ctxt, uint32_t reg);
94939518 static char* GetFlagNameCallback(void* ctxt, uint32_t flag);
94949519 static char* GetFlagWriteTypeNameCallback(void* ctxt, uint32_t flags);
@@ -9666,6 +9691,10 @@ namespace BinaryNinja {
96669691 virtual bool GetInstructionText(
96679692 const uint8_t* data, uint64_t addr, size_t& len, std::vector<InstructionTextToken>& result) = 0;
96689693
9694+ /* For use in architecture plugins that inherit from ArchitectureWithFunctionContext */
9695+ virtual bool GetInstructionTextWithContext(const uint8_t* data, uint64_t addr, size_t& len, void* context,
9696+ std::vector<InstructionTextToken>& result);
9697+
96699698 /*! Translates an instruction at addr and appends it onto the LowLevelILFunction& il.
96709699
96719700 \note Architecture subclasses should implement this method.
@@ -9692,6 +9721,9 @@ namespace BinaryNinja {
96929721 */
96939722 virtual bool LiftFunction(LowLevelILFunction* function, FunctionLifterContext& context);
96949723
9724+ /* For use in architecture plugins that inherit from ArchitectureWithFunctionContext */
9725+ virtual void FreeFunctionArchContext(void* context);
9726+
96959727 /*! Gets a register name from a register index.
96969728
96979729 \param reg Register index
@@ -10067,6 +10099,71 @@ namespace BinaryNinja {
1006710099 void AddArchitectureRedirection(Architecture* from, Architecture* to);
1006810100 };
1006910101
10102+ /*! The ArchitectureWithFunctionContext class is to be inherited by architecture plugins that need to maintain a
10103+ * function context that is set during AnalyzeBasicBlocks and accessed in LiftFunction and/or
10104+ * GetInstructionTextWithContext.
10105+
10106+ \ingroup architectures
10107+ */
10108+ template <class FnCtxT>
10109+ class ArchitectureWithFunctionContext : public Architecture
10110+ {
10111+ public:
10112+ using Architecture::Architecture;
10113+ using FunctionArchContext = FnCtxT;
10114+
10115+ /*! Set the function architecture context
10116+
10117+ \param bbac Basic block analysis context
10118+ \param ctx Function architecture context
10119+ \return True if the context was set successfully
10120+ */
10121+ bool SetFunctionArchContext(BasicBlockAnalysisContext& bbac, FnCtxT* ctx) const
10122+ {
10123+ return bbac.SetFunctionArchContextRaw(static_cast<void*>(ctx));
10124+ }
10125+
10126+ /*! Get the function architecture context from the basic block analysis context
10127+
10128+ \param bbac Basic block analysis context
10129+ \return Function architecture context
10130+ */
10131+ FnCtxT* GetFunctionArchContext(const BasicBlockAnalysisContext& bbac) const
10132+ {
10133+ return static_cast<FnCtxT*>(bbac.GetFunctionArchContextRaw());
10134+ }
10135+
10136+ /*! Free the function architecture context
10137+ \param context Function architecture context
10138+ */
10139+ virtual void FreeFunctionArchContext(FnCtxT* context) {}
10140+ void FreeFunctionArchContext(void* context) override final
10141+ {
10142+ FreeFunctionArchContext(static_cast<FnCtxT*>(context));
10143+ }
10144+
10145+ /*! Get instruction text with function context
10146+
10147+ \param data Pointer to the instruction data to retrieve text for
10148+ \param addr Address of the instruction data to retrieve text for
10149+ \param len Will be written to with the length of the instruction data which was translated
10150+ \param context Context to use when retrieving instruction text
10151+ \param result Output vector of instruction text tokens
10152+ \return Whether instruction info was successfully retrieved.
10153+ */
10154+ virtual bool GetInstructionTextWithContext(
10155+ const uint8_t* data, uint64_t addr, size_t& len, FnCtxT* context, std::vector<InstructionTextToken>& result)
10156+ {
10157+ return Architecture::GetInstructionTextWithContext(data, addr, len, static_cast<void*>(context), result);
10158+ }
10159+
10160+ bool GetInstructionTextWithContext(const uint8_t* data, uint64_t addr, size_t& len, void* context,
10161+ std::vector<InstructionTextToken>& result) override final
10162+ {
10163+ return GetInstructionTextWithContext(data, addr, len, static_cast<FnCtxT*>(context), result);
10164+ }
10165+ };
10166+
1007010167 /*!
1007110168
1007210169 \ingroup architectures
@@ -10086,10 +10183,13 @@ namespace BinaryNinja {
1008610183 const uint8_t* data, uint64_t addr, size_t maxLen, InstructionInfo& result) override;
1008710184 virtual bool GetInstructionText(
1008810185 const uint8_t* data, uint64_t addr, size_t& len, std::vector<InstructionTextToken>& result) override;
10186+ virtual bool GetInstructionTextWithContext(const uint8_t* data, uint64_t addr, size_t& len, void* context,
10187+ std::vector<InstructionTextToken>& result) override;
1008910188 virtual bool GetInstructionLowLevelIL(
1009010189 const uint8_t* data, uint64_t addr, size_t& len, LowLevelILFunction& il) override;
1009110190 virtual void AnalyzeBasicBlocks(Function* function, BasicBlockAnalysisContext& context) override;
1009210191 virtual bool LiftFunction(LowLevelILFunction* function, FunctionLifterContext& context) override;
10192+ virtual void FreeFunctionArchContext(void* context) override;
1009310193 virtual std::string GetRegisterName(uint32_t reg) override;
1009410194 virtual std::string GetFlagName(uint32_t flag) override;
1009510195 virtual std::string GetFlagWriteTypeName(uint32_t flags) override;
@@ -10173,6 +10273,8 @@ namespace BinaryNinja {
1017310273 const uint8_t* data, uint64_t addr, size_t maxLen, InstructionInfo& result) override;
1017410274 virtual bool GetInstructionText(
1017510275 const uint8_t* data, uint64_t addr, size_t& len, std::vector<InstructionTextToken>& result) override;
10276+ virtual bool GetInstructionTextWithContext(const uint8_t* data, uint64_t addr, size_t& len, void* context,
10277+ std::vector<InstructionTextToken>& result) override;
1017610278 virtual bool GetInstructionLowLevelIL(
1017710279 const uint8_t* data, uint64_t addr, size_t& len, LowLevelILFunction& il) override;
1017810280 virtual std::string GetRegisterName(uint32_t reg) override;
0 commit comments