summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cmake/config-ix.cmake1
-rw-r--r--lib/scudo/CMakeLists.txt7
-rw-r--r--lib/scudo/scudo_allocator.cpp35
-rw-r--r--lib/scudo/scudo_allocator.h4
-rw-r--r--lib/scudo/scudo_crc32.cpp17
-rw-r--r--lib/scudo/scudo_crc32.h30
-rw-r--r--lib/scudo/scudo_utils.cpp26
-rw-r--r--lib/scudo/scudo_utils.h6
8 files changed, 63 insertions, 63 deletions
diff --git a/cmake/config-ix.cmake b/cmake/config-ix.cmake
index e0e43552e..f0c96c25b 100644
--- a/cmake/config-ix.cmake
+++ b/cmake/config-ix.cmake
@@ -31,6 +31,7 @@ check_cxx_compiler_flag(-fno-lto COMPILER_RT_HAS_FNO_LTO_FLAG)
check_cxx_compiler_flag("-Werror -msse3" COMPILER_RT_HAS_MSSE3_FLAG)
check_cxx_compiler_flag("-Werror -msse4.2" COMPILER_RT_HAS_MSSE4_2_FLAG)
check_cxx_compiler_flag(--sysroot=. COMPILER_RT_HAS_SYSROOT_FLAG)
+check_cxx_compiler_flag("-Werror -mcrc" COMPILER_RT_HAS_MCRC_FLAG)
if(NOT WIN32 AND NOT CYGWIN)
# MinGW warns if -fvisibility-inlines-hidden is used.
diff --git a/lib/scudo/CMakeLists.txt b/lib/scudo/CMakeLists.txt
index 4f1acec78..ba5e8acd8 100644
--- a/lib/scudo/CMakeLists.txt
+++ b/lib/scudo/CMakeLists.txt
@@ -16,10 +16,17 @@ set(SCUDO_SOURCES
scudo_termination.cpp
scudo_utils.cpp)
+# Enable the SSE 4.2 instruction set for scudo_crc32.cpp, if available.
if (COMPILER_RT_HAS_MSSE4_2_FLAG)
set_source_files_properties(scudo_crc32.cpp PROPERTIES COMPILE_FLAGS -msse4.2)
endif()
+# Enable the AArch64 CRC32 feature for scudo_crc32.cpp, if available.
+# Note that it is enabled by default starting with armv8.1-a.
+if (COMPILER_RT_HAS_MCRC_FLAG)
+ set_source_files_properties(scudo_crc32.cpp PROPERTIES COMPILE_FLAGS -mcrc)
+endif()
+
if(COMPILER_RT_HAS_SCUDO)
foreach(arch ${SCUDO_SUPPORTED_ARCH})
add_compiler_rt_runtime(clang_rt.scudo
diff --git a/lib/scudo/scudo_allocator.cpp b/lib/scudo/scudo_allocator.cpp
index d1121b0e7..62fdf77f5 100644
--- a/lib/scudo/scudo_allocator.cpp
+++ b/lib/scudo/scudo_allocator.cpp
@@ -15,7 +15,6 @@
//===----------------------------------------------------------------------===//
#include "scudo_allocator.h"
-#include "scudo_crc32.h"
#include "scudo_utils.h"
#include "sanitizer_common/sanitizer_allocator_interface.h"
@@ -73,15 +72,21 @@ static uptr Cookie;
// at compilation or at runtime.
static atomic_uint8_t HashAlgorithm = { CRC32Software };
-// Helper function that will compute the chunk checksum, being passed all the
-// the needed information as uptrs. It will opt for the hardware version of
-// the checksumming function if available.
-INLINE u32 hashUptrs(uptr Pointer, uptr *Array, uptr ArraySize, u8 HashType) {
- u32 Crc;
- Crc = computeCRC32(Cookie, Pointer, HashType);
- for (uptr i = 0; i < ArraySize; i++)
- Crc = computeCRC32(Crc, Array[i], HashType);
- return Crc;
+SANITIZER_WEAK_ATTRIBUTE u32 computeHardwareCRC32(u32 Crc, uptr Data);
+
+INLINE u32 computeCRC32(u32 Crc, uptr Data, u8 HashType) {
+ // If SSE4.2 is defined here, it was enabled everywhere, as opposed to only
+ // for scudo_crc32.cpp. This means that other SSE instructions were likely
+ // emitted at other places, and as a result there is no reason to not use
+ // the hardware version of the CRC32.
+#if defined(__SSE4_2__) || defined(__ARM_FEATURE_CRC32)
+ return computeHardwareCRC32(Crc, Data);
+#else
+ if (computeHardwareCRC32 && HashType == CRC32Hardware)
+ return computeHardwareCRC32(Crc, Data);
+ else
+ return computeSoftwareCRC32(Crc, Data);
+#endif // defined(__SSE4_2__)
}
struct ScudoChunk : UnpackedHeader {
@@ -108,11 +113,11 @@ struct ScudoChunk : UnpackedHeader {
ZeroChecksumHeader.Checksum = 0;
uptr HeaderHolder[sizeof(UnpackedHeader) / sizeof(uptr)];
memcpy(&HeaderHolder, &ZeroChecksumHeader, sizeof(HeaderHolder));
- u32 Hash = hashUptrs(reinterpret_cast<uptr>(this),
- HeaderHolder,
- ARRAY_SIZE(HeaderHolder),
- atomic_load_relaxed(&HashAlgorithm));
- return static_cast<u16>(Hash);
+ u8 HashType = atomic_load_relaxed(&HashAlgorithm);
+ u32 Crc = computeCRC32(Cookie, reinterpret_cast<uptr>(this), HashType);
+ for (uptr i = 0; i < ARRAY_SIZE(HeaderHolder); i++)
+ Crc = computeCRC32(Crc, HeaderHolder[i], HashType);
+ return static_cast<u16>(Crc);
}
// Checks the validity of a chunk by verifying its checksum.
diff --git a/lib/scudo/scudo_allocator.h b/lib/scudo/scudo_allocator.h
index 6431a2aa0..b9fc82dc6 100644
--- a/lib/scudo/scudo_allocator.h
+++ b/lib/scudo/scudo_allocator.h
@@ -18,6 +18,10 @@
#include "sanitizer_common/sanitizer_allocator.h"
+#if !SANITIZER_LINUX
+# error "The Scudo hardened allocator is currently only supported on Linux."
+#endif
+
#include <atomic>
namespace __scudo {
diff --git a/lib/scudo/scudo_crc32.cpp b/lib/scudo/scudo_crc32.cpp
index 94c8c2424..56be22f4e 100644
--- a/lib/scudo/scudo_crc32.cpp
+++ b/lib/scudo/scudo_crc32.cpp
@@ -12,13 +12,13 @@
///
//===----------------------------------------------------------------------===//
+#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.
-#include "scudo_crc32.h"
-#include "scudo_utils.h"
#if defined(__SSE4_2__) || defined(__ARM_FEATURE_CRC32)
# ifdef __SSE4_2__
@@ -34,20 +34,9 @@
namespace __scudo {
#if defined(__SSE4_2__) || defined(__ARM_FEATURE_CRC32)
-INLINE u32 computeHardwareCRC32(u32 Crc, uptr Data) {
+u32 computeHardwareCRC32(u32 Crc, uptr Data) {
return CRC32_INTRINSIC(Crc, Data);
}
-
-u32 computeCRC32(u32 Crc, uptr Data, u8 HashType) {
- if (HashType == CRC32Hardware) {
- return computeHardwareCRC32(Crc, Data);
- }
- return computeSoftwareCRC32(Crc, Data);
-}
-#else
-u32 computeCRC32(u32 Crc, uptr Data, u8 HashType) {
- return computeSoftwareCRC32(Crc, Data);
-}
#endif // defined(__SSE4_2__) || defined(__ARM_FEATURE_CRC32)
} // namespace __scudo
diff --git a/lib/scudo/scudo_crc32.h b/lib/scudo/scudo_crc32.h
deleted file mode 100644
index 6635cc78b..000000000
--- a/lib/scudo/scudo_crc32.h
+++ /dev/null
@@ -1,30 +0,0 @@
-//===-- scudo_crc32.h -------------------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-///
-/// Header for scudo_crc32.cpp.
-///
-//===----------------------------------------------------------------------===//
-
-#ifndef SCUDO_CRC32_H_
-#define SCUDO_CRC32_H_
-
-#include "sanitizer_common/sanitizer_internal_defs.h"
-
-namespace __scudo {
-
-enum : u8 {
- CRC32Software = 0,
- CRC32Hardware = 1,
-};
-
-u32 computeCRC32(u32 Crc, uptr Data, u8 HashType);
-
-} // namespace __scudo
-
-#endif // SCUDO_CRC32_H_
diff --git a/lib/scudo/scudo_utils.cpp b/lib/scudo/scudo_utils.cpp
index 74144080c..4e2f6e08e 100644
--- a/lib/scudo/scudo_utils.cpp
+++ b/lib/scudo/scudo_utils.cpp
@@ -20,8 +20,9 @@
#if defined(__x86_64__) || defined(__i386__)
# include <cpuid.h>
#endif
-
-#include <cstring>
+#if defined(__arm__) || defined(__aarch64__)
+# include <sys/auxv.h>
+#endif
// TODO(kostyak): remove __sanitizer *Printf uses in favor for our own less
// complicated string formatting code. The following is a
@@ -82,7 +83,7 @@ CPUIDRegs getCPUFeatures() {
}
#ifndef bit_SSE4_2
-#define bit_SSE4_2 bit_SSE42 // clang and gcc have different defines.
+# define bit_SSE4_2 bit_SSE42 // clang and gcc have different defines.
#endif
bool testCPUFeature(CPUFeature Feature)
@@ -97,6 +98,25 @@ bool testCPUFeature(CPUFeature Feature)
}
return false;
}
+#elif defined(__arm__) || defined(__aarch64__)
+// For ARM and AArch64, hardware CRC32 support is indicated in the
+// AT_HWVAL auxiliary vector.
+
+#ifndef HWCAP_CRC32
+# define HWCAP_CRC32 (1<<7) // HWCAP_CRC32 is missing on older platforms.
+#endif
+
+bool testCPUFeature(CPUFeature Feature) {
+ uptr HWCap = getauxval(AT_HWCAP);
+
+ switch (Feature) {
+ case CRC32CPUFeature:
+ return !!(HWCap & HWCAP_CRC32);
+ default:
+ break;
+ }
+ return false;
+}
#else
bool testCPUFeature(CPUFeature Feature) {
return false;
diff --git a/lib/scudo/scudo_utils.h b/lib/scudo/scudo_utils.h
index ef2a60967..5082d79f6 100644
--- a/lib/scudo/scudo_utils.h
+++ b/lib/scudo/scudo_utils.h
@@ -53,7 +53,11 @@ struct Xorshift128Plus {
u64 State[2];
};
-// Software CRC32 functions, to be used when hardware support is not detected.
+enum : u8 {
+ CRC32Software = 0,
+ CRC32Hardware = 1,
+};
+
u32 computeSoftwareCRC32(u32 Crc, uptr Data);
} // namespace __scudo