hctim updated this revision to Diff 347814.
hctim marked an inline comment as done.
hctim added a comment.

Address Vitaly's suggestions, make some slight changes so that 
cross-compilation and running under QEMU doesn't require staging the runtimes 
in the host compiler.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D102543/new/

https://reviews.llvm.org/D102543

Files:
  clang/lib/Driver/ToolChains/CommonArgs.cpp
  
clang/test/Driver/Inputs/resource_dir_with_per_target_subdir/lib/aarch64-unknown-fuchsia/libclang_rt.scudo.so
  
clang/test/Driver/Inputs/resource_dir_with_per_target_subdir/lib/aarch64-unknown-fuchsia/libclang_rt.scudo_standalone.so
  
clang/test/Driver/Inputs/resource_dir_with_per_target_subdir/lib/x86_64-unknown-fuchsia/libclang_rt.scudo.so
  
clang/test/Driver/Inputs/resource_dir_with_per_target_subdir/lib/x86_64-unknown-fuchsia/libclang_rt.scudo_standalone.so
  clang/test/Driver/fuchsia.c
  clang/test/Driver/sanitizer-ld.c
  compiler-rt/lib/scudo/standalone/wrappers_cpp.cpp
  compiler-rt/test/scudo/CMakeLists.txt
  compiler-rt/test/scudo/aligned-new.cpp
  compiler-rt/test/scudo/alignment.c
  compiler-rt/test/scudo/dealloc-race.c
  compiler-rt/test/scudo/double-free.cpp
  compiler-rt/test/scudo/fsanitize.c
  compiler-rt/test/scudo/interface.cpp
  compiler-rt/test/scudo/lit.cfg.py
  compiler-rt/test/scudo/lit.site.cfg.py.in
  compiler-rt/test/scudo/malloc.cpp
  compiler-rt/test/scudo/memalign.c
  compiler-rt/test/scudo/mismatch.cpp
  compiler-rt/test/scudo/options.cpp
  compiler-rt/test/scudo/overflow.c
  compiler-rt/test/scudo/preinit.c
  compiler-rt/test/scudo/preload.cpp
  compiler-rt/test/scudo/quarantine.c
  compiler-rt/test/scudo/random_shuffle.cpp
  compiler-rt/test/scudo/realloc.cpp
  compiler-rt/test/scudo/rss.c
  compiler-rt/test/scudo/secondary.c
  compiler-rt/test/scudo/sized-delete.cpp
  compiler-rt/test/scudo/sizes.cpp
  compiler-rt/test/scudo/standalone/CMakeLists.txt
  compiler-rt/test/scudo/standalone/aligned-new.cpp
  compiler-rt/test/scudo/standalone/alignment.c
  compiler-rt/test/scudo/standalone/dealloc-race.c
  compiler-rt/test/scudo/standalone/double-free.cpp
  compiler-rt/test/scudo/standalone/fsanitize.c
  compiler-rt/test/scudo/standalone/lit-unmigrated/overflow.c
  compiler-rt/test/scudo/standalone/lit-unmigrated/quarantine.c
  compiler-rt/test/scudo/standalone/lit-unmigrated/realloc.cpp
  compiler-rt/test/scudo/standalone/lit-unmigrated/rss.c
  compiler-rt/test/scudo/standalone/lit-unmigrated/secondary.c
  compiler-rt/test/scudo/standalone/lit-unmigrated/sizes.cpp
  compiler-rt/test/scudo/standalone/lit-unmigrated/threads.c
  compiler-rt/test/scudo/standalone/lit-unmigrated/valloc.c
  compiler-rt/test/scudo/standalone/lit.cfg.py
  compiler-rt/test/scudo/standalone/lit.site.cfg.py.in
  compiler-rt/test/scudo/standalone/malloc.cpp
  compiler-rt/test/scudo/standalone/memalign.c
  compiler-rt/test/scudo/standalone/mismatch.cpp
  compiler-rt/test/scudo/standalone/options.cpp
  compiler-rt/test/scudo/standalone/preinit.c
  compiler-rt/test/scudo/standalone/preload.cpp
  compiler-rt/test/scudo/standalone/random_shuffle.cpp
  compiler-rt/test/scudo/standalone/sized-delete.cpp
  compiler-rt/test/scudo/standalone/stats.c
  compiler-rt/test/scudo/standalone/tsd_destruction.c
  compiler-rt/test/scudo/stats.c
  compiler-rt/test/scudo/symbols.test
  compiler-rt/test/scudo/threads.c
  compiler-rt/test/scudo/tsd_destruction.c
  compiler-rt/test/scudo/valloc.c

Index: compiler-rt/test/scudo/symbols.test
===================================================================
--- compiler-rt/test/scudo/symbols.test
+++ /dev/null
@@ -1,8 +0,0 @@
-UNSUPPORTED: android
-
-Verify that various functions are *not* present in the minimal binary. Presence
-of those symbols in the minimal runtime would mean that the split code made it
-back into the core Sanitizer runtime library.
-
-RUN: nm %shared_minlibscudo | not grep Symbolizer
-RUN: nm %shared_minlibscudo | not grep Coverage
Index: compiler-rt/test/scudo/tsd_destruction.c
===================================================================
--- /dev/null
+++ compiler-rt/test/scudo/tsd_destruction.c
@@ -1,43 +0,0 @@
-// RUN: %clang_scudo %s -o %t
-// RUN: %run %t 2>&1
-
-#include <locale.h>
-#include <pthread.h>
-#include <stdint.h>
-#include <stdlib.h>
-#include <string.h>
-
-// Some of glibc's own thread local data is destroyed after a user's thread
-// local destructors are called, via __libc_thread_freeres. This might involve
-// calling free, as is the case for strerror_thread_freeres.
-// If there is no prior heap operation in the thread, this free would end up
-// initializing some thread specific data that would never be destroyed
-// properly, while still being deallocated when the TLS goes away. As a result,
-// a program could SEGV, usually in
-// __sanitizer::AllocatorGlobalStats::Unregister, where one of the doubly
-// linked list links would refer to a now unmapped memory area.
-
-// This test reproduces those circumstances. Success means executing without
-// a segmentation fault.
-
-const int kNumThreads = 16;
-pthread_t tid[kNumThreads];
-
-void *thread_func(void *arg) {
-  uintptr_t i = (uintptr_t)arg;
-  if ((i & 1) == 0)
-    free(malloc(16));
-  // Calling strerror_l allows for strerror_thread_freeres to be called.
-  strerror_l(0, LC_GLOBAL_LOCALE);
-  return 0;
-}
-
-int main(int argc, char **argv) {
-  for (uintptr_t j = 0; j < 8; j++) {
-    for (uintptr_t i = 0; i < kNumThreads; i++)
-      pthread_create(&tid[i], 0, thread_func, (void *)i);
-    for (uintptr_t i = 0; i < kNumThreads; i++)
-      pthread_join(tid[i], 0);
-  }
-  return 0;
-}
Index: compiler-rt/test/scudo/standalone/stats.c
===================================================================
--- compiler-rt/test/scudo/standalone/stats.c
+++ compiler-rt/test/scudo/standalone/stats.c
@@ -9,7 +9,7 @@
 
 #include <stdlib.h>
 
