From 2e855275732aed00486ca100f4151f4074d9949e Mon Sep 17 00:00:00 2001 From: Mason Reed Date: Fri, 4 Apr 2025 23:45:06 -0400 Subject: [SharedCache] Add a named symbol map Fixes https://github.com/Vector35/binaryninja-api/issues/6561 - Also tightens the SharedCache class to move only, to prevent accidental copies. - Also removes some extra copies in FFI when should pass by ref - Also adds `get_symbol_with_name` to python API The current named symbol map is populated in a worker thread spawned in the view init. This is because populating the map can take about 1 second. If we are fine with another 1 second added to the view init time then we can add it serially but I don't think this way is _that_ bad, no analysis consults this, however a user might add a workflow that would be racing this. So we need to add a mutex. --- view/sharedcache/core/SharedCache.h | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) (limited to 'view/sharedcache/core/SharedCache.h') diff --git a/view/sharedcache/core/SharedCache.h b/view/sharedcache/core/SharedCache.h index 674e00c3..3b9e9fe1 100644 --- a/view/sharedcache/core/SharedCache.h +++ b/view/sharedcache/core/SharedCache.h @@ -199,8 +199,11 @@ class SharedCache AddressRangeMap m_regions {}; // Describes the images of the cache. std::unordered_map m_images {}; - // All the symbols for this cache. Both mapped and unmapped (not in the view). + // All the external symbols for this cache. Both mapped and unmapped (not in the view). std::unordered_map m_symbols {}; + // Quickly lookup a symbol by name, populated by `FinalizeSymbols`. + // `m_namedSymbols` is modified in a worker thread spawned by view init so we must not get a symbol until its populated. + std::unordered_map m_namedSymbols {}; bool ProcessEntryImage(const std::string& path, const dyld_cache_image_info& info); @@ -211,12 +214,19 @@ class SharedCache public: explicit SharedCache(uint64_t addressSize); + SharedCache(const SharedCache &) = delete; + SharedCache &operator=(const SharedCache &) = delete; + + SharedCache(SharedCache &&) noexcept = default; + SharedCache &operator=(SharedCache &&) noexcept = default; + uint64_t GetBaseAddress() const { return m_baseAddress; } std::shared_ptr GetVirtualMemory() { return m_vm; } const std::unordered_map& GetEntries() const { return m_entries; } const AddressRangeMap& GetRegions() const { return m_regions; } const std::unordered_map& GetImages() const { return m_images; } const std::unordered_map& GetSymbols() const { return m_symbols; } + const std::unordered_map& GetNamedSymbols() const { return m_namedSymbols; } void AddImage(CacheImage image); @@ -225,7 +235,7 @@ public: void AddSymbol(CacheSymbol symbol); - void AddSymbols(std::vector symbols); + void AddSymbols(std::vector&& symbols); // Adds the cache entry and populates the virtual memory using the mapping information. // After being added the entry is read only, there is nothing that can modify it. @@ -237,6 +247,9 @@ public: void ProcessEntrySlideInfo(const CacheEntry& entry); + // Construct the named symbols lookup map for use with `GetSymbolWithName`. + void ProcessSymbols(); + std::optional GetEntryContaining(uint64_t address) const; std::optional GetEntryWithImage(const CacheImage& image) const; -- cgit v1.3.1