From aa0ebc7e281e25ae5f2b9795c9f26ed79f79690b 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 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

