Commit 4c7bde32ea3af479babdf527d94f241282951cb9

Ole André Vadla Ravnås 2020-03-10T02:05:42

Port to iOS/arm64e (#548)

diff --git a/configure.ac b/configure.ac
index b764368..bf96297 100644
--- a/configure.ac
+++ b/configure.ac
@@ -176,6 +176,28 @@ case "$TARGET" in
     ;;
 esac
 
+AC_CACHE_CHECK([whether compiler supports pointer authentication],
+   libffi_cv_as_ptrauth, [
+   libffi_cv_as_ptrauth=unknown
+   AC_TRY_COMPILE(,[
+#ifdef __clang__
+# if __has_feature(ptrauth_calls)
+#  define HAVE_PTRAUTH 1
+# endif
+#endif
+
+#ifndef HAVE_PTRAUTH
+# error Pointer authentication not supported
+#endif
+		   ],
+		   [libffi_cv_as_ptrauth=yes],
+		   [libffi_cv_as_ptrauth=no])
+])
+if test "x$libffi_cv_as_ptrauth" = xyes; then
+    AC_DEFINE(HAVE_PTRAUTH, 1,
+	      [Define if your compiler supports pointer authentication.])
+fi
+
 # On PaX enable kernels that have MPROTECT enable we can't use PROT_EXEC.
 AC_ARG_ENABLE(pax_emutramp,
   [  --enable-pax_emutramp       enable pax emulated trampolines, for we can't use PROT_EXEC],
diff --git a/src/aarch64/ffi.c b/src/aarch64/ffi.c
index 1ebf43c..4cc5925 100644
--- a/src/aarch64/ffi.c
+++ b/src/aarch64/ffi.c
@@ -62,6 +62,9 @@ struct call_context
 #if FFI_EXEC_TRAMPOLINE_TABLE
 
 #ifdef __MACH__
+#ifdef HAVE_PTRAUTH
+#include <ptrauth.h>
+#endif
 #include <mach/vm_param.h>
 #endif
 
@@ -789,6 +792,9 @@ ffi_prep_closure_loc (ffi_closure *closure,
 
 #if FFI_EXEC_TRAMPOLINE_TABLE
 #ifdef __MACH__
+#ifdef HAVE_PTRAUTH
+  codeloc = ptrauth_strip (codeloc, ptrauth_key_asia);
+#endif
   void **config = (void **)((uint8_t *)codeloc - PAGE_MAX_SIZE);
   config[0] = closure;
   config[1] = start;
diff --git a/src/aarch64/sysv.S b/src/aarch64/sysv.S
index 6761ee1..a345439 100644
--- a/src/aarch64/sysv.S
+++ b/src/aarch64/sysv.S
@@ -58,6 +58,14 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.  */
 #define PTR_SIZE	8
 #endif
 
+#if FFI_EXEC_TRAMPOLINE_TABLE && defined(__MACH__) && defined(HAVE_PTRAUTH)
+# define BR(r)  braaz r
+# define BLR(r) blraaz r
+#else
+# define BR(r)  br r
+# define BLR(r) blr r
+#endif
+
 	.text
 	.align 4
 
@@ -111,7 +119,7 @@ CNAME(ffi_call_SYSV):
 	/* Deallocate the context, leaving the stacked arguments.  */
 	add	sp, sp, #CALL_CONTEXT_SIZE
 
-	blr     x9			/* call fn */
+	BLR(x9)				/* call fn */
 
 	ldp	x3, x4, [x29, #16]	/* reload rvalue and flags */
 
@@ -271,6 +279,9 @@ CNAME(ffi_closure_SYSV):
 	bl      CNAME(ffi_closure_SYSV_inner)
 
 	/* Load the return value as directed.  */
+#if FFI_EXEC_TRAMPOLINE_TABLE && defined(__MACH__) && defined(HAVE_PTRAUTH)
+	autiza	x1
+#endif
 	adr	x1, 0f
 	and	w0, w0, #AARCH64_RET_MASK
 	add	x1, x1, x0, lsl #3
@@ -365,7 +376,7 @@ CNAME(ffi_closure_trampoline_table_page):
     .rept PAGE_MAX_SIZE / FFI_TRAMPOLINE_SIZE
     adr x16, -PAGE_MAX_SIZE
     ldp x17, x16, [x16]
-    br x16
+    BR(x16)
 	nop		/* each entry in the trampoline config page is 2*sizeof(void*) so the trampoline itself cannot be smaller that 16 bytes */
     .endr
 
diff --git a/src/closures.c b/src/closures.c
index 047abcd..b5eb2bb 100644
--- a/src/closures.c
+++ b/src/closures.c
@@ -148,6 +148,9 @@ ffi_closure_free (void *ptr)
 
 #include <mach/mach.h>
 #include <pthread.h>
+#ifdef HAVE_PTRAUTH
+#include <ptrauth.h>
+#endif
 #include <stdio.h>
 #include <stdlib.h>
 
@@ -301,6 +304,9 @@ ffi_closure_alloc (size_t size, void **code)
 
   /* Initialize the return values */
   *code = entry->trampoline;
+#ifdef HAVE_PTRAUTH
+  *code = ptrauth_sign_unauthenticated (*code, ptrauth_key_asia, 0);
+#endif
   closure->trampoline_table = table;
   closure->trampoline_table_entry = entry;