-#include <sanitizer/scudo_interface.h>
+void __scudo_print_stats();
 
 int main(int argc, char **argv) {
   free(malloc(1U));
Index: compiler-rt/test/scudo/standalone/sized-delete.cpp
===================================================================
--- compiler-rt/test/scudo/standalone/sized-delete.cpp
+++ compiler-rt/test/scudo/standalone/sized-delete.cpp
@@ -1,10 +1,10 @@
 // RUN: %clangxx_scudo -fsized-deallocation %s -o %t
-// RUN: %env_scudo_opts=DeleteSizeMismatch=1     %run %t gooddel    2>&1
-// RUN: %env_scudo_opts=DeleteSizeMismatch=1 not %run %t baddel     2>&1 | FileCheck %s
-// RUN: %env_scudo_opts=DeleteSizeMismatch=0     %run %t baddel     2>&1
-// RUN: %env_scudo_opts=DeleteSizeMismatch=1     %run %t gooddelarr 2>&1
-// RUN: %env_scudo_opts=DeleteSizeMismatch=1 not %run %t baddelarr  2>&1 | FileCheck %s
-// RUN: %env_scudo_opts=DeleteSizeMismatch=0     %run %t baddelarr  2>&1
+// RUN: %env_scudo_opts=delete_size_mismatch=1             %run %t gooddel    2>&1
+// RUN: %env_scudo_opts=delete_size_mismatch=1 not --crash %run %t baddel     2>&1 | FileCheck %s
+// RUN: %env_scudo_opts=delete_size_mismatch=0             %run %t baddel     2>&1
+// RUN: %env_scudo_opts=delete_size_mismatch=1             %run %t gooddelarr 2>&1
+// RUN: %env_scudo_opts=delete_size_mismatch=1 not --crash %run %t baddelarr  2>&1 | FileCheck %s
+// RUN: %env_scudo_opts=delete_size_mismatch=0             %run %t baddelarr  2>&1
 
 // Ensures that the sized delete operator errors out when the appropriate
 // option is passed and the sizes do not match between allocation and
Index: compiler-rt/test/scudo/random_shuffle.cpp
===================================================================
--- /dev/null
+++ compiler-rt/test/scudo/random_shuffle.cpp
@@ -1,23 +0,0 @@
-// RUN: %clangxx_scudo %s -o %t
-// RUN: rm -rf %t-dir/random_shuffle_tmp_dir
-// RUN: mkdir -p %t-dir/random_shuffle_tmp_dir
-// RUN: %run %t 100 > %t-dir/random_shuffle_tmp_dir/out1
-// RUN: %run %t 100 > %t-dir/random_shuffle_tmp_dir/out2
-// RUN: %run %t 10000 > %t-dir/random_shuffle_tmp_dir/out1
-// RUN: %run %t 10000 > %t-dir/random_shuffle_tmp_dir/out2
-// RUN: not diff %t-dir/random_shuffle_tmp_dir/out?
-// RUN: rm -rf %t-dir/random_shuffle_tmp_dir
-
-// Tests that the allocator shuffles the chunks before returning to the user.
-
-#include <stdio.h>
-#include <stdlib.h>
-
-int main(int argc, char **argv) {
-  int alloc_size = argc == 2 ? atoi(argv[1]) : 100;
-  char *base = new char[alloc_size];
-  for (int i = 0; i < 20; i++) {
-    char *p = new char[alloc_size];
-    printf("%zd\n", base - p);
-  }
-}
Index: compiler-rt/test/scudo/standalone/preload.cpp
===================================================================
--- compiler-rt/test/scudo/standalone/preload.cpp
+++ compiler-rt/test/scudo/standalone/preload.cpp
@@ -1,8 +1,7 @@
 // Test that the preloaded runtime works without linking the static library.
 
 // RUN: %clang %s -lstdc++ -o %t
-// RUN: env LD_PRELOAD=%shared_libscudo    not %run %t 2>&1 | FileCheck %s
-// RUN: env LD_PRELOAD=%shared_minlibscudo not %run %t 2>&1 | FileCheck %s
+// RUN: env LD_PRELOAD=%shared_libscudo    not --crash %run %t 2>&1 | FileCheck %s
 
 // This way of setting LD_PRELOAD does not work with Android test runner.
 // REQUIRES: !android
Index: compiler-rt/test/scudo/preinit.c
===================================================================
--- /dev/null
+++ compiler-rt/test/scudo/preinit.c
@@ -1,37 +0,0 @@
-// RUN: %clang_scudo %s -o %t
-// RUN: %run %t 2>&1
-
-// Verifies that calling malloc in a preinit_array function succeeds, and that
-// the resulting pointer can be freed at program termination.
-
-// On some Android versions, calling mmap() from a preinit function segfaults.
-// It looks like __mmap2.S ends up calling a NULL function pointer.
-// UNSUPPORTED: android
-
-#include <assert.h>
-#include <stdlib.h>
-#include <string.h>
-
-static void *global_p = NULL;
-
-void __init(void) {
-  global_p = malloc(1);
-  if (!global_p)
-    exit(1);
-}
-
-void __fini(void) {
-  if (global_p)
-    free(global_p);
-}
-
-int main(int argc, char **argv) {
-  void *p = malloc(1);
-  assert(p);
-  free(p);
-
-  return 0;
-}
-
-__attribute__((section(".preinit_array"), used)) void (*__local_preinit)(void) = __init;
-__attribute__((section(".fini_array"), used)) void (*__local_fini)(void) = __fini;
Index: compiler-rt/test/scudo/standalone/options.cpp
===================================================================
--- compiler-rt/test/scudo/standalone/options.cpp
+++ compiler-rt/test/scudo/standalone/options.cpp
@@ -1,7 +1,7 @@
 // RUN: %clangxx_scudo %s -o %t
-// RUN:                                                %run %t 2>&1
-// RUN: %env_scudo_opts=DeallocationTypeMismatch=0     %run %t 2>&1
-// RUN: %env_scudo_opts=DeallocationTypeMismatch=1 not %run %t 2>&1 | FileCheck %s
+// RUN:                                         not --crash %run %t 2>&1 | FileCheck %s
+// RUN: %env_scudo_opts=dealloc_type_mismatch=0             %run %t 2>&1
+// RUN: %env_scudo_opts=dealloc_type_mismatch=1 not --crash %run %t 2>&1 | FileCheck %s
 
 // Tests that the options can be passed using getScudoDefaultOptions, and that
 // the environment ones take precedence over them.
@@ -11,7 +11,7 @@
 #include <stdlib.h>
 
 extern "C" const char *__scudo_default_options() {
-  return "DeallocationTypeMismatch=0"; // Defaults to true in scudo_flags.inc.
+  return "dealloc_type_mismatch=1"; // Defaults to false in flags.inc.
 }
 
 int main(int argc, char **argv) {
Index: compiler-rt/test/scudo/standalone/mismatch.cpp
===================================================================
--- compiler-rt/test/scudo/standalone/mismatch.cpp
+++ compiler-rt/test/scudo/standalone/mismatch.cpp
@@ -1,8 +1,8 @@
 // RUN: %clangxx_scudo %s -o %t
-// RUN: %env_scudo_opts=DeallocationTypeMismatch=1 not %run %t mallocdel 2>&1 | FileCheck --check-prefix=CHECK-dealloc %s
-// RUN: %env_scudo_opts=DeallocationTypeMismatch=0     %run %t mallocdel 2>&1
-// RUN: %env_scudo_opts=DeallocationTypeMismatch=1 not %run %t newfree   2>&1 | FileCheck --check-prefix=CHECK-dealloc %s
-// RUN: %env_scudo_opts=DeallocationTypeMismatch=0     %run %t newfree   2>&1
+// RUN: %env_scudo_opts=dealloc_type_mismatch=1 not --crash %run %t mallocdel 2>&1 | FileCheck --check-prefix=CHECK-dealloc %s
+// RUN: %env_scudo_opts=dealloc_type_mismatch=0             %run %t mallocdel 2>&1
+// RUN: %env_scudo_opts=dealloc_type_mismatch=1 not --crash %run %t newfree   2>&1 | FileCheck --check-prefix=CHECK-dealloc %s
+// RUN: %env_scudo_opts=dealloc_type_mismatch=0             %run %t newfree   2>&1
 
 // Tests that type mismatches between allocation and deallocation functions are
 // caught when the related option is set.
Index: compiler-rt/test/scudo/standalone/memalign.c
===================================================================
--- compiler-rt/test/scudo/standalone/memalign.c
+++ compiler-rt/test/scudo/standalone/memalign.c
@@ -1,10 +1,10 @@
 // RUN: %clang_scudo %s -o %t
-// RUN:                                                 %run %t valid       2>&1
-// RUN:                                             not %run %t invalid     2>&1 | FileCheck --check-prefix=CHECK-align %s
-// RUN: %env_scudo_opts=allocator_may_return_null=1     %run %t invalid     2>&1
-// RUN:                                             not %run %t double-free 2>&1 | FileCheck --check-prefix=CHECK-double-free %s
-// RUN: %env_scudo_opts=DeallocationTypeMismatch=1  not %run %t realloc     2>&1 | FileCheck --check-prefix=CHECK-realloc %s
-// RUN: %env_scudo_opts=DeallocationTypeMismatch=0      %run %t realloc     2>&1
+// RUN:                                         %run %t valid       2>&1
+// RUN: %env_scudo_opts=may_return_null=0       not --crash %run %t invalid     2>&1 | FileCheck --check-prefix=CHECK-align %s
+// RUN: %env_scudo_opts=may_return_null=1       %run %t invalid     2>&1
+// RUN:                                         not --crash %run %t double-free 2>&1 | FileCheck --check-prefix=CHECK-double-free %s
+// RUN: %env_scudo_opts=dealloc_type_mismatch=1 not --crash %run %t realloc     2>&1 | FileCheck --check-prefix=CHECK-realloc %s
+// RUN: %env_scudo_opts=dealloc_type_mismatch=0 %run %t realloc     2>&1
 
 // Tests that the various aligned allocation functions work as intended. Also
 // tests for the condition where the alignment is not a power of 2.
Index: compiler-rt/test/scudo/malloc.cpp
===================================================================
--- /dev/null
+++ compiler-rt/test/scudo/malloc.cpp
@@ -1,36 +0,0 @@
-// RUN: %clangxx_scudo %s -lstdc++ -o %t
-// RUN: %run %t 2>&1
-
-// Tests that a regular workflow of allocation, memory fill and free works as
-// intended. Tests various sizes serviced by the primary and secondary
-// allocators.
-
-#include <assert.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <vector>
-
-int main(int argc, char **argv) {
-  void *p;
-  std::vector<ssize_t> sizes{1, 8, 16, 32, 1024, 32768,
-                             1 << 16, 1 << 17, 1 << 20, 1 << 24};
-  std::vector<int> offsets{1, 0, -1, -7, -8, -15, -16, -31, -32};
-
-  p = malloc(0);
-  assert(p);
-  free(p);
-  for (ssize_t size : sizes) {
-    for (int offset : offsets) {
-      ssize_t actual_size = size + offset;
-      if (actual_size <= 0)
-        continue;
-      p = malloc(actual_size);
-      assert(p);
-      memset(p, 0xff, actual_size);
-      free(p);
-    }
-  }
-
-  return 0;
-}
Index: compiler-rt/test/scudo/standalone/lit.site.cfg.py.in
===================================================================
--- /dev/null
+++ compiler-rt/test/scudo/standalone/lit.site.cfg.py.in
@@ -0,0 +1,12 @@
+@LIT_SITE_CFG_IN_HEADER@
+
+config.name_suffix = "@SCUDO_STANDALONE_TEST_CONFIG_SUFFIX@"
+config.target_arch = "@SCUDO_STANDALONE_TEST_TARGET_ARCH@"
+config.target_cflags = "@SCUDO_STANDALONE_TEST_TARGET_CFLAGS@"
+config.test_suite_supports_overriding_runtime_lib_path = True
+
+# Load common config for all compiler-rt lit tests.
+lit_config.load_config(config, "@COMPILER_RT_BINARY_DIR@/test/lit.common.configured")
+
+# Load tool-specific config that would do the real work.
+lit_config.load_config(config, "@SCUDO_STANDALONE_LIT_SOURCE_DIR@/lit.cfg.py")
Index: compiler-rt/test/scudo/standalone/lit.cfg.py
===================================================================
--- /dev/null
+++ compiler-rt/test/scudo/standalone/lit.cfg.py
@@ -0,0 +1,49 @@
+# -*- Python -*-
+
+import os
+
+# Setup config name.
+config.name = 'ScudoStandalone' + config.name_suffix
+
+# Setup source root.
+config.test_source_root = os.path.dirname(__file__)
+
+# Path to the shared library
+shared_libscudo = os.path.join(config.compiler_rt_libdir,
+    "libclang_rt.scudo_standalone%s.so" % config.target_suffix)
+
+# Test suffixes.
+config.suffixes = ['.c', '.cpp']
+config.excludes = ['lit-unmigrated']
+
+# C & CXX flags. For cross-compiling, make sure that we pick up the
+# libclang_rt.scudo_standalone libraries from the working build directory (using
+# `-resource-dir`), rather than the host compiler.
+c_flags = ([config.target_cflags] +
+           ["-pthread", "-fPIE", "-pie", "-O0", "-UNDEBUG", "-Wl,--gc-sections",
+            "-resource-dir=" + config.compiler_rt_libdir + "/../../"])
+
+cxx_flags = (c_flags + config.cxx_mode_flags + ["-std=c++14"])
+
+scudo_flags = ["-fsanitize=scudo"]
+
+def build_invocation(compile_flags):
+  return " " + " ".join([config.clang] + compile_flags) + " "
+
+# Add substitutions.
+config.substitutions.append(("%clang ", build_invocation(c_flags)))
+config.substitutions.append(("%clang_scudo ", build_invocation(c_flags + scudo_flags)))
+config.substitutions.append(("%clangxx_scudo ", build_invocation(cxx_flags + scudo_flags)))
+config.substitutions.append(("%shared_libscudo", shared_libscudo))
+
+# Disable GWP-ASan for scudo internal tests.
+default_scudo_opts = ''
+if config.gwp_asan:
+  default_scudo_opts += 'GWP_ASAN_Enabled=false:'
+
+config.substitutions.append(('%env_scudo_opts=',
+                             'env SCUDO_OPTIONS=' + default_scudo_opts))
+
+# Hardened Allocator tests are currently supported on Linux only.
+if config.host_os not in ['Linux']:
+   config.unsupported = True
Index: compiler-rt/test/scudo/standalone/lit-unmigrated/valloc.c
===================================================================
--- compiler-rt/test/scudo/standalone/lit-unmigrated/valloc.c
+++ compiler-rt/test/scudo/standalone/lit-unmigrated/valloc.c
@@ -1,7 +1,7 @@
 // RUN: %clang_scudo %s -o %t
-// RUN:                                                 %run %t valid   2>&1
-// RUN:                                             not %run %t invalid 2>&1 | FileCheck %s
-// RUN: %env_scudo_opts=allocator_may_return_null=1     %run %t invalid 2>&1
+// RUN:                                       %run %t valid   2>&1
+// RUN:                                       not --crash %run %t invalid 2>&1 | FileCheck %s
+// RUNX: %env_scudo_opts=may_return_null=1     %run %t invalid 2>&1
 // UNSUPPORTED: android
 
 // Tests that valloc and pvalloc work as intended.
Index: compiler-rt/test/scudo/threads.c
===================================================================
--- /dev/null
+++ compiler-rt/test/scudo/threads.c
@@ -1,69 +0,0 @@
-// RUN: %clang_scudo %s -o %t
-// RUN: %env_scudo_opts="QuarantineSizeKb=0:ThreadLocalQuarantineSizeKb=0"     %run %t 5 1000000 2>&1
-// RUN: %env_scudo_opts="QuarantineSizeKb=1024:ThreadLocalQuarantineSizeKb=64" %run %t 5 1000000 2>&1
-
-// Tests parallel allocations and deallocations of memory chunks from a number
-// of concurrent threads, with and without quarantine.
-// This test passes if everything executes properly without crashing.
-
-#include <assert.h>
-#include <pthread.h>
-#include <stdio.h>
-#include <stdlib.h>
-
-#include <sanitizer/allocator_interface.h>
-
-int num_threads;
-int total_num_alloc;
-const int kMaxNumThreads = 500;
-pthread_t tid[kMaxNumThreads];
-
-pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
-pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
-char go = 0;
-
-void *thread_fun(void *arg) {
-  pthread_mutex_lock(&mutex);
-  while (!go)
-    pthread_cond_wait(&cond, &mutex);
-  pthread_mutex_unlock(&mutex);
-  for (int i = 0; i < total_num_alloc / num_threads; i++) {
-    void *p = malloc(10);
-    __asm__ __volatile__(""
-                         :
-                         : "r"(p)
-                         : "memory");
-    free(p);
-  }
-  return 0;
-}
-
-int main(int argc, char **argv) {
-  assert(argc == 3);
-  num_threads = atoi(argv[1]);
-  assert(num_threads > 0);
-  assert(num_threads <= kMaxNumThreads);
-  total_num_alloc = atoi(argv[2]);
-  assert(total_num_alloc > 0);
-
-  printf("%d threads, %d allocations in each\n", num_threads,
-         total_num_alloc / num_threads);
-  fprintf(stderr, "Heap size before: %zd\n", __sanitizer_get_heap_size());
-  fprintf(stderr, "Allocated bytes before: %zd\n",
-          __sanitizer_get_current_allocated_bytes());
-
-  for (int i = 0; i < num_threads; i++)
-    pthread_create(&tid[i], 0, thread_fun, 0);
-  pthread_mutex_lock(&mutex);
-  go = 1;
-  pthread_cond_broadcast(&cond);
-  pthread_mutex_unlock(&mutex);
-  for (int i = 0; i < num_threads; i++)
-    pthread_join(tid[i], 0);
-
-  fprintf(stderr, "Heap size after: %zd\n", __sanitizer_get_heap_size());
-  fprintf(stderr, "Allocated bytes after: %zd\n",
-          __sanitizer_get_current_allocated_bytes());
-
-  return 0;
-}
Index: compiler-rt/test/scudo/standalone/lit-unmigrated/sizes.cpp
===================================================================
--- compiler-rt/test/scudo/standalone/lit-unmigrated/sizes.cpp
+++ compiler-rt/test/scudo/standalone/lit-unmigrated/sizes.cpp
@@ -1,13 +1,13 @@
 // RUN: %clangxx_scudo %s -lstdc++ -o %t
-// RUN: %env_scudo_opts=allocator_may_return_null=0 not %run %t malloc 2>&1      | FileCheck %s --check-prefix=CHECK-max
-// RUN: %env_scudo_opts=allocator_may_return_null=1     %run %t malloc 2>&1
-// RUN: %env_scudo_opts=allocator_may_return_null=0 not %run %t calloc 2>&1      | FileCheck %s --check-prefix=CHECK-calloc
-// RUN: %env_scudo_opts=allocator_may_return_null=1     %run %t calloc 2>&1
-// RUN: %env_scudo_opts=allocator_may_return_null=0 not %run %t new 2>&1         | FileCheck %s --check-prefix=CHECK-max
-// RUN: %env_scudo_opts=allocator_may_return_null=1 not %run %t new 2>&1         | FileCheck %s --check-prefix=CHECK-oom
-// RUN: %env_scudo_opts=allocator_may_return_null=0 not %run %t new-nothrow 2>&1 | FileCheck %s --check-prefix=CHECK-max
-// RUN: %env_scudo_opts=allocator_may_return_null=1     %run %t new-nothrow 2>&1
-// RUN:                                                 %run %t usable 2>&1
+// RUN: %env_scudo_opts=may_return_null=0 not --crash %run %t malloc 2>&1      | FileCheck %s --check-prefix=CHECK-max
+// RUN: %env_scudo_opts=may_return_null=1             %run %t malloc 2>&1
+// RUNZ: %env_scudo_opts=may_return_null=0 not --crash %run %t calloc 2>&1      | FileCheck %s --check-prefix=CHECK-calloc
+// RUNZ: %env_scudo_opts=may_return_null=1             %run %t calloc 2>&1
+// RUNZ: %env_scudo_opts=may_return_null=0 not --crash %run %t new 2>&1         | FileCheck %s --check-prefix=CHECK-max
+// RUNZ: %env_scudo_opts=may_return_null=1 not --crash %run %t new 2>&1         | FileCheck %s --check-prefix=CHECK-oom
+// RUNZ: %env_scudo_opts=may_return_null=0 not --crash %run %t new-nothrow 2>&1 | FileCheck %s --check-prefix=CHECK-max
+// RUNZ: %env_scudo_opts=may_return_null=1             %run %t new-nothrow 2>&1
+// RUNZ:                                               %run %t usable 2>&1
 
 // Tests for various edge cases related to sizes, notably the maximum size the
 // allocator can allocate. Tests that an integer overflow in the parameters of
@@ -54,12 +54,12 @@
     // Playing with the actual usable size of a chunk.
     void *p = malloc(1007);
     assert(p);
-    size_t size = __sanitizer_get_allocated_size(p);
+    size_t size = malloc_usable_size(p);
     assert(size >= 1007);
     memset(p, 'A', size);
     p = realloc(p, 2014);
     assert(p);
-    size = __sanitizer_get_allocated_size(p);
+    size = malloc_usable_size(p);
     assert(size >= 2014);
     memset(p, 'B', size);
     free(p);
Index: compiler-rt/test/scudo/secondary.c
===================================================================
--- /dev/null
+++ compiler-rt/test/scudo/secondary.c
@@ -1,52 +0,0 @@
-// RUN: %clang_scudo %s -o %t
-// RUN: %run %t after  2>&1 | FileCheck %s
-// RUN: %run %t before 2>&1 | FileCheck %s
-
-// Test that we hit a guard page when writing past the end of a chunk
-// allocated by the Secondary allocator, or writing too far in front of it.
-
-#include <assert.h>
-#include <malloc.h>
-#include <signal.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-void handler(int signo, siginfo_t *info, void *uctx) {
-  if (info->si_code == SEGV_ACCERR) {
-    fprintf(stderr, "SCUDO SIGSEGV\n");
-    exit(0);
-  }
-  exit(1);
-}
-
-int main(int argc, char **argv) {
-  // The size must be large enough to be serviced by the secondary allocator.
-  long page_size = sysconf(_SC_PAGESIZE);
-  size_t size = (1U << 17) + page_size;
-  struct sigaction a;
-
-  assert(argc == 2);
-  memset(&a, 0, sizeof(a));
-  a.sa_sigaction = handler;
-  a.sa_flags = SA_SIGINFO;
-
-  char *p = (char *)malloc(size);
-  assert(p);
-  memset(p, 'A', size); // This should not trigger anything.
-  // Set up the SIGSEGV handler now, as the rest should trigger an AV.
-  sigaction(SIGSEGV, &a, NULL);
-  if (!strcmp(argv[1], "after")) {
-    for (int i = 0; i < page_size; i++)
-      p[size + i] = 'A';
-  }
-  if (!strcmp(argv[1], "before")) {
-    for (int i = 1; i < page_size; i++)
-      p[-i] = 'A';
-  }
-  free(p);
-
-  return 1; // A successful test means we shouldn't reach this.
-}
-
-// CHECK: SCUDO SIGSEGV
Index: compiler-rt/test/scudo/rss.c
===================================================================
--- /dev/null
+++ compiler-rt/test/scudo/rss.c
@@ -1,57 +0,0 @@
-// RUN: %clang_scudo %s -o %t
-// RUN:                                                                                                  %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-nolimit
-// RUN: %env_scudo_opts="soft_rss_limit_mb=128"                                                          %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-nolimit
-// RUN: %env_scudo_opts="hard_rss_limit_mb=128"                                                          %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-nolimit
-// RUN: %env_scudo_opts="soft_rss_limit_mb=32:allocator_may_return_null=0"                           not %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-softlimit
-// RUN: %env_scudo_opts="soft_rss_limit_mb=32:allocator_may_return_null=1"                               %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-softlimit-returnnull
-// RUN: %env_scudo_opts="soft_rss_limit_mb=32:allocator_may_return_null=0:can_use_proc_maps_statm=0" not %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-softlimit
-// RUN: %env_scudo_opts="soft_rss_limit_mb=32:allocator_may_return_null=1:can_use_proc_maps_statm=0"     %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-softlimit-returnnull
-// RUN: %env_scudo_opts="hard_rss_limit_mb=32:allocator_may_return_null=0"                           not %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-hardlimit
-// RUN: %env_scudo_opts="hard_rss_limit_mb=32:allocator_may_return_null=1"                           not %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-hardlimit
-// RUN: %env_scudo_opts="hard_rss_limit_mb=32:allocator_may_return_null=0:can_use_proc_maps_statm=0" not %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-hardlimit
-// RUN: %env_scudo_opts="hard_rss_limit_mb=32:allocator_may_return_null=1:can_use_proc_maps_statm=0" not %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-hardlimit
-
-// Tests that the soft and hard RSS limits work as intended. Without limit or
-// with a high limit, the test should pass without any malloc returning NULL or
-// the program dying.
-// If a limit is specified, it should return some NULL or die depending on
-// allocator_may_return_null. This should also work without statm.
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-static const size_t kNumAllocs = 64;
-static const size_t kAllocSize = 1 << 20; // 1MB.
-
-static void *allocs[kNumAllocs];
-
-int main(int argc, char *argv[]) {
-  int returned_null = 0;
-  for (int i = 0; i < kNumAllocs; i++) {
-    // sleep for 100ms every 8 allocations, to allow the RSS check to catch up.
-    if (i != 0 && (i & 0x7) == 0)
-      usleep(100000);
-    allocs[i] = malloc(kAllocSize);
-    if (allocs[i])
-      memset(allocs[i], 0xff, kAllocSize); // Dirty the pages.
-    else
-      returned_null++;
-  }
-  for (int i = 0; i < kNumAllocs; i++)
-    free(allocs[i]);
-  if (returned_null == 0)
-    printf("All malloc calls succeeded\n");
-  else
-    printf("%d malloc calls returned NULL\n", returned_null);
-  return 0;
-}
-
-// CHECK-nolimit: All malloc calls succeeded
-// CHECK-softlimit: soft RSS limit exhausted
-// CHECK-softlimit-NOT: malloc calls
-// CHECK-softlimit-returnnull: soft RSS limit exhausted
-// CHECK-softlimit-returnnull: malloc calls returned NULL
-// CHECK-hardlimit: hard RSS limit exhausted
-// CHECK-hardlimit-NOT: malloc calls
Index: compiler-rt/test/scudo/standalone/lit-unmigrated/realloc.cpp
===================================================================
--- compiler-rt/test/scudo/standalone/lit-unmigrated/realloc.cpp
+++ compiler-rt/test/scudo/standalone/lit-unmigrated/realloc.cpp
@@ -37,7 +37,7 @@
         free(p);
       size += 16;
       p = malloc(size);
-      usable_size = __sanitizer_get_allocated_size(p);
+      usable_size = malloc_usable_size(p);
       assert(usable_size >= size);
     } while (usable_size == size);
     for (int i = 0; i < usable_size; i++)
