[PATCH 4/4] Add aarch64-darwin support for off-stack trampolines
Maxim Blinov
maxim.blinov@embecosm.com
Sat Nov 13 09:45:25 GMT 2021
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.burgess@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)
More information about the Gcc-patches
mailing list