Skip to content

Commit

Permalink
detect: Auto-generate static assertions for functions
Browse files Browse the repository at this point in the history
  • Loading branch information
taiki-e committed Oct 19, 2024
1 parent 667ecb1 commit f647cca
Show file tree
Hide file tree
Showing 8 changed files with 132 additions and 204 deletions.
81 changes: 30 additions & 51 deletions src/imp/detect/aarch64_aa64reg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -153,18 +153,20 @@ mod imp {
pub(crate) ctr: u64,
}

extern "C" {
// Defined in sys/sysctl.h.
// https://man.netbsd.org/sysctl.3
// https://github.com/NetBSD/src/blob/432a1357026b10c184d8a0ddb683008a23cc7cd9/sys/sys/sysctl.h
pub(crate) fn sysctlbyname(
name: *const c_char,
old_p: *mut c_void,
old_len_p: *mut c_size_t,
new_p: *const c_void,
new_len: c_size_t,
) -> c_int;
}
sys_fn!({
extern "C" {
// Defined in sys/sysctl.h.
// https://man.netbsd.org/sysctl.3
// https://github.com/NetBSD/src/blob/432a1357026b10c184d8a0ddb683008a23cc7cd9/sys/sys/sysctl.h
pub(crate) fn sysctlbyname(
name: *const c_char,
old_p: *mut c_void,
old_len_p: *mut c_size_t,
new_p: *const c_void,
new_len: c_size_t,
) -> c_int;
}
});
}

pub(super) unsafe fn sysctl_cpu_id(name: &[u8]) -> Option<AA64Reg> {
Expand Down Expand Up @@ -248,19 +250,21 @@ mod imp {
pub(crate) const CPU_ID_AA64MMFR2: c_int = 7;
});

extern "C" {
// Defined in sys/sysctl.h.
// https://man.openbsd.org/sysctl.2
// https://github.com/openbsd/src/blob/ed8f5e8d82ace15e4cefca2c82941b15cb1a7830/sys/sys/sysctl.h
pub(crate) fn sysctl(
name: *const c_int,
name_len: c_uint,
old_p: *mut c_void,
old_len_p: *mut c_size_t,
new_p: *mut c_void,
new_len: c_size_t,
) -> c_int;
}
sys_fn!({
extern "C" {
// Defined in sys/sysctl.h.
// https://man.openbsd.org/sysctl.2
// https://github.com/openbsd/src/blob/ed8f5e8d82ace15e4cefca2c82941b15cb1a7830/sys/sys/sysctl.h
pub(crate) fn sysctl(
name: *const c_int,
name_len: c_uint,
old_p: *mut c_void,
old_len_p: *mut c_size_t,
new_p: *mut c_void,
new_len: c_size_t,
) -> c_int;
}
});
}

// sysctl returns an unsupported error if operation is not supported,
Expand Down Expand Up @@ -512,10 +516,10 @@ mod tests {
// `cargo check --tests --target <target>` run in CI (via TESTS=1 build.sh)
// without actually running tests on these platforms.
// As for constants, they are checked by static assertions generated by sys_const!.
// As for functions, they are checked by static assertions generated by sys_fn!.
// See also https://github.com/taiki-e/test-helper/blob/HEAD/tools/codegen/src/ffi.rs.
// TODO(codegen): auto-generate this test
#[cfg(target_os = "netbsd")]
#[allow(clippy::no_effect_underscore_binding, clippy::used_underscore_binding)]
const _: fn() = || {
use imp::ffi;
use std::mem;
Expand Down Expand Up @@ -551,30 +555,5 @@ mod tests {
ac_clidr: ffi.clidr,
ac_ctr: ffi.ctr,
};
let mut _sysctlbyname: unsafe extern "C" fn(
*const ffi::c_char,
*mut ffi::c_void,
*mut ffi::c_size_t,
*const ffi::c_void,
ffi::c_size_t,
) -> ffi::c_int = ffi::sysctlbyname;
_sysctlbyname = libc::sysctlbyname;
_sysctlbyname = sys::sysctlbyname;
};
#[cfg(target_os = "openbsd")]
#[allow(clippy::no_effect_underscore_binding)]
const _: fn() = || {
use imp::ffi;
use test_helper::sys;
let mut _sysctl: unsafe extern "C" fn(
*const ffi::c_int,
ffi::c_uint,
*mut ffi::c_void,
*mut ffi::c_size_t,
*mut ffi::c_void,
ffi::c_size_t,
) -> ffi::c_int = ffi::sysctl;
_sysctl = libc::sysctl;
_sysctl = sys::sysctl;
};
}
48 changes: 13 additions & 35 deletions src/imp/detect/aarch64_apple.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,17 +27,19 @@ use core::{mem, ptr};
mod ffi {
pub(crate) use super::c_types::{c_char, c_int, c_size_t, c_void};

extern "C" {
// https://developer.apple.com/documentation/kernel/1387446-sysctlbyname
// https://github.com/apple-oss-distributions/xnu/blob/8d741a5de7ff4191bf97d57b9f54c2f6d4a15585/bsd/sys/sysctl.h
pub(crate) fn sysctlbyname(
name: *const c_char,
old_p: *mut c_void,
old_len_p: *mut c_size_t,
new_p: *mut c_void,
new_len: c_size_t,
) -> c_int;
}
sys_fn!({
extern "C" {
// https://developer.apple.com/documentation/kernel/1387446-sysctlbyname
// https://github.com/apple-oss-distributions/xnu/blob/8d741a5de7ff4191bf97d57b9f54c2f6d4a15585/bsd/sys/sysctl.h
pub(crate) fn sysctlbyname(
name: *const c_char,
old_p: *mut c_void,
old_len_p: *mut c_size_t,
new_p: *mut c_void,
new_len: c_size_t,
) -> c_int;
}
});
}

