Skip to content

Commit 935acb8

Browse files
committed
Re-enable runtime feature detection on non-x86 platforms
1 parent 4abdad0 commit 935acb8

File tree

7 files changed

+89
-48
lines changed

7 files changed

+89
-48
lines changed

crates/std_detect/src/detect/mod.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -98,10 +98,10 @@ cfg_if! {
9898
// On x86/x86_64 no OS specific functionality is required.
9999
#[path = "os/x86.rs"]
100100
mod os;
101-
} else if #[cfg(all(target_os = "linux", feature = "use_std"))] {
101+
} else if #[cfg(all(target_os = "linux", feature = "libc"))] {
102102
#[path = "os/linux/mod.rs"]
103103
mod os;
104-
} else if #[cfg(all(target_os = "freebsd", feature = "use_std"))] {
104+
} else if #[cfg(all(target_os = "freebsd", feature = "libc"))] {
105105
#[cfg(target_arch = "aarch64")]
106106
#[path = "os/aarch64.rs"]
107107
mod aarch64;

crates/std_detect/src/detect/os/freebsd/mod.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,18 +5,18 @@ mod auxvec;
55
cfg_if::cfg_if! {
66
if #[cfg(target_arch = "aarch64")] {
77
mod aarch64;
8-
pub use self::aarch64::check_for;
8+
pub(crate) use self::aarch64::detect_features;
99
} else if #[cfg(target_arch = "arm")] {
1010
mod arm;
11-
pub use self::arm::check_for;
11+
pub(crate) use self::arm::detect_features;
1212
} else if #[cfg(target_arch = "powerpc64")] {
1313
mod powerpc;
14-
pub use self::powerpc::check_for;
14+
pub(crate) use self::powerpc::detect_features;
1515
} else {
16-
use crate::arch::detect::Feature;
16+
use crate::detect::cache;
1717
/// Performs run-time feature detection.
18-
pub fn check_for(_x: Feature) -> bool {
19-
false
18+
pub(crate) fn detect_features() -> cache::Initializer {
19+
cache::Initializer::default()
2020
}
2121
}
2222
}

crates/std_detect/src/detect/os/linux/aarch64.rs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
//! Run-time feature detection for Aarch64 on Linux.
22
3-
use super::{auxvec, cpuinfo};
3+
use super::auxvec;
44
use crate::detect::{bit, cache, Feature};
55

66
/// Try to read the features from the auxiliary vector, and if that fails, try
@@ -10,7 +10,8 @@ pub(crate) fn detect_features() -> cache::Initializer {
1010
let hwcap: AtHwcap = auxv.into();
1111
return hwcap.cache();
1212
}
13-
if let Ok(c) = cpuinfo::CpuInfo::new() {
13+
#[cfg(feature = "std_detect_file_io")]
14+
if let Ok(c) = super::cpuinfo::CpuInfo::new() {
1415
let hwcap: AtHwcap = c.into();
1516
return hwcap.cache();
1617
}
@@ -77,9 +78,10 @@ impl From<auxvec::AuxVec> for AtHwcap {
7778
}
7879
}
7980

