Skip to content

Commit caeed33

Browse files
committed
aarch64-apple: Clarify feature detection.
Use the `libc` crate so we don't have to maintain the binding for `sysctlbyname`, and so `libc` will take care of the linking to libc as needed.. Wrap `sysctlbyname` in a safe wrapper. Separate the branches for the `sysctlbyname` results so we can see them individually in code coverage.
1 parent ba0ab25 commit caeed33

File tree

4 files changed

+57
-23
lines changed

4 files changed

+57
-23
lines changed

Cargo.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,7 @@ untrusted = { version = "0.9" }
162162
[target.'cfg(any(target_arch = "aarch64", target_arch = "arm", target_arch = "x86",target_arch = "x86_64"))'.dependencies]
163163
spin = { version = "0.9.8", default-features = false, features = ["once"] }
164164

165-
[target.'cfg(all(any(target_os = "android", target_os = "linux"), any(target_arch = "aarch64", target_arch = "arm")))'.dependencies]
165+
[target.'cfg(all(any(target_os = "android", target_os = "linux", any(target_os = "ios", target_os = "macos", target_os = "tvos")), any(target_arch = "aarch64", target_arch = "arm")))'.dependencies]
166166
libc = { version = "0.2.148", default-features = false }
167167

168168
[target.'cfg(all(target_arch = "aarch64", target_os = "windows"))'.dependencies]

src/cpu/arm.rs

+34-22
Original file line numberDiff line numberDiff line change
@@ -185,30 +185,42 @@ fn detect_features() -> u32 {
185185
any(target_os = "ios", target_os = "macos", target_os = "tvos")
186186
))]
187187
fn detect_features() -> u32 {
188-
let mut features = ARMCAP_STATIC;
189-
190-
extern "C" {
191-
fn sysctlbyname(
192-
name: *const u8,
193-
oldp: *mut core::ffi::c_void,
194-
oldlenp: *mut crate::c::size_t,
195-
newp: *mut core::ffi::c_void,
196-
newlen: crate::c::size_t,
197-
) -> core::ffi::c_int;
188+
use core::ffi::CStr;
189+
190+
fn detect_feature(name: &CStr) -> bool {
191+
use core::mem;
192+
193+
let mut value: libc::c_int = 0;
194+
let mut len = mem::size_of_val(&value);
195+
let value_ptr = polyfill::ptr::from_mut::from_mut(&mut value).cast::<c_void>();
196+
let rc = unsafe {
197+
libc::sysctlbyname(
198+
FEATURE_NAME.as_ptr(),
199+
value_ptr,
200+
&mut len,
201+
core::ptr::null_mut(),
202+
0,
203+
)
204+
};
205+
// All the conditions are separated so we can observe them in code coverage.
206+
if rc == 0 {
207+
return false;
208+
}
209+
debug_assert_eq!(len, mem::size_of_val(&value));
210+
if len != mem::size_of_val(&value) {
211+
return false;
212+
}
213+
if value == 0 {
214+
return false;
215+
}
216+
true
198217
}
199218

200-
let mut value: core::ffi::c_int = 0;
201-
let mut len = core::mem::size_of_val(&value);
202-
let rc = unsafe {
203-
sysctlbyname(
204-
"hw.optional.armv8_2_sha512\0".as_ptr(),
205-
&mut value as *mut _ as _,
206-
&mut len,
207-
core::ptr::null_mut(),
208-
0,
209-
)
210-
};
211-
if rc == 0 && len == core::mem::size_of_val(&value) && value != 0 {
219+
let mut features = ARMCAP_STATIC;
220+
221+
const SHA512_NAME: CStr =
222+
polyfill::unwrap_const(CStr::from_bytes_until_nul("hw.optional.armv8_2_sha512\0"));
223+
if detect_feature(SHA512_NAME) {
212224
features |= SHA512.mask;
213225
}
214226

src/polyfill.rs

+2
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,8 @@ mod array_split_map;
5151
#[cfg(feature = "alloc")]
5252
mod leading_zeros_skipped;
5353

54+
pub mod ptr;
55+
5456
#[cfg(test)]
5557
mod test;
5658

src/polyfill/ptr.rs

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
// Copyright 2024 Brian Smith.
2+
//
3+
// Permission to use, copy, modify, and/or distribute this software for any
4+
// purpose with or without fee is hereby granted, provided that the above
5+
// copyright notice and this permission notice appear in all copies.
6+
//
7+
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL WARRANTIES
8+
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
9+
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
10+
// SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
11+
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
12+
// OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
13+
// CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
14+
15+
// TODO(MSRV 1.76): Replace with `core::ptr::from_mut`.
16+
#[allow(dead_code)]
17+
#[inline(always)]
18+
pub fn from_mut<T: ?Sized>(r: &mut T) -> *mut T {
19+
<*mut T>::from(r)
20+
}

0 commit comments

Comments
 (0)