From a72b98ed5a357bb380d81f07f3f36946aa729bb2 Mon Sep 17 00:00:00 2001 From: Mark Rowe Date: Mon, 23 Feb 2026 23:26:27 -0800 Subject: [DSC] Simplify file mapping to fix intermittent unrelocated pointers The `FileAccessorCache`'s LRU eviction could discard a file's mapped data after slide info had already been applied to it. Future accesses to the file produced a fresh mapping, but failed to reapply the slide info. This could result in pointers not correctly being slid, such as in https://github.com/Vector35/binaryninja-api/issues/7689. The LRU cache existed to stay within OS file descriptor limits, since the old `MappedFile` held its fd open for the lifetime of the mapping. There's no real reason for it to hold the file descriptor open like this. Closing it after `mmap` is sufficient to avoid the file descriptor limits. `MappedFileRegion` replaces the combination of `FileAccessorCache`, `WeakFileAccessor`, and `MappedFileAccessor`. It closes the fd immediately after mmap, so all files can stay mapped without consuming descriptors, making the cache unnecessary. `MappedFileRegion` is owned directly by the `CacheEntry` for its full lifetime. Slide info is applied exactly once to each `MappedFileRegion`. --- view/sharedcache/core/MappedFile.h | 86 -------------------------------------- 1 file changed, 86 deletions(-) delete mode 100644 view/sharedcache/core/MappedFile.h (limited to 'view/sharedcache/core/MappedFile.h') diff --git a/view/sharedcache/core/MappedFile.h b/view/sharedcache/core/MappedFile.h deleted file mode 100644 index ced79f52..00000000 --- a/view/sharedcache/core/MappedFile.h +++ /dev/null @@ -1,86 +0,0 @@ -#pragma once - -#include -#include -#include -#include - -// Call this when initializing the plugin so that the process file descriptor limit is raised. -uint64_t AdjustFileDescriptorLimit(); - -enum MapStatus : int -{ - Success, - // TODO: Split this error out into more contextual errors. - Error, -}; - -struct MappedFile -{ - uint8_t* _mmap = nullptr; - size_t len = 0; - -#ifdef _MSC_VER - HANDLE hFile = INVALID_HANDLE_VALUE; -#else - FILE* fd = nullptr; -#endif - - MappedFile() = default; - - ~MappedFile(); - - MappedFile(const MappedFile&) = delete; - - MappedFile& operator=(const MappedFile&) = delete; - - MappedFile(MappedFile&& other) noexcept : _mmap(other._mmap), len(other.len) - { -#ifdef _MSC_VER - hFile = other.hFile; - // Don't close the hFile in the move. - other.hFile = nullptr; -#else - fd = other.fd; - // Don't close the fd in the move. - other.fd = nullptr; -#endif - other._mmap = nullptr; - } - - // I hate C++ - MappedFile& operator=(MappedFile&& other) noexcept - { - if (this != &other) - { - Unmap(); -#ifdef _MSC_VER - if (hFile != nullptr) - { - CloseHandle(hFile); - } - hFile = other.hFile; - // Don't close the hFile in the move. - other.hFile = nullptr; -#else - if (fd != nullptr) - { - fclose(fd); - } - fd = other.fd; - // Don't close the fd in the move. - other.fd = nullptr; -#endif - len = other.len; - _mmap = other._mmap; - other._mmap = nullptr; - } - return *this; - } - - static std::optional OpenFile(const std::string& path); - - MapStatus Map(); - - MapStatus Unmap(); -}; -- cgit v1.3.1