From aa0ebc7e281e25ae5f2b9795c9f26ed79f79690b 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 including coding that wouldn't work correctly on a big endian system. Fix by simply comparing the hw and sw implementations' results instead of hardcoding constants. 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..062058bb57d 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 crc2 hardware = %d", result); + return result; } -- 2.17.0