Summary: ARM & AArch64 runtime detection for hardware support of CRC32 has been added via check of the AT_HWVAL auxiliary vector. Following Michal's suggestions in D28417, the CRC32 code has been further changed and looks better now. When compiled with full relro (which is strongly suggested to benefit from additional hardening), the weak symbol for computeHardwareCRC32 is read-only and the assembly generated is fairly clean and straight forward. As suggested, an additional optimization is to skip the runtime check if SSE 4.2 has been enabled globally, as opposed to only for scudo_crc32.cpp. scudo_crc32.h has no purpose anymore and was removed. Reviewers: alekseyshl, kcc, rengolin, mgorny, phosek Reviewed By: rengolin, mgorny Subscribers: aemerson, rengolin, llvm-commits Differential Revision: https://reviews.llvm.org/D28574 llvm-svn: 292409
43 lines
1.5 KiB
C++
43 lines
1.5 KiB
C++
//===-- scudo_crc32.cpp -----------------------------------------*- C++ -*-===//
|
|
//
|
|
// The LLVM Compiler Infrastructure
|
|
//
|
|
// This file is distributed under the University of Illinois Open Source
|
|
// License. See LICENSE.TXT for details.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
///
|
|
/// CRC32 function leveraging hardware specific instructions. This has to be
|
|
/// kept separated to restrict the use of compiler specific flags to this file.
|
|
///
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "sanitizer_common/sanitizer_internal_defs.h"
|
|
|
|
// Hardware CRC32 is supported at compilation via the following:
|
|
// - for i386 & x86_64: -msse4.2
|
|
// - for ARM & AArch64: -march=armv8-a+crc or -mcrc
|
|
// An additional check must be performed at runtime as well to make sure the
|
|
// emitted instructions are valid on the target host.
|
|
|
|
#if defined(__SSE4_2__) || defined(__ARM_FEATURE_CRC32)
|
|
# ifdef __SSE4_2__
|
|
# include <smmintrin.h>
|
|
# define CRC32_INTRINSIC FIRST_32_SECOND_64(_mm_crc32_u32, _mm_crc32_u64)
|
|
# endif
|
|
# ifdef __ARM_FEATURE_CRC32
|
|
# include <arm_acle.h>
|
|
# define CRC32_INTRINSIC FIRST_32_SECOND_64(__crc32cw, __crc32cd)
|
|
# endif
|
|
#endif // defined(__SSE4_2__) || defined(__ARM_FEATURE_CRC32)
|
|
|
|
namespace __scudo {
|
|
|
|
#if defined(__SSE4_2__) || defined(__ARM_FEATURE_CRC32)
|
|
u32 computeHardwareCRC32(u32 Crc, uptr Data) {
|
|
return CRC32_INTRINSIC(Crc, Data);
|
|
}
|
|
#endif // defined(__SSE4_2__) || defined(__ARM_FEATURE_CRC32)
|
|
|
|
} // namespace __scudo
|