Commit 24e71928 by Sergey Ulanov

[Fuchsia] Implement ExecutableMemory support on Fuchsia.

Added fuchsia-specific versions of allocateExecutable() and markExecutable(). Bug: chromium: 778467 Change-Id: I027f1409f7b0343e102f98fcc34f2e93c2d626e4 Reviewed-on: https://swiftshader-review.googlesource.com/c/23408Reviewed-by: 's avatarAlexis Hétu <sugoi@google.com> Tested-by: 's avatarSergey Ulanov <sergeyu@chromium.org>
parent f6d56f15
......@@ -22,6 +22,10 @@
#endif
#include <windows.h>
#include <intrin.h>
#elif defined(__Fuchsia__)
#include <unistd.h>
#include <zircon/process.h>
#include <zircon/syscalls.h>
#else
#include <errno.h>
#include <sys/mman.h>
......@@ -172,10 +176,17 @@ void deallocate(void *memory)
#endif
}
// Rounds |x| up to a multiple of |m|, where |m| is a power of 2.
inline uintptr_t roundUp(uintptr_t x, uintptr_t m)
{
ASSERT(m > 0 && (m & (m - 1)) == 0); // |m| must be a power of 2.
return (x + m - 1) & ~(m - 1);
}
void *allocateExecutable(size_t bytes)
{
size_t pageSize = memoryPageSize();
size_t length = (bytes + pageSize - 1) & ~(pageSize - 1);
size_t length = roundUp(bytes, pageSize);
void *mapping;
#if defined(LINUX_ENABLE_NAMED_MMAP)
......@@ -198,6 +209,39 @@ void *allocateExecutable(size_t bytes)
{
mapping = nullptr;
}
#elif defined(__Fuchsia__)
zx_handle_t vmo;
if (zx_vmo_create(length, ZX_VMO_NON_RESIZABLE, &vmo) != ZX_OK) {
return nullptr;
}
zx_vaddr_t reservation;
zx_status_t status = zx_vmar_map(
zx_vmar_root_self(), ZX_VM_FLAG_PERM_READ | ZX_VM_FLAG_PERM_WRITE,
0, vmo, 0, length, &reservation);
zx_handle_close(vmo);
if (status != ZX_OK) {
return nullptr;
}
zx_vaddr_t alignedReservation = roundUp(reservation, pageSize);
mapping = reinterpret_cast<void*>(alignedReservation);
// Unmap extra memory reserved before the block.
if (alignedReservation != reservation) {
size_t prefix_size = alignedReservation - reservation;
status =
zx_vmar_unmap(zx_vmar_root_self(), reservation, prefix_size);
ASSERT(status == ZX_OK);
length -= prefix_size;
}
// Unmap extra memory at the end.
if (length > bytes) {
status = zx_vmar_unmap(
zx_vmar_root_self(), alignedReservation + bytes,
length - bytes);
ASSERT(status == ZX_OK);
}
#else
mapping = allocate(length, pageSize);
#endif
......@@ -210,6 +254,11 @@ void markExecutable(void *memory, size_t bytes)
#if defined(_WIN32)
unsigned long oldProtection;
VirtualProtect(memory, bytes, PAGE_EXECUTE_READ, &oldProtection);
#elif defined(__Fuchsia__)
zx_status_t status = zx_vmar_protect(
zx_vmar_root_self(), ZX_VM_FLAG_PERM_READ | ZX_VM_FLAG_PERM_EXECUTE,
reinterpret_cast<zx_vaddr_t>(memory), bytes);
ASSERT(status != ZX_OK);
#else
mprotect(memory, bytes, PROT_READ | PROT_EXEC);
#endif
......@@ -225,6 +274,9 @@ void deallocateExecutable(void *memory, size_t bytes)
size_t pageSize = memoryPageSize();
size_t length = (bytes + pageSize - 1) & ~(pageSize - 1);
munmap(memory, length);
#elif defined(__Fuchsia__)
zx_vmar_unmap(zx_vmar_root_self(), reinterpret_cast<zx_vaddr_t>(memory),
bytes);
#else
mprotect(memory, bytes, PROT_READ | PROT_WRITE);
deallocate(memory);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment