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"
# 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}],
/* 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
*/
#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
#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);
}
/*