diff --git a/configure b/configure index 56f18dfbc2..0aafd9c8c0 100755 --- a/configure +++ b/configure @@ -17344,46 +17344,6 @@ fi fi -# In order to detect at runtime, if the ARM CRC Extension is available, -# we will do "getauxval(AT_HWCAP) & HWCAP_CRC32". Check if we have -# everything we need for that. -for ac_func in getauxval -do : - ac_fn_c_check_func "$LINENO" "getauxval" "ac_cv_func_getauxval" -if test "x$ac_cv_func_getauxval" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_GETAUXVAL 1 -_ACEOF - -fi -done - -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -#include -#include - -int -main () -{ - -#ifndef AT_HWCAP -#error AT_HWCAP not defined -#endif -#ifndef HWCAP_CRC32 -#error HWCAP_CRC32 not defined -#endif - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - HAVE_HWCAP_CRC32=1 -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - # Select CRC-32C implementation. # # If we are targeting a processor that has Intel SSE 4.2 instructions, we can @@ -17414,9 +17374,8 @@ if test x"$USE_SLICING_BY_8_CRC32C" = x"" && test x"$USE_SSE42_CRC32C" = x"" && if test x"$pgac_armv8_crc32c_intrinsics" = x"yes" && test x"$CFLAGS_ARMV8_CRC32C" = x""; then USE_ARMV8_CRC32C=1 else - # ARM CRC Extension, with runtime check? The getauxval() function and - # HWCAP_CRC32 are needed for the runtime check. - if test x"$pgac_armv8_crc32c_intrinsics" = x"yes" && test x"$ac_cv_func_getauxval" = x"yes" && test x"$HAVE_HWCAP_CRC32" = x"1"; then + # ARM CRC Extension, with runtime check? + if test x"$pgac_armv8_crc32c_intrinsics" = x"yes"; then USE_ARMV8_CRC32C_WITH_RUNTIME_CHECK=1 else # fall back to slicing-by-8 algorithm, which doesn't require any diff --git a/configure.in b/configure.in index da02a56ec6..c3841d5b07 100644 --- a/configure.in +++ b/configure.in @@ -2014,22 +2014,6 @@ if test x"$pgac_armv8_crc32c_intrinsics" != x"yes"; then fi AC_SUBST(CFLAGS_ARMV8_CRC32C) -# In order to detect at runtime, if the ARM CRC Extension is available, -# we will do "getauxval(AT_HWCAP) & HWCAP_CRC32". Check if we have -# everything we need for that. -AC_CHECK_FUNCS([getauxval]) -AC_COMPILE_IFELSE([AC_LANG_PROGRAM([ -#include -#include -], [ -#ifndef AT_HWCAP -#error AT_HWCAP not defined -#endif -#ifndef HWCAP_CRC32 -#error HWCAP_CRC32 not defined -#endif -])], [HAVE_HWCAP_CRC32=1]) - # Select CRC-32C implementation. # # If we are targeting a processor that has Intel SSE 4.2 instructions, we can @@ -2060,9 +2044,8 @@ if test x"$USE_SLICING_BY_8_CRC32C" = x"" && test x"$USE_SSE42_CRC32C" = x"" && if test x"$pgac_armv8_crc32c_intrinsics" = x"yes" && test x"$CFLAGS_ARMV8_CRC32C" = x""; then USE_ARMV8_CRC32C=1 else - # ARM CRC Extension, with runtime check? The getauxval() function and - # HWCAP_CRC32 are needed for the runtime check. - if test x"$pgac_armv8_crc32c_intrinsics" = x"yes" && test x"$ac_cv_func_getauxval" = x"yes" && test x"$HAVE_HWCAP_CRC32" = x"1"; then + # ARM CRC Extension, with runtime check? + if test x"$pgac_armv8_crc32c_intrinsics" = x"yes"; then USE_ARMV8_CRC32C_WITH_RUNTIME_CHECK=1 else # fall back to slicing-by-8 algorithm, which doesn't require any diff --git a/src/include/pg_config.h.in b/src/include/pg_config.h.in index f3620231a7..9411f48512 100644 --- a/src/include/pg_config.h.in +++ b/src/include/pg_config.h.in @@ -239,9 +239,6 @@ /* Define to 1 if you have the `getaddrinfo' function. */ #undef HAVE_GETADDRINFO -/* Define to 1 if you have the `getauxval' function. */ -#undef HAVE_GETAUXVAL - /* Define to 1 if you have the `gethostbyname_r' function. */ #undef HAVE_GETHOSTBYNAME_R diff --git a/src/port/pg_crc32c_armv8_choose.c b/src/port/pg_crc32c_armv8_choose.c index f21a8243e9..d0d3a3da78 100644 --- a/src/port/pg_crc32c_armv8_choose.c +++ b/src/port/pg_crc32c_armv8_choose.c @@ -8,10 +8,6 @@ * computation. Otherwise, fall back to the pure software implementation * (slicing-by-8). * - * XXX: The glibc-specific getauxval() function, with the HWCAP_CRC32 - * flag, is used to determine if the CRC Extension is available on the - * current platform. Is there a more portable way to determine that? - * * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * @@ -24,17 +20,38 @@ #include "c.h" -#include -#include +#include +#include "libpq/pqsignal.h" #include "port/pg_crc32c.h" + +static sigjmp_buf illegal_instruction_jump; + +/* + * Probe by trying to execute pg_comp_crc32c_armv8(). If the instruction + * isn't available, we expect to get SIGILL, which we can trap. + */ +static void +illegal_instruction_handler(int signo) +{ + siglongjmp(illegal_instruction_jump, 1); +} + static bool pg_crc32c_armv8_available(void) { - unsigned long auxv = getauxval(AT_HWCAP); + uint64 data = 42; + bool result; - return (auxv & HWCAP_CRC32) != 0; + pqsignal(SIGILL, illegal_instruction_handler); + if (sigsetjmp(illegal_instruction_jump, 1) == 0) + result = (pg_comp_crc32c_armv8(0, &data, sizeof(data)) == 0xdd439b0d); + else + result = false; + pqsignal(SIGILL, SIG_DFL); + + return result; } /*