[compiler-rt] r353055 - [scudo] Initial standalone skeleton check-in

Kostya Kortchinsky via llvm-commits llvm-commits at lists.llvm.org
Mon Feb 4 08:25:41 PST 2019


Author: cryptoad
Date: Mon Feb  4 08:25:40 2019
New Revision: 353055

URL: http://llvm.org/viewvc/llvm-project?rev=353055&view=rev
Log:
[scudo] Initial standalone skeleton check-in

Summary:
This is the initial check-in for the Standalone version of Scudo.

The project is initially going to live in scudo/standalone then will
replace scudo. See http://lists.llvm.org/pipermail/llvm-dev/2019-January/129113.html
for details.

This initial CL is meant to lay out the project structure, of both
code & tests, providing a minimal amount of functionalities, namely
various definitions, some atomic helpers and an intrusive list.
(empty.cc is just here to have a compilation unit, but will go away
in the upcoming CLs).

Initial support is restricted to Linux i386 & x86_64 in make files
and will be extended once things land & work.

We will grow organically from here, adding functionalities in limited
amounts.

Reviewers: morehouse, eugenis, vitalybuka, kcc, mcgrathr, flowerhack

Reviewed By: morehouse, vitalybuka

Subscribers: srhines, mgorny, krytarowski, delcypher, jfb, #sanitizers, llvm-commits

Tags: #llvm, #sanitizers

Differential Revision: https://reviews.llvm.org/D57412

Added:
    compiler-rt/trunk/lib/scudo/standalone/
    compiler-rt/trunk/lib/scudo/standalone/CMakeLists.txt
    compiler-rt/trunk/lib/scudo/standalone/atomic_helpers.h
    compiler-rt/trunk/lib/scudo/standalone/empty.cc
    compiler-rt/trunk/lib/scudo/standalone/internal_defs.h
    compiler-rt/trunk/lib/scudo/standalone/list.h
    compiler-rt/trunk/lib/scudo/standalone/platform.h
    compiler-rt/trunk/lib/scudo/standalone/tests/
    compiler-rt/trunk/lib/scudo/standalone/tests/CMakeLists.txt
    compiler-rt/trunk/lib/scudo/standalone/tests/atomic_test.cc
    compiler-rt/trunk/lib/scudo/standalone/tests/list_test.cc
    compiler-rt/trunk/lib/scudo/standalone/tests/scudo_unit_test_main.cc
    compiler-rt/trunk/test/scudo/standalone/
    compiler-rt/trunk/test/scudo/standalone/CMakeLists.txt
    compiler-rt/trunk/test/scudo/standalone/unit/
    compiler-rt/trunk/test/scudo/standalone/unit/lit.site.cfg.in
Modified:
    compiler-rt/trunk/cmake/config-ix.cmake
    compiler-rt/trunk/lib/CMakeLists.txt
    compiler-rt/trunk/test/scudo/CMakeLists.txt

