From 540fca65afaff35343a938b86596b21f2e16b48d Mon Sep 17 00:00:00 2001 From: Mark Rowe Date: Fri, 28 Nov 2025 11:13:08 -0800 Subject: Introduce an RAII type for managing bulk symbol modifications Fixes https://github.com/Vector35/binaryninja-api/issues/7666. Correctly managing the state of bulk symbol modifications via `BeginBulkModifySymbols` / `EndBulkModifySymbols` is error-prone in the face of exceptions and early returns. Leaking a bulk symbol modification can leave the view in a state where no further changes to symbols will be applied. All users of the C++ API are encouraged to move from `BeginBulkModifySymbols` / `EndBulkModifySymbols` to the new `BulkSymbolModification` class. --- binaryninjaapi.h | 65 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) (limited to 'binaryninjaapi.h') diff --git a/binaryninjaapi.h b/binaryninjaapi.h index 9cef3ee0..55aa96ca 100644 --- a/binaryninjaapi.h +++ b/binaryninjaapi.h @@ -6869,7 +6869,24 @@ namespace BinaryNinja { */ bool IsApplyingDebugInfo() const; + /*! Begin an operation that may potentially modify many symbols + + When performing bulk symbol modifications, surrounding the modifications with + \c BeginBulkModifySymbols and \c EndBulkModifySymbols will defer some work until + the end of the operation, improving performance. + + \deprecated Prefer \c BulkSymbolModification for bulk symbol modifications. + */ void BeginBulkModifySymbols(); + + /*! Finish an operation that potentially modified many symbols + + When performing bulk symbol modifications, surrounding the modifications with + \c BeginBulkModifySymbols and \c EndBulkModifySymbols will defer some work until + the end of the operation, improving performance. + + \deprecated Prefer \c BulkSymbolModification for bulk symbol modifications. + */ void EndBulkModifySymbols(); /*! Add a new TagType to this binaryview @@ -8300,6 +8317,54 @@ namespace BinaryNinja { } }; + /*! An RAII helper for use when modifying symbols in bulk. + + \ingroup binaryview + + When modifying many symbols, it is more efficient to wrap the modifications + in a \c BulkSymbolModification object. This will defer some processing until + all bulk modifications are complete. + + While a bulk modification is active, some API calls may not reflect (or may + only partially reflect) any symbol changes made until all bulk modifications + are complete. + + The bulk modification will be active for the lifetime of the + \c BulkSymbolModification object. It can be ended early via the \c End method, + if needed. + */ + class BulkSymbolModification + { + public: + BulkSymbolModification(Ref view) + : m_view(std::move(view)) + { + m_view->BeginBulkModifySymbols(); + } + + ~BulkSymbolModification() + { + if (m_view) + m_view->EndBulkModifySymbols(); + } + + /*! End this bulk modification early. */ + void End() + { + m_view->EndBulkModifySymbols(); + m_view = nullptr; + } + + // Move-only. + BulkSymbolModification(const BulkSymbolModification&) = delete; + BulkSymbolModification& operator=(const BulkSymbolModification&) = delete; + BulkSymbolModification(BulkSymbolModification&&) = default; + BulkSymbolModification& operator=(BulkSymbolModification&&) = default; + + private: + Ref m_view; + }; + /*! \ingroup binaryview */ -- cgit v1.3.1