80-
impl From<cpuinfo::CpuInfo> for AtHwcap {
81+
#[cfg(feature = "std_detect_file_io")]
82+
impl From<super::cpuinfo::CpuInfo> for AtHwcap {
8183
/// Reads AtHwcap from /proc/cpuinfo .
82-
fn from(c: cpuinfo::CpuInfo) -> Self {
84+
fn from(c: super::cpuinfo::CpuInfo) -> Self {
8385
let f = &c.field("Features");
8486
AtHwcap {
8587
// 64-bit names. FIXME: In 32-bit compatibility mode /proc/cpuinfo will

crates/std_detect/src/detect/os/linux/arm.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
//! Run-time feature detection for ARM on Linux.
22
3-
use super::{auxvec, cpuinfo};
3+
use super::auxvec;
44
use crate::detect::{bit, cache, Feature};
55

66
/// Try to read the features from the auxiliary vector, and if that fails, try
@@ -31,7 +31,8 @@ pub(crate) fn detect_features() -> cache::Initializer {
3131
return value;
3232
}
3333

34-
if let Ok(c) = cpuinfo::CpuInfo::new() {
34+
#[cfg(feature = "std_detect_file_io")]
35+
if let Ok(c) = super::cpuinfo::CpuInfo::new() {
3536
enable_feature(
3637
&mut value,
3738
Feature::neon,
@@ -55,7 +56,8 @@ pub(crate) fn detect_features() -> cache::Initializer {
5556
/// Is the CPU known to have a broken NEON unit?
5657
///
5758
/// See https://crbug.com/341598.
58-
fn has_broken_neon(cpuinfo: &cpuinfo::CpuInfo) -> bool {
59+
#[cfg(feature = "std_detect_file_io")]
60+
fn has_broken_neon(cpuinfo: &super::cpuinfo::CpuInfo) -> bool {
5961
cpuinfo.field("CPU implementer") == "0x51"
6062
&& cpuinfo.field("CPU architecture") == "7"
6163
&& cpuinfo.field("CPU variant") == "0x1"

crates/std_detect/src/detect/os/linux/auxvec.rs

Lines changed: 59 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,11 @@ use crate::{fs::File, io::Read};
77
/// Key to access the CPU Hardware capabilities bitfield.
88
pub(crate) const AT_HWCAP: usize = 16;
99
/// Key to access the CPU Hardware capabilities 2 bitfield.
10-
#[cfg(any(target_arch = "arm", target_arch = "powerpc64"))]
10+
#[cfg(any(
11+
target_arch = "arm",
12+
target_arch = "powerpc",
13+
target_arch = "powerpc64"
14+
))]
1115
pub(crate) const AT_HWCAP2: usize = 26;
1216

1317
/// Cache HWCAP bitfields of the ELF Auxiliary Vector.
@@ -17,7 +21,11 @@ pub(crate) const AT_HWCAP2: usize = 26;
1721
#[derive(Debug, Copy, Clone)]
1822
pub(crate) struct AuxVec {
1923
pub hwcap: usize,
20-
#[cfg(any(target_arch = "arm", target_arch = "powerpc64"))]
24+
#[cfg(any(
25+
target_arch = "arm",
26+
target_arch = "powerpc",
27+
target_arch = "powerpc64"
28+
))]
2129
pub hwcap2: usize,
2230
}
2331

@@ -64,7 +72,11 @@ pub(crate) fn auxv() -> Result<AuxVec, ()> {
6472
}
6573

6674
// Targets with AT_HWCAP and AT_HWCAP2:
67-
#[cfg(any(target_arch = "arm", target_arch = "powerpc64"))]
75+
#[cfg(any(
76+
target_arch = "arm",
77+
target_arch = "powerpc",
78+
target_arch = "powerpc64"
79+
))]
6880
{
6981
if let Ok(hwcap2) = getauxval(AT_HWCAP2) {
7082
if hwcap != 0 && hwcap2 != 0 {
@@ -74,21 +86,11 @@ pub(crate) fn auxv() -> Result<AuxVec, ()> {
7486
}
7587
drop(hwcap);
7688
}
77-
#[cfg(feature = "std_detect_file_io")]
78-
{
79-
// If calling getauxval fails, try to read the auxiliary vector from
80-
// its file:
81-
auxv_from_file("/proc/self/auxv")
82-
}
83-
#[cfg(not(feature = "std_detect_file_io"))]
84-
{
85-
Err(())
86-
}
8789
}
8890

8991
#[cfg(not(feature = "std_detect_dlsym_getauxval"))]
9092
{
91-
let hwcap = unsafe { ffi_getauxval(AT_HWCAP) };
93+
let hwcap = unsafe { libc::getauxval(AT_HWCAP) };
9294

9395
// Targets with only AT_HWCAP:
9496
#[cfg(any(target_arch = "aarch64", target_arch = "mips", target_arch = "mips64"))]
@@ -99,14 +101,29 @@ pub(crate) fn auxv() -> Result<AuxVec, ()> {
99101
}
100102

101103
// Targets with AT_HWCAP and AT_HWCAP2:
102-
#[cfg(any(target_arch = "arm", target_arch = "powerpc64"))]
104+
#[cfg(any(
105+
target_arch = "arm",
106+
target_arch = "powerpc",
107+
target_arch = "powerpc64"
108+
))]
103109
{
104-
let hwcap2 = unsafe { ffi_getauxval(AT_HWCAP2) };
110+
let hwcap2 = unsafe { libc::getauxval(AT_HWCAP2) };
105111
if hwcap != 0 && hwcap2 != 0 {
106112
return Ok(AuxVec { hwcap, hwcap2 });
107113
}
108114
}
109115
}
116+
117+
#[cfg(feature = "std_detect_file_io")]
118+
{
119+
// If calling getauxval fails, try to read the auxiliary vector from
120+
// its file:
121+
auxv_from_file("/proc/self/auxv")
122+
}
123+
#[cfg(not(feature = "std_detect_file_io"))]
124+
{
125+
Err(())
126+
}
110127
}
111128

