Added support for MAP_JIT (OSX, IOS), build system and CI improvements

This commit is contained in:
kobalicek
2020-01-24 10:10:02 +01:00
parent 7e164e3ede
commit 5437d20dbb
6 changed files with 346 additions and 181 deletions

View File

@@ -8,160 +8,51 @@ env:
- BUILD_TOOLCHAIN="Unix Makefiles"
- MAKEFLAGS="-j2"
dist: xenial
dist: bionic
matrix:
include:
- name: "Linux GCC 4.8 [32-bit] [DBG]"
env: BUILD_MATRIX="BUILD_TYPE=Debug && CC=gcc-4.8 && CXX=g++-4.8" CXXFLAGS=-m32 LDFLAGS=-m32
- name: "Linux Clang Default [64-bit] [DBG]"
env: BUILD_MATRIX="BUILD_TYPE=Debug && CC=clang-9 && CXX=clang++-9"
os: linux
addons:
apt:
sources: [ubuntu-toolchain-r-test]
packages: [g++-4.8, g++-4.8-multilib, "linux-libc-dev:i386"]
sources:
- sourceline: "ppa:ubuntu-toolchain-r/test"
packages: [clang++-9]
- name: "Linux GCC 4.8 [64-bit] [DBG]"
env: BUILD_MATRIX="BUILD_TYPE=Debug && CC=gcc-4.8 && CXX=g++-4.8"
- name: "Linux Clang Default [64-bit] [REL]"
env: BUILD_MATRIX="BUILD_TYPE=Release && CC=clang-9 && CXX=clang++-9"
os: linux
addons:
apt:
sources: [ubuntu-toolchain-r-test]
packages: [g++-4.8]
sources:
- sourceline: "ppa:ubuntu-toolchain-r/test"
packages: [clang++-9]
- name: "Linux GCC 4.9 [32-bit] [DBG]"
env: BUILD_MATRIX="BUILD_TYPE=Debug && CC=gcc-4.9 && CXX=g++-4.9" CXXFLAGS=-m32 LDFLAGS=-m32
- name: "Linux Clang Default [64-bit] [REL] [Sanitize=Address]"
env: BUILD_MATRIX="BUILD_TYPE=Release && CC=clang-9 && CXX=clang++-9" SANITIZE=address
os: linux
addons:
apt:
sources: [ubuntu-toolchain-r-test]
packages: [g++-4.9, g++-4.9-multilib, "linux-libc-dev:i386"]
sources:
- sourceline: "ppa:ubuntu-toolchain-r/test"
packages: [clang++-9]
- name: "Linux GCC 4.9 [64-bit] [DBG]"
env: BUILD_MATRIX="BUILD_TYPE=Debug && CC=gcc-4.9 && CXX=g++-4.9"
- name: "Linux Clang Default [64-bit] [REL] [Sanitize=Undefined]"
env: BUILD_MATRIX="BUILD_TYPE=Release && CC=clang-9 && CXX=clang++-9" SANITIZE=undefined
os: linux
addons:
apt:
sources: [ubuntu-toolchain-r-test]
packages: [g++-4.9]
- name: "Linux GCC 5.X [32-bit] [DBG]"
env: BUILD_MATRIX="BUILD_TYPE=Debug && CC=gcc-5 && CXX=g++-5" CXXFLAGS=-m32 LDFLAGS=-m32
os: linux
addons:
apt:
sources: [ubuntu-toolchain-r-test]
packages: [g++-5, g++-5-multilib, "linux-libc-dev:i386"]
- name: "Linux GCC 5.X [64-bit] [DBG]"
env: BUILD_MATRIX="BUILD_TYPE=Debug && CC=gcc-5 && CXX=g++-5"
os: linux
addons:
apt:
sources: [ubuntu-toolchain-r-test]
packages: [g++-5]
- name: "Linux GCC 6.X [32-bit] [DBG]"
env: BUILD_MATRIX="BUILD_TYPE=Debug && CC=gcc-6 && CXX=g++-6" CXXFLAGS=-m32 LDFLAGS=-m32
os: linux
addons:
apt:
sources: [ubuntu-toolchain-r-test]
packages: [g++-6, g++-6-multilib, "linux-libc-dev:i386"]
- name: "Linux GCC 6.X [64-bit] [DBG]"
env: BUILD_MATRIX="BUILD_TYPE=Debug && CC=gcc-6 && CXX=g++-6"
os: linux
addons:
apt:
sources: [ubuntu-toolchain-r-test]
packages: [g++-6]
- name: "Linux GCC 7.X [32-bit] [DBG]"
env: BUILD_MATRIX="BUILD_TYPE=Debug && CC=gcc-7 && CXX=g++-7" CXXFLAGS=-m32 LDFLAGS=-m32
os: linux
addons:
apt:
sources: [ubuntu-toolchain-r-test]
packages: [g++-7, g++-7-multilib, "linux-libc-dev:i386"]
- name: "Linux GCC 7.X [64-bit] [DBG]"
env: BUILD_MATRIX="BUILD_TYPE=Debug && CC=gcc-7 && CXX=g++-7"
os: linux
addons:
apt:
sources: [ubuntu-toolchain-r-test]
packages: [g++-7]
- name: "Linux GCC 8.X [32-bit] [DBG]"
env: BUILD_MATRIX="BUILD_TYPE=Debug && CC=gcc-8 && CXX=g++-8" CXXFLAGS=-m32 LDFLAGS=-m32
os: linux
addons:
apt:
sources: [ubuntu-toolchain-r-test]
packages: [g++-8, g++-8-multilib, "linux-libc-dev:i386"]
- name: "Linux GCC 8.X [32-bit] [REL]"
env: BUILD_MATRIX="BUILD_TYPE=Release && CC=gcc-8 && CXX=g++-8" CXXFLAGS=-m32 LDFLAGS=-m32
os: linux
addons:
apt:
sources: [ubuntu-toolchain-r-test]
packages: [g++-8, g++-8-multilib, "linux-libc-dev:i386"]
- name: "Linux GCC 8.X [64-bit] [DBG]"
env: BUILD_MATRIX="BUILD_TYPE=Debug && CC=gcc-8 && CXX=g++-8"
os: linux
addons:
apt:
sources: [ubuntu-toolchain-r-test]
packages: [g++-8]
- name: "Linux GCC 8.X [64-bit] [REL]"
env: BUILD_MATRIX="BUILD_TYPE=Release && CC=gcc-8 && CXX=g++-8"
os: linux
addons:
apt:
sources: [ubuntu-toolchain-r-test]
packages: [g++-8]
- name: "Linux GCC 9.X [32-bit] [DBG]"
env: BUILD_MATRIX="BUILD_TYPE=Debug && CC=gcc-9 && CXX=g++-9" CXXFLAGS=-m32 LDFLAGS=-m32
os: linux
addons:
apt:
sources: [ubuntu-toolchain-r-test]
packages: [g++-9, g++-9-multilib, "linux-libc-dev:i386"]
- name: "Linux GCC 9.X [32-bit] [REL]"
env: BUILD_MATRIX="BUILD_TYPE=Release && CC=gcc-9 && CXX=g++-9" CXXFLAGS=-m32 LDFLAGS=-m32
os: linux
addons:
apt:
sources: [ubuntu-toolchain-r-test]
packages: [g++-9, g++-9-multilib, "linux-libc-dev:i386"]
- name: "Linux GCC 9.X [64-bit] [DBG]"
env: BUILD_MATRIX="BUILD_TYPE=Debug && CC=gcc-9 && CXX=g++-9"
os: linux
addons:
apt:
sources: [ubuntu-toolchain-r-test]
packages: [g++-9]
- name: "Linux GCC 9.X [64-bit] [REL]"
env: BUILD_MATRIX="BUILD_TYPE=Release && CC=gcc-9 && CXX=g++-9"
os: linux
addons:
apt:
sources: [ubuntu-toolchain-r-test]
packages: [g++-9]
sources:
- sourceline: "ppa:ubuntu-toolchain-r/test"
packages: [clang++-9]
- name: "Linux GCC Default [64-bit] [DBG + Valgrind]"
env: BUILD_MATRIX="BUILD_TYPE=Debug" USE_VALGRIND=1
os: linux
addons:
apt:
sources: [ubuntu-toolchain-r-test]
packages: [valgrind]
- name: "Linux GCC Default [64-bit] [REL + Valgrind]"
@@ -169,16 +60,135 @@ matrix:
os: linux
addons:
apt:
sources: [ubuntu-toolchain-r-test]
packages: [valgrind]
- name: "Linux GCC 4.8 [32-bit] [DBG]"
env: BUILD_MATRIX="BUILD_TYPE=Debug && CC=gcc-4.8 && CXX=g++-4.8" CXXFLAGS=-m32 LDFLAGS=-m32
os: linux
addons:
apt:
packages: [g++-4.8, g++-4.8-multilib, "linux-libc-dev:i386"]
- name: "Linux GCC 4.8 [64-bit] [DBG]"
env: BUILD_MATRIX="BUILD_TYPE=Debug && CC=gcc-4.8 && CXX=g++-4.8"
os: linux
addons:
apt:
packages: [g++-4.8]
- name: "Linux GCC 5.X [32-bit] [DBG]"
env: BUILD_MATRIX="BUILD_TYPE=Debug && CC=gcc-5 && CXX=g++-5" CXXFLAGS=-m32 LDFLAGS=-m32
os: linux
addons:
apt:
packages: [g++-5, g++-5-multilib, "linux-libc-dev:i386"]
- name: "Linux GCC 5.X [64-bit] [DBG]"
env: BUILD_MATRIX="BUILD_TYPE=Debug && CC=gcc-5 && CXX=g++-5"
os: linux
addons:
apt:
packages: [g++-5]
- name: "Linux GCC 6.X [32-bit] [DBG]"
env: BUILD_MATRIX="BUILD_TYPE=Debug && CC=gcc-6 && CXX=g++-6" CXXFLAGS=-m32 LDFLAGS=-m32
os: linux
addons:
apt:
packages: [g++-6, g++-6-multilib, "linux-libc-dev:i386"]
- name: "Linux GCC 6.X [64-bit] [DBG]"
env: BUILD_MATRIX="BUILD_TYPE=Debug && CC=gcc-6 && CXX=g++-6"
os: linux
addons:
apt:
packages: [g++-6]
- name: "Linux GCC 7.X [32-bit] [DBG]"
env: BUILD_MATRIX="BUILD_TYPE=Debug && CC=gcc-7 && CXX=g++-7" CXXFLAGS=-m32 LDFLAGS=-m32
os: linux
addons:
apt:
packages: [g++-7, g++-7-multilib, "linux-libc-dev:i386"]
- name: "Linux GCC 7.X [64-bit] [DBG]"
env: BUILD_MATRIX="BUILD_TYPE=Debug && CC=gcc-7 && CXX=g++-7"
os: linux
addons:
apt:
packages: [g++-7]
- name: "Linux GCC 8.X [32-bit] [DBG]"
env: BUILD_MATRIX="BUILD_TYPE=Debug && CC=gcc-8 && CXX=g++-8" CXXFLAGS=-m32 LDFLAGS=-m32
os: linux
addons:
apt:
packages: [g++-8, g++-8-multilib, "linux-libc-dev:i386"]
- name: "Linux GCC 8.X [32-bit] [REL]"
env: BUILD_MATRIX="BUILD_TYPE=Release && CC=gcc-8 && CXX=g++-8" CXXFLAGS=-m32 LDFLAGS=-m32
os: linux
addons:
apt:
packages: [g++-8, g++-8-multilib, "linux-libc-dev:i386"]
- name: "Linux GCC 8.X [64-bit] [DBG]"
env: BUILD_MATRIX="BUILD_TYPE=Debug && CC=gcc-8 && CXX=g++-8"
os: linux
addons:
apt:
packages: [g++-8]
- name: "Linux GCC 8.X [64-bit] [REL]"
env: BUILD_MATRIX="BUILD_TYPE=Release && CC=gcc-8 && CXX=g++-8"
os: linux
addons:
apt:
packages: [g++-8]
- name: "Linux GCC 9.X [32-bit] [DBG]"
env: BUILD_MATRIX="BUILD_TYPE=Debug && CC=gcc-9 && CXX=g++-9" CXXFLAGS=-m32 LDFLAGS=-m32
os: linux
addons:
apt:
sources:
- sourceline: "ppa:ubuntu-toolchain-r/test"
packages: [g++-9, g++-9-multilib, "linux-libc-dev:i386"]
- name: "Linux GCC 9.X [32-bit] [REL]"
env: BUILD_MATRIX="BUILD_TYPE=Release && CC=gcc-9 && CXX=g++-9" CXXFLAGS=-m32 LDFLAGS=-m32
os: linux
addons:
apt:
sources:
- sourceline: "ppa:ubuntu-toolchain-r/test"
packages: [g++-9, g++-9-multilib, "linux-libc-dev:i386"]
- name: "Linux GCC 9.X [64-bit] [DBG]"
env: BUILD_MATRIX="BUILD_TYPE=Debug && CC=gcc-9 && CXX=g++-9"
os: linux
addons:
apt:
sources:
- sourceline: "ppa:ubuntu-toolchain-r/test"
packages: [g++-9]
- name: "Linux GCC 9.X [64-bit] [REL]"
env: BUILD_MATRIX="BUILD_TYPE=Release && CC=gcc-9 && CXX=g++-9"
os: linux
addons:
apt:
sources:
- sourceline: "ppa:ubuntu-toolchain-r/test"
packages: [g++-9]
- name: "OSX Clang XCode 9.4 [32-bit] [DBG]"
env: BUILD_MATRIX="BUILD_TYPE=Debug" CXXFLAGS=-m32 && LDFLAGS=-m32
env: BUILD_MATRIX="BUILD_TYPE=Debug" CXXFLAGS=-m32 LDFLAGS=-m32
os: osx
osx_image: xcode9.4
- name: "OSX Clang XCode 9.4 [32-bit] [REL]"
env: BUILD_MATRIX="BUILD_TYPE=Release" CXXFLAGS=-m32 && LDFLAGS=-m32
env: BUILD_MATRIX="BUILD_TYPE=Release" CXXFLAGS=-m32 LDFLAGS=-m32
os: osx
osx_image: xcode9.4
@@ -236,9 +246,9 @@ before_script:
- cd build
- |
if [[ "$BUILD_TOOLCHAIN" =~ ^Visual\ Studio ]]; then
cmake .. -G"${BUILD_TOOLCHAIN}" -DASMJIT_TEST=1
cmake .. -G"${BUILD_TOOLCHAIN}" -DASMJIT_TEST=1 -DASMJIT_SANITIZE="${SANITIZE}"
else
cmake .. -G"${BUILD_TOOLCHAIN}" -DASMJIT_TEST=1 -DCMAKE_PREFIX_PATH="$MINGW_PATH" -DCMAKE_BUILD_TYPE="${BUILD_TYPE}"
cmake .. -G"${BUILD_TOOLCHAIN}" -DASMJIT_TEST=1 -DASMJIT_SANITIZE="${SANITIZE}" -DCMAKE_PREFIX_PATH="${MINGW_PATH}" -DCMAKE_BUILD_TYPE="${BUILD_TYPE}"
fi
- cd ..
@@ -246,7 +256,7 @@ script:
- cd build
- |
if [[ "$BUILD_TOOLCHAIN" =~ ^Visual\ Studio ]]; then
cmake --build . --config ${BUILD_TYPE} -- -nologo -v:quiet
cmake --build . --config ${BUILD_TYPE} -- -nologo -v:minimal
cd ${BUILD_TYPE}
else
cmake --build .

