@@ -30,12 +30,11 @@ target_feature="v8.7a"
3030target_feature="wfxt"
3131```
3232
33- Refs: https://developer.apple.com/documentation/kernel/1387446-sysctlbyname/determining_instruction_set_characteristics
33+ Non-macOS targets doesn't always supports FEAT_LSE2, so we use this module on them.
34+ As used in the example in https://developer.apple.com/documentation/xcode/writing-arm64-code-for-apple-platforms#Enable-DIT-for-constant-time-cryptographic-operations,
35+ sysctlbyname is supported on all Apple platforms.
3436
35- TODO: non-macOS targets doesn't always supports FEAT_LSE2, but sysctl on them on the App Store is...?
36- - https://developer.apple.com/forums/thread/9440
37- - https://nabla-c0d3.github.io/blog/2015/06/16/ios9-security-privacy
38- - https://github.com/rust-lang/stdarch/pull/1636
37+ Refs: https://developer.apple.com/documentation/kernel/1387446-sysctlbyname/determining_instruction_set_characteristics
3938*/
4039
4140include ! ( "common.rs" ) ;
@@ -102,16 +101,15 @@ fn _detect(info: &mut CpuInfo) {
102101 // Query both names in case future versions of macOS remove the old name.
103102 // https://github.com/golang/go/commit/c15593197453b8bf90fc3a9080ba2afeaf7934ea
104103 // https://github.com/google/boringssl/commit/91e0b11eba517d83b910b20fe3740eeb39ecb37e
104+ // TODO: use hw.optional.arm.caps on macOS 15+.
105+ // - https://github.com/apple-oss-distributions/xnu/blob/f6217f891ac0bb64f3d375211650a4c1ff8ca1ea/osfmk/arm/cpu_capabilities_public.h
106+ // - https://github.com/llvm/llvm-project/blob/llvmorg-22.1.0/compiler-rt/lib/builtins/cpu_model/aarch64/fmv/apple.inc#L56
105107 check ! ( lse, "hw.optional.arm.FEAT_LSE" || "hw.optional.armv8_1_atomics" ) ;
106108 check ! ( lse2, "hw.optional.arm.FEAT_LSE2" ) ;
107- check ! ( lse128, "hw.optional.arm.FEAT_LSE128" ) ;
108- #[ cfg( test) ]
109- check ! ( lsfe, "hw.optional.arm.FEAT_LSFE" ) ;
110109 #[ cfg( test) ]
111110 check ! ( rcpc, "hw.optional.arm.FEAT_LRCPC" ) ;
112111 #[ cfg( test) ]
113112 check ! ( rcpc2, "hw.optional.arm.FEAT_LRCPC2" ) ;
114- check ! ( rcpc3, "hw.optional.arm.FEAT_LRCPC3" ) ;
115113}
116114
117115#[ allow(
@@ -131,123 +129,6 @@ mod tests {
131129 fn test_alternative ( ) {
132130 use crate :: utils:: ffi:: * ;
133131
134- // Call syscall using asm instead of libc.
135- // Note that macOS does not guarantee the stability of raw syscall.
136- // (And they actually changed it: https://go-review.googlesource.com/c/go/+/25495)
137- //
138- // This is currently used only for testing.
139- fn sysctlbyname32_no_libc ( name : & CStr ) -> Result < u32 , c_int > {
140- #[ cfg( not( portable_atomic_no_asm) ) ]
141- use std:: arch:: asm;
142- use std:: mem;
143-
144- use test_helper:: sys;
145-
146- use crate :: utils:: { RegISize , RegSize } ;
147-
148- // Refs: https://github.com/apple-oss-distributions/xnu/blob/f6217f891ac0bb64f3d375211650a4c1ff8ca1ea/libsyscall/custom/SYS.h#L427
149- #[ inline]
150- unsafe fn sysctl (
151- name : * const c_int ,
152- name_len : c_uint ,
153- old_p : * mut c_void ,
154- old_len_p : * mut c_size_t ,
155- new_p : * const c_void ,
156- new_len : c_size_t ,
157- ) -> Result < c_int , c_int > {
158- // https://github.com/apple-oss-distributions/xnu/blob/8d741a5de7ff4191bf97d57b9f54c2f6d4a15585/osfmk/mach/i386/syscall_sw.h#L158
159- #[ inline]
160- const fn syscall_construct_unix ( n : u64 ) -> u64 {
161- const SYSCALL_CLASS_UNIX : u64 = 2 ;
162- const SYSCALL_CLASS_SHIFT : u64 = 24 ;
163- const SYSCALL_CLASS_MASK : u64 = 0xFF << SYSCALL_CLASS_SHIFT ;
164- const SYSCALL_NUMBER_MASK : u64 = !SYSCALL_CLASS_MASK ;
165- ( SYSCALL_CLASS_UNIX << SYSCALL_CLASS_SHIFT ) | ( SYSCALL_NUMBER_MASK & n)
166- }
167- // https://github.com/apple-oss-distributions/xnu/blob/8d741a5de7ff4191bf97d57b9f54c2f6d4a15585/bsd/kern/syscalls.master#L298
168- let mut n = syscall_construct_unix ( 202 ) ;
169- let arg1 = ptr_reg ! ( name) ;
170- let arg2 = name_len as RegSize ;
171- let arg3 = ptr_reg ! ( old_p) ;
172- let arg4 = ptr_reg ! ( old_len_p) ;
173- let arg5 = ptr_reg ! ( new_p) ;
174- let arg6 = new_len as RegSize ;
175- let r: RegISize ;
176- // SAFETY: the caller must uphold the safety contract.
177- unsafe {
178- asm ! (
179- "svc 0x80" , // #SWI_SYSCALL https://github.com/apple-oss-distributions/xnu/blob/f6217f891ac0bb64f3d375211650a4c1ff8ca1ea/osfmk/mach/arm/vm_param.h#L417
180- "b.cc 2f" ,
181- "mov x16, x0" ,
182- "mov x0, #-1" ,
183- "2:" ,
184- inout( "x16" ) n,
185- inout( "x0" ) arg1 => r,
186- inout( "x1" ) arg2 => _,
187- in( "x2" ) arg3,
188- in( "x3" ) arg4,
189- in( "x4" ) arg5,
190- in( "x5" ) arg6,
191- // Do not use `preserves_flags` because AArch64 Darwin syscalls modify the condition flags.
192- options( nostack) ,
193- ) ;
194- }
195- #[ allow( clippy:: cast_possible_truncation) ]
196- if r as c_int == -1 { Err ( n as c_int ) } else { Ok ( r as c_int ) }
197- }
198- // https://github.com/apple-oss-distributions/Libc/blob/af11da5ca9d527ea2f48bb7efbd0f0f2a4ea4812/gen/FreeBSD/sysctlbyname.c
199- unsafe fn sysctlbyname (
200- name : & CStr ,
201- old_p : * mut c_void ,
202- old_len_p : * mut c_size_t ,
203- new_p : * mut c_void ,
204- new_len : c_size_t ,
205- ) -> Result < c_int , c_int > {
206- let mut real_oid: [ c_int ; sys:: CTL_MAXNAME as usize + 2 ] = unsafe { mem:: zeroed ( ) } ;
207-
208- // Note that this is undocumented API.
209- // Although FreeBSD defined it in sys/sysctl.h since https://github.com/freebsd/freebsd-src/commit/382e01c8dc7f328f46c61c82a29222f432f510f7
210- let mut name2oid_oid: [ c_int ; 2 ] = [ 0 , 3 ] ;
211-
212- let mut oid_len = mem:: size_of_val ( & real_oid) ;
213- unsafe {
214- sysctl (
215- name2oid_oid. as_mut_ptr ( ) ,
216- 2 ,
217- real_oid. as_mut_ptr ( ) . cast :: < c_void > ( ) ,
218- & mut oid_len,
219- name. as_ptr ( ) . cast :: < c_void > ( ) as * mut c_void ,
220- name. to_bytes_with_nul ( ) . len ( ) - 1 ,
221- ) ?;
222- }
223- oid_len /= mem:: size_of :: < c_int > ( ) ;
224- #[ allow( clippy:: cast_possible_truncation) ]
225- unsafe {
226- sysctl ( real_oid. as_mut_ptr ( ) , oid_len as u32 , old_p, old_len_p, new_p, new_len)
227- }
228- }
229-
230- const OUT_LEN : ffi:: c_size_t = mem:: size_of :: < u32 > ( ) as ffi:: c_size_t ;
231-
232- let mut out = 0_u32 ;
233- let mut out_len = OUT_LEN ;
234- // SAFETY:
235- // - `out_len` does not exceed the size of `out`.
236- // - `sysctlbyname` is thread-safe.
237- let res = unsafe {
238- sysctlbyname (
239- name,
240- ( & mut out as * mut u32 ) . cast :: < ffi:: c_void > ( ) ,
241- & mut out_len,
242- ptr:: null_mut ( ) ,
243- 0 ,
244- ) ?
245- } ;
246- debug_assert_eq ! ( res, 0 ) ;
247- debug_assert_eq ! ( out_len, OUT_LEN ) ;
248- Ok ( out)
249- }
250-
251132 // Call sysctl command instead of libc API.
252133 //
253134 // This is used only for testing.
@@ -292,10 +173,8 @@ mod tests {
292173 ) ;
293174 }
294175 if let Some ( res) = res {
295- assert_eq ! ( res, sysctlbyname32_no_libc( name) . unwrap( ) ) ;
296176 assert_eq ! ( res, sysctl_output. field( name) . unwrap( ) ) ;
297177 } else {
298- assert_eq ! ( sysctlbyname32_no_libc( name) . unwrap_err( ) , libc:: ENOENT ) ;
299178 assert ! ( sysctl_output. field( name) . is_none( ) ) ;
300179 }
301180 }
0 commit comments