Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 1 Jul 2017 13:24:15 +0000 (UTC)
From:      Dimitry Andric <dim@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-vendor@freebsd.org
Subject:   svn commit: r320537 - in vendor/compiler-rt/dist: lib lib/asan lib/lsan lib/msan lib/msan/tests lib/profile lib/sanitizer_common lib/sanitizer_common/tests lib/scudo lib/tsan/rtl lib/tsan/tests lib...
Message-ID:  <201707011324.v61DOFvd022195@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: dim
Date: Sat Jul  1 13:24:15 2017
New Revision: 320537
URL: https://svnweb.freebsd.org/changeset/base/320537

Log:
  Vendor import of compiler-rt trunk r306956:
  https://llvm.org/svn/llvm-project/compiler-rt/trunk@306956

Added:
  vendor/compiler-rt/dist/lib/profile/InstrProfilingNameVar.c   (contents, props changed)
  vendor/compiler-rt/dist/lib/xray/xray_always_instrument.txt   (contents, props changed)
  vendor/compiler-rt/dist/lib/xray/xray_never_instrument.txt   (contents, props changed)
  vendor/compiler-rt/dist/test/asan/TestCases/Darwin/nil-return-struct.mm
  vendor/compiler-rt/dist/test/lsan/TestCases/allocator_returns_null.cc   (contents, props changed)
  vendor/compiler-rt/dist/test/xray/TestCases/Linux/always-never-instrument.cc   (contents, props changed)
Modified:
  vendor/compiler-rt/dist/lib/CMakeLists.txt
  vendor/compiler-rt/dist/lib/asan/asan_allocator.cc
  vendor/compiler-rt/dist/lib/asan/asan_interceptors.cc
  vendor/compiler-rt/dist/lib/asan/asan_new_delete.cc
  vendor/compiler-rt/dist/lib/asan/asan_win_dll_thunk.cc
  vendor/compiler-rt/dist/lib/lsan/lsan_allocator.cc
  vendor/compiler-rt/dist/lib/lsan/lsan_interceptors.cc
  vendor/compiler-rt/dist/lib/msan/msan_allocator.cc
  vendor/compiler-rt/dist/lib/msan/msan_interceptors.cc
  vendor/compiler-rt/dist/lib/msan/msan_new_delete.cc
  vendor/compiler-rt/dist/lib/msan/tests/msan_test.cc
  vendor/compiler-rt/dist/lib/profile/CMakeLists.txt
  vendor/compiler-rt/dist/lib/profile/InstrProfiling.c
  vendor/compiler-rt/dist/lib/profile/InstrProfilingBuffer.c
  vendor/compiler-rt/dist/lib/profile/InstrProfilingFile.c
  vendor/compiler-rt/dist/lib/profile/InstrProfilingInternal.h
  vendor/compiler-rt/dist/lib/profile/InstrProfilingWriter.c
  vendor/compiler-rt/dist/lib/sanitizer_common/sanitizer_allocator.cc
  vendor/compiler-rt/dist/lib/sanitizer_common/sanitizer_allocator.h
  vendor/compiler-rt/dist/lib/sanitizer_common/sanitizer_allocator_local_cache.h
  vendor/compiler-rt/dist/lib/sanitizer_common/sanitizer_allocator_primary32.h
  vendor/compiler-rt/dist/lib/sanitizer_common/sanitizer_allocator_primary64.h
  vendor/compiler-rt/dist/lib/sanitizer_common/sanitizer_common.h
  vendor/compiler-rt/dist/lib/sanitizer_common/sanitizer_common_interceptors.inc
  vendor/compiler-rt/dist/lib/sanitizer_common/sanitizer_platform_interceptors.h
  vendor/compiler-rt/dist/lib/sanitizer_common/sanitizer_posix.cc
  vendor/compiler-rt/dist/lib/sanitizer_common/sanitizer_win.cc
  vendor/compiler-rt/dist/lib/sanitizer_common/tests/sanitizer_allocator_test.cc
  vendor/compiler-rt/dist/lib/scudo/scudo_allocator.cpp
  vendor/compiler-rt/dist/lib/scudo/scudo_allocator.h
  vendor/compiler-rt/dist/lib/scudo/scudo_allocator_combined.h
  vendor/compiler-rt/dist/lib/scudo/scudo_new_delete.cpp
  vendor/compiler-rt/dist/lib/scudo/scudo_tls_android.cpp
  vendor/compiler-rt/dist/lib/tsan/rtl/tsan_mman.cc
  vendor/compiler-rt/dist/lib/tsan/rtl/tsan_new_delete.cc
  vendor/compiler-rt/dist/lib/tsan/tests/CMakeLists.txt
  vendor/compiler-rt/dist/test/CMakeLists.txt
  vendor/compiler-rt/dist/test/asan/TestCases/Darwin/asan_gen_prefixes.cc
  vendor/compiler-rt/dist/test/asan/TestCases/Linux/allocator_oom_test.cc
  vendor/compiler-rt/dist/test/asan/TestCases/Linux/asan_preload_test-3.cc
  vendor/compiler-rt/dist/test/asan/TestCases/Linux/init_fini_sections.cc
  vendor/compiler-rt/dist/test/asan/TestCases/Linux/textdomain.c
  vendor/compiler-rt/dist/test/asan/TestCases/Posix/asan-sigbus.cpp
  vendor/compiler-rt/dist/test/asan/TestCases/allocator_returns_null.cc
  vendor/compiler-rt/dist/test/asan/TestCases/malloc-no-intercept.c
  vendor/compiler-rt/dist/test/asan/TestCases/throw_call_test.cc
  vendor/compiler-rt/dist/test/asan/android_commands/android_common.py
  vendor/compiler-rt/dist/test/builtins/Unit/fp_test.h
  vendor/compiler-rt/dist/test/cfi/sibling.cpp
  vendor/compiler-rt/dist/test/msan/allocator_returns_null.cc
  vendor/compiler-rt/dist/test/profile/instrprof-override-filename.c
  vendor/compiler-rt/dist/test/scudo/memalign.cpp
  vendor/compiler-rt/dist/test/scudo/sizes.cpp
  vendor/compiler-rt/dist/test/tsan/allocator_returns_null.cc

Modified: vendor/compiler-rt/dist/lib/CMakeLists.txt
==============================================================================
--- vendor/compiler-rt/dist/lib/CMakeLists.txt	Sat Jul  1 13:24:12 2017	(r320536)
+++ vendor/compiler-rt/dist/lib/CMakeLists.txt	Sat Jul  1 13:24:15 2017	(r320537)
@@ -21,21 +21,12 @@ function(compiler_rt_build_runtime runtime)
   string(TOUPPER ${runtime} runtime_uppercase)
   if(COMPILER_RT_HAS_${runtime_uppercase})
     add_subdirectory(${runtime})
-    foreach(directory ${ARGN})
-      add_subdirectory(${directory})
-    endforeach()
+    if(${runtime} STREQUAL tsan)
+      add_subdirectory(tsan/dd)
+    endif()
   endif()
 endfunction()
 
-function(compiler_rt_build_sanitizer sanitizer)
-  string(TOUPPER ${sanitizer} sanitizer_uppercase)
-  string(TOLOWER ${sanitizer} sanitizer_lowercase)
-  list(FIND COMPILER_RT_SANITIZERS_TO_BUILD ${sanitizer_lowercase} result)
-  if(NOT ${result} EQUAL -1)
-    compiler_rt_build_runtime(${sanitizer} ${ARGN})
-  endif()
-endfunction()
-
 if(COMPILER_RT_BUILD_SANITIZERS)
   compiler_rt_build_runtime(interception)
 
@@ -45,14 +36,9 @@ if(COMPILER_RT_BUILD_SANITIZERS)
     add_subdirectory(ubsan)
   endif()
 