unsafe fn sysctlbyname32(name: &[u8]) -> Option<u32> {
Expand Down Expand Up @@ -258,28 +260,4 @@ mod tests {
}
}
}

// Static assertions for FFI bindings.
// This checks that FFI bindings defined in this crate, FFI bindings defined
// in libc, and FFI bindings generated for the platform's latest header file
// using bindgen have compatible signatures.
// Since this is static assertion, we can detect problems with
// `cargo check --tests --target <target>` run in CI (via TESTS=1 build.sh)
// without actually running tests on these platforms.
// As for constants, they are checked by static assertions generated by sys_const!.
// See also https://github.com/taiki-e/test-helper/blob/HEAD/tools/codegen/src/ffi.rs.
// TODO(codegen): auto-generate this test
#[allow(clippy::no_effect_underscore_binding)]
const _: fn() = || {
use test_helper::sys;
let mut _sysctlbyname: unsafe extern "C" fn(
*const ffi::c_char,
*mut ffi::c_void,
*mut ffi::c_size_t,
*mut ffi::c_void,
ffi::c_size_t,
) -> ffi::c_int = ffi::sysctlbyname;
_sysctlbyname = libc::sysctlbyname;
_sysctlbyname = sys::sysctlbyname;
};
}
8 changes: 2 additions & 6 deletions src/imp/detect/aarch64_fuchsia.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ mod ffi {
pub(crate) const ZX_ARM64_FEATURE_ISA_ATOMICS: u32 = 1 << 8;
});

// TODO: use sys_fn!
#[link(name = "zircon")]
extern "C" {
// https://fuchsia.dev/reference/syscalls/system_get_features
Expand Down Expand Up @@ -80,12 +81,7 @@ mod tests {
// As for constants, they are checked by static assertions generated by sys_const!.
// See also https://github.com/taiki-e/test-helper/blob/HEAD/tools/codegen/src/ffi.rs.
// TODO(codegen): auto-generate this test
#[allow(
clippy::cast_possible_wrap,
clippy::cast_sign_loss,
clippy::cast_possible_truncation,
clippy::no_effect_underscore_binding
)]
#[allow(clippy::cast_possible_wrap, clippy::cast_sign_loss, clippy::cast_possible_truncation)]
const _: fn() = || {
use test_helper::sys;
// TODO(codegen): zx_system_get_features
Expand Down
44 changes: 8 additions & 36 deletions src/imp/detect/aarch64_illumos.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,14 @@ mod ffi {
pub(crate) const AV_AARCH64_2_LSE2: u32 = 1 << 2;
});

extern "C" {
// Defined in sys/auxv.h.
// https://illumos.org/man/2/getisax
// https://github.com/richlowe/illumos-gate/blob/arm64-gate/usr/src/uts/common/sys/auxv.h
pub(crate) fn getisax(array: *mut u32, n: c_uint) -> c_uint;
}
sys_fn!({
extern "C" {
// Defined in sys/auxv.h.
// https://illumos.org/man/2/getisax
// https://github.com/richlowe/illumos-gate/blob/arm64-gate/usr/src/uts/common/sys/auxv.h
pub(crate) fn getisax(array: *mut u32, n: c_uint) -> c_uint;
}
});
}

