libffi_sys/
arch.rs

1//! This module defines the different ffi_abi values for each platform.
2//!
3//! This module is set-up to define all the constants for each platform, but only export those which
4//! are actually relevant to the target arch. This is done as a compile check to ensure the code
5//! paths in less utilized architectures largely continue to compile.
6
7#![allow(unused)]
8
9/// From libffi:src/x86/ffitarget.h.
10/// See: <https://github.com/libffi/libffi/blob/252c0f463641e6100169c3f0a4a590d7df438278/src/x86/ffitarget.h#L83>
11mod x86 {
12    pub mod x86_win64 {
13        use crate::ffi_abi;
14
15        pub const ffi_abi_FFI_FIRST_ABI: ffi_abi = 0;
16        pub const ffi_abi_FFI_WIN64: ffi_abi = 1;
17        pub const ffi_abi_FFI_GNUW64: ffi_abi = 2;
18        pub const ffi_abi_FFI_LAST_ABI: ffi_abi = 3;
19
20        mod gnu {
21            pub const ffi_abi_FFI_DEFAULT_ABI: crate::ffi_abi = super::ffi_abi_FFI_GNUW64;
22        }
23
24        mod msvc {
25            pub const ffi_abi_FFI_DEFAULT_ABI: crate::ffi_abi = super::ffi_abi_FFI_WIN64;
26        }
27
28        #[cfg(target_env = "gnu")]
29        pub use gnu::*;
30        #[cfg(target_env = "msvc")]
31        pub use msvc::*;
32
33        // See: https://github.com/libffi/libffi/blob/252c0f463641e6100169c3f0a4a590d7df438278/src/x86/ffitarget.h#L140
34        pub const FFI_TRAMPOLINE_SIZE: usize = 32;
35        pub const FFI_NATIVE_RAW_API: u32 = 0;
36    }
37
38    pub mod x86_64 {
39        use crate::ffi_abi;
40
41        pub const ffi_abi_FFI_FIRST_ABI: ffi_abi = 1;
42        pub const ffi_abi_FFI_UNIX64: ffi_abi = 2;
43        pub const ffi_abi_FFI_WIN64: ffi_abi = 3;
44        pub const ffi_abi_FFI_EFI64: ffi_abi = ffi_abi_FFI_WIN64;
45        pub const ffi_abi_FFI_GNUW64: ffi_abi = 4;
46        pub const ffi_abi_FFI_LAST_ABI: ffi_abi = 5;
47        pub const ffi_abi_FFI_DEFAULT_ABI: ffi_abi = ffi_abi_FFI_UNIX64;
48
49        // See: https://github.com/libffi/libffi/blob/252c0f463641e6100169c3f0a4a590d7df438278/src/x86/ffitarget.h#L140
50        pub const FFI_TRAMPOLINE_SIZE: usize = 32;
51        pub const FFI_NATIVE_RAW_API: u32 = 0;
52    }
53
54    pub mod x86_win32 {
55        use crate::ffi_abi;
56
57        pub const ffi_abi_FFI_FIRST_ABI: ffi_abi = 0;
58        pub const ffi_abi_FFI_SYSV: ffi_abi = 1;
59        pub const ffi_abi_FFI_STDCALL: ffi_abi = 2;
60        pub const ffi_abi_FFI_THISCALL: ffi_abi = 3;
61        pub const ffi_abi_FFI_FASTCALL: ffi_abi = 4;
62        pub const ffi_abi_FFI_MS_CDECL: ffi_abi = 5;
63        pub const ffi_abi_FFI_PASCAL: ffi_abi = 6;
64        pub const ffi_abi_FFI_REGISTER: ffi_abi = 7;
65        pub const ffi_abi_FFI_LAST_ABI: ffi_abi = 8;
66        pub const ffi_abi_FFI_DEFAULT_ABI: ffi_abi = ffi_abi_FFI_MS_CDECL;
67
68        // See: https://github.com/libffi/libffi/blob/252c0f463641e6100169c3f0a4a590d7df438278/src/x86/ffitarget.h#L149
69        pub const FFI_TRAMPOLINE_SIZE: usize = 16;
70        pub const FFI_NATIVE_RAW_API: u32 = 1;
71    }
72
73    pub mod x86 {
74        use crate::ffi_abi;
75
76        pub const ffi_abi_FFI_FIRST_ABI: ffi_abi = 0;
77        pub const ffi_abi_FFI_SYSV: ffi_abi = 1;
78        pub const ffi_abi_FFI_THISCALL: ffi_abi = 3;
79        pub const ffi_abi_FFI_FASTCALL: ffi_abi = 4;
80        pub const ffi_abi_FFI_STDCALL: ffi_abi = 5;
81        pub const ffi_abi_FFI_PASCAL: ffi_abi = 6;
82        pub const ffi_abi_FFI_REGISTER: ffi_abi = 7;
83        pub const ffi_abi_FFI_MS_CDECL: ffi_abi = 8;
84        pub const ffi_abi_FFI_LAST_ABI: ffi_abi = 9;
85        pub const ffi_abi_FFI_DEFAULT_ABI: ffi_abi = ffi_abi_FFI_SYSV;
86
87        // See: https://github.com/libffi/libffi/blob/252c0f463641e6100169c3f0a4a590d7df438278/src/x86/ffitarget.h#L149
88        pub const FFI_TRAMPOLINE_SIZE: usize = 16;
89        pub const FFI_NATIVE_RAW_API: u32 = 1;
90    }
91
92    pub const FFI_GO_CLOSURES: u32 = 1;
93}
94
95#[cfg(all(target_arch = "x86_64", windows))]
96pub use x86::x86_win64::*;
97
98#[cfg(all(target_arch = "x86_64", unix))]
99pub use x86::x86_64::*;
100
101#[cfg(all(target_arch = "x86", windows))]
102pub use x86::x86_win32::*;
103
104#[cfg(all(target_arch = "x86", unix))]
105pub use x86::x86::*;
106
107/// From libffi:src/arm/ffitarget.h.
108/// See: <https://github.com/libffi/libffi/blob/252c0f463641e6100169c3f0a4a590d7df438278/src/arm/ffitarget.h#L41>
109mod arm {
110    use crate::ffi_abi;
111
112    pub const ffi_abi_FFI_FIRST_ABI: ffi_abi = 0;
113    pub const ffi_abi_FFI_SYSV: ffi_abi = 1;
114    pub const ffi_abi_FFI_VFP: ffi_abi = 2;
115    pub const ffi_abi_FFI_LAST_ABI: ffi_abi = 3;
116
117    // On systems with a hard(ware) float ("hf"), ffi_abi_FFI_VPF is the default ABI.
118    #[cfg(target_abi = "eabihf")]
119    pub const ffi_abi_FFI_DEFAULT_ABI: ffi_abi = ffi_abi_FFI_VFP;
120    #[cfg(not(target_abi = "eabihf"))]
121    pub const ffi_abi_FFI_DEFAULT_ABI: ffi_abi = ffi_abi_FFI_SYSV;
122
123    // See: <https://github.com/libffi/libffi/blob/252c0f463641e6100169c3f0a4a590d7df438278/src/arm/ffitarget.h#L84>
124    pub const FFI_GO_CLOSURES: u32 = 1;
125    pub const FFI_TRAMPOLINE_SIZE: usize = 12;
126    pub const FFI_NATIVE_RAW_API: u32 = 0;
127}
128
129#[cfg(target_arch = "arm")]
130pub use arm::*;
131
132/// From libffi:src/aarch64/ffitarget.h.
133/// See: <https://github.com/libffi/libffi/blob/252c0f463641e6100169c3f0a4a590d7df438278/src/aarch64/ffitarget.h#L44>
134mod aarch64 {
135    use crate::ffi_abi;
136
137    pub const ffi_abi_FFI_FIRST_ABI: ffi_abi = 0;
138    pub const ffi_abi_FFI_SYSV: ffi_abi = 1;
139    pub const ffi_abi_FFI_WIN64: ffi_abi = 2;
140    pub const ffi_abi_FFI_LAST_ABI: ffi_abi = 3;
141
142    #[cfg(unix)]
143    pub const ffi_abi_FFI_DEFAULT_ABI: ffi_abi = ffi_abi_FFI_SYSV;
144    #[cfg(windows)]
145    pub const ffi_abi_FFI_DEFAULT_ABI: ffi_abi = ffi_abi_FFI_WIN64;
146
147    pub const FFI_NATIVE_RAW_API: u32 = 0;
148
149    // See: <https://github.com/libffi/libffi/blob/252c0f463641e6100169c3f0a4a590d7df438278/src/aarch64/ffitarget.h#L66>
150    #[cfg(target_vendor = "apple")]
151    pub const FFI_TRAMPOLINE_SIZE: usize = 16;
152
153    // See: <https://github.com/libffi/libffi/blob/252c0f463641e6100169c3f0a4a590d7df438278/src/aarch64/ffitarget.h#L66>
154    #[cfg(not(target_vendor = "apple"))]
155    pub const FFI_TRAMPOLINE_SIZE: usize = 24;
156
157    // No GO_CLOSURES on iOS or Windows
158    #[cfg(not(any(target_os = "windows", target_vendor = "apple")))]
159    pub const FFI_GO_CLOSURES: u32 = 1;
160}
161
162#[cfg(target_arch = "aarch64")]
163pub use aarch64::*;
164
165/// From libffi:src/powerpc/ffitarget.h.
166/// See: <https://github.com/libffi/libffi/blob/252c0f463641e6100169c3f0a4a590d7df438278/src/powerpc/ffitarget.h#L60>
167mod powerpc {
168    pub mod powerpc {
169        use crate::ffi_abi;
170
171        pub const ffi_abi_FFI_FIRST_ABI: ffi_abi = 0;
172        pub const ffi_abi_FFI_SYSV_SOFT_FLOAT: ffi_abi = 0b00_0001;
173        pub const ffi_abi_FFI_SYSV_STRUCT_RET: ffi_abi = 0b00_0010;
174        pub const ffi_abi_FFI_SYSV_IBM_LONG_DOUBLE: ffi_abi = 0b00_0100;
175        pub const ffi_abi_FFI_SYSV: ffi_abi = 0b00_1000;
176        pub const ffi_abi_FFI_SYSV_LONG_DOUBLE_128: ffi_abi = 0b01_0000;
177
178        mod fprs {
179            pub const SOFT_FLOAT_FLAG: crate::ffi_abi = 0b0;
180        }
181
182        mod no_fprs {
183            pub const SOFT_FLOAT_FLAG: crate::ffi_abi = super::ffi_abi_FFI_SYSV_SOFT_FLOAT;
184        }
185
186        #[cfg(target_abi = "spe")]
187        use no_fprs::*;
188
189        #[cfg(not(target_abi = "spe"))]
190        use fprs::*;
191
192        mod struct_ret {
193            pub const STRUCT_RET_FLAG: crate::ffi_abi = super::ffi_abi_FFI_SYSV_STRUCT_RET;
194        }
195
196        mod no_struct_ret {
197            pub const STRUCT_RET_FLAG: crate::ffi_abi = 0b0;
198        }
199
200        #[cfg(target_os = "netbsd")]
201        use struct_ret::*;
202
203        #[cfg(not(target_os = "netbsd"))]
204        use no_struct_ret::*;
205
206        mod long_double_64 {
207            pub const LONG_DOUBLE_128_FLAG: crate::ffi_abi = 0b0;
208        }
209
210        mod long_double_128 {
211            pub const LONG_DOUBLE_128_FLAG: crate::ffi_abi =
212                super::ffi_abi_FFI_SYSV_LONG_DOUBLE_128;
213        }
214
215        // IEEE128 is not supported on BSD or when targeting musl:
216        // https://github.com/rust-lang/llvm-project/blob/cb7f903994646c5b9223e0bb6cee3792190991f7/clang/lib/Basic/Targets/PPC.h#L379
217
218        #[cfg(any(target_os = "netbsd", target_os = "freebsd", target_env = "musl"))]
219        use long_double_64::*;
220
221        #[cfg(not(any(target_os = "netbsd", target_os = "freebsd", target_env = "musl")))]
222        use long_double_128::*;
223
224        pub const ffi_abi_FFI_DEFAULT_ABI: ffi_abi = ffi_abi_FFI_SYSV
225            | ffi_abi_FFI_SYSV_IBM_LONG_DOUBLE
226            | SOFT_FLOAT_FLAG
227            | STRUCT_RET_FLAG
228            | LONG_DOUBLE_128_FLAG;
229
230        pub const FFI_TRAMPOLINE_SIZE: usize = 40;
231        pub const FFI_NATIVE_RAW_API: u32 = 0;
232        pub const FFI_GO_CLOSURES: u32 = 1;
233    }
234
235    pub mod powerpc64 {
236        use crate::ffi_abi;
237
238        pub const ffi_abi_FFI_FIRST_ABI: ffi_abi = 0;
239        pub const ffi_abi_FFI_LINUX_STRUCT_ALIGN: ffi_abi = 0b00_0001;
240        pub const ffi_abi_FFI_LINUX_LONG_DOUBLE_128: ffi_abi = 0b00_0010;
241        pub const ffi_abi_FFI_LINUX_LONG_DOUBLE_IEEE128: ffi_abi = 0b00_0100;
242        pub const ffi_abi_FFI_LINUX: ffi_abi = 0b00_1000;
243
244        mod elfv1 {
245            pub const FFI_TRAMPOLINE_SIZE: usize = 24;
246        }
247
248        mod elfv2 {
249            pub const FFI_TRAMPOLINE_SIZE: usize = 32;
250        }
251
252        #[cfg(any(
253            all(target_arch = "powerpc64", target_abi = "elfv1"),
254            not(target_arch = "powerpc64")
255        ))]
256        mod elf {
257            pub use super::elfv1::*;
258        }
259
260        #[cfg(all(target_arch = "powerpc64", target_abi = "elfv2"))]
261        mod elf {
262            pub use super::elfv2::*;
263        }
264
265        pub use elf::FFI_TRAMPOLINE_SIZE;
266
267        mod long_double_64 {
268            pub const LONG_DOUBLE_128_FLAG: crate::ffi_abi = 0b0;
269        }
270
271        mod long_double_128 {
272            pub const LONG_DOUBLE_128_FLAG: crate::ffi_abi =
273                super::ffi_abi_FFI_LINUX_LONG_DOUBLE_128;
274        }
275
276        // IEEE128 is not supported on BSD or when targeting musl:
277        // https://github.com/rust-lang/llvm-project/blob/cb7f903994646c5b9223e0bb6cee3792190991f7/clang/lib/Basic/Targets/PPC.h#L417
278
279        #[cfg(any(target_os = "netbsd", target_os = "freebsd", target_env = "musl"))]
280        use long_double_64::*;
281
282        #[cfg(not(any(target_os = "netbsd", target_os = "freebsd", target_env = "musl")))]
283        use long_double_128::*;
284
285        pub const ffi_abi_FFI_DEFAULT_ABI: ffi_abi =
286            ffi_abi_FFI_LINUX | ffi_abi_FFI_LINUX_STRUCT_ALIGN | LONG_DOUBLE_128_FLAG;
287
288        pub const FFI_NATIVE_RAW_API: u32 = 0;
289        pub const FFI_GO_CLOSURES: u32 = 1;
290    }
291}
292
293#[cfg(target_arch = "powerpc")]
294pub use powerpc::powerpc::*;
295
296#[cfg(target_arch = "powerpc64")]
297pub use powerpc::powerpc64::*;
298
299/// From libffi:src/riscv/ffitarget.h
300/// See: <https://github.com/libffi/libffi/blob/252c0f463641e6100169c3f0a4a590d7df438278/src/riscv/ffitarget.h#L46>
301mod riscv {
302    use crate::ffi_abi;
303
304    pub const ffi_abi_FFI_FIRST_ABI: ffi_abi = 0;
305    pub const ffi_abi_FFI_SYSV: ffi_abi = 1;
306    pub const ffi_abi_FFI_UNUSED_1: ffi_abi = 2;
307    pub const ffi_abi_FFI_UNUSED_2: ffi_abi = 3;
308    pub const ffi_abi_FFI_UNUSED_3: ffi_abi = 4;
309    pub const ffi_abi_LAST_ABI: ffi_abi = 5;
310    pub const ffi_abi_FFI_DEFAULT_ABI: ffi_abi = ffi_abi_FFI_SYSV;
311
312    /// See: <https://github.com/libffi/libffi/blob/252c0f463641e6100169c3f0a4a590d7df438278/src/riscv/ffitarget.h#L63>
313    pub const FFI_GO_CLOSURES: u32 = 1;
314    pub const FFI_TRAMPOLINE_SIZE: usize = 24;
315    pub const FFI_NATIVE_RAW_API: u32 = 0;
316}
317
318#[cfg(target_arch = "riscv32")]
319pub use riscv::*;
320
321#[cfg(target_arch = "riscv64")]
322pub use riscv::*;
323
324/// From libffi:src/s390/ffitarget.h
325/// See: <https://github.com/libffi/libffi/blob/252c0f463641e6100169c3f0a4a590d7df438278/src/s390/ffitarget.h#L47>
326mod s390x {
327    use crate::ffi_abi;
328
329    pub const ffi_abi_FFI_FIRST_ABI: ffi_abi = 0;
330    pub const ffi_abi_FFI_SYSV: ffi_abi = 1;
331    pub const ffi_abi_LAST_ABI: ffi_abi = 2;
332    pub const ffi_abi_FFI_DEFAULT_ABI: ffi_abi = ffi_abi_FFI_SYSV;
333
334    pub const FFI_GO_CLOSURES: u32 = 1;
335    pub const FFI_TRAMPOLINE_SIZE: usize = 32;
336    pub const FFI_NATIVE_RAW_API: u32 = 0;
337}
338
339#[cfg(target_arch = "s390x")]
340pub use s390x::*;
341
342/// From libffi:src/sparc/ffitarget.h
343/// See <https://github.com/libffi/libffi/blob/252c0f463641e6100169c3f0a4a590d7df438278/src/sparc/ffitarget.h#L47>
344mod sparcv9 {
345    use crate::ffi_abi;
346
347    pub const ffi_abi_FFI_FIRST_ABI: ffi_abi = 0;
348    pub const ffi_abi_FFI_V9: ffi_abi = 1;
349    pub const ffi_abi_LAST_ABI: ffi_abi = 2;
350    pub const ffi_abi_FFI_DEFAULT_ABI: ffi_abi = ffi_abi_FFI_V9;
351
352    pub const FFI_GO_CLOSURES: u32 = 1;
353    pub const FFI_TRAMPOLINE_SIZE: usize = 24;
354    pub const FFI_NATIVE_RAW_API: u32 = 0;
355}
356
357#[cfg(target_arch = "sparc64")]
358pub use sparcv9::*;
359
360/// From libffi:src/loongarch64/ffitarget.h.
361/// See: <https://github.com/libffi/libffi/blob/252c0f463641e6100169c3f0a4a590d7df438278/src/loongarch64/ffitarget.h#L47>
362mod loongarch64 {
363    use crate::ffi_abi;
364
365    pub const ffi_abi_FFI_FIRST_ABI: ffi_abi = 0;
366    pub const ffi_abi_FFI_LP64S: ffi_abi = 1;
367    pub const ffi_abi_FFI_LP64F: ffi_abi = 2;
368    pub const ffi_abi_FFI_LP64D: ffi_abi = 3;
369    pub const ffi_abi_FFI_LAST_ABI: ffi_abi = 4;
370    pub const ffi_abi_FFI_DEFAULT_ABI: ffi_abi = ffi_abi_FFI_LP64D;
371
372    pub const FFI_GO_CLOSURES: u32 = 1;
373    pub const FFI_TRAMPOLINE_SIZE: usize = 24;
374    pub const FFI_NATIVE_RAW_API: u32 = 0;
375}
376
377#[cfg(target_arch = "loongarch64")]
378pub use loongarch64::*;
379
380/// From libffi:src/mips/ffitarget.h
381/// See: <https://github.com/libffi/libffi/blob/252c0f463641e6100169c3f0a4a590d7df438278/src/mips/ffitarget.h#L201>
382mod mips {
383    mod common {
384        use crate::ffi_abi;
385        pub const ffi_abi_FFI_FIRST_ABI: ffi_abi = 0;
386        pub const ffi_abi_FFI_O32: ffi_abi = 1;
387        pub const ffi_abi_FFI_N32: ffi_abi = 2;
388        pub const ffi_abi_FFI_N64: ffi_abi = 3;
389        pub const ffi_abi_FFI_O32_SOFT_FLOAT: ffi_abi = 4;
390        pub const ffi_abi_FFI_N32_SOFT_FLOAT: ffi_abi = 5;
391        pub const ffi_abi_FFI_N64_SOFT_FLOAT: ffi_abi = 6;
392        pub const ffi_abi_FFI_LAST_ABI: ffi_abi = 7;
393
394        pub const FFI_CLOSURES: u32 = 1;
395        pub const FFI_GO_CLOSURES: u32 = 1;
396        pub const FFI_NATIVE_RAW_ABI: u32 = 0;
397    }
398
399    pub mod mips {
400        use crate::ffi_abi;
401
402        pub use super::common::*;
403
404        pub const ffi_abi_FFI_DEFAULT_ABI: ffi_abi = ffi_abi_FFI_O32;
405
406        pub const FFI_TRAMPOLINE_SIZE: usize = 20;
407    }
408
409    pub mod mips64 {
410        use crate::ffi_abi;
411
412        pub use super::common::*;
413
414        pub const ffi_abi_FFI_DEFAULT_ABI: ffi_abi = ffi_abi_FFI_N64;
415
416        pub const FFI_TRAMPOLINE_SIZE: usize = 56;
417    }
418}
419
420#[cfg(any(target_arch = "mips", target_arch = "mips32r6"))]
421pub use mips::mips::*;
422
423#[cfg(any(target_arch = "mips64", target_arch = "mips64r6"))]
424pub use mips::mips64::*;
425
426#[cfg(all(test, feature = "std"))]
427mod test {
428    use core::ffi::c_uint;
429
430    use super::*;
431
432    // `ffi_get_default_abi` was added in libffi v3.5.0. This test cannot be
433    // executed without the function, so it is disabled when performing dynamic
434    // linking to libffi until version 3.5.0. is required for dynamic linking by
435    // libffi-rs.
436    #[cfg(not(feature = "system"))]
437    #[test]
438    fn verify_default_abi() {
439        extern "C" {
440            fn ffi_get_default_abi() -> c_uint;
441        }
442
443        unsafe { assert_eq!(ffi_abi_FFI_DEFAULT_ABI, ffi_get_default_abi()) }
444    }
445}