summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2022-04-19 03:10:09 +0000
committerAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2022-04-19 03:10:09 +0000
commit502f6a06a50ed58d01b7ad3d2dcb19ae7d614684 (patch)
tree88ac1f51173fc7d412e45ff0f937fb8970af4a7f
parentabfbbec3463a6fadc39a6da5594c7bc494317be2 (diff)
parentf6426c10f686c444b2d445568797e42b4fadbc29 (diff)
downloadscudo-android13-qpr1-s4-release.tar.gz
Change-Id: I779dd72bc3611de68300c5d22aea9e2b25cb190c
-rw-r--r--standalone/checksum.cpp1
-rw-r--r--standalone/checksum.h8
-rw-r--r--standalone/chunk.h4
-rw-r--r--standalone/crc32_hw.cpp4
-rw-r--r--standalone/memtag.h29
-rw-r--r--standalone/secondary.h20
-rw-r--r--standalone/wrappers_c.cpp2
-rw-r--r--standalone/wrappers_c.h5
-rw-r--r--standalone/wrappers_c_checks.h7
-rw-r--r--standalone/wrappers_cpp.cpp4
10 files changed, 55 insertions, 29 deletions
diff --git a/standalone/checksum.cpp b/standalone/checksum.cpp
index 05d4ba54bfc..2c277391a2e 100644
--- a/standalone/checksum.cpp
+++ b/standalone/checksum.cpp
@@ -8,6 +8,7 @@
#include "checksum.h"
#include "atomic_helpers.h"
+#include "chunk.h"
#if defined(__x86_64__) || defined(__i386__)
#include <cpuid.h>
diff --git a/standalone/checksum.h b/standalone/checksum.h
index a63b1b4f064..0f787ce2b5c 100644
--- a/standalone/checksum.h
+++ b/standalone/checksum.h
@@ -12,12 +12,16 @@
#include "internal_defs.h"
// Hardware CRC32 is supported at compilation via the following:
-// - for i386 & x86_64: -msse4.2
+// - for i386 & x86_64: -mcrc32 (earlier: -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.
-#ifdef __SSE4_2__
+#if defined(__CRC32__)
+// NB: clang has <crc32intrin.h> but GCC does not
+#include <smmintrin.h>
+#define CRC32_INTRINSIC FIRST_32_SECOND_64(__builtin_ia32_crc32si, __builtin_ia32_crc32di)
+#elif defined(__SSE4_2__)
#include <smmintrin.h>
#define CRC32_INTRINSIC FIRST_32_SECOND_64(_mm_crc32_u32, _mm_crc32_u64)
#endif
diff --git a/standalone/chunk.h b/standalone/chunk.h
index 69b8e1b12a9..0581420dfc9 100644
--- a/standalone/chunk.h
+++ b/standalone/chunk.h
@@ -25,7 +25,7 @@ inline u16 computeChecksum(u32 Seed, uptr Value, uptr *Array, uptr ArraySize) {
// as opposed to only for crc32_hw.cpp. This means that other hardware
// specific instructions were likely emitted at other places, and as a result
// there is no reason to not use it here.
-#if defined(__SSE4_2__) || defined(__ARM_FEATURE_CRC32)
+#if defined(__CRC32__) || defined(__SSE4_2__) || defined(__ARM_FEATURE_CRC32)
u32 Crc = static_cast<u32>(CRC32_INTRINSIC(Seed, Value));
for (uptr I = 0; I < ArraySize; I++)
Crc = static_cast<u32>(CRC32_INTRINSIC(Crc, Array[I]));
@@ -42,7 +42,7 @@ inline u16 computeChecksum(u32 Seed, uptr Value, uptr *Array, uptr ArraySize) {
Checksum = computeBSDChecksum(Checksum, Array[I]);
return Checksum;
}
-#endif // defined(__SSE4_2__) || defined(__ARM_FEATURE_CRC32)
+#endif // defined(__CRC32__) || defined(__SSE4_2__) || defined(__ARM_FEATURE_CRC32)
}
namespace Chunk {
diff --git a/standalone/crc32_hw.cpp b/standalone/crc32_hw.cpp
index 62841ba5101..d13c615498f 100644
--- a/standalone/crc32_hw.cpp
+++ b/standalone/crc32_hw.cpp
@@ -10,10 +10,10 @@
namespace scudo {
-#if defined(__SSE4_2__) || defined(__ARM_FEATURE_CRC32)
+#if defined(__CRC32__) || defined(__SSE4_2__) || defined(__ARM_FEATURE_CRC32)
u32 computeHardwareCRC32(u32 Crc, uptr Data) {
return static_cast<u32>(CRC32_INTRINSIC(Crc, Data));
}
-#endif // defined(__SSE4_2__) || defined(__ARM_FEATURE_CRC32)
+#endif // defined(__CRC32__) || defined(__SSE4_2__) || defined(__ARM_FEATURE_CRC32)
} // namespace scudo
diff --git a/standalone/memtag.h b/standalone/memtag.h
index df346bce1bd..7578aff17be 100644
--- a/standalone/memtag.h
+++ b/standalone/memtag.h
@@ -41,16 +41,16 @@ inline uint8_t extractTag(uptr Ptr) { return (Ptr >> 56) & 0xf; }
inline constexpr bool archSupportsMemoryTagging() { return false; }
-inline uptr archMemoryTagGranuleSize() {
+inline NORETURN uptr archMemoryTagGranuleSize() {
UNREACHABLE("memory tagging not supported");
}
-inline uptr untagPointer(uptr Ptr) {
+inline NORETURN uptr untagPointer(uptr Ptr) {
(void)Ptr;
UNREACHABLE("memory tagging not supported");
}
-inline uint8_t extractTag(uptr Ptr) {
+inline NORETURN uint8_t extractTag(uptr Ptr) {
(void)Ptr;
UNREACHABLE("memory tagging not supported");
}
@@ -109,11 +109,11 @@ inline void enableSystemMemoryTaggingTestOnly() {
inline bool systemSupportsMemoryTagging() { return false; }
-inline bool systemDetectsMemoryTagFaultsTestOnly() {
+inline NORETURN bool systemDetectsMemoryTagFaultsTestOnly() {
UNREACHABLE("memory tagging not supported");
}
-inline void enableSystemMemoryTaggingTestOnly() {
+inline NORETURN void enableSystemMemoryTaggingTestOnly() {
UNREACHABLE("memory tagging not supported");
}
@@ -255,15 +255,15 @@ inline uptr loadTag(uptr Ptr) {
#else
-inline bool systemSupportsMemoryTagging() {
+inline NORETURN bool systemSupportsMemoryTagging() {
UNREACHABLE("memory tagging not supported");
}
-inline bool systemDetectsMemoryTagFaultsTestOnly() {
+inline NORETURN bool systemDetectsMemoryTagFaultsTestOnly() {
UNREACHABLE("memory tagging not supported");
}
-inline void enableSystemMemoryTaggingTestOnly() {
+inline NORETURN void enableSystemMemoryTaggingTestOnly() {
UNREACHABLE("memory tagging not supported");
}
@@ -271,41 +271,44 @@ struct ScopedDisableMemoryTagChecks {
ScopedDisableMemoryTagChecks() {}
};
-inline uptr selectRandomTag(uptr Ptr, uptr ExcludeMask) {
+inline NORETURN uptr selectRandomTag(uptr Ptr, uptr ExcludeMask) {
(void)Ptr;
(void)ExcludeMask;
UNREACHABLE("memory tagging not supported");
}
-inline uptr addFixedTag(uptr Ptr, uptr Tag) {
+inline NORETURN uptr addFixedTag(uptr Ptr, uptr Tag) {
(void)Ptr;
(void)Tag;
UNREACHABLE("memory tagging not supported");
}
-inline uptr storeTags(uptr Begin, uptr End) {
+inline NORETURN uptr storeTags(uptr Begin, uptr End) {
(void)Begin;
(void)End;
UNREACHABLE("memory tagging not supported");
}
-inline void storeTag(uptr Ptr) {
+inline NORETURN void storeTag(uptr Ptr) {
(void)Ptr;
UNREACHABLE("memory tagging not supported");
}
-inline uptr loadTag(uptr Ptr) {
+inline NORETURN uptr loadTag(uptr Ptr) {
(void)Ptr;
UNREACHABLE("memory tagging not supported");
}
#endif
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wmissing-noreturn"
inline void setRandomTag(void *Ptr, uptr Size, uptr ExcludeMask,
uptr *TaggedBegin, uptr *TaggedEnd) {
*TaggedBegin = selectRandomTag(reinterpret_cast<uptr>(Ptr), ExcludeMask);
*TaggedEnd = storeTags(*TaggedBegin, *TaggedBegin + Size);
}
+#pragma GCC diagnostic pop
inline void *untagPointer(void *Ptr) {
return reinterpret_cast<void *>(untagPointer(reinterpret_cast<uptr>(Ptr)));
diff --git a/standalone/secondary.h b/standalone/secondary.h
index abb58a2882a..2d177576258 100644
--- a/standalone/secondary.h
+++ b/standalone/secondary.h
@@ -113,6 +113,19 @@ void mapSecondary(Options Options, uptr CommitBase, uptr CommitSize,
}
}
+// Template specialization to avoid producing zero-length array
+template <typename T, size_t Size> class NonZeroLengthArray {
+public:
+ T &operator[](uptr Idx) { return values[Idx]; }
+
+private:
+ T values[Size];
+};
+template <typename T> class NonZeroLengthArray<T, 0> {
+public:
+ T &operator[](uptr UNUSED Idx) { UNREACHABLE("Unsupported!"); }
+};
+
template <typename Config> class MapAllocatorCache {
public:
// Ensure the default maximum specified fits the array.
@@ -219,7 +232,7 @@ public:
const u32 MaxCount = atomic_load_relaxed(&MaxEntriesCount);
bool Found = false;
CachedBlock Entry;
- uptr HeaderPos;
+ uptr HeaderPos = 0;
{
ScopedLock L(Mutex);
if (EntriesCount == 0)
@@ -395,7 +408,8 @@ private:
atomic_s32 ReleaseToOsIntervalMs = {};
CachedBlock Entries[Config::SecondaryCacheEntriesArraySize] = {};
- CachedBlock Quarantine[Config::SecondaryCacheQuarantineSize] = {};
+ NonZeroLengthArray<CachedBlock, Config::SecondaryCacheQuarantineSize>
+ Quarantine = {};
};
template <typename Config> class MapAllocator {
@@ -445,7 +459,7 @@ public:
}
}
- uptr canCache(uptr Size) { return Cache.canCache(Size); }
+ bool canCache(uptr Size) { return Cache.canCache(Size); }
bool setOption(Option O, sptr Value) { return Cache.setOption(O, Value); }
diff --git a/standalone/wrappers_c.cpp b/standalone/wrappers_c.cpp
index 81c7dd60ee3..b4d51be716c 100644
--- a/standalone/wrappers_c.cpp
+++ b/standalone/wrappers_c.cpp
@@ -21,8 +21,6 @@
#define SCUDO_PREFIX(name) name
#define SCUDO_ALLOCATOR Allocator
-extern "C" void SCUDO_PREFIX(malloc_postinit)();
-
// Export the static allocator so that the C++ wrappers can access it.
// Technically we could have a completely separated heap for C & C++ but in
// reality the amount of cross pollination between the two is staggering.
diff --git a/standalone/wrappers_c.h b/standalone/wrappers_c.h
index 5f7f51f3ced..08dc679b34c 100644
--- a/standalone/wrappers_c.h
+++ b/standalone/wrappers_c.h
@@ -54,4 +54,9 @@ struct __scudo_mallinfo2 {
#define SCUDO_MALLINFO __scudo_mallinfo
#endif
+#if !SCUDO_ANDROID || !_BIONIC
+extern "C" void malloc_postinit();
+extern HIDDEN scudo::Allocator<scudo::Config, malloc_postinit> Allocator;
+#endif
+
#endif // SCUDO_WRAPPERS_C_H_
diff --git a/standalone/wrappers_c_checks.h b/standalone/wrappers_c_checks.h
index ec9c1a104e8..815d40023b6 100644
--- a/standalone/wrappers_c_checks.h
+++ b/standalone/wrappers_c_checks.h
@@ -47,9 +47,12 @@ inline bool checkPosixMemalignAlignment(uptr Alignment) {
// costly division.
inline bool checkForCallocOverflow(uptr Size, uptr N, uptr *Product) {
#if __has_builtin(__builtin_umull_overflow) && (SCUDO_WORDSIZE == 64U)
- return __builtin_umull_overflow(Size, N, Product);
+ return __builtin_umull_overflow(Size, N,
+ reinterpret_cast<unsigned long *>(Product));
#elif __has_builtin(__builtin_umul_overflow) && (SCUDO_WORDSIZE == 32U)
- return __builtin_umul_overflow(Size, N, Product);
+ // On, e.g. armv7, uptr/uintptr_t may be defined as unsigned long
+ return __builtin_umul_overflow(Size, N,
+ reinterpret_cast<unsigned int *>(Product));
#else
*Product = Size * N;
if (!Size)
diff --git a/standalone/wrappers_cpp.cpp b/standalone/wrappers_cpp.cpp
index adb10411812..16f495b6a35 100644
--- a/standalone/wrappers_cpp.cpp
+++ b/standalone/wrappers_cpp.cpp
@@ -12,12 +12,10 @@
#if !SCUDO_ANDROID || !_BIONIC
#include "allocator_config.h"
+#include "wrappers_c.h"
#include <stdint.h>
-extern "C" void malloc_postinit();
-extern HIDDEN scudo::Allocator<scudo::Config, malloc_postinit> Allocator;
-
namespace std {
struct nothrow_t {};
enum class align_val_t : size_t {};