Note: This patch is not yet ready for trunk as its dependent on some patches that are not-yet-upstream, however it serves as motivation for the previous patch(es) which are independent.
---- Implement the __builtin_nested_func_ptr_{created,deleted} functions for the aarch64-darwin platform. For this platform --enable-off-stack-trampolines is enabled by default, and -foff-stack-trampolines is enabled by default if the host MacOS operating system version is 11.x or greater. Co-authored-by: Andrew Burgess <andrew.burg...@embecosm.com> libgcc/ChangeLog: * config/aarch64/heap-trampoline.c (allocate_trampoline_page): Request for MAP_JIT in the case of __APPLE__. Provide __APPLE__ variant of aarch64_trampoline_insns that uses x16 as the chain pointer. (__builtin_nested_func_ptr_created): Call pthread_jit_write_protect_np() to toggle read/write permission on page. * config.host (aarch64*-*darwin* | arm64*-*darwin*): Handle --enable-off-stack-trampolines. * configure.ac (--enable-off-stack-trampolines): Permit setting for target aarch64*-*darwin* | arm64*-*darwin*, and set default to enabled. * configure: Regenerate. --- gcc/config.gcc | 7 +++++ libgcc/config.host | 4 +++ libgcc/config/aarch64/heap-trampoline.c | 36 +++++++++++++++++++++++++ libgcc/configure | 6 +++++ libgcc/configure.ac | 6 +++++ 5 files changed, 59 insertions(+) diff --git a/gcc/config.gcc b/gcc/config.gcc index 031be563c5d..c13f7629d44 100644 --- a/gcc/config.gcc +++ b/gcc/config.gcc @@ -1072,6 +1072,13 @@ esac # Figure out if we need to enable -foff-stack-trampolines by default. case ${target} in +aarch64*-*darwin* | arm64*-*darwin*) + if test ${macos_maj} = 11 || test ${macos_maj} = 12; then + tm_defines="$tm_defines OFF_STACK_TRAMPOLINES_INIT=1" + else + tm_defines="$tm_defines OFF_STACK_TRAMPOLINES_INIT=0" + fi + ;; *) tm_defines="$tm_defines OFF_STACK_TRAMPOLINES_INIT=0" ;; diff --git a/libgcc/config.host b/libgcc/config.host index d1a491d27e7..3c536b0928a 100644 --- a/libgcc/config.host +++ b/libgcc/config.host @@ -414,6 +414,10 @@ aarch64*-*darwin* | arm64*-*darwin* ) tmake_file="${tmake_file} t-crtfm" # No soft float for now because our long double is DF not TF. md_unwind_header=aarch64/aarch64-unwind.h + if test x$off_stack_trampolines = xyes; then + extra_parts="$extra_parts heap-trampoline.o" + tmake_file="${tmake_file} ${cpu_type}/t-heap-trampoline" + fi ;; aarch64*-*-freebsd*) extra_parts="$extra_parts crtfastmath.o" diff --git a/libgcc/config/aarch64/heap-trampoline.c b/libgcc/config/aarch64/heap-trampoline.c index 721a2bed400..6994602beaf 100644 --- a/libgcc/config/aarch64/heap-trampoline.c +++ b/libgcc/config/aarch64/heap-trampoline.c @@ -5,6 +5,9 @@ #include <stdio.h> #include <string.h> +/* For pthread_jit_write_protect_np */ +#include <pthread.h> + void *allocate_trampoline_page (void); int get_trampolines_per_page (void); struct tramp_ctrl_data *allocate_tramp_ctrl (struct tramp_ctrl_data *parent); @@ -43,8 +46,15 @@ allocate_trampoline_page (void) { void *page; +#if defined(__gnu_linux__) page = mmap (0, getpagesize (), PROT_WRITE | PROT_EXEC, MAP_ANON | MAP_PRIVATE, 0, 0); +#elif defined(__APPLE__) + page = mmap (0, getpagesize (), PROT_WRITE | PROT_EXEC, + MAP_ANON | MAP_PRIVATE | MAP_JIT, 0, 0); +#else + page = MAP_FAILED; +#endif return page; } @@ -67,6 +77,7 @@ allocate_tramp_ctrl (struct tramp_ctrl_data *parent) return p; } +#if defined(__gnu_linux__) static const uint32_t aarch64_trampoline_insns[] = { 0xd503245f, /* hint 34 */ 0x580000b1, /* ldr x17, .+20 */ @@ -76,6 +87,20 @@ static const uint32_t aarch64_trampoline_insns[] = { 0xd5033fdf /* isb */ }; +#elif defined(__APPLE__) +static const uint32_t aarch64_trampoline_insns[] = { + 0xd503245f, /* hint 34 */ + 0x580000b1, /* ldr x17, .+20 */ + 0x580000d0, /* ldr x16, .+24 */ + 0xd61f0220, /* br x17 */ + 0xd5033f9f, /* dsb sy */ + 0xd5033fdf /* isb */ +}; + +#else +#error "Unsupported AArch64 platform for heap trampolines" +#endif + void __builtin_nested_func_ptr_created (void *chain, void *func, void **dst) { @@ -99,11 +124,22 @@ __builtin_nested_func_ptr_created (void *chain, void *func, void **dst) = &tramp_ctrl_curr->trampolines[get_trampolines_per_page () - tramp_ctrl_curr->free_trampolines]; +#if defined(__APPLE__) + /* Disable write protection for the MAP_JIT regions in this thread (see + https://developer.apple.com/documentation/apple-silicon/porting-just-in-time-compilers-to-apple-silicon) */ + pthread_jit_write_protect_np (0); +#endif + memcpy (trampoline->insns, aarch64_trampoline_insns, sizeof(aarch64_trampoline_insns)); trampoline->func_ptr = func; trampoline->chain_ptr = chain; +#if defined(__APPLE__) + /* Re-enable write protection. */ + pthread_jit_write_protect_np (1); +#endif + tramp_ctrl_curr->free_trampolines -= 1; __builtin___clear_cache ((void *)trampoline->insns, diff --git a/libgcc/configure b/libgcc/configure index 5abcea8bed3..35cdf8f8c05 100755 --- a/libgcc/configure +++ b/libgcc/configure @@ -2267,6 +2267,9 @@ case "$target" in aarch64*-*-linux* ) off_stack_trampolines=$enableval ;; + aarch64*-*darwin* | arm64*-*darwin* ) + off_stack_trampolines=$enableval + ;; *) as_fn_error $? "Configure option --enable-off-stack-trampolines is not supported \ for this platform" "$LINENO" 5 @@ -2276,6 +2279,9 @@ esac else case "$target" in + aarch64*-*darwin* | arm64*-*darwin* ) + off_stack_trampolines=yes + ;; *) off_stack_trampolines=no ;; diff --git a/libgcc/configure.ac b/libgcc/configure.ac index c6eaceec957..3b129f1a4b8 100644 --- a/libgcc/configure.ac +++ b/libgcc/configure.ac @@ -78,6 +78,9 @@ case "$target" in aarch64*-*-linux* ) off_stack_trampolines=$enableval ;; + aarch64*-*darwin* | arm64*-*darwin* ) + off_stack_trampolines=$enableval + ;; *) AC_MSG_ERROR([Configure option --enable-off-stack-trampolines is not supported \ for this platform]) @@ -85,6 +88,9 @@ for this platform]) ;; esac],[ case "$target" in + aarch64*-*darwin* | arm64*-*darwin* ) + off_stack_trampolines=yes + ;; *) off_stack_trampolines=no ;; -- 2.30.1 (Apple Git-130)