From: Brad Smith Date: Fri, 14 Nov 2025 11:45:41 +0000 (-0500) Subject: Use elf_aux_info() on FreeBSD and OpenBSD ARM / AArch64 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=368a926fdb0fee977719ff927178b8eff0de4a62;p=thirdparty%2Fzlib-ng.git Use elf_aux_info() on FreeBSD and OpenBSD ARM / AArch64 Use elf_aux_info() as the prefered API for modern FreeBSD and OpenBSD ARM and AArch64. This adds 32-bit ARM support. --- diff --git a/CMakeLists.txt b/CMakeLists.txt index d2ef3c9fa..f4d184bb5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -802,6 +802,54 @@ if(WITH_OPTIM) endif() endif() endif() + if(${CMAKE_SYSTEM_NAME} STREQUAL "FreeBSD" OR + ${CMAKE_SYSTEM_NAME} STREQUAL "OpenBSD") + if("${ARCH}" MATCHES "aarch64") + check_c_source_compiles( + "#include + int main() { + unsigned long hwcap; + elf_aux_info(AT_HWCAP, &hwcap, sizeof(hwcap)); + return (hwcap & HWCAP_CRC32); + }" + ARM_AUXV_HAS_CRC32 + ) + if(ARM_AUXV_HAS_CRC32) + add_definitions(-DARM_AUXV_HAS_CRC32) + else() + message(STATUS "HWCAP_CRC32 not present in sys/auxv.h; cannot detect support at runtime.") + endif() + else() + check_c_source_compiles( + "#include + int main() { + unsigned long hwcap2; + elf_aux_info(AT_HWCAP2, &hwcap2, sizeof(hwcap2)); + return (hwcap2 & HWCAP2_CRC32); + }" + ARM_AUXV_HAS_CRC32 + ) + if(ARM_AUXV_HAS_CRC32) + add_definitions(-DARM_AUXV_HAS_CRC32) + else() + message(STATUS "HWCAP2_CRC32 not present in sys/auxv.h; cannot detect support at runtime.") + endif() + check_c_source_compiles( + "#include + int main() { + unsigned long hwcap; + elf_aux_info(AT_HWCAP, &hwcap, sizeof(hwcap)); + return (hwcap & HWCAP_NEON); + }" + ARM_AUXV_HAS_NEON + ) + if(ARM_AUXV_HAS_NEON) + add_definitions(-DARM_AUXV_HAS_NEON) + else() + message(STATUS "HWCAP_NEON not present in sys/auxv.h; cannot detect support at runtime.") + endif() + endif() + endif() list(APPEND ZLIB_ARCH_HDRS ${ARCHDIR}/arm_functions.h) if(WITH_RUNTIME_CPU_DETECTION) list(APPEND ZLIB_ARCH_HDRS ${ARCHDIR}/arm_features.h) diff --git a/arch/arm/arm_features.c b/arch/arm/arm_features.c index fa48c4aaf..b7849284f 100644 --- a/arch/arm/arm_features.c +++ b/arch/arm/arm_features.c @@ -1,7 +1,7 @@ #include "zbuild.h" #include "arm_features.h" -#if defined(__linux__) && defined(HAVE_SYS_AUXV_H) +#if defined(HAVE_SYS_AUXV_H) # include # ifdef ARM_ASM_HWCAP # include @@ -26,11 +26,23 @@ #endif static int arm_has_crc32(void) { -#if defined(__linux__) && defined(ARM_AUXV_HAS_CRC32) -# ifdef HWCAP_CRC32 - return (getauxval(AT_HWCAP) & HWCAP_CRC32) != 0 ? 1 : 0; +#if defined(ARM_AUXV_HAS_CRC32) +# if defined(__FreeBSD__) || defined(__OpenBSD__) +# ifdef HWCAP_CRC32 + unsigned long hwcap = 0; + elf_aux_info(AT_HWCAP, &hwcap, sizeof(hwcap)); + return (hwcap & HWCAP_CRC32) != 0 ? 1 : 0; +# else + unsigned long hwcap2 = 0; + elf_aux_info(AT_HWCAP2, &hwcap2, sizeof(hwcap2)); + return (hwcap2 & HWCAP2_CRC32) != 0 ? 1 : 0; +# endif # else - return (getauxval(AT_HWCAP2) & HWCAP2_CRC32) != 0 ? 1 : 0; +# ifdef HWCAP_CRC32 + return (getauxval(AT_HWCAP) & HWCAP_CRC32) != 0 ? 1 : 0; +# else + return (getauxval(AT_HWCAP2) & HWCAP2_CRC32) != 0 ? 1 : 0; +# endif # endif #elif defined(__FreeBSD__) && defined(__aarch64__) return getenv("QEMU_EMULATING") == NULL @@ -62,11 +74,17 @@ static int arm_has_crc32(void) { /* AArch64 has neon. */ #if !defined(__aarch64__) && !defined(_M_ARM64) && !defined(_M_ARM64EC) static inline int arm_has_neon(void) { -#if defined(__linux__) && defined(ARM_AUXV_HAS_NEON) -# ifdef HWCAP_ARM_NEON - return (getauxval(AT_HWCAP) & HWCAP_ARM_NEON) != 0 ? 1 : 0; +#if defined(ARM_AUXV_HAS_NEON) +# if defined(__FreeBSD__) || defined(__OpenBSD__) + unsigned long hwcap = 0; + elf_aux_info(AT_HWCAP, &hwcap, sizeof(hwcap)); + return (hwcap & HWCAP_NEON) != 0 ? 1 : 0; # else - return (getauxval(AT_HWCAP) & HWCAP_NEON) != 0 ? 1 : 0; +# ifdef HWCAP_ARM_NEON + return (getauxval(AT_HWCAP) & HWCAP_ARM_NEON) != 0 ? 1 : 0; +# else + return (getauxval(AT_HWCAP) & HWCAP_NEON) != 0 ? 1 : 0; +# endif # endif #elif defined(__APPLE__) int hasneon; diff --git a/configure b/configure index c9b12561e..e7092c8ed 100755 --- a/configure +++ b/configure @@ -569,11 +569,17 @@ case "$uname" in esac # Simplify some later conditionals +LINUX=0 +FREEBSD=0 +OPENBSD=0 + case "$uname" in Linux* | linux*) LINUX=1 ;; -*) - LINUX=0 ;; +FreeBSD*) + FREEBSD=1 ;; +OpenBSD*) + OPENBSD=1 ;; esac # destination names for shared library if not defined above @@ -2037,6 +2043,55 @@ EOF fi fi + if test $FREEBSD -eq 1 -o $OPENBSD -eq 1; then + if test "$ARCH" = "aarch64"; then + cat > $test.c < +int main() { + unsigned long hwcap; + elf_aux_info(AT_HWCAP, &hwcap, sizeof(hwcap)); + return (hwcap & HWCAP_CRC32); +} +EOF + if try $CC -c $CFLAGS $test.c; then + CFLAGS="${CFLAGS} -DARM_AUXV_HAS_CRC32" + SFLAGS="${SFLAGS} -DARM_AUXV_HAS_CRC32" + else + echo "HWCAP_CRC32 not present in sys/auxv.h; cannot detect support at runtime." | tee -a configure.log + fi + else + cat > $test.c < +int main() { + unsigned long hwcap2; + elf_aux_info(AT_HWCAP2, &hwcap2, sizeof(hwcap2)); + return (hwcap2 & HWCAP2_CRC32); +} +EOF + if try $CC -c $CFLAGS $test.c; then + CFLAGS="${CFLAGS} -DARM_AUXV_HAS_CRC32" + SFLAGS="${SFLAGS} -DARM_AUXV_HAS_CRC32" + else + echo "HWCAP2_CRC32 not present in sys/auxv.h; cannot detect support at runtime." | tee -a configure.log + fi + + cat > $test.c < +int main() { + unsigned long hwcap; + elf_aux_info(AT_HWCAP, &hwcap, sizeof(hwcap)); + return (hwcap & HWCAP_NEON); +} +EOF + if try $CC -c $CFLAGS $test.c; then + CFLAGS="${CFLAGS} -DARM_AUXV_HAS_NEON" + SFLAGS="${SFLAGS} -DARM_AUXV_HAS_NEON" + else + echo "HWCAP_NEON not present in sys/auxv.h; cannot detect support at runtime." | tee -a configure.log + fi + fi + fi + if test $buildarmv8 -eq 1; then check_armv8_intrinsics