From de79154a58dac7d81f3ba75c50ec25ad00557af7 Mon Sep 17 00:00:00 2001 From: Brad Smith Date: Sat, 12 Sep 2026 19:33:46 -0400 Subject: [PATCH] Add CPU detection for FreeBSD / OpenBSD AArch64 --- absl/base/config.h | 9 +++++++++ absl/base/internal/cpu_detect.cc | 24 ++++++++++++++++++++---- 2 files changed, 29 insertions(+), 4 deletions(-) diff --git a/absl/base/config.h b/absl/base/config.h index e3e2c96a39c..f4926e59e9f 100644 --- a/absl/base/config.h +++ b/absl/base/config.h @@ -381,6 +381,15 @@ static_assert(ABSL_INTERNAL_INLINE_NAMESPACE_STR[0] != 'h' || #define ABSL_HAVE_SCHED_YIELD 1 #endif +// ABSL_HAVE_ELF_AUX_INFO +// +// Checks whether the platform implements elf_aux_info(3). +#ifdef ABSL_HAVE_ELF_AUX_INFO +#error ABSL_HAVE_ELF_AUX_INFO cannot be directly set +#elif (defined(__FreeBSD__) || defined(__OpenBSD__)) && __has_include() +#define ABSL_HAVE_ELF_AUX_INFO 1 +#endif + // ABSL_HAVE_SEMAPHORE_H // // Checks whether the platform supports the header and sem_init(3) diff --git a/absl/base/internal/cpu_detect.cc b/absl/base/internal/cpu_detect.cc index 4ceed84a0c7..1fbedfabaff 100644 --- a/absl/base/internal/cpu_detect.cc +++ b/absl/base/internal/cpu_detect.cc @@ -20,8 +20,11 @@ #include "absl/base/config.h" -#if defined(__aarch64__) && defined(__linux__) +#if defined(__aarch64__) && \ + (defined(__linux__) || defined(ABSL_HAVE_ELF_AUX_INFO)) +#if defined(__linux__) #include +#endif #include #endif @@ -265,7 +268,8 @@ bool SupportsBmi2() { return (cpu_info[1] & (1 << 8)) != 0; } -#elif defined(__aarch64__) && defined(__linux__) +#elif defined(__aarch64__) && \ + (defined(__linux__) || defined(ABSL_HAVE_ELF_AUX_INFO)) #ifndef HWCAP_CPUID #define HWCAP_CPUID (1 << 11) @@ -276,12 +280,18 @@ bool SupportsBmi2() { CpuType GetCpuType() { // MIDR_EL1 is not visible to EL0, however the access will be emulated by - // linux if AT_HWCAP has HWCAP_CPUID set. + // Linux, FreeBSD and OpenBSD if AT_HWCAP has HWCAP_CPUID set. // // This method will be unreliable on heterogeneous computing systems (ex: // big.LITTLE) since the value of MIDR_EL1 will change based on the calling // thread. +#if defined(ABSL_HAVE_ELF_AUX_INFO) + uint64_t hwcaps; + if (elf_aux_info(AT_HWCAP, &hwcaps, sizeof(hwcaps)) != 0) + return CpuType::kUnknown; +#else uint64_t hwcaps = getauxval(AT_HWCAP); +#endif if (hwcaps & HWCAP_CPUID) { uint64_t midr = 0; ABSL_INTERNAL_AARCH64_ID_REG_READ(MIDR_EL1, midr); @@ -328,7 +338,13 @@ CpuType GetCpuType() { } bool SupportsArmCRC32PMULL() { -#if defined(HWCAP_CRC32) && defined(HWCAP_PMULL) +#if defined(ABSL_HAVE_ELF_AUX_INFO) + uint64_t hwcaps; + bool ret = false; + if (elf_aux_info(AT_HWCAP, &hwcaps, sizeof(hwcaps)) == 0) + ret = (hwcaps & HWCAP_CRC32) && (hwcaps & HWCAP_PMULL); + return ret; +#elif defined(HWCAP_CRC32) && defined(HWCAP_PMULL) uint64_t hwcaps = getauxval(AT_HWCAP); return (hwcaps & HWCAP_CRC32) && (hwcaps & HWCAP_PMULL); #else