You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
166 lines
6.9 KiB
166 lines
6.9 KiB
// AsmJit - Machine code generation for C++
|
|
//
|
|
// * Official AsmJit Home Page: https://asmjit.com
|
|
// * Official Github Repository: https://github.com/asmjit/asmjit
|
|
//
|
|
// Copyright (c) 2008-2020 The AsmJit Authors
|
|
//
|
|
// This software is provided 'as-is', without any express or implied
|
|
// warranty. In no event will the authors be held liable for any damages
|
|
// arising from the use of this software.
|
|
//
|
|
// Permission is granted to anyone to use this software for any purpose,
|
|
// including commercial applications, and to alter it and redistribute it
|
|
// freely, subject to the following restrictions:
|
|
//
|
|
// 1. The origin of this software must not be misrepresented; you must not
|
|
// claim that you wrote the original software. If you use this software
|
|
// in a product, an acknowledgment in the product documentation would be
|
|
// appreciated but is not required.
|
|
// 2. Altered source versions must be plainly marked as such, and must not be
|
|
// misrepresented as being the original software.
|
|
// 3. This notice may not be removed or altered from any source distribution.
|
|
|
|
#ifndef ASMJIT_CORE_VIRTMEM_H_INCLUDED
|
|
#define ASMJIT_CORE_VIRTMEM_H_INCLUDED
|
|
|
|
#include "../core/api-config.h"
|
|
#ifndef ASMJIT_NO_JIT
|
|
|
|
#include "../core/globals.h"
|
|
|
|
ASMJIT_BEGIN_NAMESPACE
|
|
|
|
//! \addtogroup asmjit_virtual_memory
|
|
//! \{
|
|
|
|
// ============================================================================
|
|
// [asmjit::VirtMem]
|
|
// ============================================================================
|
|
|
|
//! Virtual memory management.
|
|
namespace VirtMem {
|
|
|
|
//! Virtual memory access and mmap-specific flags.
|
|
enum Flags : uint32_t {
|
|
//! No access flags.
|
|
kAccessNone = 0x00000000u,
|
|
//! Memory is readable.
|
|
kAccessRead = 0x00000001u,
|
|
//! Memory is writable.
|
|
kAccessWrite = 0x00000002u,
|
|
//! Memory is executable.
|
|
kAccessExecute = 0x00000004u,
|
|
|
|
//! A combination of \ref kAccessRead and \ref kAccessWrite.
|
|
kAccessReadWrite = kAccessRead | kAccessWrite,
|
|
//! A combination of \ref kAccessRead, \ref kAccessWrite.
|
|
kAccessRW = kAccessRead | kAccessWrite,
|
|
//! A combination of \ref kAccessRead and \ref kAccessExecute.
|
|
kAccessRX = kAccessRead | kAccessExecute,
|
|
//! A combination of \ref kAccessRead, \ref kAccessWrite, and \ref kAccessExecute.
|
|
kAccessRWX = kAccessRead | kAccessWrite | kAccessExecute,
|
|
|
|
//! Use a `MAP_JIT` flag available on Apple platforms (introduced by Mojave),
|
|
//! which allows JIT code to be executed in MAC bundles. This flag is not turned
|
|
//! on by default, because when a process uses `fork()` the child process
|
|
//! has no access to the pages mapped with `MAP_JIT`, which could break code
|
|
//! that doesn't expect this behavior.
|
|
kMMapEnableMapJit = 0x00000010u,
|
|
|
|
//! Pass `PROT_MAX(PROT_READ)` to mmap() on platforms that support `PROT_MAX`.
|
|
kMMapMaxAccessRead = 0x00000020u,
|
|
//! Pass `PROT_MAX(PROT_WRITE)` to mmap() on platforms that support `PROT_MAX`.
|
|
kMMapMaxAccessWrite = 0x00000040u,
|
|
//! Pass `PROT_MAX(PROT_EXEC)` to mmap() on platforms that support `PROT_MAX`.
|
|
kMMapMaxAccessExecute = 0x00000080u,
|
|
|
|
//! A combination of \ref kMMapMaxAccessRead and \ref kMMapMaxAccessWrite.
|
|
kMMapMaxAccessReadWrite = kMMapMaxAccessRead | kMMapMaxAccessWrite,
|
|
//! A combination of \ref kMMapMaxAccessRead and \ref kMMapMaxAccessWrite.
|
|
kMMapMaxAccessRW = kMMapMaxAccessRead | kMMapMaxAccessWrite,
|
|
//! A combination of \ref kMMapMaxAccessRead and \ref kMMapMaxAccessExecute.
|
|
kMMapMaxAccessRX = kMMapMaxAccessRead | kMMapMaxAccessExecute,
|
|
//! A combination of \ref kMMapMaxAccessRead, \ref kMMapMaxAccessWrite, \ref kMMapMaxAccessExecute.
|
|
kMMapMaxAccessRWX = kMMapMaxAccessRead | kMMapMaxAccessWrite | kMMapMaxAccessExecute,
|
|
|
|
//! Not an access flag, only used by `allocDualMapping()` to override the
|
|
//! default allocation strategy to always use a 'tmp' directory instead of
|
|
//! "/dev/shm" (on POSIX platforms). Please note that this flag will be
|
|
//! ignored if the operating system allows to allocate an executable memory
|
|
//! by a different API than `open()` or `shm_open()`. For example on Linux
|
|
//! `memfd_create()` is preferred and on BSDs `shm_open(SHM_ANON, ...)` is
|
|
//! used if SHM_ANON is defined.
|
|
kMappingPreferTmp = 0x80000000u
|
|
};
|
|
|
|
//! Virtual memory information.
|
|
struct Info {
|
|
//! Virtual memory page size.
|
|
uint32_t pageSize;
|
|
//! Virtual memory page granularity.
|
|
uint32_t pageGranularity;
|
|
};
|
|
|
|
//! Dual memory mapping used to map an anonymous memory into two memory regions
|
|
//! where one region is read-only, but executable, and the second region is
|
|
//! read+write, but not executable. Please see \ref VirtMem::allocDualMapping()
|
|
//! for more details.
|
|
struct DualMapping {
|
|
//! Pointer to data with 'Read' or 'Read+Execute' access.
|
|
void* ro;
|
|
//! Pointer to data with 'Read-Write' access, but never 'Write+Execute'.
|
|
void* rw;
|
|
};
|
|
|
|
//! Returns virtual memory information, see `VirtMem::Info` for more details.
|
|
ASMJIT_API Info info() noexcept;
|
|
|
|
//! Allocates virtual memory by either using `mmap()` (POSIX) or `VirtualAlloc()`
|
|
//! (Windows).
|
|
//!
|
|
//! \note `size` should be aligned to page size, use \ref VirtMem::info()
|
|
//! to obtain it. Invalid size will not be corrected by the implementation
|
|
//! and the allocation would not succeed in such case.
|
|
ASMJIT_API Error alloc(void** p, size_t size, uint32_t flags) noexcept;
|
|
|
|
//! Releases virtual memory previously allocated by \ref VirtMem::alloc().
|
|
//!
|
|
//! \note The size must be the same as used by \ref VirtMem::alloc(). If the
|
|
//! size is not the same value the call will fail on any POSIX system, but
|
|
//! pass on Windows, because it's implemented differently.
|
|
ASMJIT_API Error release(void* p, size_t size) noexcept;
|
|
|
|
//! A cross-platform wrapper around `mprotect()` (POSIX) and `VirtualProtect()`
|
|
//! (Windows).
|
|
ASMJIT_API Error protect(void* p, size_t size, uint32_t flags) noexcept;
|
|
|
|
//! Allocates virtual memory and creates two views of it where the first view
|
|
//! has no write access. This is an addition to the API that should be used
|
|
//! in cases in which the operating system either enforces W^X security policy
|
|
//! or the application wants to use this policy by default to improve security
|
|
//! and prevent an accidental (or purposed) self-modifying code.
|
|
//!
|
|
//! The memory returned in the `dm` are two independent mappings of the same
|
|
//! shared memory region. You must use \ref VirtMem::releaseDualMapping() to
|
|
//! release it when it's no longer needed. Never use `VirtMem::release()` to
|
|
//! release the memory returned by `allocDualMapping()` as that would fail on
|
|
//! Windows.
|
|
//!
|
|
//! \remarks Both pointers in `dm` would be set to `nullptr` if the function fails.
|
|
ASMJIT_API Error allocDualMapping(DualMapping* dm, size_t size, uint32_t flags) noexcept;
|
|
|
|
//! Releases virtual memory mapping previously allocated by \ref VirtMem::allocDualMapping().
|
|
//!
|
|
//! \remarks Both pointers in `dm` would be set to `nullptr` if the function succeeds.
|
|
ASMJIT_API Error releaseDualMapping(DualMapping* dm, size_t size) noexcept;
|
|
|
|
} // VirtMem
|
|
|
|
//! \}
|
|
|
|
ASMJIT_END_NAMESPACE
|
|
|
|
#endif
|
|
#endif // ASMJIT_CORE_VIRTMEM_H_INCLUDED
|