@@ -58,7 +58,7 @@
       if (!strcmp(argv[1], "pointers")) {
         old_p = p = realloc(nullptr, size);
         assert(p);
-        size = __sanitizer_get_allocated_size(p);
+        size = malloc_usable_size(p);
         // Our realloc implementation will return the same pointer if the size
         // requested is lower than or equal to the usable size of the associated
         // chunk.
Index: compiler-rt/test/scudo/quarantine.c
===================================================================
--- /dev/null
+++ compiler-rt/test/scudo/quarantine.c
@@ -1,123 +0,0 @@
-// RUN: %clang_scudo %s -o %t
-// RUN: %env_scudo_opts="QuarantineSizeMb=1:QuarantineSizeKb=64"           not %run %t unused 2>&1
-// RUN: %env_scudo_opts="QuarantineSizeMb=1:QuarantineChunksUpToSize=256"  not %run %t unused 2>&1
-// RUN: %env_scudo_opts="QuarantineSizeKb=0:ThreadLocalQuarantineSizeKb=0"     %run %t zeroquarantine 2>&1
-// RUN: %env_scudo_opts=QuarantineSizeKb=64                                    %run %t smallquarantine 2>&1
-// RUN: %env_scudo_opts=QuarantineChunksUpToSize=256                           %run %t threshold 2>&1
-// RUN: %env_scudo_opts="QuarantineSizeMb=1"                                   %run %t oldquarantine 2>&1
-
-// Tests that the quarantine prevents a chunk from being reused right away.
-// Also tests that a chunk will eventually become available again for
-// allocation when the recycling criteria has been met. Finally, tests the
-// threshold up to which a chunk is quarantine, and the old quarantine behavior.
-
-#include <assert.h>
-#include <malloc.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <sanitizer/allocator_interface.h>
-
-int main(int argc, char **argv) {
-  void *p, *old_p;
-  size_t allocated_bytes, size = 1U << 8, alignment = 1U << 8;
-
-  assert(argc == 2);
-  // First, warm up the allocator for the classes used.
-  p = malloc(size);
-  assert(p);
-  free(p);
-  p = malloc(size + 1);
-  assert(p);
-  free(p);
-  assert(posix_memalign(&p, alignment, size) == 0);
-  assert(p);
-  free(p);
-  assert(posix_memalign(&p, alignment, size + 1) == 0);
-  assert(p);
-  free(p);
-
-  if (!strcmp(argv[1], "zeroquarantine")) {
-    // Verifies that a chunk is deallocated right away when the local and
-    // global quarantine sizes are 0.
-    allocated_bytes = __sanitizer_get_current_allocated_bytes();
-    p = malloc(size);
-    assert(p);
-    assert(__sanitizer_get_current_allocated_bytes() > allocated_bytes);
-    free(p);
-    assert(__sanitizer_get_current_allocated_bytes() == allocated_bytes);
-  }
-  if (!strcmp(argv[1], "smallquarantine")) {
-    // The delayed freelist will prevent a chunk from being available right
-    // away.
-    p = malloc(size);
-    assert(p);
-    old_p = p;
-    free(p);
-    p = malloc(size);
-    assert(p);
-    assert(old_p != p);
-    free(p);
-
-    // Eventually the chunk should become available again.
-    char found = 0;
-    for (int i = 0; i < 0x200 && !found; i++) {
-      p = malloc(size);
-      assert(p);
-      found = (p == old_p);
-      free(p);
-    }
-    assert(found);
-  }
-  if (!strcmp(argv[1], "threshold")) {
-    // Verifies that a chunk of size greater than the threshold will be freed
-    // right away. Alignment has no impact on the threshold.
-    allocated_bytes = __sanitizer_get_current_allocated_bytes();
-    p = malloc(size + 1);
-    assert(p);
-    assert(__sanitizer_get_current_allocated_bytes() > allocated_bytes);
-    free(p);
-    assert(__sanitizer_get_current_allocated_bytes() == allocated_bytes);
-    assert(posix_memalign(&p, alignment, size + 1) == 0);
-    assert(__sanitizer_get_current_allocated_bytes() > allocated_bytes);
-    free(p);
-    assert(__sanitizer_get_current_allocated_bytes() == allocated_bytes);
-    // Verifies that a chunk of size lower or equal to the threshold will be
-    // quarantined.
-    p = malloc(size);
-    assert(p);
-    assert(__sanitizer_get_current_allocated_bytes() > allocated_bytes);
-    free(p);
-    assert(__sanitizer_get_current_allocated_bytes() > allocated_bytes);
-    allocated_bytes = __sanitizer_get_current_allocated_bytes();
-    assert(posix_memalign(&p, alignment, size) == 0);
-    assert(__sanitizer_get_current_allocated_bytes() > allocated_bytes);
-    free(p);
-    assert(__sanitizer_get_current_allocated_bytes() > allocated_bytes);
-  }
-  if (!strcmp(argv[1], "oldquarantine")) {
-    // Verifies that we quarantine everything if the deprecated quarantine
-    // option is specified. Alignment has no impact on the threshold.
-    allocated_bytes = __sanitizer_get_current_allocated_bytes();
-    p = malloc(size);
-    assert(p);
-    assert(__sanitizer_get_current_allocated_bytes() > allocated_bytes);
-    free(p);
-    assert(__sanitizer_get_current_allocated_bytes() > allocated_bytes);
-    allocated_bytes = __sanitizer_get_current_allocated_bytes();
-    assert(posix_memalign(&p, alignment, size) == 0);
-    assert(p);
-    assert(__sanitizer_get_current_allocated_bytes() > allocated_bytes);
-    free(p);
-    assert(__sanitizer_get_current_allocated_bytes() > allocated_bytes);
-    // Secondary backed allocation.
-    allocated_bytes = __sanitizer_get_current_allocated_bytes();
-    p = malloc(1U << 19);
-    assert(p);
-    assert(__sanitizer_get_current_allocated_bytes() > allocated_bytes);
-    free(p);
-    assert(__sanitizer_get_current_allocated_bytes() > allocated_bytes);
-  }
-
-  return 0;
-}
Index: compiler-rt/test/scudo/overflow.c
===================================================================
--- /dev/null
+++ compiler-rt/test/scudo/overflow.c
@@ -1,38 +0,0 @@
-// RUN: %clang_scudo %s -o %t
-// RUN:                                     not %run %t malloc     2>&1 | FileCheck %s
-// RUN: %env_scudo_opts=QuarantineSizeKb=64 not %run %t quarantine 2>&1 | FileCheck %s
-
-// Tests that header corruption of an allocated or quarantined chunk is caught.
-
-#include <assert.h>
-#include <stdlib.h>
-#include <string.h>
-
-int main(int argc, char **argv) {
-  ssize_t offset = sizeof(void *) == 8 ? 8 : 0;
-
-  assert(argc == 2);
-
-  if (!strcmp(argv[1], "malloc")) {
-    // Simulate a header corruption of an allocated chunk (1-bit)
-    void *p = malloc(1U << 4);
-    assert(p);
-    ((char *)p)[-(offset + 1)] ^= 1;
-    free(p);
-  }
-  if (!strcmp(argv[1], "quarantine")) {
-    void *p = malloc(1U << 4);
-    assert(p);
-    free(p);
-    // Simulate a header corruption of a quarantined chunk
-    ((char *)p)[-(offset + 2)] ^= 1;
-    // Trigger the quarantine recycle
-    for (int i = 0; i < 0x100; i++) {
-      p = malloc(1U << 8);
-      free(p);
-    }
-  }
-  return 0;
-}
-
-// CHECK: ERROR: corrupted chunk header at address
Index: compiler-rt/test/scudo/standalone/fsanitize.c
===================================================================
--- compiler-rt/test/scudo/standalone/fsanitize.c
+++ compiler-rt/test/scudo/standalone/fsanitize.c
@@ -1,17 +1,15 @@
 // Test various -fsanitize= additional flags combinations.
 
 // RUN: %clang_scudo %s -o %t
-// RUN: not %run %t 2>&1 | FileCheck %s
+// RUN: not --crash %run %t 2>&1 | FileCheck %s
 
 // RUN: %clang_scudo -shared-libsan %s -o %t
-// RUN: env LD_LIBRARY_PATH=`dirname %shared_libscudo`:$LD_LIBRARY_PATH not %run %t 2>&1 | FileCheck %s
-// RUN: %clang_scudo -shared-libsan -fsanitize-minimal-runtime %s -o %t
-// RUN: env LD_LIBRARY_PATH=`dirname %shared_minlibscudo`:$LD_LIBRARY_PATH not %run %t 2>&1 | FileCheck %s
+// RUN: env LD_LIBRARY_PATH=`dirname %shared_libscudo`:$LD_LIBRARY_PATH not --crash %run %t 2>&1 | FileCheck %s
 
 // RUN: %clang_scudo -static-libsan %s -o %t
-// RUN: not %run %t 2>&1 | FileCheck %s
+// RUN: not --crash %run %t 2>&1 | FileCheck %s
 // RUN: %clang_scudo -static-libsan -fsanitize-minimal-runtime %s -o %t
-// RUN: not %run %t 2>&1 | FileCheck %s
+// RUN: not --crash %run %t 2>&1 | FileCheck %s
 
 #include <assert.h>
 #include <stdlib.h>
Index: compiler-rt/test/scudo/standalone/double-free.cpp
===================================================================
--- compiler-rt/test/scudo/standalone/double-free.cpp
+++ compiler-rt/test/scudo/standalone/double-free.cpp
@@ -1,7 +1,7 @@
 // RUN: %clangxx_scudo %s -o %t
-// RUN: not %run %t malloc   2>&1 | FileCheck %s
-// RUN: not %run %t new      2>&1 | FileCheck %s
-// RUN: not %run %t newarray 2>&1 | FileCheck %s
+// RUN: not --crash %run %t malloc   2>&1 | FileCheck %s
+// RUN: not --crash %run %t new      2>&1 | FileCheck %s
+// RUN: not --crash %run %t newarray 2>&1 | FileCheck %s
 
 // Tests double-free error on pointers allocated with different allocation
 // functions.
Index: compiler-rt/test/scudo/standalone/dealloc-race.c
===================================================================
--- compiler-rt/test/scudo/standalone/dealloc-race.c
+++ compiler-rt/test/scudo/standalone/dealloc-race.c
@@ -1,12 +1,12 @@
 // RUN: %clang_scudo %s -O2 -o %t
 // RUN: %env_scudo_opts="QuarantineChunksUpToSize=0" %run %t 2>&1
 
-// This test attempts to reproduce a race condition in the deallocation path
-// when bypassing the Quarantine. The old behavior was to zero-out the chunk
-// header after checking its checksum, state & various other things, but that
-// left a window during which 2 (or more) threads could deallocate the same
-// chunk, with a net result of having said chunk present in those distinct
-// thread caches.
+// This test attempts to reproduce a race condition in the original Scudo in the
+// deallocation path when bypassing the Quarantine. The old behavior was to
+// zero-out the chunk header after checking its checksum, state & various other
+// things, but that left a window during which 2 (or more) threads could
+// deallocate the same chunk, with a net result of having said chunk present in
+// those distinct thread caches.
 
 // A passing test means all the children died with an error. The failing
 // scenario involves winning a race, so repro can be scarce.
Index: compiler-rt/test/scudo/standalone/alignment.c
===================================================================
--- compiler-rt/test/scudo/standalone/alignment.c
+++ compiler-rt/test/scudo/standalone/alignment.c
@@ -1,5 +1,5 @@
 // RUN: %clang_scudo %s -o %t
-// RUN: not %run %t pointers 2>&1 | FileCheck %s
+// RUN: not --crash %run %t pointers 2>&1 | FileCheck %s
 
 // Tests that a non MinAlignment aligned pointer will trigger the associated
 // error on deallocation.
Index: compiler-rt/test/scudo/standalone/aligned-new.cpp
===================================================================
--- compiler-rt/test/scudo/standalone/aligned-new.cpp
+++ compiler-rt/test/scudo/standalone/aligned-new.cpp
@@ -1,7 +1,7 @@
-// RUN: %clangxx_scudo -std=c++1z -faligned-allocation %s -o %t
+// RUN: %clangxx_scudo -std=c++17 -faligned-allocation %s -o %t
 // RUN:                                                 %run %t valid   2>&1
-// RUN: %env_scudo_opts=allocator_may_return_null=1     %run %t invalid 2>&1
-// RUN: %env_scudo_opts=allocator_may_return_null=0 not %run %t invalid 2>&1 | FileCheck %s
+// RUN: %env_scudo_opts=may_return_null=1     %run %t invalid 2>&1
+// RUN: %env_scudo_opts=may_return_null=0 not --crash %run %t invalid 2>&1 | FileCheck %s
 
 // Tests that the C++17 aligned new/delete operators are working as expected.
 // Currently we do not check the consistency of the alignment on deallocation,
Index: compiler-rt/test/scudo/standalone/CMakeLists.txt
===================================================================
--- compiler-rt/test/scudo/standalone/CMakeLists.txt
+++ compiler-rt/test/scudo/standalone/CMakeLists.txt
@@ -1,3 +1,21 @@
+set(SCUDO_STANDALONE_LIT_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR})
+set(SCUDO_STANDALONE_LIT_BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR})
+set(SCUDO_STANDALONE_TESTSUITES)
+set(SCUDO_STANDALONE_TEST_DEPS ${SANITIZER_COMMON_LIT_TEST_DEPS} scudo_standalone)
+
+foreach(arch ${SCUDO_STANDALONE_SUPPORTED_ARCH})
+  set(SCUDO_STANDALONE_TEST_TARGET_ARCH ${arch})
+  string(TOLOWER "-${arch}" SCUDO_STANDALONE_TEST_CONFIG_SUFFIX)
+  get_target_flags_for_arch(${arch} SCUDO_STANDALONE_TEST_TARGET_CFLAGS)
+  string(TOUPPER ${arch} ARCH_UPPER_CASE)
+  set(CONFIG_NAME ${ARCH_UPPER_CASE}${OS_NAME}Config)
+
+  configure_lit_site_cfg(
+    ${CMAKE_CURRENT_SOURCE_DIR}/lit.site.cfg.py.in
+    ${CMAKE_CURRENT_BINARY_DIR}/${CONFIG_NAME}/lit.site.cfg.py)
+  list(APPEND SCUDO_STANDALONE_TESTSUITES ${CMAKE_CURRENT_BINARY_DIR}/${CONFIG_NAME})
+endforeach()
+
 if(COMPILER_RT_INCLUDE_TESTS AND COMPILER_RT_HAS_SCUDO_STANDALONE)
   configure_lit_site_cfg(
     ${CMAKE_CURRENT_SOURCE_DIR}/unit/lit.site.cfg.py.in
Index: compiler-rt/test/scudo/lit.site.cfg.py.in
===================================================================
--- compiler-rt/test/scudo/lit.site.cfg.py.in
+++ /dev/null
@@ -1,11 +0,0 @@
-@LIT_SITE_CFG_IN_HEADER@
-
-config.name_suffix = "@SCUDO_TEST_CONFIG_SUFFIX@"
-config.target_arch = "@SCUDO_TEST_TARGET_ARCH@"
-config.target_cflags = "@SCUDO_TEST_TARGET_CFLAGS@"
-
-# Load common config for all compiler-rt lit tests.
-lit_config.load_config(config, "@COMPILER_RT_BINARY_DIR@/test/lit.common.configured")
-
-# Load tool-specific config that would do the real work.
-lit_config.load_config(config, "@SCUDO_LIT_SOURCE_DIR@/lit.cfg.py")
Index: compiler-rt/test/scudo/lit.cfg.py
===================================================================
--- compiler-rt/test/scudo/lit.cfg.py
+++ /dev/null
@@ -1,64 +0,0 @@
-# -*- Python -*-
-
-import os
-
-# Setup config name.
-config.name = 'Scudo' + config.name_suffix
-
-# Setup source root.
-config.test_source_root = os.path.dirname(__file__)
-
-# Path to the shared library
-shared_libscudo = os.path.join(config.compiler_rt_libdir, "libclang_rt.scudo%s.so" % config.target_suffix)
-shared_minlibscudo = os.path.join(config.compiler_rt_libdir, "libclang_rt.scudo_minimal%s.so" % config.target_suffix)
-
-# Test suffixes.
-config.suffixes = ['.c', '.cpp', '.test']
-
-# C & CXX flags.
-c_flags = ([config.target_cflags] +
-           ["-pthread",
-           "-fPIE",
-           "-pie",
-           "-O0",
-           "-UNDEBUG",
-           "-ldl",
-           "-Wl,--gc-sections"])
-
-# Android doesn't want -lrt.
-if not config.android:
-  c_flags += ["-lrt"]
-
-cxx_flags = (c_flags + config.cxx_mode_flags + ["-std=c++11"])
-
-scudo_flags = ["-fsanitize=scudo"]
-
-def build_invocation(compile_flags):
-  return " " + " ".join([config.clang] + compile_flags) + " "
-
-# Add substitutions.
-config.substitutions.append(("%clang ", build_invocation(c_flags)))
-config.substitutions.append(("%clang_scudo ", build_invocation(c_flags + scudo_flags)))
-config.substitutions.append(("%clangxx_scudo ", build_invocation(cxx_flags + scudo_flags)))
-config.substitutions.append(("%shared_libscudo", shared_libscudo))
-config.substitutions.append(("%shared_minlibscudo", shared_minlibscudo))
-
-# Platform-specific default SCUDO_OPTIONS for lit tests.
-default_scudo_opts = ''
-if config.android:
-  # Android defaults to abort_on_error=1, which doesn't work for us.
-  default_scudo_opts = 'abort_on_error=0'
-
-# Disable GWP-ASan for scudo internal tests.
-if config.gwp_asan:
-  config.environment['GWP_ASAN_OPTIONS'] = 'Enabled=0'
-
-if default_scudo_opts:
-  config.environment['SCUDO_OPTIONS'] = default_scudo_opts
-  default_scudo_opts += ':'
-config.substitutions.append(('%env_scudo_opts=',
-                             'env SCUDO_OPTIONS=' + default_scudo_opts))
-
-# Hardened Allocator tests are currently supported on Linux only.
-if config.host_os not in ['Linux']:
-   config.unsupported = True
Index: compiler-rt/test/scudo/interface.cpp
===================================================================
--- compiler-rt/test/scudo/interface.cpp
+++ /dev/null
@@ -1,91 +0,0 @@
-// RUN: %clangxx_scudo %s -lstdc++ -o %t
-// RUN:                                                   %run %t ownership          2>&1
-// RUN:                                                   %run %t ownership-and-size 2>&1
-// RUN:                                                   %run %t heap-size          2>&1
-// RUN: %env_scudo_opts="allocator_may_return_null=1"     %run %t soft-limit         2>&1
-// RUN: %env_scudo_opts="allocator_may_return_null=1" not %run %t hard-limit         2>&1
-
-// Tests that the sanitizer interface functions behave appropriately.
-
-#include <assert.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-#include <vector>
-
-#include <sanitizer/allocator_interface.h>
-#include <sanitizer/scudo_interface.h>
-
-int main(int argc, char **argv) {
-  assert(argc == 2);
-
-  if (!strcmp(argv[1], "ownership")) {
-    // Ensures that __sanitizer_get_ownership can be called before any other
-    // allocator function, and that it behaves properly on a pointer not owned
-    // by us.
-    assert(!__sanitizer_get_ownership(argv));
-  }
-  if (!strcmp(argv[1], "ownership-and-size")) {
-    // Tests that __sanitizer_get_ownership and __sanitizer_get_allocated_size
-    // behave properly on chunks allocated by the Primary and Secondary.
-    void *p;
-    std::vector<ssize_t> sizes{1, 8, 16, 32, 1024, 32768,
-                               1 << 16, 1 << 17, 1 << 20, 1 << 24};
-    for (size_t size : sizes) {
-      p = malloc(size);
-      assert(p);
-      assert(__sanitizer_get_ownership(p));
-      assert(__sanitizer_get_allocated_size(p) >= size);
-      free(p);
-    }
-  }
-  if (!strcmp(argv[1], "heap-size")) {
-    // Ensures that __sanitizer_get_heap_size can be called before any other
-    // allocator function.
-    assert(__sanitizer_get_heap_size() >= 0);
-  }
-  if (!strcmp(argv[1], "soft-limit")) {
-    // Verifies that setting the soft RSS limit at runtime works as expected.
-    std::vector<void *> pointers;
-    size_t size = 1 << 19; // 512Kb
-    for (int i = 0; i < 5; i++) {
-      void *p = malloc(size);
-      memset(p, 0, size);
-      pointers.push_back(p);
-    }
-    // Set the soft RSS limit to 1Mb.
-    __scudo_set_rss_limit(1, 0);
-    usleep(20000);
-    // The following allocation should return NULL.
-    void *p = malloc(size);
-    assert(!p);
-    // Remove the soft RSS limit.
-    __scudo_set_rss_limit(0, 0);
-    // The following allocation should succeed.
-    p = malloc(size);
-    assert(p);
-    free(p);
-    while (!pointers.empty()) {
-      free(pointers.back());
-      pointers.pop_back();
-    }
-  }
-  if (!strcmp(argv[1], "hard-limit")) {
-    // Verifies that setting the hard RSS limit at runtime works as expected.
-    std::vector<void *> pointers;
-    size_t size = 1 << 19; // 512Kb
-    for (int i = 0; i < 5; i++) {
-      void *p = malloc(size);
-      memset(p, 0, size);
-      pointers.push_back(p);
-    }
-    // Set the hard RSS limit to 1Mb
-    __scudo_set_rss_limit(1, 1);
-    usleep(20000);
-    // The following should trigger our death.
-    void *p = malloc(size);
-  }
-
-  return 0;
-}
Index: compiler-rt/test/scudo/CMakeLists.txt
===================================================================
--- compiler-rt/test/scudo/CMakeLists.txt
+++ compiler-rt/test/scudo/CMakeLists.txt
@@ -1,35 +1 @@
-set(SCUDO_LIT_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR})
-set(SCUDO_LIT_BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR})
-
-set(SCUDO_TESTSUITES)
-
-set(SCUDO_TEST_DEPS ${SANITIZER_COMMON_LIT_TEST_DEPS})
-if(NOT COMPILER_RT_STANDALONE_BUILD)
-  list(APPEND SCUDO_TEST_DEPS scudo)
-endif()
-
-configure_lit_site_cfg(
-  ${CMAKE_CURRENT_SOURCE_DIR}/lit.site.cfg.py.in
-  ${CMAKE_CURRENT_BINARY_DIR}/lit.site.cfg.py
-  )
-
-set(SCUDO_TEST_ARCH ${SCUDO_SUPPORTED_ARCH})
-foreach(arch ${SCUDO_TEST_ARCH})
-  set(SCUDO_TEST_TARGET_ARCH ${arch})
-  string(TOLOWER "-${arch}" SCUDO_TEST_CONFIG_SUFFIX)
-  get_test_cc_for_arch(${arch} SCUDO_TEST_TARGET_CC SCUDO_TEST_TARGET_CFLAGS)
-  string(TOUPPER ${arch} ARCH_UPPER_CASE)
-  set(CONFIG_NAME ${ARCH_UPPER_CASE}${OS_NAME}Config)
-
-  configure_lit_site_cfg(
-    ${CMAKE_CURRENT_SOURCE_DIR}/lit.site.cfg.py.in
-    ${CMAKE_CURRENT_BINARY_DIR}/${CONFIG_NAME}/lit.site.cfg.py)
-  list(APPEND SCUDO_TESTSUITES ${CMAKE_CURRENT_BINARY_DIR}/${CONFIG_NAME})
-endforeach()
-
 add_subdirectory(standalone)