#[cold]
Expand All @@ -46,33 +48,3 @@ fn _detect(info: &mut CpuInfo) {
info.set(CpuInfo::HAS_LSE2);
}
}

#[allow(
clippy::alloc_instead_of_core,
clippy::std_instead_of_alloc,
clippy::std_instead_of_core,
clippy::undocumented_unsafe_blocks,
clippy::wildcard_imports
)]
#[cfg(test)]
mod tests {
use super::*;

// Static assertions for FFI bindings.
// This checks that FFI bindings defined in this crate, FFI bindings defined
// in libc, and FFI bindings generated for the platform's latest header file
// using bindgen have compatible signatures.
// Since this is static assertion, we can detect problems with
// `cargo check --tests --target <target>` run in CI (via TESTS=1 build.sh)
// without actually running tests on these platforms.
// As for constants, they are checked by static assertions generated by sys_const!.
// See also https://github.com/taiki-e/test-helper/blob/HEAD/tools/codegen/src/ffi.rs.
// TODO(codegen): auto-generate this test
#[allow(clippy::no_effect_underscore_binding)]
const _: fn() = || {
use test_helper::sys;
let mut _getisax: unsafe extern "C" fn(*mut u32, ffi::c_uint) -> ffi::c_uint = ffi::getisax;
_getisax = libc::getisax;
_getisax = sys::getisax;
};
}
7 changes: 1 addition & 6 deletions src/imp/detect/aarch64_windows.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,12 +61,7 @@ mod tests {
// windows-sys' signatures/values.)
// See also https://github.com/taiki-e/test-helper/blob/HEAD/tools/codegen/src/ffi.rs.
// TODO(codegen): auto-generate this test
#[allow(
clippy::cast_possible_wrap,
clippy::cast_sign_loss,
clippy::cast_possible_truncation,
clippy::no_effect_underscore_binding
)]
#[allow(clippy::cast_possible_wrap, clippy::cast_sign_loss, clippy::cast_possible_truncation)]
const _: fn() = || {
let _: ffi::DWORD = 0 as windows_sys::Win32::System::Threading::PROCESSOR_FEATURE_ID;
let _: ffi::BOOL = 0 as windows_sys::Win32::Foundation::BOOL;
Expand Down
108 changes: 39 additions & 69 deletions src/imp/detect/auxv.rs
Original file line number Diff line number Diff line change
Expand Up @@ -137,21 +137,26 @@ mod os {
pub(crate) const PROP_VALUE_MAX: c_int = 92;
});

extern "C" {
// Defined in sys/auxv.h.
// https://man7.org/linux/man-pages/man3/getauxval.3.html
// https://github.com/bminor/glibc/blob/glibc-2.40/misc/sys/auxv.h
// https://github.com/bminor/musl/blob/v1.2.5/include/sys/auxv.h
// https://github.com/wbx-github/uclibc-ng/blob/v1.0.47/include/sys/auxv.h
// https://github.com/aosp-mirror/platform_bionic/blob/d3ebc2f7c49a9893b114124d4a6b315f3a328764/libc/include/sys/auxv.h
// https://github.com/picolibc/picolibc/blob/1.8.6/newlib/libc/include/sys/auxv.h
pub(crate) fn getauxval(type_: c_ulong) -> c_ulong;

// Defined in sys/system_properties.h.
// https://github.com/aosp-mirror/platform_bionic/blob/d3ebc2f7c49a9893b114124d4a6b315f3a328764/libc/include/sys/system_properties.h
#[cfg(all(target_arch = "aarch64", target_os = "android"))]
pub(crate) fn __system_property_get(name: *const c_char, value: *mut c_char) -> c_int;
}
sys_fn!({
extern "C" {
// Defined in sys/auxv.h.
// https://man7.org/linux/man-pages/man3/getauxval.3.html
// https://github.com/bminor/glibc/blob/glibc-2.40/misc/sys/auxv.h
// https://github.com/bminor/musl/blob/v1.2.5/include/sys/auxv.h
// https://github.com/wbx-github/uclibc-ng/blob/v1.0.47/include/sys/auxv.h
// https://github.com/aosp-mirror/platform_bionic/blob/d3ebc2f7c49a9893b114124d4a6b315f3a328764/libc/include/sys/auxv.h
// https://github.com/picolibc/picolibc/blob/1.8.6/newlib/libc/include/sys/auxv.h
pub(crate) fn getauxval(type_: c_ulong) -> c_ulong;

// Defined in sys/system_properties.h.
// https://github.com/aosp-mirror/platform_bionic/blob/d3ebc2f7c49a9893b114124d4a6b315f3a328764/libc/include/sys/system_properties.h
#[cfg(all(target_arch = "aarch64", target_os = "android"))]
pub(crate) fn __system_property_get(
name: *const c_char,
value: *mut c_char,
) -> c_int;
}
});
}

