Snap for 8558685 from 8efb27c704e4d0a84430e2559c7845346a1511e2 to tm-frc-extservices-release

Change-Id: I44c78e6545c98ee9e4e3c1ecc0cb5bb9b5ed0952
diff --git a/Android.bp b/Android.bp
index 3eaeef5..ab3fb0d 100644
--- a/Android.bp
+++ b/Android.bp
@@ -149,9 +149,6 @@
                 "bionic_libc_platform_headers",
             ],
         },
-        linux_glibc: {
-            enabled: true,
-        },
         native_bridge: {
             cflags: ["-DSCUDO_DISABLE_TBI"],
         },
@@ -214,10 +211,7 @@
         "-fno-emulated-tls",
     ],
     target: {
-        android: {
-            header_libs: ["bionic_libc_platform_headers"],
-        },
-        linux_bionic: {
+        bionic: {
             header_libs: ["bionic_libc_platform_headers"],
         },
     },
diff --git a/standalone/checksum.cpp b/standalone/checksum.cpp
index 05d4ba5..2c27739 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 a63b1b4..0f787ce 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 69b8e1b..0581420 100644
--- a/standalone/chunk.h
+++ b/standalone/chunk.h
@@ -25,7 +25,7 @@
   // 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 @@
       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/combined.h b/standalone/combined.h
index 371fb78..365720d 100644
--- a/standalone/combined.h
+++ b/standalone/combined.h
@@ -1271,8 +1271,8 @@
   }
 
   static const size_t NumErrorReports =
-      sizeof(((scudo_error_info *)0)->reports) /
-      sizeof(((scudo_error_info *)0)->reports[0]);
+      sizeof(((scudo_error_info *)nullptr)->reports) /
+      sizeof(((scudo_error_info *)nullptr)->reports[0]);
 
   static void getInlineErrorInfo(struct scudo_error_info *ErrorInfo,
                                  size_t &NextErrorReport, uintptr_t FaultAddr,
diff --git a/standalone/crc32_hw.cpp b/standalone/crc32_hw.cpp
index 62841ba..d13c615 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 df346bc..7578aff 100644
--- a/standalone/memtag.h
+++ b/standalone/memtag.h
@@ -41,16 +41,16 @@
 
 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 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 @@
 
 #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 @@
   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/platform.h b/standalone/platform.h
index 36378d1..db4217d 100644
--- a/standalone/platform.h
+++ b/standalone/platform.h
@@ -37,7 +37,7 @@
 #define SCUDO_TRUSTY 0
 #endif
 
-#if __LP64__
+#if defined(__LP64__)
 #define SCUDO_WORDSIZE 64U
 #else
 #define SCUDO_WORDSIZE 32U
diff --git a/standalone/primary64.h b/standalone/primary64.h
index 6c17855..14784ee 100644
--- a/standalone/primary64.h
+++ b/standalone/primary64.h
@@ -89,7 +89,9 @@
       RegionInfo *Region = getRegionInfo(I);
       *Region = {};
     }
-    unmap(reinterpret_cast<void *>(PrimaryBase), PrimarySize, UNMAP_ALL, &Data);
+    if (PrimaryBase)
+      unmap(reinterpret_cast<void *>(PrimaryBase), PrimarySize, UNMAP_ALL,
+            &Data);
     PrimaryBase = 0U;
   }
 
diff --git a/standalone/secondary.h b/standalone/secondary.h
index abb58a2..2d177576 100644
--- a/standalone/secondary.h
+++ b/standalone/secondary.h
@@ -113,6 +113,19 @@
   }
 }
 
+// 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 @@
     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 @@
   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 @@
     }
   }
 
-  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/size_class_map.h b/standalone/size_class_map.h
index 28b16d9..6b06095 100644
--- a/standalone/size_class_map.h
+++ b/standalone/size_class_map.h
@@ -345,7 +345,7 @@
   Buffer.output();
 }
 
