]> git.ipfire.org Git - thirdparty/zlib-ng.git/commitdiff
Use elf_aux_info() on FreeBSD and OpenBSD ARM / AArch64
authorBrad Smith <brad@comstyle.com>
Fri, 14 Nov 2025 11:45:41 +0000 (06:45 -0500)
committerHans Kristian Rosbach <hk-github@circlestorm.org>
Tue, 2 Dec 2025 23:21:37 +0000 (00:21 +0100)
Use elf_aux_info() as the prefered API for modern FreeBSD and OpenBSD
ARM and AArch64. This adds 32-bit ARM support.

CMakeLists.txt
arch/arm/arm_features.c
configure

index d2ef3c9faf435f97d444bb80110eeb3d4ba78c9a..f4d184bb5dbdbd101a2d00274437c8f7f78ab3bd 100644 (file)
@@ -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 <sys/auxv.h>
+                    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 <sys/auxv.h>
+                    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 <sys/auxv.h>
+                    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)
index fa48c4aaf1ba9639d3a8f04eedca18e72dc9410b..b7849284f87759bfca170213a55c4c58fa839951 100644 (file)
@@ -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 <sys/auxv.h>
 #  ifdef ARM_ASM_HWCAP
 #    include <asm/hwcap.h>
 #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;
index c9b12561eec96841d8741336f2b31963da98020a..e7092c8ed53f359956a207116904a33caeb1d26f 100755 (executable)
--- 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 <<EOF
+#include <sys/auxv.h>
+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 <<EOF
+#include <sys/auxv.h>
+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 <<EOF
+#include <sys/auxv.h>
+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