pub(super) fn getauxval(type_: ffi::c_ulong) -> ffi::c_ulong {
Expand Down Expand Up @@ -202,17 +207,19 @@ mod os {
pub(crate) const AT_HWCAP2: c_int = 26;
});

extern "C" {
// FreeBSD
// Defined in sys/auxv.h.
// https://man.freebsd.org/elf_aux_info(3)
// https://github.com/freebsd/freebsd-src/blob/release/14.1.0/sys/sys/auxv.h
// OpenBSD
// Defined in sys/auxv.h.
// https://man.openbsd.org/elf_aux_info.3
// https://github.com/openbsd/src/blob/ed8f5e8d82ace15e4cefca2c82941b15cb1a7830/sys/sys/auxv.h
pub(crate) fn elf_aux_info(aux: c_int, buf: *mut c_void, buf_len: c_int) -> c_int;
}
sys_fn!({
extern "C" {
// FreeBSD
// Defined in sys/auxv.h.
// https://man.freebsd.org/elf_aux_info(3)
// https://github.com/freebsd/freebsd-src/blob/release/14.1.0/sys/sys/auxv.h
// OpenBSD
// Defined in sys/auxv.h.
// https://man.openbsd.org/elf_aux_info.3
// https://github.com/openbsd/src/blob/ed8f5e8d82ace15e4cefca2c82941b15cb1a7830/sys/sys/auxv.h
pub(crate) fn elf_aux_info(aux: c_int, buf: *mut c_void, buf_len: c_int) -> c_int;
}
});
}

pub(super) fn getauxval(aux: ffi::c_int) -> ffi::c_ulong {
Expand Down Expand Up @@ -370,6 +377,12 @@ mod arch {
)]
#[cfg(test)]
mod tests {
#[cfg(not(target_os = "openbsd"))]
#[cfg(not(all(
target_os = "linux",
target_arch = "aarch64",
target_pointer_width = "32",
)))]
use super::*;

#[allow(clippy::cast_sign_loss)]
Expand Down Expand Up @@ -817,47 +830,4 @@ mod tests {
getauxval_sysctl_no_libc(ffi::AT_HWCAP2).unwrap_or_else(hwcap2_else)
);
}

// Static assertions for FFI bindings.
// This checks that FFI bindings defined in this crate, FFI bindings defined
// in libc, and FFI bindings generated for the platform's latest header file
// using bindgen have compatible signatures.
// Since this is static assertion, we can detect problems with
// `cargo check --tests --target <target>` run in CI (via TESTS=1 build.sh)
// without actually running tests on these platforms.
// As for constants, they are checked by static assertions generated by sys_const!.
// See also https://github.com/taiki-e/test-helper/blob/HEAD/tools/codegen/src/ffi.rs.
// TODO(codegen): auto-generate this test
#[allow(clippy::no_effect_underscore_binding)]
const _: fn() = || {
use test_helper::sys;
#[cfg(any(target_os = "linux", target_os = "android"))]
{
let mut _getauxval: unsafe extern "C" fn(ffi::c_ulong) -> ffi::c_ulong = ffi::getauxval;
_getauxval = libc::getauxval;
_getauxval = sys::getauxval;
}
#[cfg(all(target_arch = "aarch64", target_os = "android"))]
{
let mut ___system_property_get: unsafe extern "C" fn(
*const ffi::c_char,
*mut ffi::c_char,
) -> ffi::c_int = ffi::__system_property_get;
___system_property_get = libc::__system_property_get;
___system_property_get = sys::__system_property_get;
}
#[cfg(any(target_os = "freebsd", target_os = "openbsd"))]
{
let mut _elf_aux_info: unsafe extern "C" fn(
ffi::c_int,
*mut ffi::c_void,
ffi::c_int,
) -> ffi::c_int = ffi::elf_aux_info;
#[cfg(not(target_os = "openbsd"))] // libc doesn't have this on OpenBSD
{
_elf_aux_info = libc::elf_aux_info;
}
_elf_aux_info = sys::elf_aux_info;
}
};
}
Loading

0 comments on commit f647cca

Please sign in to comment.