-
-add_lit_testsuite(check-scudo "Running the Scudo Hardened Allocator tests"
-  ${SCUDO_TESTSUITES}
-  DEPENDS ${SCUDO_TEST_DEPS})
-set_target_properties(check-scudo PROPERTIES FOLDER "Compiler-RT Misc")
Index: compiler-rt/lib/scudo/standalone/wrappers_cpp.cpp
===================================================================
--- compiler-rt/lib/scudo/standalone/wrappers_cpp.cpp
+++ compiler-rt/lib/scudo/standalone/wrappers_cpp.cpp
@@ -23,6 +23,27 @@
 enum class align_val_t : size_t {};
 } // namespace std
 
+// It's not valid for a non-throwing non-noreturn operator new to return
+// nullptr. In these cases, just terminate.
+#define CHECK_ALIGN_NORETURN(align)                                            \
+  do {                                                                         \
+    scudo::uptr alignment = static_cast<scudo::uptr>(align);                   \
+    if (UNLIKELY(!scudo::isPowerOfTwo(alignment))) {                           \
+      scudo::reportAlignmentNotPowerOfTwo(alignment);                          \
+    }                                                                          \
+  } while (0)
+
+#define CHECK_ALIGN(align)                                                     \
+  do {                                                                         \
+    scudo::uptr alignment = static_cast<scudo::uptr>(align);                   \
+    if (UNLIKELY(!scudo::isPowerOfTwo(alignment))) {                           \
+      if (Allocator.canReturnNull()) {                                         \
+        return nullptr;                                                        \
+      }                                                                        \
+      scudo::reportAlignmentNotPowerOfTwo(alignment);                          \
+    }                                                                          \
+  } while (0)
+
 INTERFACE WEAK void *operator new(size_t size) {
   return Allocator.allocate(size, scudo::Chunk::Origin::New);
 }