-  compiler_rt_build_sanitizer(asan)
-  compiler_rt_build_sanitizer(dfsan)
-  compiler_rt_build_sanitizer(msan)
-  compiler_rt_build_sanitizer(tsan tsan/dd)
-  compiler_rt_build_sanitizer(safestack)
-  compiler_rt_build_sanitizer(cfi)
-  compiler_rt_build_sanitizer(esan)
-  compiler_rt_build_sanitizer(scudo)
+  foreach(sanitizer ${COMPILER_RT_SANITIZERS_TO_BUILD})
+    compiler_rt_build_runtime(${sanitizer})
+  endforeach()
 
   compiler_rt_build_runtime(profile)
 endif()

Modified: vendor/compiler-rt/dist/lib/asan/asan_allocator.cc
==============================================================================
--- vendor/compiler-rt/dist/lib/asan/asan_allocator.cc	Sat Jul  1 13:24:12 2017	(r320536)
+++ vendor/compiler-rt/dist/lib/asan/asan_allocator.cc	Sat Jul  1 13:24:15 2017	(r320537)
@@ -160,7 +160,11 @@ struct QuarantineCallback {
   }
 
   void *Allocate(uptr size) {
-    return get_allocator().Allocate(cache_, size, 1);
+    void *res = get_allocator().Allocate(cache_, size, 1);
+    // TODO(alekseys): Consider making quarantine OOM-friendly.
+    if (UNLIKELY(!res))
+      return DieOnFailure::OnOOM();
+    return res;
   }
 
   void Deallocate(void *p) {
@@ -524,8 +528,7 @@ struct Allocator {
 
   // Expects the chunk to already be marked as quarantined by using
   // AtomicallySetQuarantineFlagIfAllocated.
-  void QuarantineChunk(AsanChunk *m, void *ptr, BufferedStackTrace *stack,
-                       AllocType alloc_type) {
+  void QuarantineChunk(AsanChunk *m, void *ptr, BufferedStackTrace *stack) {
     CHECK_EQ(m->chunk_state, CHUNK_QUARANTINE);
     CHECK_GE(m->alloc_tid, 0);
     if (SANITIZER_WORDSIZE == 64)  // On 32-bits this resides in user area.
@@ -603,7 +606,7 @@ struct Allocator {
       ReportNewDeleteSizeMismatch(p, delete_size, stack);
     }
 
-    QuarantineChunk(m, ptr, stack, alloc_type);
+    QuarantineChunk(m, ptr, stack);
   }
 
   void *Reallocate(void *old_ptr, uptr new_size, BufferedStackTrace *stack) {
@@ -632,7 +635,7 @@ struct Allocator {
   }
 
   void *Calloc(uptr nmemb, uptr size, BufferedStackTrace *stack) {
-    if (CallocShouldReturnNullDueToOverflow(size, nmemb))
+    if (CheckForCallocOverflow(size, nmemb))
       return AsanAllocator::FailureHandler::OnBadRequest();
     void *ptr = Allocate(nmemb * size, 8, stack, FROM_MALLOC, false);
     // If the memory comes from the secondary allocator no need to clear it

Modified: vendor/compiler-rt/dist/lib/asan/asan_interceptors.cc
==============================================================================
--- vendor/compiler-rt/dist/lib/asan/asan_interceptors.cc	Sat Jul  1 13:24:12 2017	(r320536)
+++ vendor/compiler-rt/dist/lib/asan/asan_interceptors.cc	Sat Jul  1 13:24:15 2017	(r320537)
@@ -579,17 +579,6 @@ INTERCEPTOR(char*, __strdup, const char *s) {
 }
 #endif // ASAN_INTERCEPT___STRDUP
 
-INTERCEPTOR(SIZE_T, wcslen, const wchar_t *s) {
-  void *ctx;
-  ASAN_INTERCEPTOR_ENTER(ctx, wcslen);
-  SIZE_T length = internal_wcslen(s);
-  if (!asan_init_is_running) {
-    ENSURE_ASAN_INITED();
-    ASAN_READ_RANGE(ctx, s, (length + 1) * sizeof(wchar_t));
-  }
-  return length;
-}
-
 INTERCEPTOR(char*, strncpy, char *to, const char *from, uptr size) {
   void *ctx;
   ASAN_INTERCEPTOR_ENTER(ctx, strncpy);
@@ -722,7 +711,6 @@ void InitializeAsanInterceptors() {
   // Intercept str* functions.
   ASAN_INTERCEPT_FUNC(strcat);  // NOLINT
   ASAN_INTERCEPT_FUNC(strcpy);  // NOLINT
-  ASAN_INTERCEPT_FUNC(wcslen);
   ASAN_INTERCEPT_FUNC(strncat);
   ASAN_INTERCEPT_FUNC(strncpy);
   ASAN_INTERCEPT_FUNC(strdup);

Modified: vendor/compiler-rt/dist/lib/asan/asan_new_delete.cc
==============================================================================
--- vendor/compiler-rt/dist/lib/asan/asan_new_delete.cc	Sat Jul  1 13:24:12 2017	(r320536)
+++ vendor/compiler-rt/dist/lib/asan/asan_new_delete.cc	Sat Jul  1 13:24:15 2017	(r320537)
@@ -25,23 +25,27 @@
 // dllexport would normally do. We need to export them in order to make the
 // VS2015 dynamic CRT (MD) work.
 #if SANITIZER_WINDOWS
-# define CXX_OPERATOR_ATTRIBUTE
-# ifdef _WIN64
-#  pragma comment(linker, "/export:??2@YAPEAX_K@Z")   // operator new
-#  pragma comment(linker, "/export:??3@YAXPEAX@Z")    // operator delete
-#  pragma comment(linker, "/export:??3@YAXPEAX_K@Z")  // sized operator delete
-#  pragma comment(linker, "/export:??_U@YAPEAX_K@Z")  // operator new[]
-#  pragma comment(linker, "/export:??_V@YAXPEAX@Z")   // operator delete[]
-# else
-#  pragma comment(linker, "/export:??2@YAPAXI@Z")   // operator new
-#  pragma comment(linker, "/export:??3@YAXPAX@Z")   // operator delete
-#  pragma comment(linker, "/export:??3@YAXPAXI@Z")  // sized operator delete
-#  pragma comment(linker, "/export:??_U@YAPAXI@Z")  // operator new[]
-#  pragma comment(linker, "/export:??_V@YAXPAX@Z")  // operator delete[]
-# endif
+#define CXX_OPERATOR_ATTRIBUTE
+#define COMMENT_EXPORT(sym) __pragma(comment(linker, "/export:"##sym))
+#ifdef _WIN64
+COMMENT_EXPORT("??2@YAPEAX_K@Z")                     // operator new
+COMMENT_EXPORT("??2@YAPEAX_KAEBUnothrow_t@std@@@Z")  // operator new nothrow
+COMMENT_EXPORT("??3@YAXPEAX@Z")                      // operator delete
+COMMENT_EXPORT("??3@YAXPEAX_K@Z")                    // sized operator delete
+COMMENT_EXPORT("??_U@YAPEAX_K@Z")                    // operator new[]
+COMMENT_EXPORT("??_V@YAXPEAX@Z")                     // operator delete[]
 #else
-# define CXX_OPERATOR_ATTRIBUTE INTERCEPTOR_ATTRIBUTE
+COMMENT_EXPORT("??2@YAPAXI@Z")                    // operator new
+COMMENT_EXPORT("??2@YAPAXIABUnothrow_t@std@@@Z")  // operator new nothrow
+COMMENT_EXPORT("??3@YAXPAX@Z")                    // operator delete
+COMMENT_EXPORT("??3@YAXPAXI@Z")                   // sized operator delete
+COMMENT_EXPORT("??_U@YAPAXI@Z")                   // operator new[]
+COMMENT_EXPORT("??_V@YAXPAX@Z")                   // operator delete[]
 #endif
+#undef COMMENT_EXPORT
+#else
+#define CXX_OPERATOR_ATTRIBUTE INTERCEPTOR_ATTRIBUTE
+#endif
 
 using namespace __asan;  // NOLINT
 
@@ -63,12 +67,17 @@ struct nothrow_t {};
 enum class align_val_t: size_t {};
 }  // namespace std
 
-#define OPERATOR_NEW_BODY(type) \
+// TODO(alekseys): throw std::bad_alloc instead of dying on OOM.
+#define OPERATOR_NEW_BODY(type, nothrow) \
   GET_STACK_TRACE_MALLOC;\
-  return asan_memalign(0, size, &stack, type);
-#define OPERATOR_NEW_BODY_ALIGN(type) \
+  void *res = asan_memalign(0, size, &stack, type);\
+  if (!nothrow && UNLIKELY(!res)) DieOnFailure::OnOOM();\
+  return res;
+#define OPERATOR_NEW_BODY_ALIGN(type, nothrow) \
   GET_STACK_TRACE_MALLOC;\
-  return asan_memalign((uptr)align, size, &stack, type);
+  void *res = asan_memalign((uptr)align, size, &stack, type);\
+  if (!nothrow && UNLIKELY(!res)) DieOnFailure::OnOOM();\
+  return res;
 
 // On OS X it's not enough to just provide our own 'operator new' and
 // 'operator delete' implementations, because they're going to be in the
@@ -79,40 +88,42 @@ enum class align_val_t: size_t {};
 // OS X we need to intercept them using their mangled names.
 #if !SANITIZER_MAC
 CXX_OPERATOR_ATTRIBUTE
-void *operator new(size_t size) { OPERATOR_NEW_BODY(FROM_NEW); }
+void *operator new(size_t size)
+{ OPERATOR_NEW_BODY(FROM_NEW, false /*nothrow*/); }
 CXX_OPERATOR_ATTRIBUTE
-void *operator new[](size_t size) { OPERATOR_NEW_BODY(FROM_NEW_BR); }
+void *operator new[](size_t size)
+{ OPERATOR_NEW_BODY(FROM_NEW_BR, false /*nothrow*/); }
 CXX_OPERATOR_ATTRIBUTE
 void *operator new(size_t size, std::nothrow_t const&)
-{ OPERATOR_NEW_BODY(FROM_NEW); }
+{ OPERATOR_NEW_BODY(FROM_NEW, true /*nothrow*/); }
 CXX_OPERATOR_ATTRIBUTE
 void *operator new[](size_t size, std::nothrow_t const&)
-{ OPERATOR_NEW_BODY(FROM_NEW_BR); }
+{ OPERATOR_NEW_BODY(FROM_NEW_BR, true /*nothrow*/); }
 CXX_OPERATOR_ATTRIBUTE
 void *operator new(size_t size, std::align_val_t align)
-{ OPERATOR_NEW_BODY_ALIGN(FROM_NEW); }
+{ OPERATOR_NEW_BODY_ALIGN(FROM_NEW, false /*nothrow*/); }
 CXX_OPERATOR_ATTRIBUTE
 void *operator new[](size_t size, std::align_val_t align)
-{ OPERATOR_NEW_BODY_ALIGN(FROM_NEW_BR); }
+{ OPERATOR_NEW_BODY_ALIGN(FROM_NEW_BR, false /*nothrow*/); }
 CXX_OPERATOR_ATTRIBUTE
 void *operator new(size_t size, std::align_val_t align, std::nothrow_t const&)
-{ OPERATOR_NEW_BODY_ALIGN(FROM_NEW); }
+{ OPERATOR_NEW_BODY_ALIGN(FROM_NEW, true /*nothrow*/); }
 CXX_OPERATOR_ATTRIBUTE
 void *operator new[](size_t size, std::align_val_t align, std::nothrow_t const&)
-{ OPERATOR_NEW_BODY_ALIGN(FROM_NEW_BR); }
+{ OPERATOR_NEW_BODY_ALIGN(FROM_NEW_BR, true /*nothrow*/); }
 
 #else  // SANITIZER_MAC
 INTERCEPTOR(void *, _Znwm, size_t size) {
-  OPERATOR_NEW_BODY(FROM_NEW);
+  OPERATOR_NEW_BODY(FROM_NEW, false /*nothrow*/);
 }
 INTERCEPTOR(void *, _Znam, size_t size) {
-  OPERATOR_NEW_BODY(FROM_NEW_BR);
+  OPERATOR_NEW_BODY(FROM_NEW_BR, false /*nothrow*/);
 }
 INTERCEPTOR(void *, _ZnwmRKSt9nothrow_t, size_t size, std::nothrow_t const&) {
-  OPERATOR_NEW_BODY(FROM_NEW);
+  OPERATOR_NEW_BODY(FROM_NEW, true /*nothrow*/);
 }
 INTERCEPTOR(void *, _ZnamRKSt9nothrow_t, size_t size, std::nothrow_t const&) {
-  OPERATOR_NEW_BODY(FROM_NEW_BR);
+  OPERATOR_NEW_BODY(FROM_NEW_BR, true /*nothrow*/);
 }
 #endif
 

Modified: vendor/compiler-rt/dist/lib/asan/asan_win_dll_thunk.cc
==============================================================================
--- vendor/compiler-rt/dist/lib/asan/asan_win_dll_thunk.cc	Sat Jul  1 13:24:12 2017	(r320536)
+++ vendor/compiler-rt/dist/lib/asan/asan_win_dll_thunk.cc	Sat Jul  1 13:24:15 2017	(r320537)
@@ -85,6 +85,7 @@ INTERCEPT_LIBRARY_FUNCTION(strstr);
 INTERCEPT_LIBRARY_FUNCTION(strtok);
 INTERCEPT_LIBRARY_FUNCTION(strtol);
 INTERCEPT_LIBRARY_FUNCTION(wcslen);
+INTERCEPT_LIBRARY_FUNCTION(wcsnlen);
 
 #ifdef _WIN64
 INTERCEPT_LIBRARY_FUNCTION(__C_specific_handler);

Modified: vendor/compiler-rt/dist/lib/lsan/lsan_allocator.cc
==============================================================================
--- vendor/compiler-rt/dist/lib/lsan/lsan_allocator.cc	Sat Jul  1 13:24:12 2017	(r320536)
+++ vendor/compiler-rt/dist/lib/lsan/lsan_allocator.cc	Sat Jul  1 13:24:15 2017	(r320537)
@@ -74,7 +74,7 @@ void *Allocate(const StackTrace &stack, uptr size, upt
     size = 1;
   if (size > kMaxAllowedMallocSize) {
     Report("WARNING: LeakSanitizer failed to allocate %zu bytes\n", size);
-    return nullptr;
+    return Allocator::FailureHandler::OnBadRequest();
   }
   void *p = allocator.Allocate(GetAllocatorCache(), size, alignment);
   // Do not rely on the allocator to clear the memory (it's slow).
@@ -99,7 +99,7 @@ void *Reallocate(const StackTrace &stack, void *p, upt
   if (new_size > kMaxAllowedMallocSize) {
     Report("WARNING: LeakSanitizer failed to allocate %zu bytes\n", new_size);
     allocator.Deallocate(GetAllocatorCache(), p);
-    return nullptr;
+    return Allocator::FailureHandler::OnBadRequest();
   }
   p = allocator.Reallocate(GetAllocatorCache(), p, new_size, alignment);
   RegisterAllocation(stack, p, new_size);
@@ -134,6 +134,8 @@ void *lsan_realloc(void *p, uptr size, const StackTrac
 }
 
 void *lsan_calloc(uptr nmemb, uptr size, const StackTrace &stack) {
+  if (CheckForCallocOverflow(size, nmemb))
+    return Allocator::FailureHandler::OnBadRequest();
   size *= nmemb;
   return Allocate(stack, size, 1, true);
 }

Modified: vendor/compiler-rt/dist/lib/lsan/lsan_interceptors.cc
==============================================================================
--- vendor/compiler-rt/dist/lib/lsan/lsan_interceptors.cc	Sat Jul  1 13:24:12 2017	(r320536)
+++ vendor/compiler-rt/dist/lib/lsan/lsan_interceptors.cc	Sat Jul  1 13:24:15 2017	(r320537)
@@ -70,7 +70,6 @@ INTERCEPTOR(void*, calloc, uptr nmemb, uptr size) {
     CHECK(allocated < kCallocPoolSize);
     return mem;
   }
-  if (CallocShouldReturnNullDueToOverflow(size, nmemb)) return nullptr;
   ENSURE_LSAN_INITED;
   GET_STACK_TRACE_MALLOC;
   return lsan_calloc(nmemb, size, stack);
@@ -199,34 +198,70 @@ INTERCEPTOR(int, mprobe, void *ptr) {
 }
 #endif // SANITIZER_INTERCEPT_MCHECK_MPROBE
 
-#define OPERATOR_NEW_BODY                              \
-  ENSURE_LSAN_INITED;                                  \
-  GET_STACK_TRACE_MALLOC;                              \
-  return Allocate(stack, size, 1, kAlwaysClearMemory);
 
-INTERCEPTOR_ATTRIBUTE
-void *operator new(size_t size) { OPERATOR_NEW_BODY; }
-INTERCEPTOR_ATTRIBUTE
-void *operator new[](size_t size) { OPERATOR_NEW_BODY; }
-INTERCEPTOR_ATTRIBUTE
-void *operator new(size_t size, std::nothrow_t const&) { OPERATOR_NEW_BODY; }
-INTERCEPTOR_ATTRIBUTE
-void *operator new[](size_t size, std::nothrow_t const&) { OPERATOR_NEW_BODY; }
+// TODO(alekseys): throw std::bad_alloc instead of dying on OOM.
+#define OPERATOR_NEW_BODY(nothrow)                         \
+  ENSURE_LSAN_INITED;                                      \
+  GET_STACK_TRACE_MALLOC;                                  \
+  void *res = Allocate(stack, size, 1, kAlwaysClearMemory);\
+  if (!nothrow && UNLIKELY(!res)) DieOnFailure::OnOOM();\
+  return res;
 
 #define OPERATOR_DELETE_BODY \
   ENSURE_LSAN_INITED;        \
   Deallocate(ptr);
 
+// On OS X it's not enough to just provide our own 'operator new' and
+// 'operator delete' implementations, because they're going to be in the runtime
+// dylib, and the main executable will depend on both the runtime dylib and
+// libstdc++, each of has its implementation of new and delete.
+// To make sure that C++ allocation/deallocation operators are overridden on
+// OS X we need to intercept them using their mangled names.
+#if !SANITIZER_MAC
+
 INTERCEPTOR_ATTRIBUTE
+void *operator new(size_t size) { OPERATOR_NEW_BODY(false /*nothrow*/); }
+INTERCEPTOR_ATTRIBUTE
+void *operator new[](size_t size) { OPERATOR_NEW_BODY(false /*nothrow*/); }
+INTERCEPTOR_ATTRIBUTE
+void *operator new(size_t size, std::nothrow_t const&)
+{ OPERATOR_NEW_BODY(true /*nothrow*/); }
+INTERCEPTOR_ATTRIBUTE
+void *operator new[](size_t size, std::nothrow_t const&)
+{ OPERATOR_NEW_BODY(true /*nothrow*/); }
+
+INTERCEPTOR_ATTRIBUTE
 void operator delete(void *ptr) NOEXCEPT { OPERATOR_DELETE_BODY; }
 INTERCEPTOR_ATTRIBUTE
 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;
-}
+void operator delete[](void *ptr, std::nothrow_t const &)
+{ OPERATOR_DELETE_BODY; }
+
+#else  // SANITIZER_MAC
+
+INTERCEPTOR(void *, _Znwm, size_t size)
+{ OPERATOR_NEW_BODY(false /*nothrow*/); }
+INTERCEPTOR(void *, _Znam, size_t size)
+{ OPERATOR_NEW_BODY(false /*nothrow*/); }
+INTERCEPTOR(void *, _ZnwmRKSt9nothrow_t, size_t size, std::nothrow_t const&)
+{ OPERATOR_NEW_BODY(true /*nothrow*/); }
+INTERCEPTOR(void *, _ZnamRKSt9nothrow_t, size_t size, std::nothrow_t const&)
+{ OPERATOR_NEW_BODY(true /*nothrow*/); }
+
+INTERCEPTOR(void, _ZdlPv, void *ptr)
+{ OPERATOR_DELETE_BODY; }
+INTERCEPTOR(void, _ZdaPv, void *ptr)
+{ OPERATOR_DELETE_BODY; }
+INTERCEPTOR(void, _ZdlPvRKSt9nothrow_t, void *ptr, std::nothrow_t const&)
+{ OPERATOR_DELETE_BODY; }
+INTERCEPTOR(void, _ZdaPvRKSt9nothrow_t, void *ptr, std::nothrow_t const&)
+{ OPERATOR_DELETE_BODY; }
+
+#endif  // !SANITIZER_MAC
+
 
 ///// Thread initialization and finalization. /////
 

Modified: vendor/compiler-rt/dist/lib/msan/msan_allocator.cc
==============================================================================
--- vendor/compiler-rt/dist/lib/msan/msan_allocator.cc	Sat Jul  1 13:24:12 2017	(r320536)
+++ vendor/compiler-rt/dist/lib/msan/msan_allocator.cc	Sat Jul  1 13:24:15 2017	(r320537)
@@ -195,7 +195,7 @@ void MsanDeallocate(StackTrace *stack, void *p) {
 }
 
 void *MsanCalloc(StackTrace *stack, uptr nmemb, uptr size) {
-  if (CallocShouldReturnNullDueToOverflow(size, nmemb))
+  if (CheckForCallocOverflow(size, nmemb))
     return Allocator::FailureHandler::OnBadRequest();
   return MsanReallocate(stack, nullptr, nmemb * size, sizeof(u64), true);
 }

Modified: vendor/compiler-rt/dist/lib/msan/msan_interceptors.cc
==============================================================================
--- vendor/compiler-rt/dist/lib/msan/msan_interceptors.cc	Sat Jul  1 13:24:12 2017	(r320536)
+++ vendor/compiler-rt/dist/lib/msan/msan_interceptors.cc	Sat Jul  1 13:24:15 2017	(r320537)
@@ -538,49 +538,6 @@ INTERCEPTOR(int, mbrtowc, wchar_t *dest, const char *s
   return res;
 }
 
-INTERCEPTOR(SIZE_T, wcslen, const wchar_t *s) {
-  ENSURE_MSAN_INITED();
-  SIZE_T res = REAL(wcslen)(s);
-  CHECK_UNPOISONED(s, sizeof(wchar_t) * (res + 1));
-  return res;
-}
-
-INTERCEPTOR(SIZE_T, wcsnlen, const wchar_t *s, SIZE_T n) {
-  ENSURE_MSAN_INITED();
-  SIZE_T res = REAL(wcsnlen)(s, n);
-  CHECK_UNPOISONED(s, sizeof(wchar_t) * Min(res + 1, n));
-  return res;
-}
-
-// wchar_t *wcschr(const wchar_t *wcs, wchar_t wc);
-INTERCEPTOR(wchar_t *, wcschr, void *s, wchar_t wc, void *ps) {
-  ENSURE_MSAN_INITED();
-  wchar_t *res = REAL(wcschr)(s, wc, ps);
-  return res;
-}
-
-// wchar_t *wcscpy(wchar_t *dest, const wchar_t *src);
-INTERCEPTOR(wchar_t *, wcscpy, wchar_t *dest, const wchar_t *src) {
-  ENSURE_MSAN_INITED();
-  GET_STORE_STACK_TRACE;
-  wchar_t *res = REAL(wcscpy)(dest, src);
-  CopyShadowAndOrigin(dest, src, sizeof(wchar_t) * (REAL(wcslen)(src) + 1),
-                      &stack);
-  return res;
-}
-
-INTERCEPTOR(wchar_t *, wcsncpy, wchar_t *dest, const wchar_t *src,
-            SIZE_T n) {  // NOLINT
-  ENSURE_MSAN_INITED();
-  GET_STORE_STACK_TRACE;
-  SIZE_T copy_size = REAL(wcsnlen)(src, n);
-  if (copy_size < n) copy_size++;           // trailing \0
-  wchar_t *res = REAL(wcsncpy)(dest, src, n);  // NOLINT
-  CopyShadowAndOrigin(dest, src, copy_size * sizeof(wchar_t), &stack);
-  __msan_unpoison(dest + copy_size, (n - copy_size) * sizeof(wchar_t));
-  return res;
-}
-
 // wchar_t *wmemcpy(wchar_t *dest, const wchar_t *src, SIZE_T n);
 INTERCEPTOR(wchar_t *, wmemcpy, wchar_t *dest, const wchar_t *src, SIZE_T n) {
   ENSURE_MSAN_INITED();
@@ -1344,11 +1301,11 @@ int OnExit() {
     return __msan_memcpy(to, from, size);                   \
   }
 
-#define COMMON_INTERCEPTOR_COPY_STRING(ctx, to, from, size)                    \
-  do {                                                                         \
-    GET_STORE_STACK_TRACE;                                                     \
-    CopyShadowAndOrigin(to, from, size, &stack);                               \
-    __msan_unpoison(to + size, 1);                                             \
+#define COMMON_INTERCEPTOR_COPY_STRING(ctx, to, from, size) \
+  do {                                                      \
+    GET_STORE_STACK_TRACE;                                  \
+    CopyShadowAndOrigin(to, from, size, &stack);            \
+    __msan_unpoison(to + size, 1);                          \
   } while (false)
 
 #include "sanitizer_common/sanitizer_platform_interceptors.h"
@@ -1421,6 +1378,35 @@ INTERCEPTOR(int, dl_iterate_phdr, dl_iterate_phdr_cb c
   cbdata.callback = callback;
   cbdata.data = data;
   int res = REAL(dl_iterate_phdr)(msan_dl_iterate_phdr_cb, (void *)&cbdata);
+  return res;
+}
+
+// wchar_t *wcschr(const wchar_t *wcs, wchar_t wc);
+INTERCEPTOR(wchar_t *, wcschr, void *s, wchar_t wc, void *ps) {
+  ENSURE_MSAN_INITED();
+  wchar_t *res = REAL(wcschr)(s, wc, ps);
+  return res;
+}
+
+// wchar_t *wcscpy(wchar_t *dest, const wchar_t *src);
+INTERCEPTOR(wchar_t *, wcscpy, wchar_t *dest, const wchar_t *src) {
+  ENSURE_MSAN_INITED();
+  GET_STORE_STACK_TRACE;
+  wchar_t *res = REAL(wcscpy)(dest, src);
+  CopyShadowAndOrigin(dest, src, sizeof(wchar_t) * (REAL(wcslen)(src) + 1),
+                      &stack);
+  return res;
+}
+
+INTERCEPTOR(wchar_t *, wcsncpy, wchar_t *dest, const wchar_t *src,
+            SIZE_T n) {  // NOLINT
+  ENSURE_MSAN_INITED();
+  GET_STORE_STACK_TRACE;
+  SIZE_T copy_size = REAL(wcsnlen)(src, n);
+  if (copy_size < n) copy_size++;           // trailing \0
+  wchar_t *res = REAL(wcsncpy)(dest, src, n);  // NOLINT
+  CopyShadowAndOrigin(dest, src, copy_size * sizeof(wchar_t), &stack);
+  __msan_unpoison(dest + copy_size, (n - copy_size) * sizeof(wchar_t));
   return res;
 }
 

Modified: vendor/compiler-rt/dist/lib/msan/msan_new_delete.cc
==============================================================================
--- vendor/compiler-rt/dist/lib/msan/msan_new_delete.cc	Sat Jul  1 13:24:12 2017	(r320536)
+++ vendor/compiler-rt/dist/lib/msan/msan_new_delete.cc	Sat Jul  1 13:24:15 2017	(r320537)
@@ -14,6 +14,7 @@
 
 #include "msan.h"
 #include "interception/interception.h"
+#include "sanitizer_common/sanitizer_allocator.h"
 
 #if MSAN_REPLACE_OPERATORS_NEW_AND_DELETE
 
@@ -27,18 +28,25 @@ namespace std {
 }  // namespace std
 
 
-#define OPERATOR_NEW_BODY \
+// TODO(alekseys): throw std::bad_alloc instead of dying on OOM.
+#define OPERATOR_NEW_BODY(nothrow) \
   GET_MALLOC_STACK_TRACE; \
-  return MsanReallocate(&stack, 0, size, sizeof(u64), false)
+  void *res = MsanReallocate(&stack, 0, size, sizeof(u64), false);\
+  if (!nothrow && UNLIKELY(!res)) DieOnFailure::OnOOM();\
+  return res
 
 INTERCEPTOR_ATTRIBUTE
-void *operator new(size_t size) { OPERATOR_NEW_BODY; }
+void *operator new(size_t size) { OPERATOR_NEW_BODY(false /*nothrow*/); }
 INTERCEPTOR_ATTRIBUTE
-void *operator new[](size_t size) { OPERATOR_NEW_BODY; }
+void *operator new[](size_t size) { OPERATOR_NEW_BODY(false /*nothrow*/); }
 INTERCEPTOR_ATTRIBUTE
-void *operator new(size_t size, std::nothrow_t const&) { OPERATOR_NEW_BODY; }
+void *operator new(size_t size, std::nothrow_t const&) {
+  OPERATOR_NEW_BODY(true /*nothrow*/);
+}
 INTERCEPTOR_ATTRIBUTE
-void *operator new[](size_t size, std::nothrow_t const&) { OPERATOR_NEW_BODY; }
+void *operator new[](size_t size, std::nothrow_t const&) {
+  OPERATOR_NEW_BODY(true /*nothrow*/);
+}
 
 #define OPERATOR_DELETE_BODY \
   GET_MALLOC_STACK_TRACE; \

Modified: vendor/compiler-rt/dist/lib/msan/tests/msan_test.cc
==============================================================================
--- vendor/compiler-rt/dist/lib/msan/tests/msan_test.cc	Sat Jul  1 13:24:12 2017	(r320536)
+++ vendor/compiler-rt/dist/lib/msan/tests/msan_test.cc	Sat Jul  1 13:24:15 2017	(r320537)
@@ -1707,6 +1707,48 @@ TEST(MemorySanitizer, strncat_overflow) {  // NOLINT
   EXPECT_POISONED(a[7]);
 }
 
+TEST(MemorySanitizer, wcscat) {
+  wchar_t a[10];
+  wchar_t b[] = L"def";
+  wcscpy(a, L"abc");
+
+  wcscat(a, b);
+  EXPECT_EQ(6U, wcslen(a));
+  EXPECT_POISONED(a[7]);
+
+  a[3] = 0;
+  __msan_poison(b + 1, sizeof(wchar_t));
+  EXPECT_UMR(wcscat(a, b));
+
+  __msan_unpoison(b + 1, sizeof(wchar_t));
+  __msan_poison(a + 2, sizeof(wchar_t));
+  EXPECT_UMR(wcscat(a, b));
+}
+
+TEST(MemorySanitizer, wcsncat) {
+  wchar_t a[10];
+  wchar_t b[] = L"def";
+  wcscpy(a, L"abc");
+
+  wcsncat(a, b, 5);
+  EXPECT_EQ(6U, wcslen(a));
+  EXPECT_POISONED(a[7]);
+
+  a[3] = 0;
+  __msan_poison(a + 4, sizeof(wchar_t) * 6);
+  wcsncat(a, b, 2);
+  EXPECT_EQ(5U, wcslen(a));
+  EXPECT_POISONED(a[6]);
+
+  a[3] = 0;
+  __msan_poison(b + 1, sizeof(wchar_t));
+  EXPECT_UMR(wcsncat(a, b, 2));
+
+  __msan_unpoison(b + 1, sizeof(wchar_t));
+  __msan_poison(a + 2, sizeof(wchar_t));
+  EXPECT_UMR(wcsncat(a, b, 2));
+}
+
 #define TEST_STRTO_INT(func_name, char_type, str_prefix) \
   TEST(MemorySanitizer, func_name) {                     \
     char_type *e;                                        \

Modified: vendor/compiler-rt/dist/lib/profile/CMakeLists.txt
==============================================================================
--- vendor/compiler-rt/dist/lib/profile/CMakeLists.txt	Sat Jul  1 13:24:12 2017	(r320536)
+++ vendor/compiler-rt/dist/lib/profile/CMakeLists.txt	Sat Jul  1 13:24:15 2017	(r320537)
@@ -48,6 +48,7 @@ set(PROFILE_SOURCES
   InstrProfilingFile.c
   InstrProfilingMerge.c
   InstrProfilingMergeFile.c
+  InstrProfilingNameVar.c
   InstrProfilingWriter.c
   InstrProfilingPlatformDarwin.c
   InstrProfilingPlatformLinux.c

Modified: vendor/compiler-rt/dist/lib/profile/InstrProfiling.c
==============================================================================
--- vendor/compiler-rt/dist/lib/profile/InstrProfiling.c	Sat Jul  1 13:24:12 2017	(r320536)
+++ vendor/compiler-rt/dist/lib/profile/InstrProfiling.c	Sat Jul  1 13:24:15 2017	(r320537)
@@ -19,8 +19,6 @@
 
 COMPILER_RT_WEAK uint64_t INSTR_PROF_RAW_VERSION_VAR = INSTR_PROF_RAW_VERSION;
 
-COMPILER_RT_WEAK char INSTR_PROF_PROFILE_NAME_VAR[1] = {0};
-
 COMPILER_RT_VISIBILITY uint64_t __llvm_profile_get_magic(void) {
   return sizeof(void *) == sizeof(uint64_t) ? (INSTR_PROF_RAW_MAGIC_64)
                                             : (INSTR_PROF_RAW_MAGIC_32);

Modified: vendor/compiler-rt/dist/lib/profile/InstrProfilingBuffer.c
==============================================================================
--- vendor/compiler-rt/dist/lib/profile/InstrProfilingBuffer.c	Sat Jul  1 13:24:12 2017	(r320536)
+++ vendor/compiler-rt/dist/lib/profile/InstrProfilingBuffer.c	Sat Jul  1 13:24:15 2017	(r320537)
@@ -45,15 +45,24 @@ uint64_t __llvm_profile_get_size_for_buffer_internal(
          (CountersEnd - CountersBegin) * sizeof(uint64_t) + NamesSize + Padding;
 }
 
+COMPILER_RT_VISIBILITY
+void initBufferWriter(ProfDataWriter *BufferWriter, char *Buffer) {
+  BufferWriter->Write = lprofBufferWriter;
+  BufferWriter->WriterCtx = Buffer;
+}
+
 COMPILER_RT_VISIBILITY int __llvm_profile_write_buffer(char *Buffer) {
-  return lprofWriteData(lprofBufferWriter, Buffer, 0);
+  ProfDataWriter BufferWriter;
+  initBufferWriter(&BufferWriter, Buffer);
+  return lprofWriteData(&BufferWriter, 0, 0);
 }
 
 COMPILER_RT_VISIBILITY int __llvm_profile_write_buffer_internal(
     char *Buffer, const __llvm_profile_data *DataBegin,
     const __llvm_profile_data *DataEnd, const uint64_t *CountersBegin,
     const uint64_t *CountersEnd, const char *NamesBegin, const char *NamesEnd) {
-  return lprofWriteDataImpl(lprofBufferWriter, Buffer, DataBegin, DataEnd,
-                            CountersBegin, CountersEnd, 0, NamesBegin,
-                            NamesEnd);
+  ProfDataWriter BufferWriter;
+  initBufferWriter(&BufferWriter, Buffer);
+  return lprofWriteDataImpl(&BufferWriter, DataBegin, DataEnd, CountersBegin,
+                            CountersEnd, 0, NamesBegin, NamesEnd, 0);
 }

Modified: vendor/compiler-rt/dist/lib/profile/InstrProfilingFile.c
==============================================================================
--- vendor/compiler-rt/dist/lib/profile/InstrProfilingFile.c	Sat Jul  1 13:24:12 2017	(r320536)
+++ vendor/compiler-rt/dist/lib/profile/InstrProfilingFile.c	Sat Jul  1 13:24:15 2017	(r320537)
@@ -91,24 +91,39 @@ static const char *getCurFilename(char *FilenameBuf);
 static unsigned doMerging() { return lprofCurFilename.MergePoolSize; }
 
 /* Return 1 if there is an error, otherwise return  0.  */
-static uint32_t fileWriter(ProfDataIOVec *IOVecs, uint32_t NumIOVecs,
-                           void **WriterCtx) {
+static uint32_t fileWriter(ProfDataWriter *This, ProfDataIOVec *IOVecs,
+                           uint32_t NumIOVecs) {
   uint32_t I;
-  FILE *File = (FILE *)*WriterCtx;
+  FILE *File = (FILE *)This->WriterCtx;
   for (I = 0; I < NumIOVecs; I++) {
-    if (fwrite(IOVecs[I].Data, IOVecs[I].ElmSize, IOVecs[I].NumElm, File) !=
-        IOVecs[I].NumElm)
-      return 1;
+    if (IOVecs[I].Data) {
+      if (fwrite(IOVecs[I].Data, IOVecs[I].ElmSize, IOVecs[I].NumElm, File) !=
+          IOVecs[I].NumElm)
+        return 1;
+    } else {
+      if (fseek(File, IOVecs[I].ElmSize * IOVecs[I].NumElm, SEEK_CUR) == -1)
+        return 1;
+    }
   }
   return 0;
 }
 
+static void initFileWriter(ProfDataWriter *This, FILE *File) {
+  This->Write = fileWriter;
+  This->WriterCtx = File;
+}
+
 COMPILER_RT_VISIBILITY ProfBufferIO *
 lprofCreateBufferIOInternal(void *File, uint32_t BufferSz) {
   FreeHook = &free;
   DynamicBufferIOBuffer = (uint8_t *)calloc(BufferSz, 1);
   VPBufferSize = BufferSz;
-  return lprofCreateBufferIO(fileWriter, File);
+  ProfDataWriter *fileWriter =
+      (ProfDataWriter *)calloc(sizeof(ProfDataWriter), 1);
+  initFileWriter(fileWriter, File);
+  ProfBufferIO *IO = lprofCreateBufferIO(fileWriter);
+  IO->OwnFileWriter = 1;
+  return IO;
 }
 
 static void setupIOBuffer() {
@@ -122,9 +137,10 @@ static void setupIOBuffer() {
 
 /* Read profile data in \c ProfileFile and merge with in-memory
    profile counters. Returns -1 if there is fatal error, otheriwse
-   0 is returned.
+   0 is returned. Returning 0 does not mean merge is actually
+   performed. If merge is actually done, *MergeDone is set to 1.
 */
-static int doProfileMerging(FILE *ProfileFile) {
+static int doProfileMerging(FILE *ProfileFile, int *MergeDone) {
   uint64_t ProfileFileSize;
   char *ProfileBuffer;
 
@@ -169,6 +185,8 @@ static int doProfileMerging(FILE *ProfileFile) {
   __llvm_profile_merge_from_buffer(ProfileBuffer, ProfileFileSize);
   (void)munmap(ProfileBuffer, ProfileFileSize);
 
+  *MergeDone = 1;
+
   return 0;
 }
 
@@ -190,7 +208,7 @@ static void createProfileDir(const char *Filename) {
  * dumper. With profile merging enabled, each executable as well as any of
  * its instrumented shared libraries dump profile data into their own data file.
 */
-static FILE *openFileForMerging(const char *ProfileFileName) {
+static FILE *openFileForMerging(const char *ProfileFileName, int *MergeDone) {
   FILE *ProfileFile;
   int rc;
 
@@ -199,15 +217,14 @@ static FILE *openFileForMerging(const char *ProfileFil
   if (!ProfileFile)
     return NULL;
 
-  rc = doProfileMerging(ProfileFile);
-  if (rc || COMPILER_RT_FTRUNCATE(ProfileFile, 0L) ||
+  rc = doProfileMerging(ProfileFile, MergeDone);
+  if (rc || (!*MergeDone && COMPILER_RT_FTRUNCATE(ProfileFile, 0L)) ||
       fseek(ProfileFile, 0L, SEEK_SET) == -1) {
     PROF_ERR("Profile Merging of file %s failed: %s\n", ProfileFileName,
              strerror(errno));
     fclose(ProfileFile);
     return NULL;
   }
-  fseek(ProfileFile, 0L, SEEK_SET);
   return ProfileFile;
 }
 
@@ -216,17 +233,20 @@ static int writeFile(const char *OutputName) {
   int RetVal;
   FILE *OutputFile;
 
+  int MergeDone = 0;
   if (!doMerging())
     OutputFile = fopen(OutputName, "ab");
   else
-    OutputFile = openFileForMerging(OutputName);
+    OutputFile = openFileForMerging(OutputName, &MergeDone);
 
   if (!OutputFile)
     return -1;
 
   FreeHook = &free;
   setupIOBuffer();
-  RetVal = lprofWriteData(fileWriter, OutputFile, lprofGetVPDataReader());
+  ProfDataWriter fileWriter;
+  initFileWriter(&fileWriter, OutputFile);
+  RetVal = lprofWriteData(&fileWriter, lprofGetVPDataReader(), MergeDone);
 
   fclose(OutputFile);
   return RetVal;

Modified: vendor/compiler-rt/dist/lib/profile/InstrProfilingInternal.h
==============================================================================
--- vendor/compiler-rt/dist/lib/profile/InstrProfilingInternal.h	Sat Jul  1 13:24:12 2017	(r320536)
+++ vendor/compiler-rt/dist/lib/profile/InstrProfilingInternal.h	Sat Jul  1 13:24:15 2017	(r320537)
@@ -48,17 +48,21 @@ typedef struct ProfDataIOVec {
   size_t NumElm;
 } ProfDataIOVec;
 
-typedef uint32_t (*WriterCallback)(ProfDataIOVec *, uint32_t NumIOVecs,
-                                   void **WriterCtx);
+struct ProfDataWriter;
+typedef uint32_t (*WriterCallback)(struct ProfDataWriter *This, ProfDataIOVec *,
+                                   uint32_t NumIOVecs);
 
+typedef struct ProfDataWriter {
+  WriterCallback Write;
+  void *WriterCtx;
+} ProfDataWriter;
+
 /*!
  * The data structure for buffered IO of profile data.
  */
 typedef struct ProfBufferIO {
-  /* File handle.  */
-  void *File;
-  /* Low level IO callback. */
-  WriterCallback FileWriter;
+  ProfDataWriter *FileWriter;
+  uint32_t OwnFileWriter;
   /* The start of the buffer. */
   uint8_t *BufferStart;
   /* Total size of the buffer. */
@@ -73,7 +77,7 @@ ProfBufferIO *lprofCreateBufferIOInternal(void *File, 
 /*!
  * This is the interface to create a handle for buffered IO.
  */
-ProfBufferIO *lprofCreateBufferIO(WriterCallback FileWriter, void *File);
+ProfBufferIO *lprofCreateBufferIO(ProfDataWriter *FileWriter);
 
 /*!
  * The interface to destroy the bufferIO handle and reclaim
@@ -96,8 +100,9 @@ int lprofBufferIOFlush(ProfBufferIO *BufferIO);
 /* The low level interface to write data into a buffer. It is used as the
  * callback by other high level writer methods such as buffered IO writer
  * and profile data writer.  */
-uint32_t lprofBufferWriter(ProfDataIOVec *IOVecs, uint32_t NumIOVecs,
-                           void **WriterCtx);
+uint32_t lprofBufferWriter(ProfDataWriter *This, ProfDataIOVec *IOVecs,
+                           uint32_t NumIOVecs);
+void initBufferWriter(ProfDataWriter *BufferWriter, char *Buffer);
 
 struct ValueProfData;
 struct ValueProfRecord;
@@ -133,15 +138,17 @@ typedef struct VPDataReaderType {
                                         uint32_t N);
 } VPDataReaderType;
 
-int lprofWriteData(WriterCallback Writer, void *WriterCtx,
-                   VPDataReaderType *VPDataReader);
-int lprofWriteDataImpl(WriterCallback Writer, void *WriterCtx,
+/* Write profile data to destinitation. If SkipNameDataWrite is set to 1,
+   the name data is already in destintation, we just skip over it. */
+int lprofWriteData(ProfDataWriter *Writer, VPDataReaderType *VPDataReader,
+                   int SkipNameDataWrite);
+int lprofWriteDataImpl(ProfDataWriter *Writer,
                        const __llvm_profile_data *DataBegin,
                        const __llvm_profile_data *DataEnd,
                        const uint64_t *CountersBegin,
                        const uint64_t *CountersEnd,
                        VPDataReaderType *VPDataReader, const char *NamesBegin,
-                       const char *NamesEnd);
+                       const char *NamesEnd, int SkipNameDataWrite);
 
 /* Merge value profile data pointed to by SrcValueProfData into
  * in-memory profile counters pointed by to DstData.  */

Added: vendor/compiler-rt/dist/lib/profile/InstrProfilingNameVar.c
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ vendor/compiler-rt/dist/lib/profile/InstrProfilingNameVar.c	Sat Jul  1 13:24:15 2017	(r320537)
@@ -0,0 +1,18 @@
+//===- InstrProfilingNameVar.c - profile name variable setup --------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "InstrProfiling.h"
+
+/* char __llvm_profile_filename[1]
+ *
+ * The runtime should only provide its own definition of this symbol when the
+ * user has not specified one. Set this up by moving the runtime's copy of this
+ * symbol to an object file within the archive.
+ */
+COMPILER_RT_WEAK char INSTR_PROF_PROFILE_NAME_VAR[1] = {0};

Modified: vendor/compiler-rt/dist/lib/profile/InstrProfilingWriter.c
==============================================================================
--- vendor/compiler-rt/dist/lib/profile/InstrProfilingWriter.c	Sat Jul  1 13:24:12 2017	(r320536)
+++ vendor/compiler-rt/dist/lib/profile/InstrProfilingWriter.c	Sat Jul  1 13:24:15 2017	(r320537)
@@ -31,41 +31,44 @@ COMPILER_RT_VISIBILITY uint32_t VPBufferSize = 0;
 /* The buffer writer is reponsponsible in keeping writer state
  * across the call.
  */
-COMPILER_RT_VISIBILITY uint32_t lprofBufferWriter(ProfDataIOVec *IOVecs,
-                                                  uint32_t NumIOVecs,
-                                                  void **WriterCtx) {
+COMPILER_RT_VISIBILITY uint32_t lprofBufferWriter(ProfDataWriter *This,
+                                                  ProfDataIOVec *IOVecs,
+                                                  uint32_t NumIOVecs) {
   uint32_t I;
-  char **Buffer = (char **)WriterCtx;
+  char **Buffer = (char **)&This->WriterCtx;
   for (I = 0; I < NumIOVecs; I++) {
     size_t Length = IOVecs[I].ElmSize * IOVecs[I].NumElm;
-    memcpy(*Buffer, IOVecs[I].Data, Length);
+    if (IOVecs[I].Data)
+      memcpy(*Buffer, IOVecs[I].Data, Length);
     *Buffer += Length;
   }
   return 0;
 }
 
-static void llvmInitBufferIO(ProfBufferIO *BufferIO, WriterCallback FileWriter,
-                             void *File, uint8_t *Buffer, uint32_t BufferSz) {
-  BufferIO->File = File;
+static void llvmInitBufferIO(ProfBufferIO *BufferIO, ProfDataWriter *FileWriter,
+                             uint8_t *Buffer, uint32_t BufferSz) {
   BufferIO->FileWriter = FileWriter;
+  BufferIO->OwnFileWriter = 0;
   BufferIO->BufferStart = Buffer;
   BufferIO->BufferSz = BufferSz;
   BufferIO->CurOffset = 0;
 }
 
 COMPILER_RT_VISIBILITY ProfBufferIO *
-lprofCreateBufferIO(WriterCallback FileWriter, void *File) {
+lprofCreateBufferIO(ProfDataWriter *FileWriter) {
   uint8_t *Buffer = DynamicBufferIOBuffer;
   uint32_t BufferSize = VPBufferSize;
   if (!Buffer) {
     Buffer = &BufferIOBuffer[0];
     BufferSize = sizeof(BufferIOBuffer);
   }
-  llvmInitBufferIO(&TheBufferIO, FileWriter, File, Buffer, BufferSize);
+  llvmInitBufferIO(&TheBufferIO, FileWriter, Buffer, BufferSize);
   return &TheBufferIO;
 }
 
 COMPILER_RT_VISIBILITY void lprofDeleteBufferIO(ProfBufferIO *BufferIO) {
+  if (BufferIO->OwnFileWriter)
+    FreeHook(BufferIO->FileWriter);
   if (DynamicBufferIOBuffer) {
     FreeHook(DynamicBufferIOBuffer);
     DynamicBufferIOBuffer = 0;
@@ -83,13 +86,16 @@ lprofBufferIOWrite(ProfBufferIO *BufferIO, const uint8
   /* Special case, bypass the buffer completely. */
   ProfDataIOVec IO[] = {{Data, sizeof(uint8_t), Size}};
   if (Size > BufferIO->BufferSz) {
-    if (BufferIO->FileWriter(IO, 1, &BufferIO->File))
+    if (BufferIO->FileWriter->Write(BufferIO->FileWriter, IO, 1))
       return -1;
   } else {
     /* Write the data to buffer */
     uint8_t *Buffer = BufferIO->BufferStart + BufferIO->CurOffset;
-    lprofBufferWriter(IO, 1, (void **)&Buffer);
-    BufferIO->CurOffset = Buffer - BufferIO->BufferStart;
+    ProfDataWriter BufferWriter;
+    initBufferWriter(&BufferWriter, (char *)Buffer);
+    lprofBufferWriter(&BufferWriter, IO, 1);
+    BufferIO->CurOffset =
+        (uint8_t *)BufferWriter.WriterCtx - BufferIO->BufferStart;
   }
   return 0;
 }
@@ -98,7 +104,7 @@ COMPILER_RT_VISIBILITY int lprofBufferIOFlush(ProfBuff
   if (BufferIO->CurOffset) {
     ProfDataIOVec IO[] = {
         {BufferIO->BufferStart, sizeof(uint8_t), BufferIO->CurOffset}};
-    if (BufferIO->FileWriter(IO, 1, &BufferIO->File))
+    if (BufferIO->FileWriter->Write(BufferIO->FileWriter, IO, 1))
       return -1;
     BufferIO->CurOffset = 0;
   }
@@ -201,7 +207,7 @@ static int writeOneValueProfData(ProfBufferIO *BufferI
   return 0;
 }
 
-static int writeValueProfData(WriterCallback Writer, void *WriterCtx,
+static int writeValueProfData(ProfDataWriter *Writer,
                               VPDataReaderType *VPDataReader,
                               const __llvm_profile_data *DataBegin,
                               const __llvm_profile_data *DataEnd) {
@@ -211,7 +217,7 @@ static int writeValueProfData(WriterCallback Writer, v
   if (!VPDataReader)
     return 0;
 
-  BufferIO = lprofCreateBufferIO(Writer, WriterCtx);
+  BufferIO = lprofCreateBufferIO(Writer);
 
   for (DI = DataBegin; DI < DataEnd; DI++) {
     if (writeOneValueProfData(BufferIO, VPDataReader, DI))
@@ -225,9 +231,9 @@ static int writeValueProfData(WriterCallback Writer, v
   return 0;
 }
 
-COMPILER_RT_VISIBILITY int lprofWriteData(WriterCallback Writer,
-                                          void *WriterCtx,
-                                          VPDataReaderType *VPDataReader) {
+COMPILER_RT_VISIBILITY int lprofWriteData(ProfDataWriter *Writer,
+                                          VPDataReaderType *VPDataReader,
+                                          int SkipNameDataWrite) {
   /* Match logic in __llvm_profile_write_buffer(). */
   const __llvm_profile_data *DataBegin = __llvm_profile_begin_data();
   const __llvm_profile_data *DataEnd = __llvm_profile_end_data();
@@ -235,18 +241,17 @@ COMPILER_RT_VISIBILITY int lprofWriteData(WriterCallba
   const uint64_t *CountersEnd = __llvm_profile_end_counters();
   const char *NamesBegin = __llvm_profile_begin_names();
   const char *NamesEnd = __llvm_profile_end_names();
-  return lprofWriteDataImpl(Writer, WriterCtx, DataBegin, DataEnd,
-                            CountersBegin, CountersEnd, VPDataReader,
-                            NamesBegin, NamesEnd);
+  return lprofWriteDataImpl(Writer, DataBegin, DataEnd, CountersBegin,
+                            CountersEnd, VPDataReader, NamesBegin, NamesEnd,
+                            SkipNameDataWrite);
 }
 
 COMPILER_RT_VISIBILITY int
-lprofWriteDataImpl(WriterCallback Writer, void *WriterCtx,
-                   const __llvm_profile_data *DataBegin,
+lprofWriteDataImpl(ProfDataWriter *Writer, const __llvm_profile_data *DataBegin,
                    const __llvm_profile_data *DataEnd,
                    const uint64_t *CountersBegin, const uint64_t *CountersEnd,
                    VPDataReaderType *VPDataReader, const char *NamesBegin,
-                   const char *NamesEnd) {
+                   const char *NamesEnd, int SkipNameDataWrite) {
 
   /* Calculate size of sections. */
   const uint64_t DataSize = __llvm_profile_get_data_size(DataBegin, DataEnd);
@@ -268,14 +273,14 @@ lprofWriteDataImpl(WriterCallback Writer, void *Writer
 #include "InstrProfData.inc"
 
   /* Write the data. */
-  ProfDataIOVec IOVec[] = {{&Header, sizeof(__llvm_profile_header), 1},
-                           {DataBegin, sizeof(__llvm_profile_data), DataSize},
-                           {CountersBegin, sizeof(uint64_t), CountersSize},
-                           {NamesBegin, sizeof(uint8_t), NamesSize},
-                           {Zeroes, sizeof(uint8_t), Padding}};
-  if (Writer(IOVec, sizeof(IOVec) / sizeof(*IOVec), &WriterCtx))

*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201707011324.v61DOFvd022195>