From 90f807317ced813163fa2e5bf16341b6400448e2 Mon Sep 17 00:00:00 2001
From: Thomas Munro <thomas.munro@enterprisedb.com>
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

