diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2019-10-23 17:52:22 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2019-10-23 17:52:22 +0000 |
commit | 3a1720af1d7f43edc5b214cde0be11bfb94d077e (patch) | |
tree | 029e0ff2d5e3c0eaf2405fd8e669555fdf5e1297 /lib/scudo/standalone/checksum.cpp | |
parent | 8f3cadc28cb2bb9e8f9d69eeaaea1f57f2f7b2ab (diff) | |
download | src-3a1720af1d7f43edc5b214cde0be11bfb94d077e.tar.gz src-3a1720af1d7f43edc5b214cde0be11bfb94d077e.zip |
Vendor import of stripped compiler-rt trunk r375505, the last commitvendor/compiler-rt/compiler-rt-trunk-r375505vendor/compiler-rt
before the upstream Subversion repository was made read-only, and the
LLVM project migrated to GitHub:
https://llvm.org/svn/llvm-project/compiler-rt/trunk@375505
Notes
Notes:
svn path=/vendor/compiler-rt/dist/; revision=353944
svn path=/vendor/compiler-rt/compiler-rt-r375505/; revision=353945; tag=vendor/compiler-rt/compiler-rt-trunk-r375505
Diffstat (limited to 'lib/scudo/standalone/checksum.cpp')
-rw-r--r-- | lib/scudo/standalone/checksum.cpp | 70 |
1 files changed, 70 insertions, 0 deletions
diff --git a/lib/scudo/standalone/checksum.cpp b/lib/scudo/standalone/checksum.cpp new file mode 100644 index 000000000000..f713f5a81609 --- /dev/null +++ b/lib/scudo/standalone/checksum.cpp @@ -0,0 +1,70 @@ +//===-- checksum.cpp --------------------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "checksum.h" +#include "atomic_helpers.h" + +#if defined(__x86_64__) || defined(__i386__) +#include <cpuid.h> +#elif defined(__arm__) || defined(__aarch64__) +#if SCUDO_FUCHSIA +#include <zircon/features.h> +#include <zircon/syscalls.h> +#else +#include <sys/auxv.h> +#endif +#endif + +namespace scudo { + +Checksum HashAlgorithm = {Checksum::BSD}; + +#if defined(__x86_64__) || defined(__i386__) +// i386 and x86_64 specific code to detect CRC32 hardware support via CPUID. +// CRC32 requires the SSE 4.2 instruction set. +#ifndef bit_SSE4_2 +#define bit_SSE4_2 bit_SSE42 // clang and gcc have different defines. +#endif + +bool hasHardwareCRC32() { + u32 Eax, Ebx = 0, Ecx = 0, Edx = 0; + __get_cpuid(0, &Eax, &Ebx, &Ecx, &Edx); + const bool IsIntel = (Ebx == signature_INTEL_ebx) && + (Edx == signature_INTEL_edx) && + (Ecx == signature_INTEL_ecx); + const bool IsAMD = (Ebx == signature_AMD_ebx) && (Edx == signature_AMD_edx) && + (Ecx == signature_AMD_ecx); + if (!IsIntel && !IsAMD) + return false; + __get_cpuid(1, &Eax, &Ebx, &Ecx, &Edx); + return !!(Ecx & bit_SSE4_2); +} + +#elif defined(__arm__) || defined(__aarch64__) +#ifndef AT_HWCAP +#define AT_HWCAP 16 +#endif +#ifndef HWCAP_CRC32 +#define HWCAP_CRC32 (1U << 7) // HWCAP_CRC32 is missing on older platforms. +#endif + +bool hasHardwareCRC32() { +#if SCUDO_FUCHSIA + u32 HWCap; + const zx_status_t Status = + zx_system_get_features(ZX_FEATURE_KIND_CPU, &HWCap); + if (Status != ZX_OK) + return false; + return !!(HWCap & ZX_ARM64_FEATURE_ISA_CRC32); +#else + return !!(getauxval(AT_HWCAP) & HWCAP_CRC32); +#endif // SCUDO_FUCHSIA +} +#endif // defined(__x86_64__) || defined(__i386__) + +} // namespace scudo |