View File

@@ -62,6 +62,20 @@ set(ASMJIT_SANITIZE ${ASMJIT_SANITIZE} CACHE BOOL "Build with C/C++ s
set(ASMJIT_BUILD_X86 ${ASMJIT_BUILD_X86} CACHE BOOL "Build X86 backends (X86 and X86_64)")
set(ASMJIT_BUILD_ARM ${ASMJIT_BUILD_ARM} CACHE BOOL "Build ARM backends")
# =============================================================================
# [AsmJit - Project]
# =============================================================================
set(ASMJIT_INCLUDE_DIRS "${ASMJIT_DIR}/src") # Include directory is the same as source dir.
set(ASMJIT_DEPS "") # AsmJit dependencies (libraries) for the linker.
set(ASMJIT_LIBS "") # Dependencies of libs/apps that want to use AsmJit.
set(ASMJIT_CFLAGS "") # Public compiler flags.
set(ASMJIT_PRIVATE_CFLAGS "") # Private compiler flags independent of build type.
set(ASMJIT_PRIVATE_CFLAGS_DBG "") # Private compiler flags used by debug builds.
set(ASMJIT_PRIVATE_CFLAGS_REL "") # Private compiler flags used by release builds.
set(ASMJIT_SANITIZE_CFLAGS "") # Compiler flags required by currently enabled sanitizers.
set(ASMJIT_SANITIZE_LFLAGS "") # Linker flags required by currently enabled sanitizers.
# =============================================================================
# [AsmJit - Utilities]
# =============================================================================
@@ -79,6 +93,30 @@ function(asmjit_detect_cflags out)
set(${out} "${out_array}" PARENT_SCOPE)
endfunction()
# Support for various sanitizers provided by C/C++ compilers.
function(asmjit_detect_sanitizers out)
set(_out_array ${${out}})
set(_flags "")
foreach(_arg ${ARGN})
string(REPLACE "," ";" _arg "${_arg}")
list(APPEND _flags ${_arg})
endforeach()
foreach(_flag ${_flags})
if (NOT "${_flag}" MATCHES "^-fsanitize=")
SET(_flag "-fsanitize=${_flag}")
endif()
# Sanitizers also require link flags, see CMAKE_REQUIRED_FLAGS.
set(CMAKE_REQUIRED_FLAGS "${_flag}")
asmjit_detect_cflags(_out_array ${_flag})
unset(CMAKE_REQUIRED_FLAGS)
endforeach()
set(${out} "${_out_array}" PARENT_SCOPE)
endfunction()
function(asmjit_add_target target target_type src deps cflags cflags_dbg cflags_rel)
if ("${target_type}" STREQUAL "EXECUTABLE")
add_executable(${target} ${src})
@@ -89,8 +127,8 @@ function(asmjit_add_target target target_type src deps cflags cflags_dbg cflags_
target_link_libraries(${target} PRIVATE ${deps})
# target_link_options was added in cmake 3.13, which doesn't work for us.
# target_link_options(${target} PRIVATE ${ASMJIT_SANITIZE_FLAGS})
foreach(link_flag ${ASMJIT_SANITIZE_FLAGS})
# target_link_options(${target} PRIVATE ${flags})
foreach(link_flag ${ASMJIT_SANITIZE_LFLAGS})
set_property(TARGET ${target} APPEND_STRING PROPERTY LINK_FLAGS " ${link_flag}")
endforeach()
@@ -101,11 +139,11 @@ function(asmjit_add_target target target_type src deps cflags cflags_dbg cflags_
endif()
set_property(TARGET ${target} PROPERTY CXX_EXTENSIONS NO)
set_property(TARGET ${target} PROPERTY CXX_VISIBILITY_PRESET hidden)
target_compile_options(${target} PRIVATE ${cflags} ${ASMJIT_SANITIZE_FLAGS} $<$<CONFIG:Debug>:${cflags_dbg}> $<$<NOT:$<CONFIG:Debug>>:${cflags_rel}>)
target_compile_options(${target} PRIVATE ${cflags} ${ASMJIT_SANITIZE_CFLAGS} $<$<CONFIG:Debug>:${cflags_dbg}> $<$<NOT:$<CONFIG:Debug>>:${cflags_rel}>)
endfunction()
# =============================================================================
# [AsmJit - Project]
# [AsmJit - Compiler Support]
# =============================================================================
set(ASMJIT_INCLUDE_DIRS "${ASMJIT_DIR}/src") # Include directory is the same as source dir.
@@ -115,7 +153,8 @@ set(ASMJIT_CFLAGS "") # Public compiler flags.
set(ASMJIT_PRIVATE_CFLAGS "") # Private compiler flags independent of build type.
set(ASMJIT_PRIVATE_CFLAGS_DBG "") # Private compiler flags used by debug builds.
set(ASMJIT_PRIVATE_CFLAGS_REL "") # Private compiler flags used by release builds.
set(ASMJIT_SANITIZE_FLAGS "") # Sanitizer flags used as compile and link flags.
set(ASMJIT_SANITIZE_CFLAGS "") # Compiler flags required by currently enabled sanitizers.
set(ASMJIT_SANITIZE_LFLAGS "") # Linker flags required by currently enabled sanitizers.
# TODO: Backward compatibility.
set(ASMJIT_INCLUDE_DIR "${ASMJIT_INCLUDE_DIRS}")
@@ -146,8 +185,25 @@ if (NOT ASMJIT_NO_CUSTOM_FLAGS)
endif()
endif()
if (ASMJIT_SANITIZE AND "${CMAKE_CXX_COMPILER_ID}" MATCHES "^(GNU|Clang|AppleClang)$")
asmjit_detect_cflags(ASMJIT_SANITIZE_FLAGS "-fsanitize=undefined")
# Support for sanitizers.
if (ASMJIT_SANITIZE)
ASMJIT_detect_sanitizers(ASMJIT_SANITIZE_CFLAGS ${ASMJIT_SANITIZE})
if (ASMJIT_SANITIZE_CFLAGS)
message("-- Enabling sanitizers: '${ASMJIT_SANITIZE_CFLAGS}'")
# Linker must receive the same flags as the compiler when it comes to sanitizers.
set(ASMJIT_SANITIZE_LFLAGS ${ASMJIT_SANITIZE_CFLAGS})
# Don't omit frame pointer if sanitizers are enabled.
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC" OR "x${CMAKE_CXX_SIMULATE_ID}" STREQUAL "xMSVC")
list(APPEND ASMJIT_SANITIZE_CFLAGS -Oy-)
else()
list(APPEND ASMJIT_SANITIZE_CFLAGS -fno-omit-frame-pointer -g)
endif()
list(APPEND ASMJIT_PRIVATE_CFLAGS ${ASMJIT_SANITIZE_CFLAGS})
list(APPEND ASMJIT_PRIVATE_LFLAGS ${ASMJIT_SANITIZE_LFLAGS})
endif()
endif()
if (NOT WIN32)

View File

@@ -27,6 +27,18 @@
#include <sys/syscall.h>
#endif
// Apple recently introduced MAP_JIT flag, which we want to use.
#if defined(__APPLE__)
#include <TargetConditionals.h>
#if TARGET_OS_OSX
#include <sys/utsname.h>
#endif
// Older SDK doesn't define `MAP_JIT`.
#ifndef MAP_JIT
#define MAP_JIT 0x800
#endif
#endif
// BSD/OSX: `MAP_ANONYMOUS` is not defined, `MAP_ANON` is.
#if !defined(MAP_ANONYMOUS)
#define MAP_ANONYMOUS MAP_ANON
@@ -35,13 +47,19 @@
#include <atomic>
#if defined(__APPLE__)
#define ASMJIT_VM_SHM_DETECT 0
#else
#define ASMJIT_VM_SHM_DETECT 1
#endif
ASMJIT_BEGIN_NAMESPACE
// ============================================================================
// [asmjit::VirtMem - Utilities]
// ============================================================================
static const uint32_t dualMappingFilter[2] = {
static const uint32_t VirtMem_dualMappingFilter[2] = {
VirtMem::kAccessWrite,
VirtMem::kAccessExecute
};
@@ -51,7 +69,6 @@ static const uint32_t dualMappingFilter[2] = {
// ============================================================================
#if defined(_WIN32)
struct ScopedHandle {
inline ScopedHandle() noexcept
: value(nullptr) {}
@@ -148,7 +165,7 @@ Error VirtMem::allocDualMapping(DualMapping* dm, size_t size, uint32_t flags) no
void* ptr[2];
for (uint32_t i = 0; i < 2; i++) {
DWORD desiredAccess = VirtMem_accessToWinDesiredAccess(flags & ~dualMappingFilter[i]);
DWORD desiredAccess = VirtMem_accessToWinDesiredAccess(flags & ~VirtMem_dualMappingFilter[i]);
ptr[i] = ::MapViewOfFile(handle.value, desiredAccess, 0, 0, size);
if (ptr[i] == nullptr) {
@@ -180,7 +197,6 @@ Error VirtMem::releaseDualMapping(DualMapping* dm, size_t size) noexcept {
dm->rw = nullptr;
return kErrorOk;
}
#endif
// ============================================================================
@@ -200,11 +216,12 @@ struct ScopedFD {
int value;
};
#if defined(SYS_memfd_create)
// Zero initialized, if ever changed to '1' that would mean the syscall is not
// available and we must use `shm_open()` and `shm_unlink()`.
static volatile uint32_t vm_memfd_create_not_supported;
#endif
static void VirtMem_getInfo(VirtMem::Info& vmInfo) noexcept {
uint32_t pageSize = uint32_t(::getpagesize());
vmInfo.pageSize = pageSize;
vmInfo.pageGranularity = Support::max<uint32_t>(pageSize, 65536);
}
// Some operating systems don't allow /dev/shm to be executable. On Linux this
// happens when /dev/shm is mounted with 'noexec', which is enforced by systemd.
@@ -218,25 +235,6 @@ enum ShmStrategy : uint32_t {
kShmStrategyTmpDir = 2
};
#if defined(__APPLE__)
#define ASMJIT_VM_SHM_DETECT 0
#else
#define ASMJIT_VM_SHM_DETECT 1
#endif
#if ASMJIT_VM_SHM_DETECT
// Initially don't assume anything. It has to be tested whether '/dev/shm' was
// mounted with 'noexec' flag or not.
static volatile uint32_t vm_shm_strategy = kShmStrategyUnknown;
#endif
static void VirtMem_getInfo(VirtMem::Info& vmInfo) noexcept {
uint32_t pageSize = uint32_t(::getpagesize());
vmInfo.pageSize = pageSize;
vmInfo.pageGranularity = Support::max<uint32_t>(pageSize, 65536);
}
// Posix specific implementation that uses `mmap()` and `munmap()`.
static int VirtMem_accessToPosixProtection(uint32_t flags) noexcept {
int protection = 0;
@@ -246,6 +244,7 @@ static int VirtMem_accessToPosixProtection(uint32_t flags) noexcept {
return protection;
}
// Translates libc errors specific to VirtualMemory mapping to `asmjit::Error`.
static Error VirtMem_makeErrorFromErrno(int e) noexcept {
switch (e) {
case EACCES:
@@ -268,6 +267,75 @@ static Error VirtMem_makeErrorFromErrno(int e) noexcept {
}
}
#if defined(__APPLE__)
// Detects whether the current process is hardened, which means that pages that
// have WRITE and EXECUTABLE flags cannot be allocated without MAP_JIT flag.
static ASMJIT_INLINE bool VirtMem_isHardened() noexcept {
static volatile uint32_t globalHardenedFlag;
enum HardenedFlag : uint32_t {
kHardenedFlagUnknown = 0,
kHardenedFlagDisabled = 1,
kHardenedFlagEnabled = 2
};
uint32_t flag = globalHardenedFlag;
if (flag == kHardenedFlagUnknown) {
VirtMem::Info memInfo;
VirtMem_getInfo(memInfo);
void* ptr = mmap(nullptr, memInfo.pageSize, PROT_WRITE | PROT_EXEC, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
if (ptr == MAP_FAILED) {
flag = kHardenedFlagEnabled;
}
else {
flag = kHardenedFlagDisabled;
munmap(ptr, memInfo.pageSize);
}
globalHardenedFlag = flag;
}
return flag == kHardenedFlagEnabled;
}
// MAP_JIT flag required to run unsigned JIT code is only supported by kernel
// version 10.14+ (Mojave) and IOS.
static ASMJIT_INLINE bool VirtMem_hasMapJitSupport() noexcept {
#if TARGET_OS_OSX
static volatile uint32_t globalVersion;
uint32_t ver = globalVersion;
if (!ver) {
struct utsname osname;
uname(&osname);
ver = atoi(osname.release);
globalVersion = ver;
}
return ver >= 18;
#else
// Assume it's available.
return true;
#endif
}
static ASMJIT_INLINE uint32_t VirtMem_appleSpecificMMapFlags(uint32_t flags) {
// Always use MAP_JIT flag if user asked for it (could be used for testing
// on non-hardened processes) and detect whether it must be used when the
// process is actually hardened (in that case it doesn't make sense to rely
// on user `flags`).
bool useMapJit = ((flags & VirtMem::kMMapEnableMapJit) != 0) || VirtMem_isHardened();
if (useMapJit)
return VirtMem_hasMapJitSupport() ? MAP_JIT : 0u;
else
return 0;
}
#else
static ASMJIT_INLINE uint32_t VirtMem_appleSpecificMMapFlags(uint32_t flags) {
ASMJIT_UNUSED(flags);
return 0;
}
#endif
static const char* VirtMem_getTmpDir() noexcept {
const char* tmpDir = getenv("TMPDIR");
return tmpDir ? tmpDir : "/tmp";
@@ -277,14 +345,19 @@ static Error VirtMem_openAnonymousMemory(int* fd, bool preferTmpOverDevShm) noex
#if defined(SYS_memfd_create)
// Linux specific 'memfd_create' - if the syscall returns `ENOSYS` it means
// it's not available and we will never call it again (would be pointless).
if (!vm_memfd_create_not_supported) {
// Zero initialized, if ever changed to '1' that would mean the syscall is not
// available and we must use `shm_open()` and `shm_unlink()`.
static volatile uint32_t memfd_create_not_supported;
if (!memfd_create_not_supported) {
*fd = (int)syscall(SYS_memfd_create, "vmem", 0);
if (ASMJIT_LIKELY(*fd >= 0))
return kErrorOk;
int e = errno;
if (e == ENOSYS)
vm_memfd_create_not_supported = 1;
memfd_create_not_supported = 1;
else
return DebugUtils::errored(VirtMem_makeErrorFromErrno(e));
}
@@ -373,11 +446,14 @@ static Error VirtMem_detectShmStrategy(uint32_t* strategyOut) noexcept {
#if ASMJIT_VM_SHM_DETECT
static Error VirtMem_getShmStrategy(uint32_t* strategyOut) noexcept {
uint32_t strategy = vm_shm_strategy;
// Initially don't assume anything. It has to be tested whether
// '/dev/shm' was mounted with 'noexec' flag or not.
static volatile uint32_t globalShmStrategy = kShmStrategyUnknown;
uint32_t strategy = globalShmStrategy;
if (strategy == kShmStrategyUnknown) {
ASMJIT_PROPAGATE(VirtMem_detectShmStrategy(&strategy));
vm_shm_strategy = strategy;
globalShmStrategy = strategy;
}
*strategyOut = strategy;
@@ -397,7 +473,8 @@ Error VirtMem::alloc(void** p, size_t size, uint32_t flags) noexcept {
return DebugUtils::errored(kErrorInvalidArgument);
int protection = VirtMem_accessToPosixProtection(flags);
void* ptr = mmap(nullptr, size, protection, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
int mmFlags = MAP_PRIVATE | MAP_ANONYMOUS | VirtMem_appleSpecificMMapFlags(flags);
void* ptr = mmap(nullptr, size, protection, mmFlags, -1, 0);
if (ptr == MAP_FAILED)
return DebugUtils::errored(kErrorOutOfMemory);
@@ -444,7 +521,7 @@ Error VirtMem::allocDualMapping(DualMapping* dm, size_t size, uint32_t flags) no
void* ptr[2];
for (uint32_t i = 0; i < 2; i++) {
ptr[i] = mmap(nullptr, size, VirtMem_accessToPosixProtection(flags & ~dualMappingFilter[i]), MAP_SHARED, fd.value, 0);
ptr[i] = mmap(nullptr, size, VirtMem_accessToPosixProtection(flags & ~VirtMem_dualMappingFilter[i]), MAP_SHARED, fd.value, 0);
if (ptr[i] == MAP_FAILED) {
// Get the error now before `munmap` has a chance to clobber it.
int e = errno;

View File

@@ -38,9 +38,16 @@ enum Flags : uint32_t {
//! A combination of `kAccessRead | kAccessWrite`
kAccessReadWrite = 0x00000003u,
//! Use a `MAP_JIT` flag available on Apple platforms (OSX Mojave+), which
//! allows JIT code to be executed in OSX 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,
//! Not an access flag, only used by `allocDualMapping()` to override the
//! default allocation strategy to always use a temporary directory instead
//! on "/dev/shm" (on POSIX systems). Please note that this flag will be
//! 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

View File

@@ -674,8 +674,6 @@ ASMJIT_FAVOR_SIZE Error LoggingInternal::formatInstruction(
// Format instruction options and instruction mnemonic.
if (instId < Inst::_kIdCount) {
const InstDB::InstInfo& instInfo = InstDB::infoById(instId);
// SHORT|LONG options.
if (options & Inst::kOptionShortForm) ASMJIT_PROPAGATE(sb.appendString("short "));
if (options & Inst::kOptionLongForm) ASMJIT_PROPAGATE(sb.appendString("long "));

17
tools/configure-sanitizers.sh Executable file
View File

@@ -0,0 +1,17 @@
#!/bin/sh
CURRENT_DIR=`pwd`
BUILD_DIR="build"
BUILD_OPTIONS="-DCMAKE_EXPORT_COMPILE_COMMANDS=ON -DASMJIT_TEST=1"
echo "** Configuring '${BUILD_DIR}_rel_asan' [Sanitize=Address] **"
mkdir -p ../${BUILD_DIR}_rel_asan
cd ../${BUILD_DIR}_rel_asan
eval cmake .. -GNinja -DCMAKE_BUILD_TYPE=Release ${BUILD_OPTIONS} -DASMJIT_SANITIZE=address
cd ${CURRENT_DIR}
echo "** Configuring '${BUILD_DIR}_rel_ubsan' [Sanitize=Undefined] **"
mkdir -p ../${BUILD_DIR}_rel_ubsan
cd ../${BUILD_DIR}_rel_ubsan
eval cmake .. -GNinja -DCMAKE_BUILD_TYPE=Release ${BUILD_OPTIONS} -DASMJIT_SANITIZE=undefined
cd ${CURRENT_DIR}