clemenswasser updated this revision to Diff 393750.
clemenswasser added a comment.
Herald added subscribers: luke957, s.egerton, simoncook.

Implement ProcessGlobalRegions
Fix Interceptors for Windows


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

https://reviews.llvm.org/D115103

Files:
  clang/lib/Driver/ToolChains/MSVC.cpp
  compiler-rt/cmake/config-ix.cmake
  compiler-rt/lib/lsan/CMakeLists.txt
  compiler-rt/lib/lsan/lsan.h
  compiler-rt/lib/lsan/lsan_allocator.h
  compiler-rt/lib/lsan/lsan_common.cpp
  compiler-rt/lib/lsan/lsan_common.h
  compiler-rt/lib/lsan/lsan_common_win.cpp
  compiler-rt/lib/lsan/lsan_interceptors.cpp
  compiler-rt/lib/lsan/lsan_win.cpp
  compiler-rt/lib/lsan/lsan_win.h

Index: compiler-rt/lib/lsan/lsan_win.h
===================================================================
--- /dev/null
+++ compiler-rt/lib/lsan/lsan_win.h
@@ -0,0 +1,41 @@
+//=-- lsan_win.h -----------------------------------------------------===//
+//
+// 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
+//
+//===---------------------------------------------------------------------===//
+//
+// This file is a part of LeakSanitizer.
+// Standalone LSan RTL code common to Windows systems.
+//
+//===---------------------------------------------------------------------===//
+
+#ifndef LSAN_WINDOWS_H
+#define LSAN_WINDOWS_H
+
+#include "lsan_thread.h"
+#include "sanitizer_common/sanitizer_platform.h"
+
+#if !SANITIZER_WINDOWS
+#  error "lsan_win.h is used only on Windows systems (SANITIZER_WINDOWS)"
+#endif
+
+namespace __sanitizer {
+struct DTLS;
+}
+
+namespace __lsan {
+
+class ThreadContext final : public ThreadContextLsanBase {
+ public:
+  explicit ThreadContext(int tid);
+  void OnStarted(void *arg) override;
+};
+
+void ThreadStart(u32 tid, tid_t os_id,
+                 ThreadType thread_type = ThreadType::Regular);
+
+}  // namespace __lsan
+
+#endif  // LSAN_WINDOWS_H
Index: compiler-rt/lib/lsan/lsan_win.cpp
===================================================================
--- /dev/null
+++ compiler-rt/lib/lsan/lsan_win.cpp
@@ -0,0 +1,106 @@
+//=-- lsan_win.cpp -------------------------------------------------------===//
+//
+// 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
+//
+//===---------------------------------------------------------------------===//
+//
+// This file is a part of LeakSanitizer.
+// Standalone LSan RTL code common to POSIX-like systems.
+//
+//===---------------------------------------------------------------------===//
+
+#include "sanitizer_common/sanitizer_platform.h"
+
+#if SANITIZER_WINDOWS
+#  include "lsan.h"
+#  include "lsan_allocator.h"
+#  include "sanitizer_common/sanitizer_stacktrace.h"
+#  include "sanitizer_common/sanitizer_tls_get_addr.h"
+
+namespace __lsan {
+
+ThreadContext::ThreadContext(int tid) : ThreadContextLsanBase(tid) {}
+
+struct OnStartedArgs {
+  uptr stack_begin;
+  uptr stack_end;
+  uptr cache_begin;
+  uptr cache_end;
+  uptr tls_begin;
+  uptr tls_end;
+};
+
+void ThreadContext::OnStarted(void *arg) {
+  auto args = reinterpret_cast<const OnStartedArgs *>(arg);
+  stack_begin_ = args->stack_begin;
+  stack_end_ = args->stack_end;
+  cache_begin_ = args->cache_begin;
+  cache_end_ = args->cache_end;
+}
+
+void ThreadStart(u32 tid, tid_t os_id, ThreadType thread_type) {
+  OnStartedArgs args;
+  uptr stack_size = 0;
+  uptr tls_size = 0;
+  GetThreadStackAndTls(tid == kMainTid, &args.stack_begin, &stack_size,
+                       &args.tls_begin, &tls_size);
+  args.stack_end = args.stack_begin + stack_size;
+  args.tls_end = args.tls_begin + tls_size;
+  GetAllocatorCacheRange(&args.cache_begin, &args.cache_end);
+  ThreadContextLsanBase::ThreadStart(tid, os_id, thread_type, &args);
+}
+
+bool GetThreadRangesLocked(tid_t os_id, uptr *stack_begin, uptr *stack_end,
+                           uptr *tls_begin, uptr *tls_end, uptr *cache_begin,
+                           uptr *cache_end, DTLS **dtls) {
+  ThreadContext *context = static_cast<ThreadContext *>(
+      GetThreadRegistryLocked()->FindThreadContextByOsIDLocked(os_id));
+  if (!context)
+    return false;
+  *stack_begin = context->stack_begin();
+  *stack_end = context->stack_end();
+  *cache_begin = context->cache_begin();
+  *cache_end = context->cache_end();
+  *dtls = 0;
+  return true;
+}
+
+void InitializeMainThread() {
+  u32 tid = ThreadCreate(kMainTid, true);
+  CHECK_EQ(tid, kMainTid);
+  ThreadStart(tid, GetTid());
+}
+
+static void OnStackUnwind(const SignalContext &sig, const void *,
+                          BufferedStackTrace *stack) {
+  stack->Unwind(StackTrace::GetNextInstructionPc(sig.pc), sig.bp, sig.context,
+                common_flags()->fast_unwind_on_fatal);
+}
+
+void LsanOnDeadlySignal(int signo, void *siginfo, void *context) {
+  HandleDeadlySignal(siginfo, context, GetCurrentThread(), &OnStackUnwind,
+                     nullptr);
+}
+
+void ReplaceSystemMalloc() {}
+
+static THREADLOCAL u32 current_thread_tid = kInvalidTid;
+u32 GetCurrentThread() { return current_thread_tid; }
+void SetCurrentThread(u32 tid) { current_thread_tid = tid; }
+
+static THREADLOCAL AllocatorCache allocator_cache;
+AllocatorCache *GetAllocatorCache() { return &allocator_cache; }
+
+}  // namespace __lsan
+
+int lsan_win_init() {
+  __lsan_init();
+  return 0;
+}
+
+#  pragma section(".CRT$XIB", long, read)
+__declspec(allocate(".CRT$XIB")) int (*__lsan_preinit)() = lsan_win_init;
+
+#endif  // SANITIZER_WINDOWS
Index: compiler-rt/lib/lsan/lsan_interceptors.cpp
===================================================================
--- compiler-rt/lib/lsan/lsan_interceptors.cpp
+++ compiler-rt/lib/lsan/lsan_interceptors.cpp
@@ -99,26 +99,30 @@
   return lsan_realloc(ptr, size, stack);
 }
 
