diff options
| author | Mason Reed <mason@vector35.com> | 2025-03-10 11:05:40 -0400 |
|---|---|---|
| committer | Mason Reed <mason@vector35.com> | 2025-04-02 05:36:54 -0400 |
| commit | 25cc02431b61097b2adfc2fbc493b648b0300c3b (patch) | |
| tree | a79d9c4f4f67234d3bf9bda413e8608f479a4cc8 /view/sharedcache/core/MappedFileAccessor.h | |
| parent | fa85bf28502286c4821427c5d0ed91a7ed46f8f6 (diff) | |
[SharedCache] Refactor Shared Cache
In absence of a better name, this commit refactors the shared cache code.
Diffstat (limited to 'view/sharedcache/core/MappedFileAccessor.h')
| -rw-r--r-- | view/sharedcache/core/MappedFileAccessor.h | 103 |
1 files changed, 103 insertions, 0 deletions
diff --git a/view/sharedcache/core/MappedFileAccessor.h b/view/sharedcache/core/MappedFileAccessor.h new file mode 100644 index 00000000..7b01cb0d --- /dev/null +++ b/view/sharedcache/core/MappedFileAccessor.h @@ -0,0 +1,103 @@ +#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 {0: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); + + int8_t ReadInt8(size_t address); + + uint16_t ReadUInt16(size_t address); + + int16_t ReadInt16(size_t address); + + uint32_t ReadUInt32(size_t address); + + int32_t ReadInt32(size_t address); + + uint64_t ReadUInt64(size_t address); + + int64_t ReadInt64(size_t address); + + BinaryNinja::DataBuffer ReadBuffer(size_t addr, size_t length); + + // 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); +}; |