-template <typename SCMap> static void validateMap() {
+template <typename SCMap> static UNUSED void validateMap() {
   for (uptr C = 0; C < SCMap::NumClasses; C++) {
     if (C == SCMap::BatchClassId)
       continue;
diff --git a/standalone/tests/checksum_test.cpp b/standalone/tests/checksum_test.cpp
index 781f990..c5d5b73 100644
--- a/standalone/tests/checksum_test.cpp
+++ b/standalone/tests/checksum_test.cpp
@@ -12,16 +12,16 @@
 
 #include <string.h>
 
-scudo::u16 computeSoftwareChecksum(scudo::u32 Seed, scudo::uptr *Array,
-                                   scudo::uptr ArraySize) {
+static scudo::u16 computeSoftwareChecksum(scudo::u32 Seed, scudo::uptr *Array,
+                                          scudo::uptr ArraySize) {
   scudo::u16 Checksum = static_cast<scudo::u16>(Seed & 0xffff);
   for (scudo::uptr I = 0; I < ArraySize; I++)
     Checksum = scudo::computeBSDChecksum(Checksum, Array[I]);
   return Checksum;
 }
 
-scudo::u16 computeHardwareChecksum(scudo::u32 Seed, scudo::uptr *Array,
-                                   scudo::uptr ArraySize) {
+static scudo::u16 computeHardwareChecksum(scudo::u32 Seed, scudo::uptr *Array,
+                                          scudo::uptr ArraySize) {
   scudo::u32 Crc = Seed;
   for (scudo::uptr I = 0; I < ArraySize; I++)
     Crc = scudo::computeHardwareCRC32(Crc, Array[I]);
@@ -32,7 +32,7 @@
 
 // This verifies that flipping bits in the data being checksummed produces a
 // different checksum. We do not use random data to avoid flakyness.
-template <ComputeChecksum F> void verifyChecksumFunctionBitFlip() {
+template <ComputeChecksum F> static void verifyChecksumFunctionBitFlip() {
   scudo::uptr Array[sizeof(scudo::u64) / sizeof(scudo::uptr)];
   const scudo::uptr ArraySize = ARRAY_SIZE(Array);
   memset(Array, 0xaa, sizeof(Array));
diff --git a/standalone/tests/combined_test.cpp b/standalone/tests/combined_test.cpp
index deccccf..94d97df 100644
--- a/standalone/tests/combined_test.cpp
+++ b/standalone/tests/combined_test.cpp
@@ -118,7 +118,7 @@
 
 #define SCUDO_TYPED_TEST_TYPE(FIXTURE, NAME, TYPE)                             \
   using FIXTURE##NAME##_##TYPE = FIXTURE##NAME<scudo::TYPE>;                   \
-  TEST_F(FIXTURE##NAME##_##TYPE, NAME) { Run(); }
+  TEST_F(FIXTURE##NAME##_##TYPE, NAME) { FIXTURE##NAME<scudo::TYPE>::Run(); }
 
 #define SCUDO_TYPED_TEST(FIXTURE, NAME)                                        \
   template <class TypeParam>                                                   \
@@ -643,7 +643,7 @@
 SCUDO_TYPED_TEST(ScudoCombinedTest, DisableMemInit) {
   auto *Allocator = this->Allocator.get();
 
-  std::vector<void *> Ptrs(65536, nullptr);
+  std::vector<void *> Ptrs(65536);
 
   Allocator->setOption(scudo::Option::ThreadDisableMemInit, 1);
 
diff --git a/standalone/tests/map_test.cpp b/standalone/tests/map_test.cpp
index 095e1b6..ff05258 100644
--- a/standalone/tests/map_test.cpp
+++ b/standalone/tests/map_test.cpp
@@ -17,7 +17,7 @@
 
 TEST(ScudoMapTest, PageSize) {
   EXPECT_EQ(scudo::getPageSizeCached(),
-            static_cast<scudo::uptr>(getpagesize()));
+            static_cast<scudo::uptr>(sysconf(_SC_PAGESIZE)));
 }
 
 TEST(ScudoMapDeathTest, MapNoAccessUnmap) {
diff --git a/standalone/tests/memtag_test.cpp b/standalone/tests/memtag_test.cpp
index 72c9de3..283edaa 100644
--- a/standalone/tests/memtag_test.cpp
+++ b/standalone/tests/memtag_test.cpp
@@ -38,7 +38,7 @@
   EXPECT_DEATH(addFixedTag(nullptr, 0), "not supported");
 }
 
-class MemtagTest : public ::testing::Test {
+class MemtagTest : public Test {
 protected:
   void SetUp() override {
     if (!archSupportsMemoryTagging() || !systemDetectsMemoryTagFaultsTestOnly())
diff --git a/standalone/tests/primary_test.cpp b/standalone/tests/primary_test.cpp
index 5ec4361..283e297 100644
--- a/standalone/tests/primary_test.cpp
+++ b/standalone/tests/primary_test.cpp
@@ -105,7 +105,7 @@
 
 #define SCUDO_TYPED_TEST_TYPE(FIXTURE, NAME, TYPE)                             \
   using FIXTURE##NAME##_##TYPE = FIXTURE##NAME<TYPE>;                          \
-  TEST_F(FIXTURE##NAME##_##TYPE, NAME) { Run(); }
+  TEST_F(FIXTURE##NAME##_##TYPE, NAME) { FIXTURE##NAME<TYPE>::Run(); }
 
 #define SCUDO_TYPED_TEST(FIXTURE, NAME)                                        \
   template <class TypeParam>                                                   \
@@ -207,7 +207,7 @@
     V.push_back(std::make_pair(ClassId, P));
   }
   scudo::uptr Found = 0;
-  auto Lambda = [V, &Found](scudo::uptr Block) {
+  auto Lambda = [&V, &Found](scudo::uptr Block) {
     for (const auto &Pair : V) {
       if (Pair.second == reinterpret_cast<void *>(Block))
         Found++;
diff --git a/standalone/tests/secondary_test.cpp b/standalone/tests/secondary_test.cpp
index 7236792..e656466 100644
--- a/standalone/tests/secondary_test.cpp
+++ b/standalone/tests/secondary_test.cpp
@@ -12,6 +12,7 @@
 #include "allocator_config.h"
 #include "secondary.h"
 
+#include <algorithm>
 #include <condition_variable>
 #include <memory>
 #include <mutex>
@@ -152,7 +153,7 @@
   const scudo::uptr PageSize = scudo::getPageSizeCached();
   for (scudo::uptr I = 0; I < 32U; I++)
     V.push_back(Allocator->allocate(Options, (std::rand() % 16) * PageSize));
-  auto Lambda = [V](scudo::uptr Block) {
+  auto Lambda = [&V](scudo::uptr Block) {
     EXPECT_NE(std::find(V.begin(), V.end(), reinterpret_cast<void *>(Block)),
               V.end());
   };
diff --git a/standalone/tsd_exclusive.h b/standalone/tsd_exclusive.h
index bba0c27..d49427b 100644
--- a/standalone/tsd_exclusive.h
+++ b/standalone/tsd_exclusive.h
@@ -15,7 +15,7 @@
 
 struct ThreadState {
   bool DisableMemInit : 1;
-  enum {
+  enum : unsigned {
     NotInitialized = 0,
     Initialized,
     TornDown,
@@ -87,7 +87,7 @@
     Mutex.unlock();
   }
 
-  bool setOption(Option O, UNUSED sptr Value) {
+  bool setOption(Option O, sptr Value) {
     if (O == Option::ThreadDisableMemInit)
       State.DisableMemInit = Value;
     if (O == Option::MaxTSDsCount)
diff --git a/standalone/wrappers_c.cpp b/standalone/wrappers_c.cpp
index 81c7dd6..b4d51be 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 5f7f51f..08dc679 100644
--- a/standalone/wrappers_c.h
+++ b/standalone/wrappers_c.h
@@ -54,4 +54,9 @@
 #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 ec9c1a1..815d400 100644
--- a/standalone/wrappers_c_checks.h
+++ b/standalone/wrappers_c_checks.h
@@ -47,9 +47,12 @@
 // 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 adb1041..16f495b 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 {};