summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xconfigure2
-rw-r--r--configure.ac2
-rw-r--r--meson.build2
-rw-r--r--src/include/pg_config.h.in6
-rw-r--r--src/port/pg_crc32c_armv8_choose.c66
5 files changed, 34 insertions, 44 deletions
diff --git a/configure b/configure
index bb67e5fcda4..28719ed30c6 100755
--- a/configure
+++ b/configure
@@ -15144,7 +15144,7 @@ fi
LIBS_including_readline="$LIBS"
LIBS=`echo "$LIBS" | sed -e 's/-ledit//g' -e 's/-lreadline//g'`
-for ac_func in backtrace_symbols copyfile copy_file_range getifaddrs getpeerucred inet_pton kqueue mbstowcs_l memset_s posix_fallocate ppoll pthread_is_threaded_np setproctitle setproctitle_fast strchrnul strsignal syncfs sync_file_range uselocale wcstombs_l
+for ac_func in backtrace_symbols copyfile copy_file_range elf_aux_info getauxval getifaddrs getpeerucred inet_pton kqueue mbstowcs_l memset_s posix_fallocate ppoll pthread_is_threaded_np setproctitle setproctitle_fast strchrnul strsignal syncfs sync_file_range uselocale wcstombs_l
do :
as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
diff --git a/configure.ac b/configure.ac
index 12136261347..533f4ab78a5 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1723,6 +1723,8 @@ AC_CHECK_FUNCS(m4_normalize([
backtrace_symbols
copyfile
copy_file_range
+ elf_aux_info
+ getauxval
getifaddrs
getpeerucred
inet_pton
diff --git a/meson.build b/meson.build
index 5b0510cef78..b64d253fe41 100644
--- a/meson.build
+++ b/meson.build
@@ -2623,7 +2623,9 @@ func_checks = [
# when enabling asan the dlopen check doesn't notice that -ldl is actually
# required. Just checking for dlsym() ought to suffice.
['dlsym', {'dependencies': [dl_dep], 'define': false}],
+ ['elf_aux_info'],
['explicit_bzero'],
+ ['getauxval'],
['getifaddrs'],
['getopt', {'dependencies': [getopt_dep, gnugetopt_dep], 'skip': always_replace_getopt}],
['getopt_long', {'dependencies': [getopt_dep, gnugetopt_dep], 'skip': always_replace_getopt_long}],
diff --git a/src/include/pg_config.h.in b/src/include/pg_config.h.in
index cdd9a6e9355..a903c60a3a0 100644
--- a/src/include/pg_config.h.in
+++ b/src/include/pg_config.h.in
@@ -125,6 +125,9 @@
/* Define to 1 if you have the <editline/readline.h> header file. */
#undef HAVE_EDITLINE_READLINE_H
+/* Define to 1 if you have the `elf_aux_info' function. */
+#undef HAVE_ELF_AUX_INFO
+
/* Define to 1 if you have the <execinfo.h> header file. */
#undef HAVE_EXECINFO_H
@@ -154,6 +157,9 @@
*/
#undef HAVE_GCC__SYNC_INT64_CAS
+/* Define to 1 if you have the `getauxval' function. */
+#undef HAVE_GETAUXVAL
+
/* Define to 1 if you have the `getifaddrs' function. */
#undef HAVE_GETIFADDRS
diff --git a/src/port/pg_crc32c_armv8_choose.c b/src/port/pg_crc32c_armv8_choose.c
index eaf39cf3e81..306500154ee 100644
--- a/src/port/pg_crc32c_armv8_choose.c
+++ b/src/port/pg_crc32c_armv8_choose.c
@@ -24,57 +24,37 @@
#include "postgres_fe.h"
#endif
-#include <setjmp.h>
-#include <signal.h>
+#if defined(HAVE_ELF_AUX_INFO) || defined(HAVE_GETAUXVAL)
+#include <sys/auxv.h>
+#if defined(__linux__) && !defined(__aarch64__) && !defined(HWCAP2_CRC32)
+#include <asm/hwcap.h>
+#endif
+#endif
#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(SIGNAL_ARGS)
-{
- siglongjmp(illegal_instruction_jump, 1);
-}
-
static bool
pg_crc32c_armv8_available(void)
{
- uint64 data = 42;
- int result;
+#if defined(HAVE_ELF_AUX_INFO)
+ unsigned long value;
- /*
- * Be careful not to do anything that might throw an error while we have
- * the SIGILL handler set to a nonstandard value.
- */
- pqsignal(SIGILL, illegal_instruction_handler);
- if (sigsetjmp(illegal_instruction_jump, 1) == 0)
- {
- /* Rather than hard-wiring an expected result, compare to SB8 code */
- result = (pg_comp_crc32c_armv8(0, &data, sizeof(data)) ==
- pg_comp_crc32c_sb8(0, &data, sizeof(data)));
- }
- else
- {
- /* We got the SIGILL trap */
- result = -1;
- }
- pqsignal(SIGILL, SIG_DFL);
-
-#ifndef FRONTEND
- /* We don't expect this case, so complain loudly */
- if (result == 0)
- elog(ERROR, "crc32 hardware and software results disagree");
-
- elog(DEBUG1, "using armv8 crc32 hardware = %d", (result > 0));
+#ifdef __aarch64__
+ return elf_aux_info(AT_HWCAP, &value, sizeof(value)) == 0 &&
+ (value & HWCAP_CRC32) != 0;
+#else
+ return elf_aux_info(AT_HWCAP2, &value, sizeof(value)) == 0 &&
+ (value & HWCAP2_CRC32) != 0;
+#endif
+#elif defined(HAVE_GETAUXVAL)
+#ifdef __aarch64__
+ return (getauxval(AT_HWCAP) & HWCAP_CRC32) != 0;
+#else
+ return (getauxval(AT_HWCAP2) & HWCAP2_CRC32) != 0;
+#endif
+#else
+ return false;
#endif
-
- return (result > 0);
}
/*