From f62b9361524a74f912283ac9beac40fc4754282e Mon Sep 17 00:00:00 2001 From: Aleksey Kliger Date: Fri, 14 May 2021 10:54:20 -0400 Subject: [PATCH 1/9] Bring back arm64 JITing hack for ios simulator On iossimulator-arm64 and tvossimulator-arm64, use the pthread_jit_write_protect_np function to toggle the W^X bit for the current thread. Unfortunately, the above function is marked as __API_UNAVAILABLE on ios, tvos, watchos in the apple headers. But in the simulator frameworks it is still present and usable. So we declare our own prototype of the function and avoid the clang error. --- This reverts commit 89a816f077bb7314e829288c1f867920d9c6bfb8, but for IOS simulator, not for Catalyst. That commit in turn reverted a9f1207d9f14d6bdf6e4be0f206d11df8e032382 (ie this current commit is the same as a9f1207 but for ios simulator instead of catalyst) --- src/mono/mono/utils/CMakeLists.txt | 2 ++ src/mono/mono/utils/mono-codeman.c | 15 +++++++++++---- src/mono/mono/utils/write-protect.c | 27 +++++++++++++++++++++++++++ src/mono/mono/utils/write-protect.h | 18 ++++++++++++++++++ 4 files changed, 58 insertions(+), 4 deletions(-) create mode 100644 src/mono/mono/utils/write-protect.c create mode 100644 src/mono/mono/utils/write-protect.h diff --git a/src/mono/mono/utils/CMakeLists.txt b/src/mono/mono/utils/CMakeLists.txt index 115570cf39df4..6b3b3b02d3f2a 100644 --- a/src/mono/mono/utils/CMakeLists.txt +++ b/src/mono/mono/utils/CMakeLists.txt @@ -33,6 +33,8 @@ set(utils_common_sources mono-logger.c mono-logger-internals.h mono-codeman.c + write-protect.c + write-protect.h mono-counters.c mono-compiler.h mono-dl.c diff --git a/src/mono/mono/utils/mono-codeman.c b/src/mono/mono/utils/mono-codeman.c index 10cc823eddf64..88bd4dbe61f5c 100644 --- a/src/mono/mono/utils/mono-codeman.c +++ b/src/mono/mono/utils/mono-codeman.c @@ -28,6 +28,7 @@ static void* mono_code_manager_heap; #include #include +#include static uintptr_t code_memory_used = 0; static size_t dynamic_code_alloc_count; @@ -669,8 +670,10 @@ mono_codeman_enable_write (void) pthread_jit_write_protect_np (0); } #elif defined(HOST_MACCAT) && defined(__aarch64__) - /* JITing in Catalyst apps is not allowed on Apple Silicon. */ - g_assert_not_reached (); + int level = GPOINTER_TO_INT (mono_native_tls_get_value (write_level_tls_id)); + level ++; + mono_native_tls_set_value (write_level_tls_id, GINT_TO_POINTER (level)); + mono_jit_write_protect (0); #endif } @@ -693,7 +696,11 @@ mono_codeman_disable_write (void) pthread_jit_write_protect_np (1); } #elif defined(HOST_MACCAT) && defined(__aarch64__) - /* JITing in Catalyst apps is not allowed on Apple Silicon. */ - g_assert_not_reached (); + int level = GPOINTER_TO_INT (mono_native_tls_get_value (write_level_tls_id)); + g_assert (level); + level --; + mono_native_tls_set_value (write_level_tls_id, GINT_TO_POINTER (level)); + if (level == 0) + mono_jit_write_protect (1); #endif } diff --git a/src/mono/mono/utils/write-protect.c b/src/mono/mono/utils/write-protect.c new file mode 100644 index 0000000000000..a7aeebee63052 --- /dev/null +++ b/src/mono/mono/utils/write-protect.c @@ -0,0 +1,27 @@ +/** + * \file + */ + +#include "config.h" + +#include "mono-compiler.h" +#include "write-protect.h" + +#if defined (HOST_MACCAT) && defined (__aarch64__) + +/* our own declaration of pthread_jit_write_protect_np so that we don't see the __API_UNAVAILABLE__ header */ +void +pthread_jit_write_protect_np (int enabled); + + +void +mono_jit_write_protect (int enabled) +{ + pthread_jit_write_protect_np (enabled); +} + +#else + +MONO_EMPTY_SOURCE_FILE (write_protect); + +#endif diff --git a/src/mono/mono/utils/write-protect.h b/src/mono/mono/utils/write-protect.h new file mode 100644 index 0000000000000..f218bb6a93f30 --- /dev/null +++ b/src/mono/mono/utils/write-protect.h @@ -0,0 +1,18 @@ +/** + * \file + */ + +#ifndef __MONO_WRITE_PROTECT_H__ +#define __MONO_WRITE_PROTECT_H__ + +#include + +#if defined (HOST_MACCAT) && defined (__aarch64__) + +void +mono_jit_write_protect (int enabled); + +#endif /* defined (HOST_MACCAT) && defined (__aarch64__) */ + +#endif /* __MONO_WRITE_PROTECT_H__ */ + From 8b2f750e637c8a4975d54a44e54061670a3f3210 Mon Sep 17 00:00:00 2001 From: Aleksey Kliger Date: Fri, 14 May 2021 11:09:08 -0400 Subject: [PATCH 2/9] [build] define CMAKE_SYSTEM_VARIANT for iOSSimulator and tvOSSimulator For Mono, set HOST_DARWIN_SIMULATOR in cmake and C --- eng/native/build-commons.sh | 4 ++++ src/mono/CMakeLists.txt | 3 +++ src/mono/cmake/config.h.in | 3 +++ 3 files changed, 10 insertions(+) diff --git a/eng/native/build-commons.sh b/eng/native/build-commons.sh index d568f9bf51748..9ff810df8e1f9 100755 --- a/eng/native/build-commons.sh +++ b/eng/native/build-commons.sh @@ -94,6 +94,10 @@ build_native() cmakeArgs="-DCMAKE_SYSTEM_VARIANT=MacCatalyst $cmakeArgs" fi + if [[ "$targetOS" == "iOSSimulator" || "$targetOS" == "tvOSSimulator" ]]; then + cmakeArgs="-DCMAKE_SYSTEM_VARIANT=$targetOS $cmakeArgs" + fi + if [[ "$__UseNinja" == 1 ]]; then generator="ninja" buildTool="$(command -v ninja || command -v ninja-build)" diff --git a/src/mono/CMakeLists.txt b/src/mono/CMakeLists.txt index d9efdcf81a605..6da64a7048194 100644 --- a/src/mono/CMakeLists.txt +++ b/src/mono/CMakeLists.txt @@ -213,6 +213,9 @@ elseif(CMAKE_SYSTEM_NAME STREQUAL "iOS" OR CMAKE_SYSTEM_NAME STREQUAL "tvOS") add_definitions("-DSMALL_CONFIG") add_definitions("-D_XOPEN_SOURCE") add_definitions("-DHAVE_LARGE_FILE_SUPPORT=1") + if (CMAKE_SYSTEM_VARIANT STREQUAL "iOSSimulator" OR CMAKE_SYSTEM_VARIANT STREQUAL "tvOSSimulator") + set (HOST_DARWIN_SIMULATOR 1) + endif() elseif(CMAKE_SYSTEM_NAME STREQUAL "Linux") set(HOST_LINUX 1) add_definitions(-D_GNU_SOURCE -D_REENTRANT) diff --git a/src/mono/cmake/config.h.in b/src/mono/cmake/config.h.in index 3062415827e9d..fa1ba73606180 100644 --- a/src/mono/cmake/config.h.in +++ b/src/mono/cmake/config.h.in @@ -116,6 +116,9 @@ /* Host Platform is Mac Catalyst */ #cmakedefine HOST_MACCAT 1 +/* Host Platform is iOS or tvOS simulator */ +#cmakedefine HOST_DARWIN_SIMULATOR 1 + /* Use classic Windows API support */ #cmakedefine HAVE_CLASSIC_WINAPI_SUPPORT 1 From 9dbb360a305f6f94b2a6720166a60a593536f0ad Mon Sep 17 00:00:00 2001 From: Aleksey Kliger Date: Fri, 14 May 2021 11:29:39 -0400 Subject: [PATCH 3/9] [jit] ARM64 JIT hack for iOS and tvOS simulators --- src/mono/mono/utils/mono-codeman.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/mono/mono/utils/mono-codeman.c b/src/mono/mono/utils/mono-codeman.c index 88bd4dbe61f5c..4dd29bc40d0a7 100644 --- a/src/mono/mono/utils/mono-codeman.c +++ b/src/mono/mono/utils/mono-codeman.c @@ -669,7 +669,7 @@ mono_codeman_enable_write (void) mono_native_tls_set_value (write_level_tls_id, GINT_TO_POINTER (level)); pthread_jit_write_protect_np (0); } -#elif defined(HOST_MACCAT) && defined(__aarch64__) +#elif (defined(HOST_IOS) || defined(HOST_TVOS)) && defined(HOST_DARWIN_SIMULATOR) && defined(__aarch64__) int level = GPOINTER_TO_INT (mono_native_tls_get_value (write_level_tls_id)); level ++; mono_native_tls_set_value (write_level_tls_id, GINT_TO_POINTER (level)); @@ -695,7 +695,7 @@ mono_codeman_disable_write (void) if (level == 0) pthread_jit_write_protect_np (1); } -#elif defined(HOST_MACCAT) && defined(__aarch64__) +#elif (defined(HOST_IOS) || defined(HOST_TVOS)) && defined(HOST_DARWIN_SIMULATOR) && defined(__aarch64__) int level = GPOINTER_TO_INT (mono_native_tls_get_value (write_level_tls_id)); g_assert (level); level --; From b2153bffec4e60c1999c04cb391524c26db74060 Mon Sep 17 00:00:00 2001 From: Aleksey Kliger Date: Fri, 14 May 2021 13:46:24 -0400 Subject: [PATCH 4/9] Use the right ifdefs for write-protect.[ch] --- src/mono/mono/utils/write-protect.c | 2 +- src/mono/mono/utils/write-protect.h | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/mono/mono/utils/write-protect.c b/src/mono/mono/utils/write-protect.c index a7aeebee63052..979c1efd4c60b 100644 --- a/src/mono/mono/utils/write-protect.c +++ b/src/mono/mono/utils/write-protect.c @@ -7,7 +7,7 @@ #include "mono-compiler.h" #include "write-protect.h" -#if defined (HOST_MACCAT) && defined (__aarch64__) +#if (defined(HOST_IOS) || defined(HOST_TVOS)) && defined (HOST_DARWIN_SIMULATOR) && defined (__aarch64__) /* our own declaration of pthread_jit_write_protect_np so that we don't see the __API_UNAVAILABLE__ header */ void diff --git a/src/mono/mono/utils/write-protect.h b/src/mono/mono/utils/write-protect.h index f218bb6a93f30..b02092de4c7a6 100644 --- a/src/mono/mono/utils/write-protect.h +++ b/src/mono/mono/utils/write-protect.h @@ -7,12 +7,12 @@ #include -#if defined (HOST_MACCAT) && defined (__aarch64__) +#if (defined(HOST_IOS) || defined(HOST_TVOS)) && defined (HOST_DARWIN_SIMULATOR) && defined (__aarch64__) void mono_jit_write_protect (int enabled); -#endif /* defined (HOST_MACCAT) && defined (__aarch64__) */ +#endif /* defined (HOST_DARWIN_SIMULATOR) && defined (__aarch64__) */ #endif /* __MONO_WRITE_PROTECT_H__ */ From cabbf8af6df040cbdd6f46057945a3e1e8e0d901 Mon Sep 17 00:00:00 2001 From: Aleksey Kliger Date: Mon, 17 May 2021 10:49:07 -0400 Subject: [PATCH 5/9] fix indentation --- eng/native/build-commons.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/eng/native/build-commons.sh b/eng/native/build-commons.sh index 9ff810df8e1f9..edd7cdd155609 100755 --- a/eng/native/build-commons.sh +++ b/eng/native/build-commons.sh @@ -95,7 +95,7 @@ build_native() fi if [[ "$targetOS" == "iOSSimulator" || "$targetOS" == "tvOSSimulator" ]]; then - cmakeArgs="-DCMAKE_SYSTEM_VARIANT=$targetOS $cmakeArgs" + cmakeArgs="-DCMAKE_SYSTEM_VARIANT=$targetOS $cmakeArgs" fi if [[ "$__UseNinja" == 1 ]]; then From 79c040d0ec6ef8b5533ce0a063f5da681b9308b8 Mon Sep 17 00:00:00 2001 From: Aleksey Kliger Date: Mon, 17 May 2021 10:49:29 -0400 Subject: [PATCH 6/9] use HOST_ARM64 macros instead of compiler __aarch64__ macro --- src/mono/mono/utils/write-protect.c | 4 ++-- src/mono/mono/utils/write-protect.h | 6 ++---- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/src/mono/mono/utils/write-protect.c b/src/mono/mono/utils/write-protect.c index 979c1efd4c60b..47c6ce62ba230 100644 --- a/src/mono/mono/utils/write-protect.c +++ b/src/mono/mono/utils/write-protect.c @@ -7,7 +7,7 @@ #include "mono-compiler.h" #include "write-protect.h" -#if (defined(HOST_IOS) || defined(HOST_TVOS)) && defined (HOST_DARWIN_SIMULATOR) && defined (__aarch64__) +#if (defined(HOST_IOS) || defined(HOST_TVOS)) && defined (HOST_DARWIN_SIMULATOR) && defined (HOST_ARM64) /* our own declaration of pthread_jit_write_protect_np so that we don't see the __API_UNAVAILABLE__ header */ void @@ -20,7 +20,7 @@ mono_jit_write_protect (int enabled) pthread_jit_write_protect_np (enabled); } -#else +#else /* (defined(HOST_IOS) || defined(HOST_TVOS)) && defined (HOST_DARWIN_SIMULATOR) && defined (HOST_ARM64) */ MONO_EMPTY_SOURCE_FILE (write_protect); diff --git a/src/mono/mono/utils/write-protect.h b/src/mono/mono/utils/write-protect.h index b02092de4c7a6..e1e25f9be4a40 100644 --- a/src/mono/mono/utils/write-protect.h +++ b/src/mono/mono/utils/write-protect.h @@ -7,12 +7,10 @@ #include -#if (defined(HOST_IOS) || defined(HOST_TVOS)) && defined (HOST_DARWIN_SIMULATOR) && defined (__aarch64__) - -void +#if (defined(HOST_IOS) || defined(HOST_TVOS)) && defined (HOST_DARWIN_SIMULATOR) && defined (HOST_ARM64) mono_jit_write_protect (int enabled); -#endif /* defined (HOST_DARWIN_SIMULATOR) && defined (__aarch64__) */ +#endif /* (defined(HOST_IOS) || defined(HOST_TVOS)) && defined (HOST_DARWIN_SIMULATOR) && defined (HOST_ARM64) */ #endif /* __MONO_WRITE_PROTECT_H__ */ From 75d62487fe09571368fe81ef72ce6d32b9b70f06 Mon Sep 17 00:00:00 2001 From: Aleksey Kliger Date: Mon, 17 May 2021 10:49:51 -0400 Subject: [PATCH 7/9] refactor to remove code duplication --- src/mono/mono/utils/mono-codeman.c | 34 ++++++++++++++---------------- 1 file changed, 16 insertions(+), 18 deletions(-) diff --git a/src/mono/mono/utils/mono-codeman.c b/src/mono/mono/utils/mono-codeman.c index 4dd29bc40d0a7..2d914ae4ea902 100644 --- a/src/mono/mono/utils/mono-codeman.c +++ b/src/mono/mono/utils/mono-codeman.c @@ -653,6 +653,16 @@ mono_code_manager_size (MonoCodeManager *cman, int *used_size) return size; } +#ifdef HAVE_PTHREAD_JIT_WRITE_PROTECT_NP +#define JIT_WRITE_PROTECT(enable) pthread_jit_write_protect_np ((enable)) +#define JIT_WRITE_PROTECT_AVAIL() (__builtin_available (macOS 11, *)) +#define USE_WRITE_PROTECT 1 +#elif (defined(HOST_IOS) || defined(HOST_TVOS)) && defined(HOST_DARWIN_SIMULATOR) && defined(HOST_ARM64) +#define USE_WRITE_PROTECT 1 +#define JIT_WRITE_PROTECT(enable) mono_jit_write_protect ((enable)) +#define JIT_WRITE_PROTECT_AVAIL() 1 +#endif + /* * mono_codeman_enable_write (): * @@ -662,18 +672,13 @@ mono_code_manager_size (MonoCodeManager *cman, int *used_size) void mono_codeman_enable_write (void) { -#ifdef HAVE_PTHREAD_JIT_WRITE_PROTECT_NP - if (__builtin_available (macOS 11, *)) { +#ifdef USE_WRITE_PROTECT + if (JIT_WRITE_PROTECT_AVAIL()) { int level = GPOINTER_TO_INT (mono_native_tls_get_value (write_level_tls_id)); level ++; mono_native_tls_set_value (write_level_tls_id, GINT_TO_POINTER (level)); - pthread_jit_write_protect_np (0); + JIT_WRITE_PROTECT (0); } -#elif (defined(HOST_IOS) || defined(HOST_TVOS)) && defined(HOST_DARWIN_SIMULATOR) && defined(__aarch64__) - int level = GPOINTER_TO_INT (mono_native_tls_get_value (write_level_tls_id)); - level ++; - mono_native_tls_set_value (write_level_tls_id, GINT_TO_POINTER (level)); - mono_jit_write_protect (0); #endif } @@ -686,21 +691,14 @@ mono_codeman_enable_write (void) void mono_codeman_disable_write (void) { -#ifdef HAVE_PTHREAD_JIT_WRITE_PROTECT_NP - if (__builtin_available (macOS 11, *)) { +#ifdef USE_WRITE_PROTECT + if (JIT_WRITE_PROTECT_AVAIL()) { int level = GPOINTER_TO_INT (mono_native_tls_get_value (write_level_tls_id)); g_assert (level); level --; mono_native_tls_set_value (write_level_tls_id, GINT_TO_POINTER (level)); if (level == 0) - pthread_jit_write_protect_np (1); + JIT_WRITE_PROTECT (1); } -#elif (defined(HOST_IOS) || defined(HOST_TVOS)) && defined(HOST_DARWIN_SIMULATOR) && defined(__aarch64__) - int level = GPOINTER_TO_INT (mono_native_tls_get_value (write_level_tls_id)); - g_assert (level); - level --; - mono_native_tls_set_value (write_level_tls_id, GINT_TO_POINTER (level)); - if (level == 0) - mono_jit_write_protect (1); #endif } From 810675672a9f125e6f25192dfc63bcfa8ad2abb4 Mon Sep 17 00:00:00 2001 From: Aleksey Kliger Date: Mon, 17 May 2021 13:42:01 -0400 Subject: [PATCH 8/9] fix build: clang doesn't like __builtin_available in a macro apparently it wants to see literally `if (__builtin_available(...))` --- src/mono/mono/utils/mono-codeman.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/mono/mono/utils/mono-codeman.c b/src/mono/mono/utils/mono-codeman.c index 2d914ae4ea902..bfd5431d8d7ff 100644 --- a/src/mono/mono/utils/mono-codeman.c +++ b/src/mono/mono/utils/mono-codeman.c @@ -654,13 +654,13 @@ mono_code_manager_size (MonoCodeManager *cman, int *used_size) } #ifdef HAVE_PTHREAD_JIT_WRITE_PROTECT_NP -#define JIT_WRITE_PROTECT(enable) pthread_jit_write_protect_np ((enable)) -#define JIT_WRITE_PROTECT_AVAIL() (__builtin_available (macOS 11, *)) #define USE_WRITE_PROTECT 1 +#define JIT_WRITE_PROTECT(enable) pthread_jit_write_protect_np ((enable)) +#define CHECK_WRITE_PROTECT_AVAIL 1 #elif (defined(HOST_IOS) || defined(HOST_TVOS)) && defined(HOST_DARWIN_SIMULATOR) && defined(HOST_ARM64) #define USE_WRITE_PROTECT 1 #define JIT_WRITE_PROTECT(enable) mono_jit_write_protect ((enable)) -#define JIT_WRITE_PROTECT_AVAIL() 1 +#undef CHECK_WRITE_PROTECT_AVAIL #endif /* @@ -673,7 +673,10 @@ void mono_codeman_enable_write (void) { #ifdef USE_WRITE_PROTECT - if (JIT_WRITE_PROTECT_AVAIL()) { +#ifdef CHECK_WRITE_PROTECT_AVAIL + if (__builtin_available (macOS 11, *)) +#endif + { int level = GPOINTER_TO_INT (mono_native_tls_get_value (write_level_tls_id)); level ++; mono_native_tls_set_value (write_level_tls_id, GINT_TO_POINTER (level)); From 7ed14e1a8fee5297d7356b13f207eb2bec655972 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aleksey=20Kliger=20=28=CE=BBgeek=29?= Date: Tue, 18 May 2021 08:39:34 -0400 Subject: [PATCH 9/9] fix disable_write, too --- src/mono/mono/utils/mono-codeman.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/mono/mono/utils/mono-codeman.c b/src/mono/mono/utils/mono-codeman.c index bfd5431d8d7ff..a7f74c239575f 100644 --- a/src/mono/mono/utils/mono-codeman.c +++ b/src/mono/mono/utils/mono-codeman.c @@ -695,7 +695,10 @@ void mono_codeman_disable_write (void) { #ifdef USE_WRITE_PROTECT - if (JIT_WRITE_PROTECT_AVAIL()) { +#ifdef CHECK_WRITE_PROTECT_AVAIL + if (__builtin_available (macOS 11, *)) +#endif + { int level = GPOINTER_TO_INT (mono_native_tls_get_value (write_level_tls_id)); g_assert (level); level --;