  #include <stdio.h>
  #include <stdlib.h>
  
--extern void *ffi_closure_trampoline_table_page;
--
++#ifdef FFI_TRAMPOLINE_WHOLE_DYLIB
++#include <assert.h>
++#include <dispatch/dispatch.h>
++#include <dlfcn.h>
++#else
+ extern void *ffi_closure_trampoline_table_page;
++#endif
+ 
  typedef struct ffi_trampoline_table ffi_trampoline_table;
  typedef struct ffi_trampoline_table_entry ffi_trampoline_table_entry;
- 
-@@ -160,7 +164,6 @@
+@@ -160,7 +169,6 @@
  {
    /* contiguous writable and executable pages */
    vm_address_t config_page;

-  /* Remap the trampoline table on top of the placeholder page */
-  trampoline_page = config_page + PAGE_MAX_SIZE;
-  trampoline_page_template = (vm_address_t)&ffi_closure_trampoline_table_page;
+  static dispatch_once_t trampoline_template_init_once;
+  static void *ffi_closure_trampoline_table_page;
+
+  dispatch_once(&trampoline_template_init_once, ^{
+    void * const trampoline_handle = dlopen("/usr/lib/libffi-trampolines.dylib", RTLD_NOW | RTLD_LOCAL | RTLD_FIRST);
+    assert(trampoline_handle);
+
+    ffi_closure_trampoline_table_page = dlsym(trampoline_handle, "ffi_closure_trampoline_table_page");
+    assert(ffi_closure_trampoline_table_page);
+  });
+
+#ifdef HAVE_PTRAUTH
+  trampoline_page_template = (uintptr_t)ptrauth_auth_data((void *)ffi_closure_trampoline_table_page, ptrauth_key_function_pointer, 0);
+#else
+  trampoline_page_template = (uintptr_t)ffi_closure_trampoline_table_page;
+#endif
 #ifdef __arm__
   /* ffi_closure_trampoline_table_page can be thumb-biased on some ARM archs */
   trampoline_page_template &= ~1UL;

 
       if (i < table->free_count - 1)
 	entry->next = &table->free_list_pool[i + 1];
diff -ur libffi-3.3/src/x86/ffi.c libffi-3.3.new/src/x86/ffi.c
--- libffi-3.3/src/x86/ffi.c	2019-10-31 08:49:54.000000000 -0600
+++ libffi-3.3.new/src/x86/ffi.c	2021-01-04 19:38:38.000000000 -0700