@@ -38,20 +59,24 @@
   return Allocator.allocate(size, scudo::Chunk::Origin::NewArray);
 }
 INTERFACE WEAK void *operator new(size_t size, std::align_val_t align) {
+  CHECK_ALIGN_NORETURN(align);
   return Allocator.allocate(size, scudo::Chunk::Origin::New,
                             static_cast<scudo::uptr>(align));
 }
 INTERFACE WEAK void *operator new[](size_t size, std::align_val_t align) {
+  CHECK_ALIGN_NORETURN(align);
   return Allocator.allocate(size, scudo::Chunk::Origin::NewArray,
                             static_cast<scudo::uptr>(align));
 }
 INTERFACE WEAK void *operator new(size_t size, std::align_val_t align,
                                   std::nothrow_t const &) NOEXCEPT {
+  CHECK_ALIGN(align);
   return Allocator.allocate(size, scudo::Chunk::Origin::New,
                             static_cast<scudo::uptr>(align));
 }
 INTERFACE WEAK void *operator new[](size_t size, std::align_val_t align,
                                     std::nothrow_t const &) NOEXCEPT {
+  CHECK_ALIGN(align);
   return Allocator.allocate(size, scudo::Chunk::Origin::NewArray,
                             static_cast<scudo::uptr>(align));
 }