Modified: compiler-rt/trunk/cmake/config-ix.cmake
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/cmake/config-ix.cmake?rev=353055&r1=353054&r2=353055&view=diff
==============================================================================
--- compiler-rt/trunk/cmake/config-ix.cmake (original)
+++ compiler-rt/trunk/cmake/config-ix.cmake Mon Feb  4 08:25:40 2019
@@ -246,6 +246,7 @@ set(ALL_SAFESTACK_SUPPORTED_ARCH ${X86}
 set(ALL_CFI_SUPPORTED_ARCH ${X86} ${X86_64} ${ARM32} ${ARM64} ${MIPS64})
 set(ALL_ESAN_SUPPORTED_ARCH ${X86_64} ${MIPS64})
 set(ALL_SCUDO_SUPPORTED_ARCH ${X86} ${X86_64} ${ARM32} ${ARM64} ${MIPS32} ${MIPS64} ${PPC64})
+set(ALL_SCUDO_STANDALONE_SUPPORTED_ARCH ${X86} ${X86_64})
 if(APPLE)
 set(ALL_XRAY_SUPPORTED_ARCH ${X86_64})
 else()
@@ -459,6 +460,9 @@ if(APPLE)
   list_intersect(SCUDO_SUPPORTED_ARCH
     ALL_SCUDO_SUPPORTED_ARCH
     SANITIZER_COMMON_SUPPORTED_ARCH)
+  list_intersect(SCUDO_STANDALONE_SUPPORTED_ARCH
+    ALL_SCUDO_STANDALONE_SUPPORTED_ARCH
+    SANITIZER_COMMON_SUPPORTED_ARCH)
   list_intersect(FUZZER_SUPPORTED_ARCH
     ALL_FUZZER_SUPPORTED_ARCH
     SANITIZER_COMMON_SUPPORTED_ARCH)
@@ -493,6 +497,7 @@ else()
   filter_available_targets(CFI_SUPPORTED_ARCH ${ALL_CFI_SUPPORTED_ARCH})
   filter_available_targets(ESAN_SUPPORTED_ARCH ${ALL_ESAN_SUPPORTED_ARCH})
   filter_available_targets(SCUDO_SUPPORTED_ARCH ${ALL_SCUDO_SUPPORTED_ARCH})
+  filter_available_targets(SCUDO_STANDALONE_SUPPORTED_ARCH ${ALL_SCUDO_SUPPORTED_ARCH})
   filter_available_targets(XRAY_SUPPORTED_ARCH ${ALL_XRAY_SUPPORTED_ARCH})
   filter_available_targets(SHADOWCALLSTACK_SUPPORTED_ARCH
     ${ALL_SHADOWCALLSTACK_SUPPORTED_ARCH})
@@ -634,6 +639,13 @@ else()
   set(COMPILER_RT_HAS_ESAN FALSE)
 endif()
 
+#TODO(kostyak): add back Android & Fuchsia when the code settles a bit.
+if (SCUDO_STANDALONE_SUPPORTED_ARCH AND OS_NAME MATCHES "Linux")
+  set(COMPILER_RT_HAS_SCUDO_STANDALONE TRUE)
+else()
+  set(COMPILER_RT_HAS_SCUDO_STANDALONE FALSE)
+endif()
+
 if (COMPILER_RT_HAS_SANITIZER_COMMON AND SCUDO_SUPPORTED_ARCH AND
     OS_NAME MATCHES "Linux|Android|Fuchsia")
   set(COMPILER_RT_HAS_SCUDO TRUE)

Modified: compiler-rt/trunk/lib/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/CMakeLists.txt?rev=353055&r1=353054&r2=353055&view=diff
==============================================================================
--- compiler-rt/trunk/lib/CMakeLists.txt (original)
+++ compiler-rt/trunk/lib/CMakeLists.txt Mon Feb  4 08:25:40 2019
@@ -24,6 +24,9 @@ function(compiler_rt_build_runtime runti
     if(${runtime} STREQUAL tsan)
       add_subdirectory(tsan/dd)
     endif()
+    if(${runtime} STREQUAL scudo)
+      add_subdirectory(scudo/standalone)
+    endif()
   endif()
 endfunction()
 

Added: compiler-rt/trunk/lib/scudo/standalone/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/scudo/standalone/CMakeLists.txt?rev=353055&view=auto
==============================================================================
--- compiler-rt/trunk/lib/scudo/standalone/CMakeLists.txt (added)
+++ compiler-rt/trunk/lib/scudo/standalone/CMakeLists.txt Mon Feb  4 08:25:40 2019
@@ -0,0 +1,54 @@
+add_compiler_rt_component(scudo_standalone)
+
+include_directories(../..)
+
+set(SCUDO_CFLAGS)
+
+list(APPEND SCUDO_CFLAGS
+  -Wall
+  -Werror
+  -nostdinc++)
+
+append_list_if(COMPILER_RT_HAS_FFREESTANDING_FLAG -ffreestanding SCUDO_CFLAGS)
+
+append_list_if(COMPILER_RT_HAS_FVISIBILITY_HIDDEN_FLAG -fvisibility=hidden SCUDO_CFLAGS)
+
+if(COMPILER_RT_DEBUG)
+  list(APPEND SCUDO_CFLAGS -O0)
+else()
+  list(APPEND SCUDO_CFLAGS -O3)
+endif()
+
+set(SCUDO_LINK_FLAGS)
+
+list(APPEND SCUDO_LINK_FLAGS -Wl,-z,defs,-z,now,-z,relro)
+
+append_list_if(COMPILER_RT_HAS_NODEFAULTLIBS_FLAG -nodefaultlibs SCUDO_LINK_FLAGS)
+
+if(ANDROID)
+# Put the shared library in the global group. For more details, see
+# android-changes-for-ndk-developers.md#changes-to-library-search-order
+  append_list_if(COMPILER_RT_HAS_Z_GLOBAL -Wl,-z,global SCUDO_LINK_FLAGS)
+endif()
+
+set(SCUDO_SOURCES empty.cc)
+
+set(SCUDO_HEADERS
+  platform.h
+  internal_defs.h
+  atomic_helpers.h
+  list.h)
+
+if(COMPILER_RT_HAS_SCUDO_STANDALONE)
+  add_compiler_rt_runtime(clang_rt.scudo_standalone
+    STATIC
+    ARCHS ${SCUDO_SUPPORTED_ARCH}
+    SOURCES ${SCUDO_SOURCES}
+    ADDITIONAL_HEADERS ${SCUDO_HEADERS}
+    CFLAGS ${SCUDO_CFLAGS}
+    PARENT_TARGET scudo_standalone)
+
+  if(COMPILER_RT_INCLUDE_TESTS)
+    add_subdirectory(tests)
+  endif()
+endif()

Added: compiler-rt/trunk/lib/scudo/standalone/atomic_helpers.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/scudo/standalone/atomic_helpers.h?rev=353055&view=auto
==============================================================================
--- compiler-rt/trunk/lib/scudo/standalone/atomic_helpers.h (added)
+++ compiler-rt/trunk/lib/scudo/standalone/atomic_helpers.h Mon Feb  4 08:25:40 2019
@@ -0,0 +1,131 @@
+//===-- atomic_helpers.h ----------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef SCUDO_ATOMIC_H_
+#define SCUDO_ATOMIC_H_
+
+#include "internal_defs.h"
+
+namespace scudo {
+
+enum memory_order {
+  memory_order_relaxed = 0,
+  memory_order_consume = 1,
+  memory_order_acquire = 2,
+  memory_order_release = 3,
+  memory_order_acq_rel = 4,
+  memory_order_seq_cst = 5
+};
+COMPILER_CHECK(memory_order_relaxed == __ATOMIC_RELAXED);
+COMPILER_CHECK(memory_order_consume == __ATOMIC_CONSUME);
+COMPILER_CHECK(memory_order_acquire == __ATOMIC_ACQUIRE);
+COMPILER_CHECK(memory_order_release == __ATOMIC_RELEASE);
+COMPILER_CHECK(memory_order_acq_rel == __ATOMIC_ACQ_REL);
+COMPILER_CHECK(memory_order_seq_cst == __ATOMIC_SEQ_CST);
+
+struct atomic_u8 {
+  typedef u8 Type;
+  volatile Type ValDoNotUse;
+};
+
+struct atomic_u16 {
+  typedef u16 Type;
+  volatile Type ValDoNotUse;
+};
+
+struct atomic_s32 {
+  typedef s32 Type;
+  volatile Type ValDoNotUse;
+};
+
+struct atomic_u32 {
+  typedef u32 Type;
+  volatile Type ValDoNotUse;
+};
+
+struct atomic_u64 {
+  typedef u64 Type;
+  // On 32-bit platforms u64 is not necessarily aligned on 8 bytes.
+  volatile ALIGNED(8) Type ValDoNotUse;
+};
+
+struct atomic_uptr {
+  typedef uptr Type;
+  volatile Type ValDoNotUse;
+};
+
+template <typename T>
+INLINE typename T::Type atomic_load(const volatile T *A, memory_order MO) {
+  DCHECK(!(reinterpret_cast<uptr>(A) % sizeof(*A)));
+  typename T::Type V;
+  __atomic_load(&A->ValDoNotUse, &V, MO);
+  return V;
+}
+
+template <typename T>
+INLINE void atomic_store(volatile T *A, typename T::Type V, memory_order MO) {
+  DCHECK(!(reinterpret_cast<uptr>(A) % sizeof(*A)));
+  __atomic_store(&A->ValDoNotUse, &V, MO);
+}
+
+INLINE void atomic_thread_fence(memory_order) { __sync_synchronize(); }
+
+template <typename T>
+INLINE typename T::Type atomic_fetch_add(volatile T *A, typename T::Type V,
+                                         memory_order MO) {
+  DCHECK(!(reinterpret_cast<uptr>(A) % sizeof(*A)));
+  return __atomic_fetch_add(&A->ValDoNotUse, V, MO);
+}
+
+template <typename T>
+INLINE typename T::Type atomic_fetch_sub(volatile T *A, typename T::Type V,
+                                         memory_order MO) {
+  DCHECK(!(reinterpret_cast<uptr>(A) % sizeof(*A)));
+  return __atomic_fetch_sub(&A->ValDoNotUse, V, MO);
+}
+
+template <typename T>
+INLINE typename T::Type atomic_exchange(volatile T *A, typename T::Type V,
+                                        memory_order MO) {
+  DCHECK(!(reinterpret_cast<uptr>(A) % sizeof(*A)));
+  typename T::Type R;
+  __atomic_exchange(&A->ValDoNotUse, &V, &R, MO);
+  return R;
+}
+
+template <typename T>
+INLINE bool atomic_compare_exchange_strong(volatile T *A, typename T::Type *Cmp,
+                                           typename T::Type Xchg,
+                                           memory_order MO) {
+  return __atomic_compare_exchange(&A->ValDoNotUse, Cmp, &Xchg, false, MO,
+                                   __ATOMIC_RELAXED);
+}
+
+template <typename T>
+INLINE bool atomic_compare_exchange_weak(volatile T *A, typename T::Type *Cmp,
+                                         typename T::Type Xchg,
+                                         memory_order MO) {
+  return __atomic_compare_exchange(&A->ValDoNotUse, Cmp, &Xchg, true, MO,
+                                   __ATOMIC_RELAXED);
+}
+
+// Clutter-reducing helpers.
+
+template <typename T>
+INLINE typename T::Type atomic_load_relaxed(const volatile T *A) {
+  return atomic_load(A, memory_order_relaxed);
+}
+
+template <typename T>
+INLINE void atomic_store_relaxed(volatile T *A, typename T::Type V) {
+  atomic_store(A, V, memory_order_relaxed);
+}
+
+} // namespace scudo
+
+#endif // SCUDO_ATOMIC_H_

Added: compiler-rt/trunk/lib/scudo/standalone/empty.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/scudo/standalone/empty.cc?rev=353055&view=auto
==============================================================================
--- compiler-rt/trunk/lib/scudo/standalone/empty.cc (added)
+++ compiler-rt/trunk/lib/scudo/standalone/empty.cc Mon Feb  4 08:25:40 2019
@@ -0,0 +1,10 @@
+//===-- empty.cc ------------------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "atomic_helpers.h"
+#include "list.h"

Added: compiler-rt/trunk/lib/scudo/standalone/internal_defs.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/scudo/standalone/internal_defs.h?rev=353055&view=auto
==============================================================================
--- compiler-rt/trunk/lib/scudo/standalone/internal_defs.h (added)
+++ compiler-rt/trunk/lib/scudo/standalone/internal_defs.h Mon Feb  4 08:25:40 2019
@@ -0,0 +1,135 @@
+//===-- internal_defs.h -----------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef SCUDO_INTERNAL_DEFS_H_
+#define SCUDO_INTERNAL_DEFS_H_
+
+#include "platform.h"
+
+#ifndef SCUDO_DEBUG
+#define SCUDO_DEBUG 0
+#endif
+
+#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
+
+// String related macros.
+
+#define STRINGIFY_(S) #S
+#define STRINGIFY(S) STRINGIFY_(S)
+#define CONCATENATE_(S, C) S##C
+#define CONCATENATE(S, C) CONCATENATE_(S, C)
+
+// Attributes & builtins related macros.
+
+#define INTERFACE __attribute__((visibility("default")))
+#define WEAK __attribute__((weak))
+#define INLINE inline
+#define ALWAYS_INLINE inline __attribute__((always_inline))
+#define ALIAS(x) __attribute__((alias(x)))
+#define ALIGNED(x) __attribute__((aligned(x)))
+#define FORMAT(f, a) __attribute__((format(printf, f, a)))
+#define NOINLINE __attribute__((noinline))
+#define NORETURN __attribute__((noreturn))
+#define THREADLOCAL __thread
+#define LIKELY(x) __builtin_expect(!!(x), 1)
+#define UNLIKELY(x) __builtin_expect(!!(x), 0)
+#if defined(__i386__) || defined(__x86_64__)
+// __builtin_prefetch(x) generates prefetchnt0 on x86
+#define PREFETCH(x) __asm__("prefetchnta (%0)" : : "r"(x))
+#else
+#define PREFETCH(x) __builtin_prefetch(x)
+#endif
+#define UNUSED __attribute__((unused))
+#define USED __attribute__((used))
+#define NOEXCEPT noexcept
+
+namespace scudo {
+
+typedef unsigned long uptr;
+typedef signed long sptr;
+typedef unsigned char u8;
+typedef unsigned short u16;
+typedef unsigned int u32;
+typedef unsigned long long u64;
+typedef signed char s8;
+typedef signed short s16;
+typedef signed int s32;
+typedef signed long long s64;
+
+// Various integer constants.
+
+#undef __INT64_C
+#undef __UINT64_C
+#undef UINTPTR_MAX
+#if SCUDO_WORDSIZE == 64U
+#define __INT64_C(c) c##L
+#define __UINT64_C(c) c##UL
+#define UINTPTR_MAX (18446744073709551615UL)
+#else
+#define __INT64_C(c) c##LL
+#define __UINT64_C(c) c##ULL
+#define UINTPTR_MAX (4294967295U)
+#endif // SCUDO_WORDSIZE == 64U
+#undef INT32_MIN
+#define INT32_MIN (-2147483647 - 1)
+#undef INT32_MAX
+#define INT32_MAX (2147483647)
+#undef UINT32_MAX
+#define UINT32_MAX (4294967295U)
+#undef INT64_MIN
+#define INT64_MIN (-__INT64_C(9223372036854775807) - 1)
+#undef INT64_MAX
+#define INT64_MAX (__INT64_C(9223372036854775807))
+#undef UINT64_MAX
+#define UINT64_MAX (__UINT64_C(18446744073709551615))
+
+enum LinkerInitialized { LINKER_INITIALIZED = 0 };
+
+// Various CHECK related macros.
+
+#define COMPILER_CHECK(Pred) static_assert(Pred, "")
+
+// TODO(kostyak): implement at a later check-in.
+#define CHECK_IMPL(c1, op, c2)                                                 \
+  do {                                                                         \
+  } while (false)
+
+#define CHECK(a) CHECK_IMPL((a), !=, 0)
+#define CHECK_EQ(a, b) CHECK_IMPL((a), ==, (b))
+#define CHECK_NE(a, b) CHECK_IMPL((a), !=, (b))
+#define CHECK_LT(a, b) CHECK_IMPL((a), <, (b))
+#define CHECK_LE(a, b) CHECK_IMPL((a), <=, (b))
+#define CHECK_GT(a, b) CHECK_IMPL((a), >, (b))
+#define CHECK_GE(a, b) CHECK_IMPL((a), >=, (b))
+
+#if SCUDO_DEBUG
+#define DCHECK(a) CHECK(a)
+#define DCHECK_EQ(a, b) CHECK_EQ(a, b)
+#define DCHECK_NE(a, b) CHECK_NE(a, b)
+#define DCHECK_LT(a, b) CHECK_LT(a, b)
+#define DCHECK_LE(a, b) CHECK_LE(a, b)
+#define DCHECK_GT(a, b) CHECK_GT(a, b)
+#define DCHECK_GE(a, b) CHECK_GE(a, b)
+#else
+#define DCHECK(a)
+#define DCHECK_EQ(a, b)
+#define DCHECK_NE(a, b)
+#define DCHECK_LT(a, b)
+#define DCHECK_LE(a, b)
+#define DCHECK_GT(a, b)
+#define DCHECK_GE(a, b)
+#endif
+
+// TODO(kostyak): implement at a later check-in.
+#define UNREACHABLE(msg)                                                       \
+  do {                                                                         \
+  } while (false)
+
+} // namespace scudo
+
+#endif // SCUDO_INTERNAL_DEFS_H_

Added: compiler-rt/trunk/lib/scudo/standalone/list.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/scudo/standalone/list.h?rev=353055&view=auto
==============================================================================
--- compiler-rt/trunk/lib/scudo/standalone/list.h (added)
+++ compiler-rt/trunk/lib/scudo/standalone/list.h Mon Feb  4 08:25:40 2019
@@ -0,0 +1,156 @@
+//===-- list.h --------------------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef SCUDO_LIST_H_
+#define SCUDO_LIST_H_
+
+#include "internal_defs.h"
+
+namespace scudo {
+
+// Intrusive POD singly-linked list.
+// An object with all zero fields should represent a valid empty list. clear()
+// should be called on all non-zero-initialized objects before using.
+template <class Item> struct IntrusiveList {
+  friend class Iterator;
+
+  void clear() {
+    First = Last = nullptr;
+    Size = 0;
+  }
+
+  bool empty() const { return Size == 0; }
+  uptr size() const { return Size; }
+
+  void push_back(Item *X) {
+    if (empty()) {
+      X->Next = nullptr;
+      First = Last = X;
+      Size = 1;
+    } else {
+      X->Next = nullptr;
+      Last->Next = X;
+      Last = X;
+      Size++;
+    }
+  }
+
+  void push_front(Item *X) {
+    if (empty()) {
+      X->Next = nullptr;
+      First = Last = X;
+      Size = 1;
+    } else {
+      X->Next = First;
+      First = X;
+      Size++;
+    }
+  }
+
+  void pop_front() {
+    DCHECK(!empty());
+    First = First->Next;
+    if (!First)
+      Last = nullptr;
+    Size--;
+  }
+
+  void extract(Item *Prev, Item *X) {
+    DCHECK(!empty());
+    DCHECK_NE(Prev, nullptr);
+    DCHECK_NE(X, nullptr);
+    DCHECK_EQ(Prev->Next, X);
+    Prev->Next = X->Next;
+    if (Last == X)
+      Last = Prev;
+    Size--;
+  }
+
+  Item *front() { return First; }
+  const Item *front() const { return First; }
+  Item *back() { return Last; }
+  const Item *back() const { return Last; }
+
+  void append_front(IntrusiveList<Item> *L) {
+    DCHECK_NE(this, L);
+    if (L->empty())
+      return;
+    if (empty()) {
+      *this = *L;
+    } else if (!L->empty()) {
+      L->Last->Next = First;
+      First = L->First;
+      Size += L->size();
+    }
+    L->clear();
+  }
+
+  void append_back(IntrusiveList<Item> *L) {
+    DCHECK_NE(this, L);
+    if (L->empty())
+      return;
+    if (empty()) {
+      *this = *L;
+    } else {
+      Last->Next = L->First;
+      Last = L->Last;
+      Size += L->size();
+    }
+    L->clear();
+  }
+
+  void checkConsistency() {
+    if (Size == 0) {
+      CHECK_EQ(First, 0);
+      CHECK_EQ(Last, 0);
+    } else {
+      uptr count = 0;
+      for (Item *i = First;; i = i->Next) {
+        count++;
+        if (i == Last)
+          break;
+      }
+      CHECK_EQ(size(), count);
+      CHECK_EQ(Last->Next, 0);
+    }
+  }
+
+  template <class ItemT> class IteratorBase {
+  public:
+    explicit IteratorBase(ItemT *CurrentItem) : Current(CurrentItem) {}
+    IteratorBase &operator++() {
+      Current = Current->Next;
+      return *this;
+    }
+    bool operator!=(IteratorBase Other) const {
+      return Current != Other.Current;
+    }
+    ItemT &operator*() { return *Current; }
+
+  private:
+    ItemT *Current;
+  };
+
+  typedef IteratorBase<Item> Iterator;
+  typedef IteratorBase<const Item> ConstIterator;
+
+  Iterator begin() { return Iterator(First); }
+  Iterator end() { return Iterator(nullptr); }
+
+  ConstIterator begin() const { return ConstIterator(First); }
+  ConstIterator end() const { return ConstIterator(nullptr); }
+
+private:
+  uptr Size;
+  Item *First;
+  Item *Last;
+};
+
+} // namespace scudo
+
+#endif // SCUDO_LIST_H_

Added: compiler-rt/trunk/lib/scudo/standalone/platform.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/scudo/standalone/platform.h?rev=353055&view=auto
==============================================================================
--- compiler-rt/trunk/lib/scudo/standalone/platform.h (added)
+++ compiler-rt/trunk/lib/scudo/standalone/platform.h Mon Feb  4 08:25:40 2019
@@ -0,0 +1,70 @@
+//===-- platform.h ----------------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef SCUDO_PLATFORM_H_
+#define SCUDO_PLATFORM_H_
+
+#if defined(__linux__)
+#define SCUDO_LINUX 1
+#else
+#define SCUDO_LINUX 0
+#endif
+
+#if defined(__ANDROID__)
+#define SCUDO_ANDROID 1
+#else
+#define SCUDO_ANDROID 0
+#endif
+
+#if defined(__Fuchsia__)
+#define SCUDO_FUCHSIA 1
+#else
+#define SCUDO_FUCHSIA 0
+#endif
+
+#if __LP64__
+#define SCUDO_WORDSIZE 64U
+#else
+#define SCUDO_WORDSIZE 32U
+#endif
+
+#if SCUDO_WORDSIZE == 64U
+#define FIRST_32_SECOND_64(a, b) (b)
+#else
+#define FIRST_32_SECOND_64(a, b) (a)
+#endif
+
+#ifndef SCUDO_CAN_USE_PRIMARY64
+#define SCUDO_CAN_USE_PRIMARY64 (SCUDO_WORDSIZE == 64U)
+#endif
+
+#ifndef SCUDO_MIN_ALIGNMENT_LOG
+// We force malloc-type functions to be aligned to std::max_align_t, but there
+// is no reason why the minimum alignment for all other functions can't be 8
+// bytes. Except obviously for applications making incorrect assumptions.
+// TODO(kostyak): define SCUDO_MIN_ALIGNMENT_LOG 3
+#define SCUDO_MIN_ALIGNMENT_LOG FIRST_32_SECOND_64(3, 4)
+#endif
+
+#if defined(__aarch64__)
+#define SCUDO_MMAP_RANGE_SIZE FIRST_32_SECOND_64(1ULL << 32, 1ULL << 48)
+#else
+#define SCUDO_MMAP_RANGE_SIZE FIRST_32_SECOND_64(1ULL << 32, 1ULL << 47)
+#endif
+
+// Older gcc have issues aligning to a constexpr, and require an integer.
+// See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=56859 among others.
+#if defined(__powerpc__) || defined(__powerpc64__)
+#define SCUDO_CACHE_LINE_SIZE 128
+#else
+#define SCUDO_CACHE_LINE_SIZE 64
+#endif
+
+#define SCUDO_POINTER_FORMAT_LENGTH FIRST_32_SECOND_64(8, 12)
+
+#endif // SCUDO_PLATFORM_H_

Added: compiler-rt/trunk/lib/scudo/standalone/tests/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/scudo/standalone/tests/CMakeLists.txt?rev=353055&view=auto
==============================================================================
--- compiler-rt/trunk/lib/scudo/standalone/tests/CMakeLists.txt (added)
+++ compiler-rt/trunk/lib/scudo/standalone/tests/CMakeLists.txt Mon Feb  4 08:25:40 2019
@@ -0,0 +1,50 @@
+include_directories(..)
+
+add_custom_target(ScudoUnitTests)
+set_target_properties(ScudoUnitTests PROPERTIES
+  FOLDER "Compiler-RT Tests")
+
+set(SCUDO_UNITTEST_CFLAGS
+  ${COMPILER_RT_UNITTEST_CFLAGS}
+  ${COMPILER_RT_GTEST_CFLAGS}
+  -I${COMPILER_RT_SOURCE_DIR}/include
+  -I${COMPILER_RT_SOURCE_DIR}/lib
+  -I${COMPILER_RT_SOURCE_DIR}/lib/scudo/standalone
+  -DGTEST_HAS_RTTI=0)
+
+set(SCUDO_TEST_ARCH ${SCUDO_SUPPORTED_ARCH})
+
+# gtests requires c++
+set(LINK_FLAGS -lstdc++ -pthread)
+
+set(TEST_HEADERS)
+foreach (header ${SCUDO_HEADERS})
+  list(APPEND TEST_HEADERS ${CMAKE_CURRENT_SOURCE_DIR}/../${header})
+endforeach()
+
+# add_scudo_unittest(<name>
+#                   SOURCES <sources list>
+#                   HEADERS <extra headers list>)
+macro(add_scudo_unittest testname)
+  cmake_parse_arguments(TEST "" "" "SOURCES;HEADERS" ${ARGN})
+  if(COMPILER_RT_HAS_SCUDO_STANDALONE)
+    foreach(arch ${SCUDO_TEST_ARCH})
+      set(ScudoUnitTestsObjects)
+      generate_compiler_rt_tests(ScudoUnitTestsObjects ScudoUnitTests
+        "${testname}-${arch}-Test" ${arch}
+        SOURCES ${TEST_SOURCES} ${COMPILER_RT_GTEST_SOURCE} 
+        COMPILE_DEPS ${TEST_HEADERS}
+        DEPS gtest scudo_standalone
+        CFLAGS ${SCUDO_UNITTEST_CFLAGS}
+        LINK_FLAGS ${LINK_FLAGS})
+    endforeach()
+  endif()
+endmacro()
+
+set(SCUDO_UNIT_TEST_SOURCES
+  atomic_test.cc
+  list_test.cc
+  scudo_unit_test_main.cc)
+
+add_scudo_unittest(ScudoUnitTest
+  SOURCES ${SCUDO_UNIT_TEST_SOURCES})

Added: compiler-rt/trunk/lib/scudo/standalone/tests/atomic_test.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/scudo/standalone/tests/atomic_test.cc?rev=353055&view=auto
==============================================================================
--- compiler-rt/trunk/lib/scudo/standalone/tests/atomic_test.cc (added)
+++ compiler-rt/trunk/lib/scudo/standalone/tests/atomic_test.cc Mon Feb  4 08:25:40 2019
@@ -0,0 +1,112 @@
+//===-- atomic_test.cc ------------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "scudo/standalone/atomic_helpers.h"
+#include "gtest/gtest.h"
+
+namespace scudo {
+
+template <typename T> struct ValAndMagic {
+  typename T::Type Magic0;
+  T A;
+  typename T::Type Magic1;
+
+  static ValAndMagic<T> *Sink;
+};
+
+template <typename T> ValAndMagic<T> *ValAndMagic<T>::Sink;
+
+template <typename T, memory_order LoadMO, memory_order StoreMO>
+void checkStoreLoad() {
+  typedef typename T::Type Type;
+  ValAndMagic<T> Val;
+  // Prevent the compiler from scalarizing the struct.
+  ValAndMagic<T>::Sink = &Val;
+  // Ensure that surrounding memory is not overwritten.
+  Val.Magic0 = Val.Magic1 = (Type)-3;
+  for (u64 I = 0; I < 100; I++) {
+    // Generate A value that occupies all bytes of the variable.
+    u64 V = I;
+    V |= V << 8;
+    V |= V << 16;
+    V |= V << 32;
+    Val.A.ValDoNotUse = (Type)V;
+    EXPECT_EQ(atomic_load(&Val.A, LoadMO), (Type)V);
+    Val.A.ValDoNotUse = (Type)-1;
+    atomic_store(&Val.A, (Type)V, StoreMO);
+    EXPECT_EQ(Val.A.ValDoNotUse, (Type)V);
+  }
+  EXPECT_EQ(Val.Magic0, (Type)-3);
+  EXPECT_EQ(Val.Magic1, (Type)-3);
+}
+
+TEST(ScudoStandalone, AtomicStoreLoad) {
+  checkStoreLoad<atomic_u8, memory_order_relaxed, memory_order_relaxed>();
+  checkStoreLoad<atomic_u8, memory_order_consume, memory_order_relaxed>();
+  checkStoreLoad<atomic_u8, memory_order_acquire, memory_order_relaxed>();
+  checkStoreLoad<atomic_u8, memory_order_relaxed, memory_order_release>();
+  checkStoreLoad<atomic_u8, memory_order_seq_cst, memory_order_seq_cst>();
+
+  checkStoreLoad<atomic_u16, memory_order_relaxed, memory_order_relaxed>();
+  checkStoreLoad<atomic_u16, memory_order_consume, memory_order_relaxed>();
+  checkStoreLoad<atomic_u16, memory_order_acquire, memory_order_relaxed>();
+  checkStoreLoad<atomic_u16, memory_order_relaxed, memory_order_release>();
+  checkStoreLoad<atomic_u16, memory_order_seq_cst, memory_order_seq_cst>();
+
+  checkStoreLoad<atomic_u32, memory_order_relaxed, memory_order_relaxed>();
+  checkStoreLoad<atomic_u32, memory_order_consume, memory_order_relaxed>();
+  checkStoreLoad<atomic_u32, memory_order_acquire, memory_order_relaxed>();
+  checkStoreLoad<atomic_u32, memory_order_relaxed, memory_order_release>();
+  checkStoreLoad<atomic_u32, memory_order_seq_cst, memory_order_seq_cst>();
+
+  checkStoreLoad<atomic_u64, memory_order_relaxed, memory_order_relaxed>();
+  checkStoreLoad<atomic_u64, memory_order_consume, memory_order_relaxed>();
+  checkStoreLoad<atomic_u64, memory_order_acquire, memory_order_relaxed>();
+  checkStoreLoad<atomic_u64, memory_order_relaxed, memory_order_release>();
+  checkStoreLoad<atomic_u64, memory_order_seq_cst, memory_order_seq_cst>();
+
+  checkStoreLoad<atomic_uptr, memory_order_relaxed, memory_order_relaxed>();
+  checkStoreLoad<atomic_uptr, memory_order_consume, memory_order_relaxed>();
+  checkStoreLoad<atomic_uptr, memory_order_acquire, memory_order_relaxed>();
+  checkStoreLoad<atomic_uptr, memory_order_relaxed, memory_order_release>();
+  checkStoreLoad<atomic_uptr, memory_order_seq_cst, memory_order_seq_cst>();
+}
+
+template <typename T> void checkAtomicCompareExchange() {
+  typedef typename T::Type Type;
+  {
+    Type OldVal = 42;
+    Type NewVal = 24;
+    Type V = OldVal;
+    EXPECT_TRUE(atomic_compare_exchange_strong(
+        reinterpret_cast<T *>(&V), &OldVal, NewVal, memory_order_relaxed));
+    EXPECT_FALSE(atomic_compare_exchange_strong(
+        reinterpret_cast<T *>(&V), &OldVal, NewVal, memory_order_relaxed));
+    EXPECT_EQ(NewVal, OldVal);
+  }
+  {
+    Type OldVal = 42;
+    Type NewVal = 24;
+    Type V = OldVal;
+    EXPECT_TRUE(atomic_compare_exchange_weak(reinterpret_cast<T *>(&V), &OldVal,
+                                             NewVal, memory_order_relaxed));
+    EXPECT_FALSE(atomic_compare_exchange_weak(
+        reinterpret_cast<T *>(&V), &OldVal, NewVal, memory_order_relaxed));
+    EXPECT_EQ(NewVal, OldVal);
+  }
+}
+
+TEST(ScudoStandalone, AtomicCompareExchangeTest) {
+  checkAtomicCompareExchange<atomic_u8>();
+  checkAtomicCompareExchange<atomic_u16>();
+  checkAtomicCompareExchange<atomic_u32>();
+  checkAtomicCompareExchange<atomic_u64>();
+  checkAtomicCompareExchange<atomic_uptr>();
+}
+
+} // namespace scudo

Added: compiler-rt/trunk/lib/scudo/standalone/tests/list_test.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/scudo/standalone/tests/list_test.cc?rev=353055&view=auto
==============================================================================
--- compiler-rt/trunk/lib/scudo/standalone/tests/list_test.cc (added)
+++ compiler-rt/trunk/lib/scudo/standalone/tests/list_test.cc Mon Feb  4 08:25:40 2019
@@ -0,0 +1,185 @@
+//===-- list_test.cc --------------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "scudo/standalone/list.h"
+#include "gtest/gtest.h"
+
+struct ListItem {
+  ListItem *Next;
+};
+
+typedef scudo::IntrusiveList<ListItem> List;
+
+static List StaticList;
+
+static void setList(List *L, ListItem *X = nullptr, ListItem *Y = nullptr,
+                    ListItem *Z = nullptr) {
+  L->clear();
+  if (X)
+    L->push_back(X);
+  if (Y)
+    L->push_back(Y);
+  if (Z)
+    L->push_back(Z);
+}
+
+static void checkList(List *L, ListItem *I1, ListItem *I2 = nullptr,
+                      ListItem *I3 = nullptr, ListItem *I4 = nullptr,
+                      ListItem *I5 = nullptr, ListItem *I6 = nullptr) {
+  if (I1) {
+    EXPECT_EQ(L->front(), I1);
+    L->pop_front();
+  }
+  if (I2) {
+    EXPECT_EQ(L->front(), I2);
+    L->pop_front();
+  }
+  if (I3) {
+    EXPECT_EQ(L->front(), I3);
+    L->pop_front();
+  }
+  if (I4) {
+    EXPECT_EQ(L->front(), I4);
+    L->pop_front();
+  }
+  if (I5) {
+    EXPECT_EQ(L->front(), I5);
+    L->pop_front();
+  }
+  if (I6) {
+    EXPECT_EQ(L->front(), I6);
+    L->pop_front();
+  }
+  EXPECT_TRUE(L->empty());
+}
+
+TEST(ScudoSandalone, IntrusiveList) {
+  ListItem Items[6];
+  EXPECT_EQ(StaticList.size(), 0U);
+
+  List L;
+  L.clear();
+
+  ListItem *X = &Items[0];
+  ListItem *Y = &Items[1];
+  ListItem *Z = &Items[2];
+  ListItem *A = &Items[3];
+  ListItem *B = &Items[4];
+  ListItem *C = &Items[5];
+
+  EXPECT_EQ(L.size(), 0U);
+  L.push_back(X);
+  EXPECT_EQ(L.size(), 1U);
+  EXPECT_EQ(L.back(), X);
+  EXPECT_EQ(L.front(), X);
+  L.pop_front();
+  EXPECT_TRUE(L.empty());
+  L.checkConsistency();
+
+  L.push_front(X);
+  EXPECT_EQ(L.size(), 1U);
+  EXPECT_EQ(L.back(), X);
+  EXPECT_EQ(L.front(), X);
+  L.pop_front();
+  EXPECT_TRUE(L.empty());
+  L.checkConsistency();
+
+  L.push_front(X);
+  L.push_front(Y);
+  L.push_front(Z);
+  EXPECT_EQ(L.size(), 3U);
+  EXPECT_EQ(L.front(), Z);
+  EXPECT_EQ(L.back(), X);
+  L.checkConsistency();
+
+  L.pop_front();
+  EXPECT_EQ(L.size(), 2U);
+  EXPECT_EQ(L.front(), Y);
+  EXPECT_EQ(L.back(), X);
+  L.pop_front();
+  L.pop_front();
+  EXPECT_TRUE(L.empty());
+  L.checkConsistency();
+
+  L.push_back(X);
+  L.push_back(Y);
+  L.push_back(Z);
+  EXPECT_EQ(L.size(), 3U);
+  EXPECT_EQ(L.front(), X);
+  EXPECT_EQ(L.back(), Z);
+  L.checkConsistency();
+
+  L.pop_front();
+  EXPECT_EQ(L.size(), 2U);
+  EXPECT_EQ(L.front(), Y);
+  EXPECT_EQ(L.back(), Z);
+  L.pop_front();
+  L.pop_front();
+  EXPECT_TRUE(L.empty());
+  L.checkConsistency();
+
+  L.push_back(X);
+  L.push_back(Y);
+  L.push_back(Z);
+  L.extract(X, Y);
+  EXPECT_EQ(L.size(), 2U);
+  EXPECT_EQ(L.front(), X);
+  EXPECT_EQ(L.back(), Z);
+  L.checkConsistency();
+  L.extract(X, Z);
+  EXPECT_EQ(L.size(), 1U);
+  EXPECT_EQ(L.front(), X);
+  EXPECT_EQ(L.back(), X);
+  L.checkConsistency();
+  L.pop_front();
+  EXPECT_TRUE(L.empty());
+
+  List L1, L2;
+  L1.clear();
+  L2.clear();
+
+  L1.append_front(&L2);
+  EXPECT_TRUE(L1.empty());
+  EXPECT_TRUE(L2.empty());
+
+  L1.append_back(&L2);
+  EXPECT_TRUE(L1.empty());
+  EXPECT_TRUE(L2.empty());
+
+  setList(&L1, X);
+  checkList(&L1, X);
+
+  setList(&L1, X, Y, Z);
+  setList(&L2, A, B, C);
+  L1.append_back(&L2);
+  checkList(&L1, X, Y, Z, A, B, C);
+  EXPECT_TRUE(L2.empty());
+
+  setList(&L1, X, Y);
+  setList(&L2);
+  L1.append_front(&L2);
+  checkList(&L1, X, Y);
+  EXPECT_TRUE(L2.empty());
+}
+
+TEST(ScudoStandalone, IntrusiveListAppendEmpty) {
+  ListItem I;
+  List L;
+  L.clear();
+  L.push_back(&I);
+  List L2;
+  L2.clear();
+  L.append_back(&L2);
+  EXPECT_EQ(L.back(), &I);
+  EXPECT_EQ(L.front(), &I);
+  EXPECT_EQ(L.size(), 1U);
+  L.append_front(&L2);
+  EXPECT_EQ(L.back(), &I);
+  EXPECT_EQ(L.front(), &I);
+  EXPECT_EQ(L.size(), 1U);
+}

Added: compiler-rt/trunk/lib/scudo/standalone/tests/scudo_unit_test_main.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/scudo/standalone/tests/scudo_unit_test_main.cc?rev=353055&view=auto
==============================================================================
--- compiler-rt/trunk/lib/scudo/standalone/tests/scudo_unit_test_main.cc (added)
+++ compiler-rt/trunk/lib/scudo/standalone/tests/scudo_unit_test_main.cc Mon Feb  4 08:25:40 2019
@@ -0,0 +1,14 @@
+//===-- scudo_unit_test_main.cc ---------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "gtest/gtest.h"
+
+int main(int argc, char **argv) {
+  testing::InitGoogleTest(&argc, argv);
+  return RUN_ALL_TESTS();
+}

Modified: compiler-rt/trunk/test/scudo/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/scudo/CMakeLists.txt?rev=353055&r1=353054&r2=353055&view=diff
==============================================================================
--- compiler-rt/trunk/test/scudo/CMakeLists.txt (original)
+++ compiler-rt/trunk/test/scudo/CMakeLists.txt Mon Feb  4 08:25:40 2019
@@ -35,6 +35,8 @@ foreach(arch ${SCUDO_TEST_ARCH})
   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})

