Skip to content

Commit 350d886

Browse files
committed
unix: backport libffi aarch64 fixes
LLVM 19 yields a compile error without these patches. Strictly speaking we may only need the final one. However there are conflicts unless we take all patches to `src/aarch64/sysv.S`. So we just take the 3 of them.
1 parent 64ad969 commit 350d886

File tree

1 file changed

+336
-0
lines changed

1 file changed

+336
-0
lines changed

cpython-unix/build-libffi.sh

Lines changed: 336 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,342 @@ tar -xf libffi-${LIBFFI_VERSION}.tar.gz
1313

1414
pushd 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+
16352
EXTRA_CONFIGURE=
17353

18354
# mkostemp() was introduced in macOS 10.10 and libffi doesn't have

0 commit comments

Comments
 (0)