@@ -13,6 +13,342 @@ tar -xf libffi-${LIBFFI_VERSION}.tar.gz
1313
1414pushd libffi-${LIBFFI_VERSION}
1515
16+ # Needed to fix compilation on macOS aarch64. Will presumably be in libffi
17+ # 3.4.7 or 3.5. Combo of upstream commits
18+ # f64141ee3f9e455a060bd09e9ab72b6c94653d7c, 45d284f2d066cc3a080c5be88e51b4d934349797,
19+ # and 8308bed5b2423878aa20d7884a99cf2e30b8daf7.
20+ patch -p1 << 'EOF '
21+ diff --git a/src/aarch64/sysv.S b/src/aarch64/sysv.S
22+ index fdd0e8b..60cfa50 100644
23+ --- a/src/aarch64/sysv.S
24+ +++ b/src/aarch64/sysv.S
25+ @@ -68,7 +68,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
26+ #define BTI_J hint #36
27+ /*
28+ * The ELF Notes section needs to indicate if BTI is supported, as the first ELF loaded that doesn't
29+ - * declare this support disables it for the whole process.
30+ + * declare this support disables it for memory region containing the loaded library.
31+ */
32+ # define GNU_PROPERTY_AARCH64_BTI (1 << 0) /* Has Branch Target Identification */
33+ .text
34+ @@ -527,6 +527,7 @@ L(do_closure):
35+ #if defined(FFI_EXEC_STATIC_TRAMP)
36+ .align 4
37+ CNAME(ffi_closure_SYSV_V_alt):
38+ + BTI_C
39+ /* See the comments above trampoline_code_table. */
40+ ldr x17, [sp, #8] /* Load closure in x17 */
41+ add sp, sp, #16 /* Restore the stack */
42+ @@ -541,6 +542,7 @@ CNAME(ffi_closure_SYSV_V_alt):
43+
44+ .align 4
45+ CNAME(ffi_closure_SYSV_alt):
46+ + BTI_C
47+ /* See the comments above trampoline_code_table. */
48+ ldr x17, [sp, #8] /* Load closure in x17 */
49+ add sp, sp, #16 /* Restore the stack */
50+ diff --git a/testsuite/Makefile.am b/testsuite/Makefile.am
51+ index d286cf7..6ba98e1 100644
52+ --- a/testsuite/Makefile.am
53+ +++ b/testsuite/Makefile.am
54+ @@ -8,7 +8,7 @@ CLEANFILES = *.exe core* *.log *.sum
55+
56+ EXTRA_DIST = config/default.exp emscripten/build.sh emscripten/conftest.py \
57+ emscripten/node-tests.sh emscripten/test.html emscripten/test_libffi.py \
58+ - emscripten/build-tests.sh lib/libffi.exp lib/target-libpath.exp \
59+ + emscripten/build-tests.sh lib/libffi.exp lib/target-libpath.exp \
60+ lib/wrapper.exp libffi.bhaible/Makefile libffi.bhaible/README \
61+ libffi.bhaible/alignof.h libffi.bhaible/bhaible.exp libffi.bhaible/test-call.c \
62+ libffi.bhaible/test-callback.c libffi.bhaible/testcases.c libffi.call/align_mixed.c \
63+ EOF
64+
65+ patch -p1 << 'EOF '
66+ diff --git a/configure.ac b/configure.ac
67+ index 816bfd6..b35a999 100644
68+ --- a/configure.ac
69+ +++ b/configure.ac
70+ @@ -189,17 +189,17 @@ AC_CACHE_CHECK([whether compiler supports pointer authentication],
71+ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[
72+ #ifdef __clang__
73+ # if __has_feature(ptrauth_calls)
74+ -# define HAVE_PTRAUTH 1
75+ +# define HAVE_ARM64E_PTRAUTH 1
76+ # endif
77+ #endif
78+
79+ -#ifndef HAVE_PTRAUTH
80+ +#ifndef HAVE_ARM64E_PTRAUTH
81+ # error Pointer authentication not supported
82+ #endif
83+ ]])],[libffi_cv_as_ptrauth=yes],[libffi_cv_as_ptrauth=no])
84+ ])
85+ if test "x$libffi_cv_as_ptrauth" = xyes; then
86+ - AC_DEFINE(HAVE_PTRAUTH, 1,
87+ + AC_DEFINE(HAVE_ARM64E_PTRAUTH, 1,
88+ [Define if your compiler supports pointer authentication.])
89+ fi
90+
91+ diff --git a/include/ffi_cfi.h b/include/ffi_cfi.h
92+ index f4c292d..8565663 100644
93+ --- a/include/ffi_cfi.h
94+ +++ b/include/ffi_cfi.h
95+ @@ -49,6 +49,7 @@
96+ # define cfi_personality(enc, exp) .cfi_personality enc, exp
97+ # define cfi_lsda(enc, exp) .cfi_lsda enc, exp
98+ # define cfi_escape(...) .cfi_escape __VA_ARGS__
99+ +# define cfi_window_save .cfi_window_save
100+
101+ #else
102+
103+ @@ -71,6 +72,7 @@
104+ # define cfi_personality(enc, exp)
105+ # define cfi_lsda(enc, exp)
106+ # define cfi_escape(...)
107+ +# define cfi_window_save
108+
109+ #endif /* HAVE_AS_CFI_PSEUDO_OP */
110+ #endif /* FFI_CFI_H */
111+ diff --git a/src/aarch64/ffi.c b/src/aarch64/ffi.c
112+ index b13738e..964934d 100644
113+ --- a/src/aarch64/ffi.c
114+ +++ b/src/aarch64/ffi.c
115+ @@ -63,7 +63,7 @@ struct call_context
116+ #if FFI_EXEC_TRAMPOLINE_TABLE
117+
118+ #ifdef __MACH__
119+ -#ifdef HAVE_PTRAUTH
120+ +#ifdef HAVE_ARM64E_PTRAUTH
121+ #include <ptrauth.h>
122+ #endif
123+ #include <mach/vm_param.h>
124+ @@ -877,7 +877,7 @@ ffi_prep_closure_loc (ffi_closure *closure,
125+
126+ #if FFI_EXEC_TRAMPOLINE_TABLE
127+ # ifdef __MACH__
128+ -# ifdef HAVE_PTRAUTH
129+ +# ifdef HAVE_ARM64E_PTRAUTH
130+ codeloc = ptrauth_auth_data(codeloc, ptrauth_key_function_pointer, 0);
131+ # endif
132+ void **config = (void **)((uint8_t *)codeloc - PAGE_MAX_SIZE);
133+ diff --git a/src/aarch64/internal.h b/src/aarch64/internal.h
134+ index b5d102b..c39f9cb 100644
135+ --- a/src/aarch64/internal.h
136+ +++ b/src/aarch64/internal.h
137+ @@ -81,20 +81,62 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
138+ /* Helpers for writing assembly compatible with arm ptr auth */
139+ #ifdef LIBFFI_ASM
140+
141+ -#ifdef HAVE_PTRAUTH
142+ -#define SIGN_LR pacibsp
143+ -#define SIGN_LR_WITH_REG(x) pacib lr, x
144+ -#define AUTH_LR_AND_RET retab
145+ -#define AUTH_LR_WITH_REG(x) autib lr, x
146+ -#define BRANCH_AND_LINK_TO_REG blraaz
147+ -#define BRANCH_TO_REG braaz
148+ -#else
149+ -#define SIGN_LR
150+ -#define SIGN_LR_WITH_REG(x)
151+ -#define AUTH_LR_AND_RET ret
152+ -#define AUTH_LR_WITH_REG(x)
153+ -#define BRANCH_AND_LINK_TO_REG blr
154+ -#define BRANCH_TO_REG br
155+ -#endif
156+ -
157+ -#endif
158+ + #if defined(HAVE_ARM64E_PTRAUTH)
159+ + /* ARM64E ABI For Darwin */
160+ + #define SIGN_LR pacibsp
161+ + #define SIGN_LR_WITH_REG(x) pacib lr, x
162+ + #define AUTH_LR_AND_RET retab
163+ + #define AUTH_LR_WITH_REG(x) autib lr, x
164+ + #define BRANCH_AND_LINK_TO_REG blraaz
165+ + #define BRANCH_TO_REG braaz
166+ + #define PAC_CFI_WINDOW_SAVE
167+ + /* Linux PAC Support */
168+ + #elif defined(__ARM_FEATURE_PAC_DEFAULT)
169+ + #define GNU_PROPERTY_AARCH64_POINTER_AUTH (1 << 1)
170+ + #define PAC_CFI_WINDOW_SAVE cfi_window_save
171+ + #define TMP_REG x9
172+ + #define BRANCH_TO_REG br
173+ + #define BRANCH_AND_LINK_TO_REG blr
174+ + #define SIGN_LR_LINUX_ONLY SIGN_LR
175+ + /* Which key to sign with? */
176+ + #if (__ARM_FEATURE_PAC_DEFAULT & 1) == 1
177+ + /* Signed with A-key */
178+ + #define SIGN_LR hint #25 /* paciasp */
179+ + #define AUTH_LR hint #29 /* autiasp */
180+ + #else
181+ + /* Signed with B-key */
182+ + #define SIGN_LR hint #27 /* pacibsp */
183+ + #define AUTH_LR hint #31 /* autibsp */
184+ + #endif /* __ARM_FEATURE_PAC_DEFAULT */
185+ + #define AUTH_LR_WITH_REG(x) _auth_lr_with_reg x
186+ +.macro _auth_lr_with_reg modifier
187+ + mov TMP_REG, sp
188+ + mov sp, \modifier
189+ + AUTH_LR
190+ + mov sp, TMP_REG
191+ +.endm
192+ + #define SIGN_LR_WITH_REG(x) _sign_lr_with_reg x
193+ +.macro _sign_lr_with_reg modifier
194+ + mov TMP_REG, sp
195+ + mov sp, \modifier
196+ + SIGN_LR
197+ + mov sp, TMP_REG
198+ +.endm
199+ + #define AUTH_LR_AND_RET _auth_lr_and_ret modifier
200+ +.macro _auth_lr_and_ret modifier
201+ + AUTH_LR
202+ + ret
203+ +.endm
204+ + #undef TMP_REG
205+ +
206+ + /* No Pointer Auth */
207+ + #else
208+ + #define SIGN_LR
209+ + #define SIGN_LR_WITH_REG(x)
210+ + #define AUTH_LR_AND_RET ret
211+ + #define AUTH_LR_WITH_REG(x)
212+ + #define BRANCH_AND_LINK_TO_REG blr
213+ + #define BRANCH_TO_REG br
214+ + #define PAC_CFI_WINDOW_SAVE
215+ + #endif /* HAVE_ARM64E_PTRAUTH */
216+ +#endif /* LIBFFI_ASM */
217+ diff --git a/src/aarch64/sysv.S b/src/aarch64/sysv.S
218+ index 60cfa50..6a9a561 100644
219+ --- a/src/aarch64/sysv.S
220+ +++ b/src/aarch64/sysv.S
221+ @@ -92,27 +92,27 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
222+ cfi_startproc
223+ CNAME(ffi_call_SYSV):
224+ BTI_C
225+ - /* Sign the lr with x1 since that is where it will be stored */
226+ + PAC_CFI_WINDOW_SAVE
227+ + /* Sign the lr with x1 since that is the CFA which is the modifer used in auth instructions */
228+ SIGN_LR_WITH_REG(x1)
229+
230+ - /* Use a stack frame allocated by our caller. */
231+ -#if defined(HAVE_PTRAUTH) && defined(__APPLE__)
232+ +#if defined(HAVE_ARM64E_PTRAUTH) && defined(__APPLE__)
233+ /* darwin's libunwind assumes that the cfa is the sp and that's the data
234+ * used to sign the lr. In order to allow unwinding through this
235+ * function it is necessary to point the cfa at the signing register.
236+ */
237+ cfi_def_cfa(x1, 0);
238+ -#else
239+ - cfi_def_cfa(x1, 40);
240+ #endif
241+ + /* Use a stack frame allocated by our caller. */
242+ stp x29, x30, [x1]
243+ + cfi_def_cfa_register(x1)
244+ + cfi_rel_offset (x29, 0)
245+ + cfi_rel_offset (x30, 8)
246+ mov x9, sp
247+ str x9, [x1, #32]
248+ mov x29, x1
249+ - mov sp, x0
250+ cfi_def_cfa_register(x29)
251+ - cfi_rel_offset (x29, 0)
252+ - cfi_rel_offset (x30, 8)
253+ + mov sp, x0
254+
255+ mov x9, x2 /* save fn */
256+ mov x8, x3 /* install structure return */
257+ @@ -326,6 +326,7 @@ CNAME(ffi_closure_SYSV_V):
258+ cfi_startproc
259+ BTI_C
260+ SIGN_LR
261+ + PAC_CFI_WINDOW_SAVE
262+ stp x29, x30, [sp, #-ffi_closure_SYSV_FS]!
263+ cfi_adjust_cfa_offset (ffi_closure_SYSV_FS)
264+ cfi_rel_offset (x29, 0)
265+ @@ -351,6 +352,7 @@ CNAME(ffi_closure_SYSV_V):
266+ CNAME(ffi_closure_SYSV):
267+ BTI_C
268+ SIGN_LR
269+ + PAC_CFI_WINDOW_SAVE
270+ stp x29, x30, [sp, #-ffi_closure_SYSV_FS]!
271+ cfi_adjust_cfa_offset (ffi_closure_SYSV_FS)
272+ cfi_rel_offset (x29, 0)
273+ @@ -648,6 +650,8 @@ CNAME(ffi_go_closure_SYSV_V):
274+ cfi_startproc
275+ CNAME(ffi_go_closure_SYSV):
276+ BTI_C
277+ + SIGN_LR_LINUX_ONLY
278+ + PAC_CFI_WINDOW_SAVE
279+ stp x29, x30, [sp, #-ffi_closure_SYSV_FS]!
280+ cfi_adjust_cfa_offset (ffi_closure_SYSV_FS)
281+ cfi_rel_offset (x29, 0)
282+ diff --git a/src/closures.c b/src/closures.c
283+ index 67a94a8..02cf78f 100644
284+ --- a/src/closures.c
285+ +++ b/src/closures.c
286+ @@ -164,7 +164,7 @@ ffi_tramp_is_present (__attribute__((unused)) void *ptr)
287+
288+ #include <mach/mach.h>
289+ #include <pthread.h>
290+ -#ifdef HAVE_PTRAUTH
291+ +#ifdef HAVE_ARM64E_PTRAUTH
292+ #include <ptrauth.h>
293+ #endif
294+ #include <stdio.h>
295+ @@ -223,7 +223,7 @@ ffi_trampoline_table_alloc (void)
296+ /* Remap the trampoline table on top of the placeholder page */
297+ trampoline_page = config_page + PAGE_MAX_SIZE;
298+
299+ -#ifdef HAVE_PTRAUTH
300+ +#ifdef HAVE_ARM64E_PTRAUTH
301+ trampoline_page_template = (vm_address_t)(uintptr_t)ptrauth_auth_data((void *)&ffi_closure_trampoline_table_page, ptrauth_key_function_pointer, 0);
302+ #else
303+ trampoline_page_template = (vm_address_t)&ffi_closure_trampoline_table_page;
304+ @@ -268,7 +268,7 @@ ffi_trampoline_table_alloc (void)
305+ ffi_trampoline_table_entry *entry = &table->free_list_pool[i];
306+ entry->trampoline =
307+ (void *) (trampoline_page + (i * FFI_TRAMPOLINE_SIZE));
308+ -#ifdef HAVE_PTRAUTH
309+ +#ifdef HAVE_ARM64E_PTRAUTH
310+ entry->trampoline = ptrauth_sign_unauthenticated(entry->trampoline, ptrauth_key_function_pointer, 0);
311+ #endif
312+
313+ EOF
314+
315+ patch -p1 << 'EOF '
316+ diff --git a/src/aarch64/sysv.S b/src/aarch64/sysv.S
317+ index 6a9a561..e83bc65 100644
318+ --- a/src/aarch64/sysv.S
319+ +++ b/src/aarch64/sysv.S
320+ @@ -89,8 +89,8 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
321+ x5 closure
322+ */
323+
324+ - cfi_startproc
325+ CNAME(ffi_call_SYSV):
326+ + cfi_startproc
327+ BTI_C
328+ PAC_CFI_WINDOW_SAVE
329+ /* Sign the lr with x1 since that is the CFA which is the modifer used in auth instructions */
330+ @@ -348,8 +348,8 @@ CNAME(ffi_closure_SYSV_V):
331+ #endif
332+
333+ .align 4
334+ - cfi_startproc
335+ CNAME(ffi_closure_SYSV):
336+ + cfi_startproc
337+ BTI_C
338+ SIGN_LR
339+ PAC_CFI_WINDOW_SAVE
340+ @@ -647,8 +647,8 @@ CNAME(ffi_go_closure_SYSV_V):
341+ #endif
342+
343+ .align 4
344+ - cfi_startproc
345+ CNAME(ffi_go_closure_SYSV):
346+ + cfi_startproc
347+ BTI_C
348+ SIGN_LR_LINUX_ONLY
349+ PAC_CFI_WINDOW_SAVE
350+ EOF
351+
16352EXTRA_CONFIGURE=
17353
18354# mkostemp() was introduced in macOS 10.10 and libffi doesn't have
0 commit comments