22class SAFETYHOOK_API Allocation final {
24 Allocation() =
default;
25 Allocation(
const Allocation&) =
delete;
26 Allocation(Allocation&& other)
noexcept;
27 Allocation& operator=(
const Allocation&) =
delete;
28 Allocation& operator=(Allocation&& other)
noexcept;
37 [[nodiscard]] uint8_t*
data() const noexcept {
return m_address; }
41 [[nodiscard]] uintptr_t
address() const noexcept {
return reinterpret_cast<uintptr_t
>(m_address); }
45 [[nodiscard]]
size_t size() const noexcept {
return m_size; }
49 explicit operator bool() const noexcept {
return m_address !=
nullptr && m_size != 0; }
54 Allocation(std::shared_ptr<Allocator> allocator, uint8_t* address,
size_t size)
noexcept;
57 std::shared_ptr<Allocator> m_allocator{};
63class SAFETYHOOK_API Allocator final :
public std::enable_shared_from_this<Allocator> {
67 [[nodiscard]]
static std::shared_ptr<Allocator>
global();
71 [[nodiscard]]
static std::shared_ptr<Allocator>
create();
73 Allocator(
const Allocator&) =
delete;
74 Allocator(Allocator&&) noexcept = delete;
75 Allocator& operator=(const Allocator&) = delete;
76 Allocator& operator=(Allocator&&) noexcept = delete;
77 ~Allocator() = default;
88 [[nodiscard]] std::expected<Allocation, Error>
allocate(
size_t size);
96 const std::vector<uint8_t*>& desired_addresses,
size_t size,
size_t max_distance = 0x7FFF'FFFF);
101 void free(uint8_t* address,
size_t size);
105 std::unique_ptr<FreeNode> next{};
113 std::unique_ptr<FreeNode> freelist{};
118 std::vector<std::unique_ptr<Memory>> m_memory{};
119 std::mutex m_mutex{};
121 Allocator() =
default;
123 [[nodiscard]] std::expected<Allocation, Error> internal_allocate_near(
124 const std::vector<uint8_t*>& desired_addresses,
size_t size,
size_t max_distance = 0x7FFF'FFFF);
125 void internal_free(uint8_t* address,
size_t size);
127 static void combine_adjacent_freenodes(Memory& memory);
128 [[nodiscard]]
static std::expected<uint8_t*, Error> allocate_nearby_memory(
129 const std::vector<uint8_t*>& desired_addresses,
size_t size,
size_t max_distance);
130 [[nodiscard]]
static bool in_range(
131 uint8_t* address,
const std::vector<uint8_t*>& desired_addresses,
size_t max_distance);
std::expected< Allocation, Error > allocate_near(const std::vector< uint8_t * > &desired_addresses, size_t size, size_t max_distance=0x7FFF 'FFFF)
Allocates memory near a target address.