112129
/// Tries to read the `key` from the auxiliary vector by calling the
@@ -122,7 +139,7 @@ fn getauxval(key: usize) -> Result<usize, ()> {
122139
return Err(());
123140
}
124141

125-
let ffi_getauxval: F = mem::transmute(ptr);
142+
let ffi_getauxval: F = crate::mem::transmute(ptr);
126143
Ok(ffi_getauxval(key))
127144
}
128145
}
@@ -140,7 +157,8 @@ fn auxv_from_file(file: &str) -> Result<AuxVec, ()> {
140157
// 2*32 `usize` elements is enough to read the whole vector.
141158
let mut buf = [0_usize; 64];
142159
{
143-
let raw: &mut [u8; 64 * mem::size_of::<usize>()] = unsafe { mem::transmute(&mut buf) };
160+
let raw: &mut [u8; 64 * crate::mem::size_of::<usize>()] =
161+
unsafe { crate::mem::transmute(&mut buf) };
144162
file.read(raw).map_err(|_| ())?;
145163
}
146164
auxv_from_buf(&buf)
@@ -161,7 +179,11 @@ fn auxv_from_buf(buf: &[usize; 64]) -> Result<AuxVec, ()> {
161179
}
162180
}
163181
// Targets with AT_HWCAP and AT_HWCAP2:
164-
#[cfg(any(target_arch = "arm", target_arch = "powerpc64"))]
182+
#[cfg(any(
183+
target_arch = "arm",
184+
target_arch = "powerpc",
185+
target_arch = "powerpc64"
186+
))]
165187
{
166188
let mut hwcap = None;
167189
let mut hwcap2 = None;
@@ -214,7 +236,12 @@ mod tests {
214236

215237
// FIXME: on mips/mips64 getauxval returns 0, and /proc/self/auxv
216238
// does not always contain the AT_HWCAP key under qemu.
217-
#[cfg(not(any(target_arch = "mips", target_arch = "mips64", target_arch = "powerpc")))]
239+
#[cfg(any(
240+
target_arch = "aarch64",
241+
target_arch = "arm",
242+
target_arch = "powerpc",
243+
target_arch = "powerpc64"
244+
))]
218245
#[test]
219246
fn auxv_crate() {
220247
let v = auxv();
@@ -224,7 +251,11 @@ mod tests {
224251
}
225252

226253
// Targets with AT_HWCAP and AT_HWCAP2:
227-
#[cfg(any(target_arch = "arm", target_arch = "powerpc64"))]
254+
#[cfg(any(
255+
target_arch = "arm",
256+
target_arch = "powerpc",
257+
target_arch = "powerpc64"
258+
))]
228259
{
229260
if let Some(hwcap2) = auxv_crate_getauxval(AT_HWCAP2) {
230261
let rt_hwcap2 = v.expect("failed to find hwcap2 key").hwcap2;
@@ -243,7 +274,7 @@ mod tests {
243274
}
244275

245276
#[cfg(feature = "std_detect_file_io")]
246-
cfg_if! {
277+
cfg_if::cfg_if! {
247278
if #[cfg(target_arch = "arm")] {
248279
#[test]
249280
fn linux_rpi3() {
@@ -287,14 +318,19 @@ mod tests {
287318
}
288319

289320
#[test]
321+
#[cfg(feature = "std_detect_file_io")]
290322
fn auxv_crate_procfs() {
291323
let v = auxv();
292324
if let Some(hwcap) = auxv_crate_getprocfs(AT_HWCAP) {
293325
assert_eq!(v.unwrap().hwcap, hwcap);
294326
}
295327

296328
// Targets with AT_HWCAP and AT_HWCAP2:
297-
#[cfg(any(target_arch = "arm", target_arch = "powerpc64"))]
329+
#[cfg(any(
330+
target_arch = "arm",
331+
target_arch = "powerpc",
332+
target_arch = "powerpc64"
333+
))]
298334
{
299335
if let Some(hwcap2) = auxv_crate_getprocfs(AT_HWCAP2) {
300336
assert_eq!(v.unwrap().hwcap2, hwcap2);

crates/std_detect/src/detect/os/linux/mod.rs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,24 +5,24 @@ mod auxvec;
55
#[cfg(feature = "std_detect_file_io")]
66
mod cpuinfo;
77

8-
cfg_if! {
8+
cfg_if::cfg_if! {
99
if #[cfg(target_arch = "aarch64")] {
1010
mod aarch64;
11-
pub use self::aarch64::check_for;
11+
pub(crate) use self::aarch64::detect_features;
1212
} else if #[cfg(target_arch = "arm")] {
1313
mod arm;
14-
pub use self::arm::check_for;
14+
pub(crate) use self::arm::detect_features;
1515
} else if #[cfg(any(target_arch = "mips", target_arch = "mips64"))] {
1616
mod mips;
17-
pub use self::mips::check_for;
17+
pub(crate) use self::mips::detect_features;
1818
} else if #[cfg(any(target_arch = "powerpc", target_arch = "powerpc64"))] {
1919
mod powerpc;
20-
pub use self::powerpc::check_for;
20+
pub(crate) use self::powerpc::detect_features;
2121
} else {
22-
use crate::detect::Feature;
22+
use crate::detect::cache;
2323
/// Performs run-time feature detection.
24-
pub fn check_for(_x: Feature) -> bool {
25-
false
24+
pub(crate) fn detect_features() -> cache::Initializer {
25+
cache::Initializer::default()
2626
}
2727
}
2828
}

crates/std_detect/src/detect/os/linux/powerpc.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
//! Run-time feature detection for PowerPC on Linux.
22
3-
use super::{auxvec, cpuinfo};
3+
use super::auxvec;
44
use crate::detect::{cache, Feature};
55

66
/// Try to read the features from the auxiliary vector, and if that fails, try
@@ -27,7 +27,8 @@ pub(crate) fn detect_features() -> cache::Initializer {
2727

2828
// PowerPC's /proc/cpuinfo lacks a proper Feature field,
2929
// but `altivec` support is indicated in the `cpu` field.
30-
if let Ok(c) = cpuinfo::CpuInfo::new() {
30+
#[cfg(feature = "std_detect_file_io")]
31+
if let Ok(c) = super::cpuinfo::CpuInfo::new() {
3132
enable_feature(&mut value, Feature::altivec, c.field("cpu").has("altivec"));
3233
return value;
3334
}

0 commit comments

Comments
 (0)