Added: compiler-rt/trunk/test/scudo/standalone/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/scudo/standalone/CMakeLists.txt?rev=353055&view=auto
==============================================================================
--- compiler-rt/trunk/test/scudo/standalone/CMakeLists.txt (added)
+++ compiler-rt/trunk/test/scudo/standalone/CMakeLists.txt Mon Feb  4 08:25:40 2019
@@ -0,0 +1,15 @@
+if(COMPILER_RT_INCLUDE_TESTS AND COMPILER_RT_HAS_SCUDO_STANDALONE)
+  configure_lit_site_cfg(
+    ${CMAKE_CURRENT_SOURCE_DIR}/unit/lit.site.cfg.in
+    ${CMAKE_CURRENT_BINARY_DIR}/unit/lit.site.cfg)
+  list(APPEND SCUDO_STANDALONE_TEST_DEPS ScudoUnitTests)
+  list(APPEND SCUDO_STANDALONE_TESTSUITES ${CMAKE_CURRENT_BINARY_DIR}/unit)
+endif()
+
+add_lit_testsuite(check-scudo_standalone
+  "Running Scudo Standalone tests"
+  ${SCUDO_STANDALONE_TESTSUITES}
+  DEPENDS ${SCUDO_STANDALONE_TEST_DEPS})
+
+set_target_properties(check-scudo_standalone
+  PROPERTIES FOLDER "Compiler-RT Tests")

Added: compiler-rt/trunk/test/scudo/standalone/unit/lit.site.cfg.in
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/scudo/standalone/unit/lit.site.cfg.in?rev=353055&view=auto
==============================================================================
--- compiler-rt/trunk/test/scudo/standalone/unit/lit.site.cfg.in (added)
+++ compiler-rt/trunk/test/scudo/standalone/unit/lit.site.cfg.in Mon Feb  4 08:25:40 2019
@@ -0,0 +1,12 @@
+ at LIT_SITE_CFG_IN_HEADER@
+
+# Load common config for all compiler-rt unit tests.
+lit_config.load_config(config, "@COMPILER_RT_BINARY_DIR@/unittests/lit.common.unit.configured")
+
+# Setup config name.
+config.name = 'ScudoStandalone-Unit'
+
+# Setup test source and exec root.
+# For unit tests, we define it as build directory with unit tests.
+config.test_exec_root = "@COMPILER_RT_BINARY_DIR@/lib/scudo/standalone/tests"
+config.test_source_root = config.test_exec_root




More information about the llvm-commits mailing list