Index: clang/test/Driver/sanitizer-ld.c
===================================================================
--- clang/test/Driver/sanitizer-ld.c
+++ clang/test/Driver/sanitizer-ld.c
@@ -773,21 +773,11 @@
 // RUN:   | FileCheck --check-prefix=CHECK-SCUDO-LINUX %s
 // CHECK-SCUDO-LINUX: "{{.*}}ld{{(.exe)?}}"
 // CHECK-SCUDO-LINUX: "-pie"
-// CHECK-SCUDO-LINUX: "--whole-archive" "{{.*}}libclang_rt.scudo-i386.a" "--no-whole-archive"
+// CHECK-SCUDO-LINUX: "--whole-archive" "{{.*}}libclang_rt.scudo_standalone-i386.a" "--no-whole-archive"
 // CHECK-SCUDO-LINUX-NOT: "-lstdc++"
 // CHECK-SCUDO-LINUX: "-lpthread"
 // CHECK-SCUDO-LINUX: "-ldl"
 
-// RUN: %clang -fsanitize=scudo -fsanitize-minimal-runtime %s -### -o %t.o 2>&1 \
-// RUN:     -target i386-unknown-linux -fuse-ld=ld \
-// RUN:     -resource-dir=%S/Inputs/resource_dir \
-// RUN:     --sysroot=%S/Inputs/basic_linux_tree \
-// RUN:   | FileCheck --check-prefix=CHECK-SCUDO-MINIMAL-LINUX %s
-// CHECK-SCUDO-MINIMAL-LINUX: "{{.*}}ld{{(.exe)?}}"
-// CHECK-SCUDO-MINIMAL-LINUX: "-pie"
-// CHECK-SCUDO-MINIMAL-LINUX: "--whole-archive" "{{.*}}libclang_rt.scudo_minimal-i386.a" "--no-whole-archive"
-// CHECK-SCUDO-MINIMAL-LINUX: "-lpthread"
-
 // RUN: %clang -no-canonical-prefixes %s -### -o %t.so -shared 2>&1 \
 // RUN:     -target i386-unknown-linux -fuse-ld=ld -fsanitize=scudo -shared-libsan \
 // RUN:     -resource-dir=%S/Inputs/resource_dir \
