From 90f807317ced813163fa2e5bf16341b6400448e2 Mon Sep 17 00:00:00 2001 From: Thomas Munro Date: Thu, 3 May 2018 05:12:12 +0000 Subject: [PATCH] Fix endianness bug in ARMv8 CRC32 detection. Andrew Gierth pointed out that commit 1c72ec6f included coding that wouldn't work correctly on a big endian system. Fix by simply comparing the hardware and software implementations' results instead of hardcoding a constant value. While here, also log the resulting decision at debug1, and error out if the hw and sw results unexpectedly differ. Thomas Munro, based on complaints from Andrew Gierth and Tom Lane Discussion: https://postgr.es/m/HE1PR0801MB1323D171938EABC04FFE7FA9E3110@HE1PR0801MB1323.eurprd08.prod.outlook.com --- src/port/pg_crc32c_armv8_choose.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/port/pg_crc32c_armv8_choose.c b/src/port/pg_crc32c_armv8_choose.c index d0d3a3da78e..802136c6954 100644 --- a/src/port/pg_crc32c_armv8_choose.c +++ b/src/port/pg_crc32c_armv8_choose.c @@ -24,6 +24,7 @@ #include "libpq/pqsignal.h" #include "port/pg_crc32c.h" +#include "utils/elog.h" static sigjmp_buf illegal_instruction_jump; @@ -46,11 +47,18 @@ pg_crc32c_armv8_available(void) pqsignal(SIGILL, illegal_instruction_handler); if (sigsetjmp(illegal_instruction_jump, 1) == 0) - result = (pg_comp_crc32c_armv8(0, &data, sizeof(data)) == 0xdd439b0d); + { + if (pg_comp_crc32c_armv8(0, &data, sizeof(data)) != + pg_comp_crc32c_sb8(0, &data, sizeof(data))) + elog(ERROR, "crc32 hardware and software results disagree"); + result = true; + } else result = false; pqsignal(SIGILL, SIG_DFL); + elog(DEBUG1, "using armv8 crc32 hardware = %d", result); + return result; } -- 2.17.0