From 25cc02431b61097b2adfc2fbc493b648b0300c3b Mon Sep 17 00:00:00 2001 From: Mason Reed Date: Mon, 10 Mar 2025 11:05:40 -0400 Subject: [SharedCache] Refactor Shared Cache In absence of a better name, this commit refactors the shared cache code. --- view/sharedcache/core/Utility.h | 106 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 106 insertions(+) create mode 100644 view/sharedcache/core/Utility.h (limited to 'view/sharedcache/core/Utility.h') diff --git a/view/sharedcache/core/Utility.h b/view/sharedcache/core/Utility.h new file mode 100644 index 00000000..86715557 --- /dev/null +++ b/view/sharedcache/core/Utility.h @@ -0,0 +1,106 @@ +#pragma once + +#include +#include + +#include "binaryninjaapi.h" + +#ifdef _MSC_VER +inline int CountTrailingZeros(uint64_t value) +{ + unsigned long index; // 32-bit long on Windows + if (_BitScanForward64(&index, value)) + { + return index; + } + else + { + return 64; // If the value is 0, return 64. + } +} +#else +inline int CountTrailingZeros(uint64_t value) +{ + return value == 0 ? 64 : __builtin_ctzll(value); +} +#endif + +BNSegmentFlag SegmentFlagsFromMachOProtections(int initProt, int maxProt); + +int64_t readSLEB128(const uint8_t*& current, const uint8_t* end); + +uint64_t readLEB128(const uint8_t*& current, const uint8_t* end); + +uint64_t readValidULEB128(const uint8_t*& current, const uint8_t* end); + +void ApplySymbol(BinaryNinja::Ref view, BinaryNinja::Ref typeLib, + BinaryNinja::Ref symbol); + +// Returns the on disk file for a given path, this is required to support project files. +std::string ResolveFilePath(BinaryNinja::Ref dscView, const std::string& path); + +// Returns the "image name" for a given path. +// /blah/foo/bar/libObjCThing.dylib -> libObjCThing.dylib +std::string BaseFileName(const std::string& path); + +// Represents a range of addresses [start, end). +// Note that `end` is not included within the range. +struct AddressRange +{ + uint64_t start; + uint64_t end; + + AddressRange(uint64_t start, uint64_t end) : start(start), end(end) {} + + AddressRange() : start(0), end(0) {} + + bool Overlaps(const AddressRange& b) const { return start < b.end && b.start < end; } + + bool operator<(const AddressRange& b) const { return start < b.start || (start == b.start && end < b.end); } + + friend bool operator<(const AddressRange& range, uint64_t address) { return range.end <= address; } + + friend bool operator<(uint64_t address, const AddressRange& range) { return address < range.start; } +}; + +// A map keyed by address ranges that can be looked up via any +// address within a range thanks to C++14's transparent comparators. +template +using AddressRangeMap = std::map>; + +// TODO: Document this! +template +class WeakAllocPtr +{ +protected: + std::weak_ptr m_weakPtr; // Weak reference to the object + std::function()> m_allocator; // Function to recreate the object + +public: + explicit WeakAllocPtr(std::function()> allocator) : m_allocator(allocator) {} + + WeakAllocPtr(std::weak_ptr weakPtr, std::function()> allocator) : m_allocator(allocator) + { + if (weakPtr == nullptr) + { + m_weakPtr = {}; + } + else + { + m_weakPtr = weakPtr; + } + } + + std::shared_ptr lock() + { + std::shared_ptr sharedPtr = m_weakPtr.lock(); + if (!sharedPtr) + { + sharedPtr = m_allocator(); + m_weakPtr = sharedPtr; + } + return sharedPtr; + } + + std::shared_ptr lock_no_allocate() { return m_weakPtr.lock(); } +}; -- cgit v1.3.1