summaryrefslogtreecommitdiff
path: root/view/sharedcache/core/MappedFileAccessor.h
diff options
context:
space:
mode:
authorMark Rowe <mark@vector35.com>2026-02-23 23:26:27 -0800
committerMark Rowe <mark@vector35.com>2026-02-24 14:24:54 -0800
commita72b98ed5a357bb380d81f07f3f36946aa729bb2 (patch)
treeca48b3607721fa2c109b7989ae4b911bab89ea6d /view/sharedcache/core/MappedFileAccessor.h
parent3eda43f185a0411538745a99e251122e6a9192e0 (diff)
[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`.
Diffstat (limited to 'view/sharedcache/core/MappedFileAccessor.h')
-rw-r--r--view/sharedcache/core/MappedFileAccessor.h103
1 files changed, 0 insertions, 103 deletions
diff --git a/view/sharedcache/core/MappedFileAccessor.h b/view/sharedcache/core/MappedFileAccessor.h
deleted file mode 100644
index 35d2d5e7..00000000
--- a/view/sharedcache/core/MappedFileAccessor.h
+++ /dev/null
@@ -1,103 +0,0 @@
-#pragma once
-
-#include "binaryninjaapi.h"
-#include "MappedFile.h"
-
-#include <cstdint>
-#include <list>
-
-class UnmappedAccessException : public std::exception
-{
- uint64_t m_address;
- uint64_t m_fileLen;
-
-public:
- explicit UnmappedAccessException(uint64_t address, uint64_t fileLength) : m_address(address), m_fileLen(fileLength)
- {}
-
- virtual const char* what() const throw()
- {
- thread_local std::string message;
- message =
- fmt::format("Tried to access unmapped address {0:x} for file with length of {1:x}", m_address, m_fileLen);
- return message.c_str();
- }
-};
-
-// std::enable_shared_from_this allows weak pointers to "revive" the shared pointer in the FileAccessorCache.
-class MappedFileAccessor : public std::enable_shared_from_this<MappedFileAccessor>
-{
- MappedFile m_file;
- bool m_dirty = false;
-
-public:
- explicit MappedFileAccessor(MappedFile file) : m_file(std::move(file)) {}
-
- ~MappedFileAccessor() = default;
-
- MappedFileAccessor(const MappedFileAccessor&) = delete;
-
- MappedFileAccessor& operator=(const MappedFileAccessor&) = delete;
-
- MappedFileAccessor(MappedFileAccessor&&) noexcept = default;
-
- MappedFileAccessor& operator=(MappedFileAccessor&&) noexcept = default;
-
- static std::shared_ptr<MappedFileAccessor> Open(const std::string& filePath);
-
- size_t Length() const { return m_file.len; };
-
- void* Data() const { return m_file._mmap; };
-
- bool IsDirty() const { return m_dirty; }
-
- /**
- * Writes to files are implemented for performance reasons and should be treated with utmost care
- *
- * They _MAY_ disappear as _soon_ as you release the lock on the file.
- * They may also NOT disappear for the lifetime of the application.
- *
- * The former is more likely to occur when concurrent DSC processing is happening. The latter is the typical
- * scenario.
- *
- * This is used explicitly for slide information in a locked scope and _NOTHING_ else. It should probably not be
- * used for anything else.
- *
- * \param address The address to write the pointer to
- * \param pointer The pointer to be written
- */
- void WritePointer(size_t address, size_t pointer);
-
- std::string ReadNullTermString(size_t address, size_t maxLength = -1) const;
-
- uint8_t ReadUInt8(size_t address) const;
-
- int8_t ReadInt8(size_t address) const;
-
- uint16_t ReadUInt16(size_t address) const;
-
- int16_t ReadInt16(size_t address) const;
-
- uint32_t ReadUInt32(size_t address) const;
-
- int32_t ReadInt32(size_t address) const;
-
- uint64_t ReadUInt64(size_t address) const;
-
- int64_t ReadInt64(size_t address) const;
-
- BinaryNinja::DataBuffer ReadBuffer(size_t addr, size_t length) const;
-
- // Returns a range of pointers within the mapped memory region corresponding to
- // {addr, length}.
- // WARNING: The pointers returned by this method is only valid for the lifetime
- // of this file accessor.
- // TODO: This should use std::span<const uint8_t> once the minimum supported
- // C++ version supports it.
- std::pair<const uint8_t*, const uint8_t*> ReadSpan(size_t addr, size_t length);
-
- void Read(void* dest, size_t addr, size_t length) const;
-
- template <typename T>
- T Read(size_t address) const;
-};