aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2018-05-02 18:06:43 -0400
committerTom Lane <tgl@sss.pgh.pa.us>2018-05-02 18:06:43 -0400
commit1c72ec6f498945eb5981cdedd448aec3977477c8 (patch)
tree581be6b9afa1d1f13d663f0d4030e6f2e7c0f96e /src
parent40f52b16dd31aa9ddc3bd42daa78459562693567 (diff)
downloadpostgresql-1c72ec6f498945eb5981cdedd448aec3977477c8.tar.gz
postgresql-1c72ec6f498945eb5981cdedd448aec3977477c8.zip
Improve our method for probing the availability of ARM CRC instructions.
Instead of depending on glibc's getauxval() function, just try to execute the CRC code, and trap SIGILL if that happens. Thomas Munro Discussion: https://postgr.es/m/HE1PR0801MB1323D171938EABC04FFE7FA9E3110@HE1PR0801MB1323.eurprd08.prod.outlook.com
Diffstat (limited to 'src')
-rw-r--r--src/include/pg_config.h.in3
-rw-r--r--src/port/pg_crc32c_armv8_choose.c33
2 files changed, 25 insertions, 11 deletions
diff --git a/src/include/pg_config.h.in b/src/include/pg_config.h.in
index f3620231a71..9411f485121 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 f21a8243e9a..d0d3a3da78e 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 <sys/auxv.h>
-#include <asm/hwcap.h>
+#include <setjmp.h>
+#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;
+
+ 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 (auxv & HWCAP_CRC32) != 0;
+ return result;
}
/*