@@ -796,8 +786,8 @@
 //
 // CHECK-SCUDO-SHARED-LINUX: "{{(.*[^-.0-9A-Z_a-z])?}}ld{{(.exe)?}}"
 // CHECK-SCUDO-SHARED-LINUX-NOT: "-lc"
-// CHECK-SCUDO-SHARED-LINUX-NOT: libclang_rt.scudo-i386.a"
-// CHECK-SCUDO-SHARED-LINUX: libclang_rt.scudo-i386.so"
+// CHECK-SCUDO-SHARED-LINUX-NOT: libclang_rt.scudo_standalone-i386.a"
+// CHECK-SCUDO-SHARED-LINUX: libclang_rt.scudo_standalone-i386.so"
 // CHECK-SCUDO-SHARED-LINUX-NOT: "-lpthread"
 // CHECK-SCUDO-SHARED-LINUX-NOT: "-lrt"
 // CHECK-SCUDO-SHARED-LINUX-NOT: "-ldl"
@@ -813,7 +803,7 @@
 // CHECK-SCUDO-ANDROID-NOT: "-lc"
 // CHECK-SCUDO-ANDROID: "-pie"
 // CHECK-SCUDO-ANDROID-NOT: "-lpthread"
-// CHECK-SCUDO-ANDROID: libclang_rt.scudo-arm-android.so"
+// CHECK-SCUDO-ANDROID: libclang_rt.scudo_standalone-arm-android.so"
 // CHECK-SCUDO-ANDROID-NOT: "-lpthread"
 
 // RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
