Skip to content

Commit

Permalink
Align trampoline to 2 bytes to pass mfp check (#82)
Browse files Browse the repository at this point in the history
  • Loading branch information
shqke authored Dec 17, 2024
1 parent 4b062f6 commit 60bdee3
Showing 1 changed file with 12 additions and 5 deletions.
17 changes: 12 additions & 5 deletions src/allocator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -84,16 +84,20 @@ void Allocator::free(uint8_t* address, size_t size) {

std::expected<Allocation, Allocator::Error> Allocator::internal_allocate_near(
const std::vector<uint8_t*>& desired_addresses, size_t size, size_t max_distance) {
// Align to 2 bytes to pass MFP virtual method check
// See https://itanium-cxx-abi.github.io/cxx-abi/abi.html#member-function-pointers
size_t aligned_size = align_up(size, 2);

// First search through our list of allocations for a free block that is large
// enough.
for (const auto& allocation : m_memory) {
if (allocation->size < size) {
if (allocation->size < aligned_size) {
continue;
}

for (auto node = allocation->freelist.get(); node != nullptr; node = node->next.get()) {
// Enough room?
if (static_cast<size_t>(node->end - node->start) < size) {
if (static_cast<size_t>(node->end - node->start) < aligned_size) {
continue;
}

Expand All @@ -104,14 +108,14 @@ std::expected<Allocation, Allocator::Error> Allocator::internal_allocate_near(
continue;
}

node->start += size;
node->start += aligned_size;

return Allocation{shared_from_this(), address, size};
}
}

// If we didn't find a free block, we need to allocate a new one.
auto allocation_size = align_up(size, system_info().allocation_granularity);
auto allocation_size = align_up(aligned_size, system_info().allocation_granularity);
auto allocation_address = allocate_nearby_memory(desired_addresses, allocation_size, max_distance);

if (!allocation_address) {
Expand All @@ -123,13 +127,16 @@ std::expected<Allocation, Allocator::Error> Allocator::internal_allocate_near(
allocation->address = *allocation_address;
allocation->size = allocation_size;
allocation->freelist = std::make_unique<FreeNode>();
allocation->freelist->start = *allocation_address + size;
allocation->freelist->start = *allocation_address + aligned_size;
allocation->freelist->end = *allocation_address + allocation_size;

return Allocation{shared_from_this(), *allocation_address, size};
}

void Allocator::internal_free(uint8_t* address, size_t size) {
// See internal_allocate_near
size = align_up(size, 2);

for (const auto& allocation : m_memory) {
if (allocation->address > address || allocation->address + allocation->size < address) {
continue;
Expand Down

0 comments on commit 60bdee3

Please sign in to comment.