summaryrefslogtreecommitdiff
path: root/view/sharedcache/core/Utility.h
blob: 5664fd9b5fb165dcb221b40477f1a00b3e55af16 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
#pragma once

#include <cstdint>
#include <map>

#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<BinaryNinja::BinaryView> view, BinaryNinja::Ref<BinaryNinja::TypeLibrary> typeLib,
	BinaryNinja::Ref<BinaryNinja::Symbol> symbol, BinaryNinja::Ref<BinaryNinja::Type> type = nullptr);

// Returns the "image name" for a given path.
// /blah/foo/bar/libObjCThing.dylib -> libObjCThing.dylib
std::string BaseFileName(const std::string& path);

bool IsSameFolderForFile(BinaryNinja::Ref<BinaryNinja::ProjectFile> a, BinaryNinja::Ref<BinaryNinja::ProjectFile> b);
bool IsSameFolder(BinaryNinja::Ref<BinaryNinja::ProjectFolder> a, BinaryNinja::Ref<BinaryNinja::ProjectFolder> b);

// 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 <typename Value>
using AddressRangeMap = std::map<AddressRange, Value, std::less<>>;

// TODO: Document this!
template <typename T>
class WeakAllocPtr
{
protected:
	std::weak_ptr<T> m_weakPtr;                       // Weak reference to the object
	std::function<std::shared_ptr<T>()> m_allocator;  // Function to recreate the object

public:
	explicit WeakAllocPtr(std::function<std::shared_ptr<T>()> allocator) : m_allocator(allocator) {}

	WeakAllocPtr(std::weak_ptr<T> weakPtr, std::function<std::shared_ptr<T>()> allocator) : m_allocator(allocator)
	{
		if (weakPtr == nullptr)
		{
			m_weakPtr = {};
		}
		else
		{
			m_weakPtr = weakPtr;
		}
	}

	std::shared_ptr<T> lock()
	{
		std::shared_ptr<T> sharedPtr = m_weakPtr.lock();
		if (!sharedPtr)
		{
			sharedPtr = m_allocator();
			m_weakPtr = sharedPtr;
		}
		return sharedPtr;
	}

	std::shared_ptr<T> lock_no_allocate() { return m_weakPtr.lock(); }
};