diff --git a/.github/.cspell/project-dictionary.txt b/.github/.cspell/project-dictionary.txt index b1757cc9..dc8913bd 100644 --- a/.github/.cspell/project-dictionary.txt +++ b/.github/.cspell/project-dictionary.txt @@ -92,6 +92,7 @@ sbcs seqlock sete sifive +SIGILL SIGINT simavr skiboot diff --git a/src/imp/atomic128/aarch64.rs b/src/imp/atomic128/aarch64.rs index 9948da78..e4976a01 100644 --- a/src/imp/atomic128/aarch64.rs +++ b/src/imp/atomic128/aarch64.rs @@ -49,18 +49,22 @@ include!("macros.rs"); #[cfg(not(portable_atomic_no_outline_atomics))] #[cfg_attr( - any(all(target_os = "linux", target_env = "gnu"), target_os = "android"), + any( + all(target_os = "linux", target_env = "gnu"), + target_os = "android", + target_os = "freebsd", + ), path = "detect/aarch64_auxv.rs" )] +#[cfg_attr(target_os = "openbsd", path = "detect/aarch64_aa64reg.rs")] #[cfg_attr(target_os = "windows", path = "detect/aarch64_windows.rs")] -#[cfg_attr(any(target_os = "freebsd", target_os = "openbsd"), path = "detect/aarch64_aa64reg.rs")] #[cfg_attr( not(any( all(target_os = "linux", target_env = "gnu"), target_os = "android", - target_os = "windows", target_os = "freebsd", target_os = "openbsd", + target_os = "windows", )), path = "detect/aarch64_std.rs" )] @@ -70,7 +74,7 @@ mod detect; #[cfg(test)] #[cfg(not(qemu))] #[cfg(not(valgrind))] -#[cfg(any(target_os = "linux", target_os = "android"))] +#[cfg(any(target_os = "linux", target_os = "android", target_os = "freebsd"))] #[path = "detect/aarch64_aa64reg.rs"] mod detect_aa64reg; #[cfg(test)] @@ -306,9 +310,9 @@ unsafe fn atomic_compare_exchange( feature = "std", target_os = "linux", target_os = "android", - target_os = "windows", target_os = "freebsd", target_os = "openbsd", + target_os = "windows", ), )))] #[cfg(not(any(target_feature = "lse", portable_atomic_target_feature = "lse")))] @@ -321,9 +325,9 @@ unsafe fn atomic_compare_exchange( feature = "std", target_os = "linux", target_os = "android", - target_os = "windows", target_os = "freebsd", target_os = "openbsd", + target_os = "windows", ), ))] #[cfg(not(any(target_feature = "lse", portable_atomic_target_feature = "lse")))] diff --git a/src/imp/atomic128/detect/aarch64_aa64reg.rs b/src/imp/atomic128/detect/aarch64_aa64reg.rs index 1cd19096..ebcf316a 100644 --- a/src/imp/atomic128/detect/aarch64_aa64reg.rs +++ b/src/imp/atomic128/detect/aarch64_aa64reg.rs @@ -17,11 +17,15 @@ // - OpenBSD 7.1+ (through sysctl) // https://github.com/openbsd/src/commit/d335af936b9d7dd9cf655cae1ce19560c45de6c8 // -// For now, this module is only used on FreeBSD/OpenBSD. +// For now, this module is only used on OpenBSD. // - On Linux, this module is test-only because this approach requires a higher // kernel version than Rust supports, and also does not work with qemu-user -// (as of QEMU 7.2) and Valgrind. (Looking into HWCAP_CPUID in auxvec, it appears -// that Valgrind is setting it to false correctly, but qemu-user is setting it to true.) +// (as of QEMU 7.2) and Valgrind. (Looking into HWCAP_CPUID in auxvec, it +// appears that Valgrind is setting it to false correctly, but qemu-user is +// setting it to true.) +// - On FreeBSD, this module is test-only because this approach does not work on +// FreeBSD 12 on QEMU (confirmed on FreeBSD 12.{2,3,4}), and we got SIGILL +// (worked on FreeBSD 13 and 14). #![cfg_attr( any( diff --git a/src/imp/atomic128/detect/aarch64_auxv.rs b/src/imp/atomic128/detect/aarch64_auxv.rs index e0f8486d..842e8057 100644 --- a/src/imp/atomic128/detect/aarch64_auxv.rs +++ b/src/imp/atomic128/detect/aarch64_auxv.rs @@ -1,4 +1,6 @@ -// Run-time feature detection on aarch64 Linux/Android by parsing ELF auxiliary vectors. +// Run-time feature detection on aarch64 Linux/Android/FreeBSD by parsing ELF auxiliary vectors. +// +// # Linux/Android // // As of nightly-2023-01-23, is_aarch64_feature_detected always uses dlsym by default // on aarch64 Linux/Android, but on the following platforms, so we can safely assume @@ -24,6 +26,24 @@ // - On Picolibc, [Picolibc 1.4.6 added getauxval stub](https://github.com/picolibc/picolibc#picolibc-version-146). // // See also https://github.com/rust-lang/stdarch/pull/1375 +// +// # FreeBSD +// +// As of nightly-2023-01-23, is_aarch64_feature_detected always uses mrs on +// aarch64 FreeBSD. However, they do not work on FreeBSD 12 on QEMU (confirmed +// on FreeBSD 12.{2,3,4}), and we got SIGILL (worked on FreeBSD 13 and 14). +// +// So use elf_aux_info instead of mrs like compiler-rt does. +// https://man.freebsd.org/elf_aux_info(3) +// https://reviews.llvm.org/D109330 +// +// elf_aux_info is available on FreeBSD 12.0+ and 11.4+: +// https://github.com/freebsd/freebsd-src/commit/0b08ae2120cdd08c20a2b806e2fcef4d0a36c470 +// https://github.com/freebsd/freebsd-src/blob/release/11.4.0/sys/sys/auxv.h +// On FreeBSD, [aarch64 support is available on FreeBSD 11.0+](https://www.freebsd.org/releases/11.0R/relnotes/#hardware-arm), +// but FreeBSD 11 (11.4) was EoL on 2021-09-30, and FreeBSD 11.3 was EoL on 2020-09-30: +// https://www.freebsd.org/security/unsupported +// See also https://github.com/rust-lang/stdarch/pull/611#issuecomment-445464613 #![cfg_attr( any( @@ -142,6 +162,67 @@ mod imp { AuxVec { hwcap } } } +#[cfg(target_os = "freebsd")] +mod imp { + use super::AuxVec; + + // core::ffi::c_* (except c_void) requires Rust 1.64 + #[allow(non_camel_case_types)] + pub(super) mod ffi { + pub(crate) use core::ffi::c_void; + // c_{,u}int is {i,u}32 on non-16-bit architectures + // https://github.com/rust-lang/rust/blob/1.67.0/library/core/src/ffi/mod.rs#L159-L173 + pub(crate) type c_int = i32; + // c_{,u}long is {i,u}64 on non-windows 64-bit targets, otherwise is {i,u}32 + // https://github.com/rust-lang/rust/blob/1.67.0/library/core/src/ffi/mod.rs#L175-L190 + #[cfg(target_pointer_width = "64")] + pub(crate) type c_ulong = u64; + #[cfg(target_pointer_width = "32")] + pub(crate) type c_ulong = u32; + + // Defined in sys/elf_common.h. + // https://github.com/freebsd/freebsd-src/blob/deb63adf945d446ed91a9d84124c71f15ae571d1/sys/sys/elf_common.h + pub(crate) const AT_HWCAP: c_int = 25; + + // Defined in machine/elf.h. + // https://github.com/freebsd/freebsd-src/blob/deb63adf945d446ed91a9d84124c71f15ae571d1/sys/arm64/include/elf.h + // available on FreeBSD 13.0+ and 12.2+ + // https://github.com/freebsd/freebsd-src/blob/release/13.0.0/sys/arm64/include/elf.h + // https://github.com/freebsd/freebsd-src/blob/release/12.2.0/sys/arm64/include/elf.h + pub(crate) const HWCAP_ATOMICS: c_ulong = 0x0000_0100; + #[cfg(test)] + pub(crate) const HWCAP_USCAT: c_ulong = 0x0200_0000; + + extern "C" { + // Defined in sys/auxv.h. + // https://man.freebsd.org/elf_aux_info(3) + // https://github.com/freebsd/freebsd-src/blob/deb63adf945d446ed91a9d84124c71f15ae571d1/sys/sys/auxv.h + pub(crate) fn elf_aux_info(aux: c_int, buf: *mut c_void, buf_len: c_int) -> c_int; + } + } + + #[inline] + fn getauxval(aux: ffi::c_int) -> ffi::c_ulong { + #[allow(clippy::cast_possible_wrap, clippy::cast_possible_truncation)] + const OUT_LEN: ffi::c_int = core::mem::size_of::() as ffi::c_int; + let mut out: ffi::c_ulong = 0; + // SAFETY: + // - the pointer is valid because we got it from a reference. + // - `OUT_LEN` is the same as the size of `out`. + // - `elf_aux_info` is thread-safe. + // If elf_aux_info fails, `out` will be left at zero (which is the proper default value). + unsafe { + ffi::elf_aux_info(aux, (&mut out as *mut ffi::c_ulong).cast::(), OUT_LEN); + } + out + } + + #[inline] + pub(super) fn auxv() -> AuxVec { + let hwcap = getauxval(ffi::AT_HWCAP); + AuxVec { hwcap } + } +} #[allow( clippy::alloc_instead_of_core, @@ -222,4 +303,31 @@ mod tests { #[cfg(target_os = "android")] static_assert!(ffi::PROP_VALUE_MAX == libc::PROP_VALUE_MAX); }; + #[cfg(target_os = "freebsd")] + #[allow( + clippy::cast_possible_wrap, + clippy::cast_sign_loss, + clippy::cast_possible_truncation, + clippy::no_effect_underscore_binding + )] + const _: fn() = || { + use test_helper::{libc, sys}; + let _: ffi::c_int = 0 as libc::c_int; + let _: ffi::c_ulong = 0 as std::os::raw::c_ulong; + let _: ffi::c_ulong = 0 as libc::c_ulong; + 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; + // libc has this, but unreleased as of 0.2.139: https://github.com/rust-lang/libc/commit/a4fd9d32c854417afa1acdbc922eeafac5fcbbfd + // _elf_aux_info = libc::elf_aux_info; + _elf_aux_info = sys::elf_aux_info; + // static_assert!(ffi::AT_HWCAP == libc::AT_HWCAP); // libc doesn't have this + static_assert!(ffi::AT_HWCAP == sys::AT_HWCAP as ffi::c_int); + // static_assert!(ffi::HWCAP_ATOMICS == libc::HWCAP_ATOMICS); // libc doesn't have this + static_assert!(ffi::HWCAP_ATOMICS == sys::HWCAP_ATOMICS as ffi::c_ulong); + // static_assert!(ffi::HWCAP_USCAT == libc::HWCAP_USCAT); // libc doesn't have this + static_assert!(ffi::HWCAP_USCAT == sys::HWCAP_USCAT as ffi::c_ulong); + }; } diff --git a/src/imp/atomic128/detect/aarch64_std.rs b/src/imp/atomic128/detect/aarch64_std.rs index efe4c7a8..ebd2f8f2 100644 --- a/src/imp/atomic128/detect/aarch64_std.rs +++ b/src/imp/atomic128/detect/aarch64_std.rs @@ -5,9 +5,9 @@ feature = "std", target_os = "linux", target_os = "android", - target_os = "windows", // target_os = "freebsd", // target_os = "openbsd", + target_os = "windows", )), any(target_feature = "lse", portable_atomic_target_feature = "lse"), ), @@ -36,9 +36,9 @@ pub(crate) fn has_lse() -> bool { feature = "std", all(target_os = "linux", any(target_env = "gnu", target_env = "musl")), target_os = "android", - target_os = "windows", // target_os = "freebsd", // target_os = "openbsd", + target_os = "windows", ), ))] { diff --git a/src/imp/atomic128/detect/common.rs b/src/imp/atomic128/detect/common.rs index 4dcb994c..ac5ba5bf 100644 --- a/src/imp/atomic128/detect/common.rs +++ b/src/imp/atomic128/detect/common.rs @@ -193,6 +193,8 @@ mod tests_aarch64_common { } } else { assert!(!detect().test(CpuInfo::HAS_LSE)); + // is_aarch64_feature_detected uses mrs on FreeBSD + #[cfg(not(target_os = "freebsd"))] #[cfg(not(any( portable_atomic_no_aarch64_target_feature, portable_atomic_unstable_aarch64_target_feature, @@ -212,6 +214,8 @@ mod tests_aarch64_common { } } else { assert!(!detect().test(CpuInfo::HAS_LSE2)); + // // is_aarch64_feature_detected uses mrs on FreeBSD + // #[cfg(not(target_os = "freebsd"))] // #[cfg(not(any( // portable_atomic_no_aarch64_target_feature, // portable_atomic_unstable_aarch64_target_feature, @@ -229,6 +233,9 @@ mod tests_aarch64_common { assert!(detect().test(CpuInfo::HAS_LSE128)); } else { assert!(!detect().test(CpuInfo::HAS_LSE128)); + // is_aarch64_feature_detected doesn't support lse128 + // // is_aarch64_feature_detected uses mrs on FreeBSD + // #[cfg(not(target_os = "freebsd"))] // #[cfg(not(any( // portable_atomic_no_aarch64_target_feature, // portable_atomic_unstable_aarch64_target_feature, @@ -241,6 +248,9 @@ mod tests_aarch64_common { assert!(detect().test(CpuInfo::HAS_RCPC3)); } else { assert!(!detect().test(CpuInfo::HAS_RCPC3)); + // is_aarch64_feature_detected doesn't support rcpc3 + // // is_aarch64_feature_detected uses mrs on FreeBSD + // #[cfg(not(target_os = "freebsd"))] // #[cfg(not(any( // portable_atomic_no_aarch64_target_feature, // portable_atomic_unstable_aarch64_target_feature, diff --git a/tests/helper/src/gen/sys/aarch64_freebsd/machine_elf.rs b/tests/helper/src/gen/sys/aarch64_freebsd/machine_elf.rs new file mode 100644 index 00000000..711dcc23 --- /dev/null +++ b/tests/helper/src/gen/sys/aarch64_freebsd/machine_elf.rs @@ -0,0 +1,54 @@ +// This file is @generated by portable-atomic-internal-codegen +// (gen function at tools/codegen/src/ffi.rs). +// It is not intended for manual editing. + +pub const HWCAP_FP: u32 = 1; +pub const HWCAP_ASIMD: u32 = 2; +pub const HWCAP_EVTSTRM: u32 = 4; +pub const HWCAP_AES: u32 = 8; +pub const HWCAP_PMULL: u32 = 16; +pub const HWCAP_SHA1: u32 = 32; +pub const HWCAP_SHA2: u32 = 64; +pub const HWCAP_CRC32: u32 = 128; +pub const HWCAP_ATOMICS: u32 = 256; +pub const HWCAP_FPHP: u32 = 512; +pub const HWCAP_ASIMDHP: u32 = 1024; +pub const HWCAP_CPUID: u32 = 2048; +pub const HWCAP_ASIMDRDM: u32 = 4096; +pub const HWCAP_JSCVT: u32 = 8192; +pub const HWCAP_FCMA: u32 = 16384; +pub const HWCAP_LRCPC: u32 = 32768; +pub const HWCAP_DCPOP: u32 = 65536; +pub const HWCAP_SHA3: u32 = 131072; +pub const HWCAP_SM3: u32 = 262144; +pub const HWCAP_SM4: u32 = 524288; +pub const HWCAP_ASIMDDP: u32 = 1048576; +pub const HWCAP_SHA512: u32 = 2097152; +pub const HWCAP_SVE: u32 = 4194304; +pub const HWCAP_ASIMDFHM: u32 = 8388608; +pub const HWCAP_DIT: u32 = 16777216; +pub const HWCAP_USCAT: u32 = 33554432; +pub const HWCAP_ILRCPC: u32 = 67108864; +pub const HWCAP_FLAGM: u32 = 134217728; +pub const HWCAP_SSBS: u32 = 268435456; +pub const HWCAP_SB: u32 = 536870912; +pub const HWCAP_PACA: u32 = 1073741824; +pub const HWCAP_PACG: u32 = 2147483648; +pub const HWCAP2_DCPODP: u32 = 1; +pub const HWCAP2_SVE2: u32 = 2; +pub const HWCAP2_SVEAES: u32 = 4; +pub const HWCAP2_SVEPMULL: u32 = 8; +pub const HWCAP2_SVEBITPERM: u32 = 16; +pub const HWCAP2_SVESHA3: u32 = 32; +pub const HWCAP2_SVESM4: u32 = 64; +pub const HWCAP2_FLAGM2: u32 = 128; +pub const HWCAP2_FRINT: u32 = 256; +pub const HWCAP2_SVEI8MM: u32 = 512; +pub const HWCAP2_SVEF32MM: u32 = 1024; +pub const HWCAP2_SVEF64MM: u32 = 2048; +pub const HWCAP2_SVEBF16: u32 = 4096; +pub const HWCAP2_I8MM: u32 = 8192; +pub const HWCAP2_BF16: u32 = 16384; +pub const HWCAP2_DGH: u32 = 32768; +pub const HWCAP2_RNG: u32 = 65536; +pub const HWCAP2_BTI: u32 = 131072; diff --git a/tests/helper/src/gen/sys/aarch64_freebsd/mod.rs b/tests/helper/src/gen/sys/aarch64_freebsd/mod.rs new file mode 100644 index 00000000..f7bcec0b --- /dev/null +++ b/tests/helper/src/gen/sys/aarch64_freebsd/mod.rs @@ -0,0 +1,21 @@ +// This file is @generated by portable-atomic-internal-codegen +// (gen function at tools/codegen/src/ffi.rs). +// It is not intended for manual editing. + +#![cfg_attr(rustfmt, rustfmt::skip)] +mod sys_auxv; +pub use sys_auxv::elf_aux_info; +mod sys_elf_common; +pub use sys_elf_common::{AT_HWCAP, AT_HWCAP2}; +mod machine_elf; +pub use machine_elf::{ + HWCAP2_BF16, HWCAP2_BTI, HWCAP2_DCPODP, HWCAP2_DGH, HWCAP2_FLAGM2, HWCAP2_FRINT, + HWCAP2_I8MM, HWCAP2_RNG, HWCAP2_SVE2, HWCAP2_SVEAES, HWCAP2_SVEBF16, + HWCAP2_SVEBITPERM, HWCAP2_SVEF32MM, HWCAP2_SVEF64MM, HWCAP2_SVEI8MM, HWCAP2_SVEPMULL, + HWCAP2_SVESHA3, HWCAP2_SVESM4, HWCAP_AES, HWCAP_ASIMD, HWCAP_ASIMDDP, HWCAP_ASIMDFHM, + HWCAP_ASIMDHP, HWCAP_ASIMDRDM, HWCAP_ATOMICS, HWCAP_CPUID, HWCAP_CRC32, HWCAP_DCPOP, + HWCAP_DIT, HWCAP_EVTSTRM, HWCAP_FCMA, HWCAP_FLAGM, HWCAP_FP, HWCAP_FPHP, + HWCAP_ILRCPC, HWCAP_JSCVT, HWCAP_LRCPC, HWCAP_PACA, HWCAP_PACG, HWCAP_PMULL, + HWCAP_SB, HWCAP_SHA1, HWCAP_SHA2, HWCAP_SHA3, HWCAP_SHA512, HWCAP_SM3, HWCAP_SM4, + HWCAP_SSBS, HWCAP_SVE, HWCAP_USCAT, +}; diff --git a/tests/helper/src/gen/sys/aarch64_freebsd/sys_auxv.rs b/tests/helper/src/gen/sys/aarch64_freebsd/sys_auxv.rs new file mode 100644 index 00000000..a2c93c10 --- /dev/null +++ b/tests/helper/src/gen/sys/aarch64_freebsd/sys_auxv.rs @@ -0,0 +1,11 @@ +// This file is @generated by portable-atomic-internal-codegen +// (gen function at tools/codegen/src/ffi.rs). +// It is not intended for manual editing. + +extern "C" { + pub fn elf_aux_info( + aux: ::std::os::raw::c_int, + buf: *mut ::core::ffi::c_void, + buflen: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} diff --git a/tests/helper/src/gen/sys/aarch64_freebsd/sys_elf_common.rs b/tests/helper/src/gen/sys/aarch64_freebsd/sys_elf_common.rs new file mode 100644 index 00000000..1d678681 --- /dev/null +++ b/tests/helper/src/gen/sys/aarch64_freebsd/sys_elf_common.rs @@ -0,0 +1,6 @@ +// This file is @generated by portable-atomic-internal-codegen +// (gen function at tools/codegen/src/ffi.rs). +// It is not intended for manual editing. + +pub const AT_HWCAP: u32 = 25; +pub const AT_HWCAP2: u32 = 26; diff --git a/tests/helper/src/gen/sys/mod.rs b/tests/helper/src/gen/sys/mod.rs index ce6c114a..49799954 100644 --- a/tests/helper/src/gen/sys/mod.rs +++ b/tests/helper/src/gen/sys/mod.rs @@ -54,6 +54,10 @@ pub use aarch64_linux_android::*; mod aarch64_apple_darwin; #[cfg(all(target_arch = "aarch64", target_os = "macos"))] pub use aarch64_apple_darwin::*; +#[cfg(all(target_arch = "aarch64", target_os = "freebsd"))] +mod aarch64_freebsd; +#[cfg(all(target_arch = "aarch64", target_os = "freebsd"))] +pub use aarch64_freebsd::*; #[cfg(all(target_arch = "aarch64", target_os = "openbsd"))] mod aarch64_openbsd; #[cfg(all(target_arch = "aarch64", target_os = "openbsd"))] diff --git a/tools/codegen/patches/freebsd.diff b/tools/codegen/patches/freebsd.diff new file mode 100644 index 00000000..3b21f7b9 --- /dev/null +++ b/tools/codegen/patches/freebsd.diff @@ -0,0 +1,12 @@ +diff --git a/sys/sys/elf_common.h b/sys/sys/elf_common.h +--- a/sys/sys/elf_common.h ++++ b/sys/sys/elf_common.h +@@ -33,6 +33,8 @@ + #ifndef _SYS_ELF_COMMON_H_ + #define _SYS_ELF_COMMON_H_ 1 + ++#include ++ + /* + * ELF definitions that are independent of architecture or word size. + */ diff --git a/tools/codegen/src/ffi.rs b/tools/codegen/src/ffi.rs index 9b02bcaf..a4a67c05 100644 --- a/tools/codegen/src/ffi.rs +++ b/tools/codegen/src/ffi.rs @@ -67,6 +67,32 @@ static TARGETS: &[Target] = &[ }, ], }, + Target { + triples: &["aarch64-unknown-freebsd"], + headers: &[ + Header { + // https://github.com/freebsd/freebsd-src/blob/HEAD/sys/sys/auxv.h + path: "sys/auxv.h", + types: &[], + vars: &[], + functions: &["elf_aux_info"], + }, + Header { + // https://github.com/freebsd/freebsd-src/blob/HEAD/sys/sys/elf_common.h + path: "sys/elf_common.h", + types: &[], + vars: &["AT_HWCAP.*"], + functions: &[], + }, + Header { + // https://github.com/freebsd/freebsd-src/blob/HEAD/sys/arm64/include/elf.h + path: "machine/elf.h", + types: &[], + vars: &["HWCAP.*"], + functions: &[], + }, + ], + }, Target { triples: &["aarch64-unknown-openbsd"], headers: &[ @@ -165,7 +191,7 @@ pub(crate) fn gen() -> Result<()> { src_dir.parent().unwrap().join("Libc/include"), src_dir.parent().unwrap().join("libpthread/include"), ], - openbsd => vec![src_dir.join("sys")], + freebsd | openbsd => vec![src_dir.join("sys")], _ => todo!("{target:?}"), }; for include in &include { @@ -188,7 +214,7 @@ pub(crate) fn gen() -> Result<()> { let header_path = match target.os { linux | android => src_dir.join(header.path), macos => src_dir.join(format!("bsd/{}", header.path)), - openbsd => src_dir.join(format!("sys/{}", header.path)), + freebsd | openbsd => src_dir.join(format!("sys/{}", header.path)), _ => todo!("{target:?}"), }; @@ -297,6 +323,7 @@ fn git_clone(target: &TargetSpec, download_cache_dir: &Utf8Path) -> Result clone(download_cache_dir, "https://github.com/freebsd/freebsd-src.git")?, openbsd => clone(download_cache_dir, "https://github.com/openbsd/src.git")?, _ => todo!("{target:?}"), }; @@ -323,6 +350,14 @@ fn arch_symlink(target: &TargetSpec, src_dir: &Utf8Path) -> Result<()> { fs::write(src_dir.join("bsd/sys/_symbol_aliasing.h"), "")?; fs::write(src_dir.join("bsd/sys/_posix_availability.h"), "")?; } + freebsd => { + let arch = match target.arch { + aarch64 => "arm64", + _ => todo!("{target:?}"), + }; + let link = &src_dir.join("sys/machine"); + fs::os::unix::fs::symlink(src_dir.join("sys").join(arch).join("include"), link)?; + } openbsd => { let arch = match target.arch { aarch64 => "arm64",