checksum.cpp revision 360784
1//===-- checksum.cpp --------------------------------------------*- C++ -*-===// 2// 3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4// See https://llvm.org/LICENSE.txt for license information. 5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6// 7//===----------------------------------------------------------------------===// 8 9#include "checksum.h" 10#include "atomic_helpers.h" 11 12#if defined(__x86_64__) || defined(__i386__) 13#include <cpuid.h> 14#elif defined(__arm__) || defined(__aarch64__) 15#if SCUDO_FUCHSIA 16#include <zircon/features.h> 17#include <zircon/syscalls.h> 18#else 19#include <sys/auxv.h> 20#endif 21#endif 22 23namespace scudo { 24 25Checksum HashAlgorithm = {Checksum::BSD}; 26 27#if defined(__x86_64__) || defined(__i386__) 28// i386 and x86_64 specific code to detect CRC32 hardware support via CPUID. 29// CRC32 requires the SSE 4.2 instruction set. 30#ifndef bit_SSE4_2 31#define bit_SSE4_2 bit_SSE42 // clang and gcc have different defines. 32#endif 33 34bool hasHardwareCRC32() { 35 u32 Eax, Ebx = 0, Ecx = 0, Edx = 0; 36 __get_cpuid(0, &Eax, &Ebx, &Ecx, &Edx); 37 const bool IsIntel = (Ebx == signature_INTEL_ebx) && 38 (Edx == signature_INTEL_edx) && 39 (Ecx == signature_INTEL_ecx); 40 const bool IsAMD = (Ebx == signature_AMD_ebx) && (Edx == signature_AMD_edx) && 41 (Ecx == signature_AMD_ecx); 42 if (!IsIntel && !IsAMD) 43 return false; 44 __get_cpuid(1, &Eax, &Ebx, &Ecx, &Edx); 45 return !!(Ecx & bit_SSE4_2); 46} 47#elif defined(__arm__) || defined(__aarch64__) 48#ifndef AT_HWCAP 49#define AT_HWCAP 16 50#endif 51#ifndef HWCAP_CRC32 52#define HWCAP_CRC32 (1U << 7) // HWCAP_CRC32 is missing on older platforms. 53#endif 54 55bool hasHardwareCRC32() { 56#if SCUDO_FUCHSIA 57 u32 HWCap; 58 const zx_status_t Status = 59 zx_system_get_features(ZX_FEATURE_KIND_CPU, &HWCap); 60 if (Status != ZX_OK) 61 return false; 62 return !!(HWCap & ZX_ARM64_FEATURE_ISA_CRC32); 63#else 64 return !!(getauxval(AT_HWCAP) & HWCAP_CRC32); 65#endif // SCUDO_FUCHSIA 66} 67#else 68// No hardware CRC32 implemented in Scudo for other architectures. 69bool hasHardwareCRC32() { return false; } 70#endif // defined(__x86_64__) || defined(__i386__) 71 72} // namespace scudo 73