-INTERCEPTOR(void*, reallocarray, void *q, uptr nmemb, uptr size) {
-  ENSURE_LSAN_INITED;
-  GET_STACK_TRACE_MALLOC;
-  return lsan_reallocarray(q, nmemb, size, stack);
-}
-
+#  if SANITIZER_WINDOWS
+#    define LSAN_MAYBE_INTERCEPT_REALLOCARRY
+#    define LSAN_MAYBE_INTERCEPT_POSIX_MEMALIGN
+#    define LSAN_MAYBE_INTERCEPT_VALLOC
+#  else
 INTERCEPTOR(int, posix_memalign, void **memptr, uptr alignment, uptr size) {
   ENSURE_LSAN_INITED;
   GET_STACK_TRACE_MALLOC;
   return lsan_posix_memalign(memptr, alignment, size, stack);
 }
+#    define LSAN_MAYBE_INTERCEPT_POSIX_MEMALIGN \
+      INTERCEPT_FUNCTION(posix_memalign)
 
-INTERCEPTOR(void*, valloc, uptr size) {
+INTERCEPTOR(void *, valloc, uptr size) {
   ENSURE_LSAN_INITED;
   GET_STACK_TRACE_MALLOC;
   return lsan_valloc(size, stack);
 }
+#    define LSAN_MAYBE_INTERCEPT_VALLOC INTERCEPT_FUNCTION(valloc)
+#  endif
+
 #endif  // !SANITIZER_MAC
 
-#if SANITIZER_INTERCEPT_MEMALIGN
+#if SANITIZER_INTERCEPT_MEMALIGN && !SANITIZER_WINDOWS
 INTERCEPTOR(void*, memalign, uptr alignment, uptr size) {
   ENSURE_LSAN_INITED;
   GET_STACK_TRACE_MALLOC;
@@ -143,17 +147,23 @@
 #endif  // SANITIZER_INTERCEPT___LIBC_MEMALIGN
 
 #if SANITIZER_INTERCEPT_ALIGNED_ALLOC
-INTERCEPTOR(void*, aligned_alloc, uptr alignment, uptr size) {
+#if SANITIZER_WINDOWS
+#define LSAN_ALIGNED_ALLOC_NAME _aligned_malloc
+#else
+#define LSAN_ALIGNED_ALLOC_NAME aligned_alloc
+#endif
+
+INTERCEPTOR(void*, LSAN_ALIGNED_ALLOC_NAME, uptr alignment, uptr size) {
   ENSURE_LSAN_INITED;
   GET_STACK_TRACE_MALLOC;
   return lsan_aligned_alloc(alignment, size, stack);
 }
-#define LSAN_MAYBE_INTERCEPT_ALIGNED_ALLOC INTERCEPT_FUNCTION(aligned_alloc)
+#define LSAN_MAYBE_INTERCEPT_ALIGNED_ALLOC INTERCEPT_FUNCTION(LSAN_ALIGNED_ALLOC_NAME)
 #else
 #define LSAN_MAYBE_INTERCEPT_ALIGNED_ALLOC
 #endif
 
-#if SANITIZER_INTERCEPT_MALLOC_USABLE_SIZE
+#if SANITIZER_INTERCEPT_MALLOC_USABLE_SIZE && !SANITIZER_WINDOWS
 INTERCEPTOR(uptr, malloc_usable_size, void *ptr) {
   ENSURE_LSAN_INITED;
   return GetMallocUsableSize(ptr);
@@ -244,9 +254,15 @@
 // OS X we need to intercept them using their mangled names.
 #if !SANITIZER_MAC
 
-INTERCEPTOR_ATTRIBUTE
+#if SANITIZER_WINDOWS
+#define INTERCEPTOR_ATTRIBUTE_DIFFERENT_LINKAGE
+#else
+#define INTERCEPTOR_ATTRIBUTE_DIFFERENT_LINKAGE INTERCEPTOR_ATTRIBUTE
+#endif
+
+INTERCEPTOR_ATTRIBUTE_DIFFERENT_LINKAGE
 void *operator new(size_t size) { OPERATOR_NEW_BODY(false /*nothrow*/); }
-INTERCEPTOR_ATTRIBUTE
+INTERCEPTOR_ATTRIBUTE_DIFFERENT_LINKAGE
 void *operator new[](size_t size) { OPERATOR_NEW_BODY(false /*nothrow*/); }
 INTERCEPTOR_ATTRIBUTE
 void *operator new(size_t size, std::nothrow_t const&)
@@ -267,19 +283,19 @@
 void *operator new[](size_t size, std::align_val_t align, std::nothrow_t const&)
 { OPERATOR_NEW_BODY_ALIGN(true /*nothrow*/); }
 
-INTERCEPTOR_ATTRIBUTE
+INTERCEPTOR_ATTRIBUTE_DIFFERENT_LINKAGE
 void operator delete(void *ptr) NOEXCEPT { OPERATOR_DELETE_BODY; }
-INTERCEPTOR_ATTRIBUTE
+INTERCEPTOR_ATTRIBUTE_DIFFERENT_LINKAGE
 void operator delete[](void *ptr) NOEXCEPT { OPERATOR_DELETE_BODY; }
 INTERCEPTOR_ATTRIBUTE
 void operator delete(void *ptr, std::nothrow_t const&) { OPERATOR_DELETE_BODY; }
 INTERCEPTOR_ATTRIBUTE
 void operator delete[](void *ptr, std::nothrow_t const &)
 { OPERATOR_DELETE_BODY; }
-INTERCEPTOR_ATTRIBUTE
+INTERCEPTOR_ATTRIBUTE_DIFFERENT_LINKAGE
 void operator delete(void *ptr, size_t size) NOEXCEPT
 { OPERATOR_DELETE_BODY; }
-INTERCEPTOR_ATTRIBUTE
+INTERCEPTOR_ATTRIBUTE_DIFFERENT_LINKAGE
 void operator delete[](void *ptr, size_t size) NOEXCEPT
 { OPERATOR_DELETE_BODY; }
 INTERCEPTOR_ATTRIBUTE
@@ -479,10 +495,14 @@
   return res;
 }
 
+#define LSAN_MAYBE_INTERCEPT_PTHREAD_CREATE INTERCEPT_FUNCTION(pthread_create)
+
 INTERCEPTOR(int, pthread_join, void *t, void **arg) {
   return REAL(pthread_join)(t, arg);
 }
 
+#define LSAN_MAYBE_INTERCEPT_PTHREAD_CREATE INTERCEPT_FUNCTION(pthread_join)
+
 DEFINE_REAL_PTHREAD_FUNCTIONS
 
 INTERCEPTOR(void, _exit, int status) {
@@ -490,9 +510,15 @@
   REAL(_exit)(status);
 }
 
+#define LSAN_MAYBE_INTERCEPT__EXIT INTERCEPT_FUNCTION(_exit)
+
 #define COMMON_INTERCEPT_FUNCTION(name) INTERCEPT_FUNCTION(name)
 #include "sanitizer_common/sanitizer_signal_interceptors.inc"
 
+#else
+#  define LSAN_MAYBE_INTERCEPT_PTHREAD_CREATE
+#  define LSAN_MAYBE_INTERCEPT_PTHREAD_JOIN
+#  define LSAN_MAYBE_INTERCEPT__EXIT
 #endif  // SANITIZER_POSIX
 
 namespace __lsan {
@@ -500,7 +526,9 @@
 void InitializeInterceptors() {
   // Fuchsia doesn't use interceptors that require any setup.
 #if !SANITIZER_FUCHSIA
+#  if SANITIZER_POSIX
   InitializeSignalInterceptors();
+#  endif
 
   INTERCEPT_FUNCTION(malloc);
   INTERCEPT_FUNCTION(free);
@@ -510,15 +538,15 @@
   LSAN_MAYBE_INTERCEPT_MEMALIGN;
   LSAN_MAYBE_INTERCEPT___LIBC_MEMALIGN;
   LSAN_MAYBE_INTERCEPT_ALIGNED_ALLOC;
-  INTERCEPT_FUNCTION(posix_memalign);
-  INTERCEPT_FUNCTION(valloc);
+  LSAN_MAYBE_INTERCEPT_POSIX_MEMALIGN;
+  LSAN_MAYBE_INTERCEPT_VALLOC;
   LSAN_MAYBE_INTERCEPT_PVALLOC;
   LSAN_MAYBE_INTERCEPT_MALLOC_USABLE_SIZE;
   LSAN_MAYBE_INTERCEPT_MALLINFO;
   LSAN_MAYBE_INTERCEPT_MALLOPT;
-  INTERCEPT_FUNCTION(pthread_create);
-  INTERCEPT_FUNCTION(pthread_join);
-  INTERCEPT_FUNCTION(_exit);
+  LSAN_MAYBE_INTERCEPT_PTHREAD_CREATE;
+  LSAN_MAYBE_INTERCEPT_PTHREAD_JOIN;
+  LSAN_MAYBE_INTERCEPT__EXIT;
 
   LSAN_MAYBE_INTERCEPT__LWP_EXIT;
   LSAN_MAYBE_INTERCEPT_THR_EXIT;
@@ -529,7 +557,7 @@
 
   LSAN_MAYBE_INTERCEPT_STRERROR;
 
-#if !SANITIZER_NETBSD && !SANITIZER_FREEBSD
+#if !SANITIZER_NETBSD && !SANITIZER_FREEBSD && !SANITIZER_WINDOWS
   if (pthread_key_create(&g_thread_finalize_key, &thread_finalize)) {
     Report("LeakSanitizer: failed to create thread key.\n");
     Die();
Index: compiler-rt/lib/lsan/lsan_common_win.cpp
===================================================================
--- /dev/null
+++ compiler-rt/lib/lsan/lsan_common_win.cpp
@@ -0,0 +1,95 @@
+//=-- lsan_common_win.cpp -------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+//
+// This file is a part of LeakSanitizer.
+// Implementation of common leak checking functionality. Darwin-specific code.
+//
+//===----------------------------------------------------------------------===//
+
+#include "lsan_common.h"
+#include "sanitizer_common/sanitizer_platform.h"
+
+#if CAN_SANITIZE_LEAKS && SANITIZER_WINDOWS
+
+#  define WIN32_LEAN_AND_MEAN
+#  include <windows.h>
+
+// `windows.h` needs to be included before `dbghelp.h`
+#  include <dbghelp.h>
+#  pragma comment(lib, "Dbghelp.lib")
+
+namespace __lsan {
+
+void HandleLeaks() {}
+
+void InitializePlatformSpecificModules() {}
+
+void LockStuffAndStopTheWorld(StopTheWorldCallback callback,
+                              CheckForLeaksParam *argument) {
+  LockThreadRegistry();
+  LockAllocator();
+  StopTheWorld(callback, argument);
+  UnlockAllocator();
+  UnlockThreadRegistry();
+}
+
+THREADLOCAL int disable_counter;
+bool DisabledInThisThread() { return disable_counter > 0; }
+void DisableInThisThread() { disable_counter++; }
+void EnableInThisThread() {
+  if (disable_counter == 0) {
+    DisableCounterUnderflow();
+  }
+  disable_counter--;
+}
+
+BOOL CALLBACK EnumLoadedModulesCallback(PCSTR module_name, DWORD64 module_base,
+                                        ULONG module_size, PVOID user_context) {
+  auto *frontier = reinterpret_cast<Frontier *>(user_context);
+
+  // Parse the PE Headers of all loaded Modules
+  const auto *module_nt_header =
+      ImageNtHeader(reinterpret_cast<PVOID>(module_base));
+
+  CHECK(module_nt_header);
+
+  const auto *section_header =
+      reinterpret_cast<const IMAGE_SECTION_HEADER *>(module_nt_header + 1);
+
+  // Find the `.data` section
+  for (WORD i = 0; i < module_nt_header->FileHeader.NumberOfSections;
+       ++i, ++section_header) {
+    const char data_section_name[6] = ".data";
+    const auto is_data_section =
+        internal_strncmp(reinterpret_cast<const char *>(section_header->Name),
+                         data_section_name, sizeof(data_section_name)) == 0;
+
+    if (!is_data_section)
+      continue;
+
+    ScanGlobalRange(module_base + section_header->VirtualAddress,
+                    module_base + section_header->VirtualAddress +
+                        section_header->Misc.VirtualSize - 1,
+                    frontier);
+  }
+
+  return TRUE;
+}
+
+void ProcessGlobalRegions(Frontier *frontier) {
+  HANDLE this_process = GetCurrentProcess();
+
+  EnumerateLoadedModules(this_process, EnumLoadedModulesCallback, frontier);
+}
+void ProcessPlatformSpecificAllocations(Frontier *frontier) {}
+
+LoadedModule *GetLinker() { return nullptr; }
+
+}  // namespace __lsan
+
+#endif  // CAN_SANITIZE_LEAKS && SANITIZER_WINDOWS
Index: compiler-rt/lib/lsan/lsan_common.h
===================================================================
--- compiler-rt/lib/lsan/lsan_common.h
+++ compiler-rt/lib/lsan/lsan_common.h
@@ -44,8 +44,8 @@
 #define CAN_SANITIZE_LEAKS 1
 #elif SANITIZER_RISCV64 && SANITIZER_LINUX
 #define CAN_SANITIZE_LEAKS 1
-#elif SANITIZER_NETBSD || SANITIZER_FUCHSIA
-#define CAN_SANITIZE_LEAKS 1
+#elif SANITIZER_NETBSD || SANITIZER_FUCHSIA || SANITIZER_WINDOWS
+#  define CAN_SANITIZE_LEAKS 1
 #else
 #define CAN_SANITIZE_LEAKS 0
 #endif
Index: compiler-rt/lib/lsan/lsan_common.cpp
===================================================================
--- compiler-rt/lib/lsan/lsan_common.cpp
+++ compiler-rt/lib/lsan/lsan_common.cpp
@@ -245,12 +245,12 @@
   const uptr kMinAddress = 4 * 4096;
   if (p < kMinAddress)
     return false;
-#  if defined(__x86_64__)
+#  if defined(__x86_64__) || defined(_M_X64)
   // Accept only canonical form user-space addresses.
   return ((p >> 47) == 0);
 #  elif defined(__mips64)
   return ((p >> 40) == 0);
-#  elif defined(__aarch64__)
+#  elif defined(__aarch64__) || defined(_M_ARM64)
   unsigned runtimeVMA = (MostSignificantSetBitIndex(GET_CURRENT_FRAME()) + 1);
   return ((p >> runtimeVMA) == 0);
 #  else
@@ -501,12 +501,16 @@
 
 static void ProcessRootRegion(Frontier *frontier,
                               const RootRegion &root_region) {
+#  if SANITIZER_WINDOWS
+  // TODO
+#  else
   MemoryMappingLayout proc_maps(/*cache_enabled*/ true);
   MemoryMappedSegment segment;
   while (proc_maps.Next(&segment)) {
     ScanRootRegion(frontier, root_region, segment.start, segment.end,
                    segment.IsReadable());
   }
+#  endif
 }
 
 // Scans root regions for heap pointers.
Index: compiler-rt/lib/lsan/lsan_allocator.h
===================================================================
--- compiler-rt/lib/lsan/lsan_allocator.h
+++ compiler-rt/lib/lsan/lsan_allocator.h
@@ -49,8 +49,9 @@
   u32 stack_trace_id;
 };
 
-#if defined(__mips64) || defined(__aarch64__) || defined(__i386__) || \
-    defined(__arm__) || SANITIZER_RISCV64 || defined(__hexagon__)
+#if defined(__mips64) || defined(__aarch64__) || defined(_M_ARM64) || \
+    defined(__i386__) || defined(_M_IX86) || defined(__arm__) ||      \
+    defined(_M_ARM) || SANITIZER_RISCV64 || defined(__hexagon__)
 template <typename AddressSpaceViewTy>
 struct AP32 {
   static const uptr kSpaceBeg = 0;
@@ -65,20 +66,21 @@
 template <typename AddressSpaceView>
 using PrimaryAllocatorASVT = SizeClassAllocator32<AP32<AddressSpaceView>>;
 using PrimaryAllocator = PrimaryAllocatorASVT<LocalAddressSpaceView>;
-#elif defined(__x86_64__) || defined(__powerpc64__) || defined(__s390x__)
-# if SANITIZER_FUCHSIA
+#elif defined(__x86_64__) || defined(_M_X64) || defined(__powerpc64__) || \
+    defined(__s390x__)
+#  if SANITIZER_FUCHSIA
 const uptr kAllocatorSpace = ~(uptr)0;
-const uptr kAllocatorSize  =  0x40000000000ULL;  // 4T.
-# elif defined(__powerpc64__)
+const uptr kAllocatorSize = 0x40000000000ULL;  // 4T.
+#  elif defined(__powerpc64__)
 const uptr kAllocatorSpace = 0xa0000000000ULL;
-const uptr kAllocatorSize  = 0x20000000000ULL;  // 2T.
-#elif defined(__s390x__)
+const uptr kAllocatorSize = 0x20000000000ULL;  // 2T.
+#  elif defined(__s390x__)
 const uptr kAllocatorSpace = 0x40000000000ULL;
 const uptr kAllocatorSize = 0x40000000000ULL;  // 4T.
-# else
+#  else
 const uptr kAllocatorSpace = 0x600000000000ULL;
-const uptr kAllocatorSize  = 0x40000000000ULL;  // 4T.
-# endif
+const uptr kAllocatorSize = 0x40000000000ULL;  // 4T.
+#  endif
 template <typename AddressSpaceViewTy>
 struct AP64 {  // Allocator64 parameters. Deliberately using a short name.
   static const uptr kSpaceBeg = kAllocatorSpace;
@@ -93,6 +95,8 @@
 template <typename AddressSpaceView>
 using PrimaryAllocatorASVT = SizeClassAllocator64<AP64<AddressSpaceView>>;
 using PrimaryAllocator = PrimaryAllocatorASVT<LocalAddressSpaceView>;
+#else
+#  error Architecture not supported!
 #endif
 
 template <typename AddressSpaceView>
Index: compiler-rt/lib/lsan/lsan.h
===================================================================
--- compiler-rt/lib/lsan/lsan.h
+++ compiler-rt/lib/lsan/lsan.h
@@ -16,6 +16,8 @@
 #  include "lsan_posix.h"
 #elif SANITIZER_FUCHSIA
 #  include "lsan_fuchsia.h"
+#elif SANITIZER_WINDOWS
+#  include "lsan_win.h"
 #endif
 #include "sanitizer_common/sanitizer_flags.h"
 #include "sanitizer_common/sanitizer_stacktrace.h"
Index: compiler-rt/lib/lsan/CMakeLists.txt
===================================================================
--- compiler-rt/lib/lsan/CMakeLists.txt
+++ compiler-rt/lib/lsan/CMakeLists.txt
@@ -11,6 +11,7 @@
   lsan_common_fuchsia.cpp
   lsan_common_linux.cpp
   lsan_common_mac.cpp
+  lsan_common_win.cpp
   )
 
 set(LSAN_SOURCES
@@ -24,6 +25,7 @@
   lsan_posix.cpp
   lsan_preinit.cpp
   lsan_thread.cpp
+  lsan_win.cpp
   )
 
 set(LSAN_HEADERS
Index: compiler-rt/cmake/config-ix.cmake
===================================================================
--- compiler-rt/cmake/config-ix.cmake
+++ compiler-rt/cmake/config-ix.cmake
@@ -709,7 +709,7 @@
 endif()
 
 if (COMPILER_RT_HAS_SANITIZER_COMMON AND LSAN_SUPPORTED_ARCH AND
-    OS_NAME MATCHES "Android|Darwin|Linux|NetBSD|Fuchsia")
+    OS_NAME MATCHES "Android|Darwin|Linux|NetBSD|Fuchsia|Windows")
   set(COMPILER_RT_HAS_LSAN TRUE)
 else()
   set(COMPILER_RT_HAS_LSAN FALSE)
Index: clang/lib/Driver/ToolChains/MSVC.cpp
===================================================================
--- clang/lib/Driver/ToolChains/MSVC.cpp
+++ clang/lib/Driver/ToolChains/MSVC.cpp
@@ -1408,6 +1408,7 @@
   Res |= SanitizerKind::PointerSubtract;
   Res |= SanitizerKind::Fuzzer;
   Res |= SanitizerKind::FuzzerNoLink;
+  Res |= SanitizerKind::Leak;
   Res &= ~SanitizerKind::CFIMFCall;
   return Res;
 }
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to