diff options
| author | Mason Reed <mason@vector35.com> | 2025-04-06 20:00:00 -0400 |
|---|---|---|
| committer | Mason Reed <mason@vector35.com> | 2025-04-06 20:00:37 -0400 |
| commit | c22d54c5d95f4d23629484579414387b0c7503ee (patch) | |
| tree | 933a58c8ed3518f507f5bd4d496364411273f5b9 /view/sharedcache/core/SharedCache.cpp | |
| parent | 4f22a944d77f784b53ee3a37d9f1966ede1c98a4 (diff) | |
[SharedCache] Replace write log with callback registration for reapplying slide info
This improves performance by ~10x with the only real issue being a copy of the cache entry existing for each weak ref.
Also fixes
- Some old TODO's that are no longer relevant
- Some function signatures not being const
- FileAccessorCache not evicting enough accessors to fit under an adjusted cache size
- Added a warning if we are over the global cache size in view initialization
- Logger name not having a `.` in `SlideInfoProcessor::SlideInfoProcessor`
- Re-added the accessor dirty check before applying slide info to fix https://github.com/Vector35/binaryninja-api/issues/6570
Diffstat (limited to 'view/sharedcache/core/SharedCache.cpp')
| -rw-r--r-- | view/sharedcache/core/SharedCache.cpp | 36 |
1 files changed, 34 insertions, 2 deletions
diff --git a/view/sharedcache/core/SharedCache.cpp b/view/sharedcache/core/SharedCache.cpp index 9bbe51e4..c6950a84 100644 --- a/view/sharedcache/core/SharedCache.cpp +++ b/view/sharedcache/core/SharedCache.cpp @@ -397,10 +397,42 @@ void SharedCache::ProcessEntryRegions(const CacheEntry& entry) } } -void SharedCache::ProcessEntrySlideInfo(const CacheEntry& entry) +void SharedCache::ProcessEntrySlideInfo(const CacheEntry& entry) const { auto slideInfoProcessor = SlideInfoProcessor(GetBaseAddress()); - slideInfoProcessor.ProcessEntry(*m_vm, entry); + + // This will be set for every associated `VirtualMemoryRegion` so that any accesses though the VM will be always be slid. + // NOTE: This MUST be called on the CacheEntry object owned by SharedCache, otherwise persistence through the `SharedCacheController` will not occur. + // NOTE: This will keep a copy of a processor in the `WeakFileAccessor` until that object is destroyed (likely view destruction). + // NOTE: This will keep a copy of the cache entry in the `WeakFileAccessor` until that object is destroyed (likely view destruction). + auto reviveCallback = [slideInfoProcessor, entry](MappedFileAccessor& revivedAccessor) { + slideInfoProcessor.ProcessEntry(revivedAccessor, entry); + }; + + // Use the current entry accessor, don't register the callback for this one as we want calls through the VM to be slid only. + // Actually process the slide info for this entry, everything else besides this is to support revived file accessors. + auto slideMappings = slideInfoProcessor.ProcessEntry(*entry.GetAccessor().lock(), entry); + + // Register the revive callback for all virtual memory regions that have been slid. + // The reason we don't just set this on the entry accessor is that accessor is not consulted for anything really after + // this point, everything else will be going through the virtual memory, and because the callback is on the weak accessor + // reference and not the file accessor cache itself this matters. + auto vm = GetVirtualMemory(); + for (const auto& mapping : slideMappings) + { + // Because the mapping address is a file offset for us to consult the virtual memory we must first call `GetMappedAddress`. + if (auto mappedMappingAddr = entry.GetMappedAddress(mapping.address)) + { + if (auto vmRegion = vm->GetRegionAtAddress(*mappedMappingAddr)) + { + // Ok we have the virtual memory region, lets register the callback on its accessor. + vmRegion->fileAccessor.RegisterReviveCallback(reviveCallback); + continue; + } + } + + LogWarn("Failed to register revive callback for slide mapping %llx in entry '%s'", mapping.address, entry.GetFileName().c_str()); + } } void SharedCache::ProcessSymbols() |
