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/369ef49f71186fc9d6ab15614488ad466fac3fc1/src/x86/ffitarget.h#L80>
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_GNUW64;
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/0f2dd369cd5edcefad29b3fca4e1d08cb34f8f19/src/x86/ffitarget.h#L141
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/0f2dd369cd5edcefad29b3fca4e1d08cb34f8f19/src/x86/ffitarget.h#L141
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/369ef49f71186fc9d6ab15614488ad466fac3fc1/src/x86/ffitarget.h#L137
69        pub const FFI_TRAMPOLINE_SIZE: usize = 12;
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/369ef49f71186fc9d6ab15614488ad466fac3fc1/src/x86/ffitarget.h#L137
88        pub const FFI_TRAMPOLINE_SIZE: usize = 12;
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/db5706ff285c476aa3c0f811ff2b188319ac3ebe/src/arm/ffitarget.h>
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    pub const ffi_abi_FFI_DEFAULT_ABI: ffi_abi = ffi_abi_FFI_SYSV;
117
118    // See: <https://github.com/libffi/libffi/blob/db5706ff285c476aa3c0f811ff2b188319ac3ebe/src/arm/ffitarget.h#L84>
119    pub const FFI_GO_CLOSURES: u32 = 1;
120    pub const FFI_TRAMPOLINE_SIZE: usize = 12;
121    pub const FFI_NATIVE_RAW_API: u32 = 0;
122}
123
124#[cfg(target_arch = "arm")]
125pub use arm::*;
126
127/// From libffi:src/aarch64/ffitarget.h.
128/// See: <https://github.com/libffi/libffi/blob/c2a6859012d928b67a83619bd5087674a96b9254/src/aarch64/ffitarget.h#L44>
129mod aarch64 {
130    use crate::ffi_abi;
131
132    pub const ffi_abi_FFI_FIRST_ABI: ffi_abi = 0;
133    pub const ffi_abi_FFI_SYSV: ffi_abi = 1;
134    pub const ffi_abi_FFI_LAST_ABI: ffi_abi = 2;
135    pub const ffi_abi_FFI_DEFAULT_ABI: ffi_abi = ffi_abi_FFI_SYSV;
136
137    pub const FFI_NATIVE_RAW_API: u32 = 0;
138
139    #[cfg(target_vendor = "apple")]
140    pub const FFI_TRAMPOLINE_SIZE: usize = 16;
141
142    #[cfg(not(target_vendor = "apple"))]
143    pub const FFI_TRAMPOLINE_SIZE: usize = 32;
144
145    // No GO_CLOSURES on iOS or Windows
146    #[cfg(not(any(target_os = "windows", target_vendor = "apple")))]
147    pub const FFI_GO_CLOSURES: u32 = 1;
148}
149
150#[cfg(target_arch = "aarch64")]
151pub use aarch64::*;
152
153/// From libffi:src/powerpc/ffitarget.h.
154/// See: <https://github.com/libffi/libffi/blob/73dd43afc8a447ba98ea02e9aad4c6898dc77fb0/src/powerpc/ffitarget.h#L60>
155mod powerpc {
156    pub mod powerpc {
157        use crate::ffi_abi;
158
159        pub const ffi_abi_FFI_FIRST_ABI: ffi_abi = 0;
160        pub const ffi_abi_FFI_SYSV_SOFT_FLOAT: ffi_abi = 0b000001;
161        pub const ffi_abi_FFI_SYSV_STRUCT_RET: ffi_abi = 0b000010;
162        pub const ffi_abi_FFI_SYSV_IBM_LONG_DOUBLE: ffi_abi = 0b000100;
163        pub const ffi_abi_FFI_SYSV: ffi_abi = 0b001000;
164        pub const ffi_abi_FFI_SYSV_LONG_DOUBLE_128: ffi_abi = 0b010000;
165
166        mod fprs {
167            pub const SOFT_FLOAT_FLAG: crate::ffi_abi = 0b0;
168        }
169
170        mod no_fprs {
171            pub const SOFT_FLOAT_FLAG: crate::ffi_abi = super::ffi_abi_FFI_SYSV_SOFT_FLOAT;
172        }
173
174        #[cfg(target_env = "gnuspe")]
175        use no_fprs::*;
176
177        #[cfg(not(target_feature = "gnuspe"))]
178        use fprs::*;
179
180        mod struct_ret {
181            pub const STRUCT_RET_FLAG: crate::ffi_abi = super::ffi_abi_FFI_SYSV_STRUCT_RET;
182        }
183
184        mod no_struct_ret {
185            pub const STRUCT_RET_FLAG: crate::ffi_abi = 0b0;
186        }
187
188        #[cfg(target_os = "netbsd")]
189        use struct_ret::*;
190
191        #[cfg(not(target_os = "netbsd"))]
192        use no_struct_ret::*;
193
194        mod long_double_64 {
195            pub const LONG_DOUBLE_128_FLAG: crate::ffi_abi = 0b0;
196        }
197
198        mod long_double_128 {
199            pub const LONG_DOUBLE_128_FLAG: crate::ffi_abi =
200                super::ffi_abi_FFI_SYSV_LONG_DOUBLE_128;
201        }
202
203        // IEEE128 is not supported on BSD or when targeting musl:
204        // https://github.com/rust-lang/llvm-project/blob/cb7f903994646c5b9223e0bb6cee3792190991f7/clang/lib/Basic/Targets/PPC.h#L379
205
206        #[cfg(any(target_os = "netbsd", target_os = "freebsd", target_env = "musl"))]
207        use long_double_64::*;
208
209        #[cfg(not(any(target_os = "netbsd", target_os = "freebsd", target_env = "musl")))]
210        use long_double_128::*;
211
212        pub const ffi_abi_FFI_DEFAULT_ABI: ffi_abi = ffi_abi_FFI_SYSV
213            | ffi_abi_FFI_SYSV_IBM_LONG_DOUBLE
214            | SOFT_FLOAT_FLAG
215            | STRUCT_RET_FLAG
216            | LONG_DOUBLE_128_FLAG;
217
218        pub const FFI_TRAMPOLINE_SIZE: usize = 40;
219        pub const FFI_NATIVE_RAW_API: u32 = 0;
220        pub const FFI_GO_CLOSURES: u32 = 1;
221    }
222
223    pub mod powerpc64 {
224        use crate::ffi_abi;
225
226        pub const ffi_abi_FFI_FIRST_ABI: ffi_abi = 0;
227        pub const ffi_abi_FFI_LINUX_STRUCT_ALIGN: ffi_abi = 0b000001;
228        pub const ffi_abi_FFI_LINUX_LONG_DOUBLE_128: ffi_abi = 0b000010;
229        pub const ffi_abi_FFI_LINUX_LONG_DOUBLE_IEEE128: ffi_abi = 0b000100;
230        pub const ffi_abi_FFI_LINUX: ffi_abi = 0b001000;
231
232        mod elfv1 {
233            pub const STRUCT_ALIGN_FLAG: crate::ffi_abi = 0b0;
234            pub const FFI_TRAMPOLINE_SIZE: usize = 24;
235        }
236
237        mod elfv2 {
238            pub const STRUCT_ALIGN_FLAG: crate::ffi_abi = super::ffi_abi_FFI_LINUX_STRUCT_ALIGN;
239            pub const FFI_TRAMPOLINE_SIZE: usize = 32;
240        }
241
242        // I think this should be something like `target_abi = "elf_v2"`, but that's not yet
243        // supported.
244        // Discussion: https://github.com/rust-lang/rust/issues/60617
245        // RFC: https://github.com/rust-lang/rfcs/pull/2992
246        //
247        // Instead, this is based on the current defaults at the time of this writing:
248        // https://github.com/rust-lang/rust/blob/50d2c3abd59af8cbed7e001b5b4e2f6a9a011112/src/librustc_target/abi/call/powerpc64.rs#L122
249
250        #[cfg(any(
251            // ELFv1 is the used for powerpc64 when not targeting musl
252            all(target_arch = "powerpc64", target_endian="big", not(target_env = "musl")),
253            // Use empty flags when targeting a non-PowerPC target, too, just so code compiles.
254            not(all(target_arch = "powerpc64", target_endian="little"))
255        ))]
256        mod elf {
257            pub use super::elfv1::*;
258        }
259
260        // ELFv2 is used for Little-Endian powerpc64 and with musl
261        #[cfg(any(
262            all(target_arch = "powerpc64", target_endian = "big", target_env = "musl"),
263            all(target_arch = "powerpc64", target_endian = "little")
264        ))]
265        mod elf {
266            pub use super::elfv2::*;
267        }
268
269        pub use elf::FFI_TRAMPOLINE_SIZE;
270        use elf::STRUCT_ALIGN_FLAG;
271
272        mod long_double_64 {
273            pub const LONG_DOUBLE_128_FLAG: crate::ffi_abi = 0b0;
274        }
275
276        mod long_double_128 {
277            pub const LONG_DOUBLE_128_FLAG: crate::ffi_abi =
278                super::ffi_abi_FFI_LINUX_LONG_DOUBLE_128;
279        }
280
281        // IEEE128 is not supported on BSD or when targeting musl:
282        // https://github.com/rust-lang/llvm-project/blob/cb7f903994646c5b9223e0bb6cee3792190991f7/clang/lib/Basic/Targets/PPC.h#L417
283
284        #[cfg(any(target_os = "netbsd", target_os = "freebsd", target_env = "musl"))]
285        use long_double_64::*;
286
287        #[cfg(not(any(target_os = "netbsd", target_os = "freebsd", target_env = "musl")))]
288        use long_double_128::*;
289
290        pub const ffi_abi_FFI_DEFAULT_ABI: ffi_abi =
291            ffi_abi_FFI_LINUX | STRUCT_ALIGN_FLAG | LONG_DOUBLE_128_FLAG;
292
293        pub const FFI_NATIVE_RAW_API: u32 = 0;
294        pub const FFI_GO_CLOSURES: u32 = 1;
295    }
296}
297
298#[cfg(target_arch = "powerpc")]
299pub use powerpc::powerpc::*;
300
301#[cfg(target_arch = "powerpc64")]
302pub use powerpc::powerpc64::*;
303
304/// From libffi:src/riscv/ffitarget.h
305/// See: <https://github.com/libffi/libffi/blob/4cb776bc8075332d2f3e59f51785d621fcda48f6/src/riscv/ffitarget.h>
306mod riscv {
307    use crate::ffi_abi;
308
309    pub const ffi_abi_FFI_FIRST_ABI: ffi_abi = 0;
310    pub const ffi_abi_FFI_SYSV: ffi_abi = 1;
311    pub const ffi_abi_FFI_UNUSED_1: ffi_abi = 2;
312    pub const ffi_abi_FFI_UNUSED_2: ffi_abi = 3;
313    pub const ffi_abi_FFI_UNUSED_3: ffi_abi = 4;
314    pub const ffi_abi_LAST_ABI: ffi_abi = 5;
315    pub const ffi_abi_FFI_DEFAULT_ABI: ffi_abi = ffi_abi_FFI_SYSV;
316
317    // See: <https://github.com/libffi/libffi/blob/4cb776bc8075332d2f3e59f51785d621fcda48f6/src/riscv/ffitarget.h#L63>
318    pub const FFI_GO_CLOSURES: u32 = 1;
319    pub const FFI_TRAMPOLINE_SIZE: usize = 24;
320    pub const FFI_NATIVE_RAW_API: u32 = 0;
321}
322
323#[cfg(target_arch = "riscv")]
324pub use riscv::*;
325
326#[cfg(target_arch = "riscv64")]
327pub use riscv::*;
328
329/// From libffi:src/s390/ffitarget.h
330/// See: <https://github.com/libffi/libffi/blob/c6dc125afba294b9b9613392c492ae18df3ede84/src/s390/ffitarget.h>
331mod s390x {
332    use crate::ffi_abi;
333
334    pub const ffi_abi_FFI_FIRST_ABI: ffi_abi = 0;
335    pub const ffi_abi_FFI_SYSV: ffi_abi = 1;
336    pub const ffi_abi_LAST_ABI: ffi_abi = 2;
337    pub const ffi_abi_FFI_DEFAULT_ABI: ffi_abi = ffi_abi_FFI_SYSV;
338
339    pub const FFI_GO_CLOSURES: u32 = 1;
340    pub const FFI_TRAMPOLINE_SIZE: usize = 32;
341    pub const FFI_NATIVE_RAW_API: u32 = 0;
342}
343
344#[cfg(target_arch = "s390x")]
345pub use s390x::*;
346
347/// From libffi:src/loongarch64/ffitarget.h.
348/// See: <https://github.com/libffi/libffi/blob/f24180be1367f942824365b131ae894b9c769c7d/src/loongarch64/ffitarget.h#L47>
349mod loongarch64 {
350    use crate::ffi_abi;
351
352    pub const ffi_abi_FFI_FIRST_ABI: ffi_abi = 0;
353    pub const ffi_abi_FFI_LP64S: ffi_abi = 1;
354    pub const ffi_abi_FFI_LP64F: ffi_abi = 2;
355    pub const ffi_abi_FFI_LP64D: ffi_abi = 3;
356    pub const ffi_abi_FFI_LAST_ABI: ffi_abi = 4;
357    pub const ffi_abi_FFI_DEFAULT_ABI: ffi_abi = ffi_abi_FFI_LP64D;
358
359    pub const FFI_GO_CLOSURES: u32 = 1;
360    pub const FFI_TRAMPOLINE_SIZE: usize = 24;
361    pub const FFI_NATIVE_RAW_API: u32 = 0;
362}
363
364#[cfg(target_arch = "loongarch64")]
365pub use loongarch64::*;