@@ -823,7 +813,7 @@
 // RUN:   | FileCheck --check-prefix=CHECK-SCUDO-ANDROID-STATIC %s
 // CHECK-SCUDO-ANDROID-STATIC: "{{(.*[^.0-9A-Z_a-z])?}}ld{{(.exe)?}}"
 // CHECK-SCUDO-ANDROID-STATIC: "-pie"
-// CHECK-SCUDO-ANDROID-STATIC: "--whole-archive" "{{.*}}libclang_rt.scudo-arm-android.a" "--no-whole-archive"
+// CHECK-SCUDO-ANDROID-STATIC: "--whole-archive" "{{.*}}libclang_rt.scudo_standalone-arm-android.a" "--no-whole-archive"
 // CHECK-SCUDO-ANDROID-STATIC-NOT: "-lstdc++"
 // CHECK-SCUDO-ANDROID-STATIC-NOT: "-lpthread"
 // CHECK-SCUDO-ANDROID-STATIC-NOT: "-lrt"
Index: clang/test/Driver/fuchsia.c
===================================================================
--- clang/test/Driver/fuchsia.c
+++ clang/test/Driver/fuchsia.c
@@ -153,7 +153,7 @@
 // CHECK-SCUDO-X86: "-resource-dir" "[[RESOURCE_DIR:[^"]+]]"
 // CHECK-SCUDO-X86: "-fsanitize=safe-stack,scudo"
 // CHECK-SCUDO-X86: "-pie"
-// CHECK-SCUDO-X86: "[[RESOURCE_DIR]]{{/|\\\\}}lib{{/|\\\\}}x86_64-unknown-fuchsia{{/|\\\\}}libclang_rt.scudo.so"
+// CHECK-SCUDO-X86: "[[RESOURCE_DIR]]{{/|\\\\}}lib{{/|\\\\}}x86_64-unknown-fuchsia{{/|\\\\}}libclang_rt.scudo_standalone.so"
 
 // RUN: %clang %s -### --target=aarch64-unknown-fuchsia \
 // RUN:     -fsanitize=scudo 2>&1 \
@@ -163,7 +163,7 @@
 // CHECK-SCUDO-AARCH64: "-resource-dir" "[[RESOURCE_DIR:[^"]+]]"
 // CHECK-SCUDO-AARCH64: "-fsanitize=shadow-call-stack,scudo"
 // CHECK-SCUDO-AARCH64: "-pie"
-// CHECK-SCUDO-AARCH64: "[[RESOURCE_DIR]]{{/|\\\\}}lib{{/|\\\\}}aarch64-unknown-fuchsia{{/|\\\\}}libclang_rt.scudo.so"
+// CHECK-SCUDO-AARCH64: "[[RESOURCE_DIR]]{{/|\\\\}}lib{{/|\\\\}}aarch64-unknown-fuchsia{{/|\\\\}}libclang_rt.scudo_standalone.so"
 
 // RUN: %clang %s -### --target=x86_64-unknown-fuchsia \
 // RUN:     -fsanitize=scudo -fPIC -shared 2>&1 \
@@ -172,7 +172,7 @@
 // RUN:     | FileCheck %s -check-prefix=CHECK-SCUDO-SHARED
 // CHECK-SCUDO-SHARED: "-resource-dir" "[[RESOURCE_DIR:[^"]+]]"
 // CHECK-SCUDO-SHARED: "-fsanitize=safe-stack,scudo"
-// CHECK-SCUDO-SHARED: "[[RESOURCE_DIR]]{{/|\\\\}}lib{{/|\\\\}}x86_64-unknown-fuchsia{{/|\\\\}}libclang_rt.scudo.so"
+// CHECK-SCUDO-SHARED: "[[RESOURCE_DIR]]{{/|\\\\}}lib{{/|\\\\}}x86_64-unknown-fuchsia{{/|\\\\}}libclang_rt.scudo_standalone.so"
 
 // RUN: %clang %s -### --target=aarch64-unknown-fuchsia \
 // RUN:     -fsanitize=leak 2>&1 \
Index: clang/lib/Driver/ToolChains/CommonArgs.cpp
===================================================================
--- clang/lib/Driver/ToolChains/CommonArgs.cpp
+++ clang/lib/Driver/ToolChains/CommonArgs.cpp
@@ -809,10 +809,7 @@
         SharedRuntimes.push_back("ubsan_standalone");
     }
     if (SanArgs.needsScudoRt() && SanArgs.linkRuntimes()) {
-      if (SanArgs.requiresMinimalRuntime())
-        SharedRuntimes.push_back("scudo_minimal");
-      else
-        SharedRuntimes.push_back("scudo");
+      SharedRuntimes.push_back("scudo_standalone");
     }
     if (SanArgs.needsTsanRt() && SanArgs.linkRuntimes())
       SharedRuntimes.push_back("tsan");
@@ -903,15 +900,9 @@
     RequiredSymbols.push_back("__sanitizer_stats_register");
   }
   if (!SanArgs.needsSharedRt() && SanArgs.needsScudoRt() && SanArgs.linkRuntimes()) {
-    if (SanArgs.requiresMinimalRuntime()) {
-      StaticRuntimes.push_back("scudo_minimal");
-      if (SanArgs.linkCXXRuntimes())
-        StaticRuntimes.push_back("scudo_cxx_minimal");
-    } else {
-      StaticRuntimes.push_back("scudo");
-      if (SanArgs.linkCXXRuntimes())
-        StaticRuntimes.push_back("scudo_cxx");
-    }
+    StaticRuntimes.push_back("scudo_standalone");
+    if (SanArgs.linkCXXRuntimes())
+      StaticRuntimes.push_back("scudo_standalone_cxx");
   }
 }
 
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to