Update aosp/master compiler-rt for rebase to r239765

Change-Id: I722dcde07e4f76a8a35ca701d89be5f311840e74
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 0d8a880..7daee7c 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -207,6 +207,7 @@
 append_list_if(COMPILER_RT_HAS_FOMIT_FRAME_POINTER_FLAG -fomit-frame-pointer SANITIZER_COMMON_CFLAGS)
 append_list_if(COMPILER_RT_HAS_FUNWIND_TABLES_FLAG -funwind-tables SANITIZER_COMMON_CFLAGS)
 append_list_if(COMPILER_RT_HAS_FNO_STACK_PROTECTOR_FLAG -fno-stack-protector SANITIZER_COMMON_CFLAGS)
+append_list_if(COMPILER_RT_HAS_FNO_SANITIZE_SAFE_STACK_FLAG -fno-sanitize=safe-stack SANITIZER_COMMON_CFLAGS)
 append_list_if(COMPILER_RT_HAS_FVISIBILITY_HIDDEN_FLAG -fvisibility=hidden SANITIZER_COMMON_CFLAGS)
 append_list_if(COMPILER_RT_HAS_FNO_FUNCTION_SECTIONS_FLAG -fno-function-sections SANITIZER_COMMON_CFLAGS)
 append_list_if(COMPILER_RT_HAS_FNO_LTO_FLAG -fno-lto SANITIZER_COMMON_CFLAGS)
@@ -293,9 +294,9 @@
 
   string(REGEX MATCH "-mmacosx-version-min="
          MACOSX_VERSION_MIN_FLAG "${CMAKE_CXX_FLAGS}")
-  set(SANITIZER_COMMON_SUPPORTED_DARWIN_OS osx)
+  set(SANITIZER_COMMON_SUPPORTED_OS osx)
   if (IOSSIM_SDK_DIR AND NOT MACOSX_VERSION_MIN_FLAG)
-    list(APPEND SANITIZER_COMMON_SUPPORTED_DARWIN_OS iossim)
+    list(APPEND SANITIZER_COMMON_SUPPORTED_OS iossim)
   endif()
 
   set(SANITIZER_MIN_OSX_VERSION 10.7)
diff --git a/cmake/Modules/AddCompilerRT.cmake b/cmake/Modules/AddCompilerRT.cmake
index a7782a1..77f59cd 100644
--- a/cmake/Modules/AddCompilerRT.cmake
+++ b/cmake/Modules/AddCompilerRT.cmake
@@ -3,40 +3,47 @@
 include(LLVMParseArguments)
 include(CompilerRTUtils)
 
-# Tries to add "object library" target for a given architecture
-# with name "<name>.<arch>" if architecture can be targeted.
-# add_compiler_rt_object_library(<name> <arch>
-#                                SOURCES <source files>
-#                                CFLAGS <compile flags>
-#                                DEFS <compile definitions>)
-macro(add_compiler_rt_object_library name arch)
-  if(CAN_TARGET_${arch})
-    parse_arguments(LIB "SOURCES;CFLAGS;DEFS" "" ${ARGN})
-    add_library(${name}.${arch} OBJECT ${LIB_SOURCES})
-    set_target_compile_flags(${name}.${arch}
-      ${CMAKE_CXX_FLAGS} ${TARGET_${arch}_CFLAGS} ${LIB_CFLAGS})
-    set_property(TARGET ${name}.${arch} APPEND PROPERTY
-      COMPILE_DEFINITIONS ${LIB_DEFS})
+# Tries to add an "object library" target for a given list of OSs and/or
+# architectures with name "<name>.<arch>" for non-Darwin platforms if
+# architecture can be targeted, and "<name>.<os>" for Darwin platforms.
+# add_compiler_rt_object_libraries(<name>
+#                                  OS <os>
+#                                  ARCH <arch>
+#                                  SOURCES <source files>
+#                                  CFLAGS <compile flags>
+#                                  DEFS <compile definitions>)
+function(add_compiler_rt_object_libraries name)
+  parse_arguments(LIB "OS;ARCH;SOURCES;CFLAGS;DEFS" "" ${ARGN})
+  set(libnames)
+  if(APPLE)
+    foreach(os ${LIB_OS})
+      set(libname "${name}.${os}")
+      set(libnames ${libnames} ${libname})
+      set(extra_cflags_${libname} ${DARWIN_${os}_CFLAGS})
+    endforeach()
   else()
-    message(FATAL_ERROR "Archtecture ${arch} can't be targeted")
+    foreach(arch ${LIB_ARCH})
+      set(libname "${name}.${arch}")
+      set(libnames ${libnames} ${libname})
+      set(extra_cflags_${libname} ${TARGET_${arch}_CFLAGS})
+      if(NOT CAN_TARGET_${arch})
+        message(FATAL_ERROR "Archtecture ${arch} can't be targeted")
+        return()
+      endif()
+    endforeach()
   endif()
-endmacro()
-
-# Same as above, but adds universal osx library for either OSX or iOS simulator
-# with name "<name>.<os>" targeting multiple architectures.
-# add_compiler_rt_darwin_object_library(<name> <os> ARCH <architectures>
-#                                                   SOURCES <source files>
-#                                                   CFLAGS <compile flags>
-#                                                   DEFS <compile definitions>)
-macro(add_compiler_rt_darwin_object_library name os)
-  parse_arguments(LIB "ARCH;SOURCES;CFLAGS;DEFS" "" ${ARGN})
-  set(libname "${name}.${os}")
-  add_library(${libname} OBJECT ${LIB_SOURCES})
-  set_target_compile_flags(${libname} ${LIB_CFLAGS} ${DARWIN_${os}_CFLAGS})
-  set_target_properties(${libname} PROPERTIES OSX_ARCHITECTURES "${LIB_ARCH}")
-  set_property(TARGET ${libname} APPEND PROPERTY
-    COMPILE_DEFINITIONS ${LIB_DEFS})
-endmacro()
+  
+  foreach(libname ${libnames})
+    add_library(${libname} OBJECT ${LIB_SOURCES})
+    set_target_compile_flags(${libname}
+      ${CMAKE_CXX_FLAGS} ${extra_cflags_${libname}} ${LIB_CFLAGS})
+    set_property(TARGET ${libname} APPEND PROPERTY
+      COMPILE_DEFINITIONS ${LIB_DEFS})
+    if(APPLE)
+      set_target_properties(${libname} PROPERTIES OSX_ARCHITECTURES "${LIB_ARCH}")
+    endif()
+  endforeach()
+endfunction()
 
 # Adds static or shared runtime for a given architecture and puts it in the
 # proper directory in the build and install trees.
@@ -47,13 +54,13 @@
 #                         OUTPUT_NAME <output library name>)
 macro(add_compiler_rt_runtime name arch type)
   if(CAN_TARGET_${arch})
-    parse_arguments(LIB "SOURCES;CFLAGS;DEFS;OUTPUT_NAME" "" ${ARGN})
+    parse_arguments(LIB "SOURCES;CFLAGS;LINKFLAGS;DEFS;OUTPUT_NAME" "" ${ARGN})
     add_library(${name} ${type} ${LIB_SOURCES})
     # Setup compile flags and definitions.
     set_target_compile_flags(${name}
       ${TARGET_${arch}_CFLAGS} ${LIB_CFLAGS})
     set_target_link_flags(${name}
-      ${TARGET_${arch}_CFLAGS} ${LIB_CFLAGS})
+      ${TARGET_${arch}_CFLAGS} ${LIB_CFLAGS} ${LIB_LINKFLAGS})
     set_property(TARGET ${name} APPEND PROPERTY
       COMPILE_DEFINITIONS ${LIB_DEFS})
     # Setup correct output directory in the build tree.
diff --git a/cmake/Modules/CompilerRTUtils.cmake b/cmake/Modules/CompilerRTUtils.cmake
index 0fdb784..f7f60a4 100644
--- a/cmake/Modules/CompilerRTUtils.cmake
+++ b/cmake/Modules/CompilerRTUtils.cmake
@@ -52,7 +52,7 @@
 
 macro(append_have_file_definition filename varname list)
   check_include_file("${filename}" "${varname}")
-  if (NOT "${varname}")
+  if (NOT ${varname})
     set("${varname}" 0)
   endif()
   list(APPEND ${list} "${varname}=${${varname}}")
diff --git a/cmake/Modules/SanitizerUtils.cmake b/cmake/Modules/SanitizerUtils.cmake
index 1ebc703..1e8e89d 100644
--- a/cmake/Modules/SanitizerUtils.cmake
+++ b/cmake/Modules/SanitizerUtils.cmake
@@ -13,9 +13,13 @@
 #   add_sanitizer_rt_symbols(<name> <files with extra symbols to export>)
 macro(add_sanitizer_rt_symbols name)
   set(stamp ${CMAKE_CURRENT_BINARY_DIR}/${name}.syms-stamp)
+  set(extra_args)
+  foreach(arg ${ARGN})
+    list(APPEND extra_args "--extra" ${arg})
+  endforeach()
   add_custom_command(OUTPUT ${stamp}
     COMMAND ${PYTHON_EXECUTABLE}
-      ${SANITIZER_GEN_DYNAMIC_LIST} $<TARGET_FILE:${name}> ${ARGN}
+      ${SANITIZER_GEN_DYNAMIC_LIST} ${extra_args} $<TARGET_FILE:${name}>
       > $<TARGET_FILE:${name}>.syms
     COMMAND ${CMAKE_COMMAND} -E touch ${stamp}
     DEPENDS ${name} ${SANITIZER_GEN_DYNAMIC_LIST} ${ARGN}
@@ -44,6 +48,29 @@
   endif()
 endmacro()
 
+macro(add_sanitizer_rt_version_list name)
+  set(vers ${CMAKE_CURRENT_BINARY_DIR}/${name}.vers)
+  parse_arguments(ARG "LIB;EXTRA" "" ${ARGN})
+  set(args)
+  foreach(arg ${ARG_EXTRA})
+    list(APPEND args "--extra" ${arg})
+  endforeach()
+  foreach(arg ${ARG_LIB})
+    list(APPEND args "$<TARGET_FILE:${arg}>")
+  endforeach()
+  add_custom_command(OUTPUT ${vers}
+    COMMAND ${PYTHON_EXECUTABLE}
+      ${SANITIZER_GEN_DYNAMIC_LIST} --version-list ${args}
+      > ${vers}
+    DEPENDS ${SANITIZER_GEN_DYNAMIC_LIST} ${ARG_EXTRA} ${ARG_LIB}
+    WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
+    COMMENT "Generating version list for ${name}"
+    VERBATIM)
+
+  add_custom_target(${name}-version-list ALL
+    DEPENDS ${vers})
+endmacro()
+
 # Add target to check code style for sanitizer runtimes.
 if(UNIX)
   add_custom_target(SanitizerLintCheck
diff --git a/cmake/config-ix.cmake b/cmake/config-ix.cmake
index 28f2761..60dae9c 100644
--- a/cmake/config-ix.cmake
+++ b/cmake/config-ix.cmake
@@ -4,6 +4,13 @@
 include(CheckSymbolExists)
 include(TestBigEndian)
 
+function(check_linker_flag flag out_var)
+  cmake_push_check_state()
+  set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} ${flag}")
+  check_cxx_compiler_flag("" ${out_var})
+  cmake_pop_check_state()
+endfunction()
+
 # CodeGen options.
 check_cxx_compiler_flag(-fPIC                COMPILER_RT_HAS_FPIC_FLAG)
 check_cxx_compiler_flag(-fPIE                COMPILER_RT_HAS_FPIE_FLAG)
@@ -12,6 +19,7 @@
 check_cxx_compiler_flag(-fomit-frame-pointer COMPILER_RT_HAS_FOMIT_FRAME_POINTER_FLAG)
 check_cxx_compiler_flag(-funwind-tables      COMPILER_RT_HAS_FUNWIND_TABLES_FLAG)
 check_cxx_compiler_flag(-fno-stack-protector COMPILER_RT_HAS_FNO_STACK_PROTECTOR_FLAG)
+check_cxx_compiler_flag(-fno-sanitize=safe-stack COMPILER_RT_HAS_FNO_SANITIZE_SAFE_STACK_FLAG)
 check_cxx_compiler_flag(-fvisibility=hidden  COMPILER_RT_HAS_FVISIBILITY_HIDDEN_FLAG)
 check_cxx_compiler_flag(-fno-rtti            COMPILER_RT_HAS_FNO_RTTI_FLAG)
 check_cxx_compiler_flag(-ffreestanding       COMPILER_RT_HAS_FFREESTANDING_FLAG)
@@ -55,10 +63,16 @@
 # Libraries.
 check_library_exists(c printf "" COMPILER_RT_HAS_LIBC)
 check_library_exists(dl dlopen "" COMPILER_RT_HAS_LIBDL)
+check_library_exists(rt shm_open "" COMPILER_RT_HAS_LIBRT)
 check_library_exists(m pow "" COMPILER_RT_HAS_LIBM)
 check_library_exists(pthread pthread_create "" COMPILER_RT_HAS_LIBPTHREAD)
 check_library_exists(stdc++ __cxa_throw "" COMPILER_RT_HAS_LIBSTDCXX)
 
+# Linker flags.
+if(ANDROID)
+  check_linker_flag("-Wl,-z,global" COMPILER_RT_HAS_Z_GLOBAL)
+endif()
+
 # Architectures.
 
 # List of all architectures we can target.
@@ -177,13 +191,18 @@
       test_target_arch(powerpc64le "" "-m64")
     endif()
   elseif("${LLVM_NATIVE_ARCH}" STREQUAL "Mips")
+    # Gcc doesn't accept -m32/-m64 so we do the next best thing and use
+    # -mips32r2/-mips64r2. We don't use -mips1/-mips3 because we want to match
+    # clang's default CPU's. In the 64-bit case, we must also specify the ABI
+    # since the default ABI differs between gcc and clang.
+    # FIXME: Ideally, we would build the N32 library too.
     if("${COMPILER_RT_TEST_TARGET_ARCH}" MATCHES "mipsel|mips64el")
       # regex for mipsel, mips64el
-      test_target_arch(mipsel "" "-m32")
-      test_target_arch(mips64el "" "-m64")
+      test_target_arch(mipsel "" "-mips32r2" "--target=mipsel-linux-gnu")
+      test_target_arch(mips64el "" "-mips64r2" "-mabi=n64")
     else()
-      test_target_arch(mips "" "-m32")
-      test_target_arch(mips64 "" "-m64")
+      test_target_arch(mips "" "-mips32r2" "--target=mips-linux-gnu")
+      test_target_arch(mips64 "" "-mips64r2" "-mabi=n64")
     endif()
   elseif("${COMPILER_RT_TEST_TARGET_ARCH}" MATCHES "arm")
     test_target_arch(arm "" "-march=armv7-a")
@@ -209,6 +228,7 @@
   set(${out_var} ${archs} PARENT_SCOPE)
 endfunction()
 
+# Returns a list of architecture specific target cflags in @out_var list.
 function(get_target_flags_for_arch arch out_var)
   list(FIND COMPILER_RT_SUPPORTED_ARCH ${arch} ARCH_INDEX)
   if(ARCH_INDEX EQUAL -1)
@@ -237,6 +257,7 @@
 filter_available_targets(TSAN_SUPPORTED_ARCH x86_64 mips64 mips64el)
 filter_available_targets(UBSAN_SUPPORTED_ARCH x86_64 i386 i686 arm aarch64 mips
   mipsel mips64 mips64el powerpc64 powerpc64le)
+filter_available_targets(SAFESTACK_SUPPORTED_ARCH x86_64 i386 i686)
 
 if(ANDROID)
   set(OS_NAME "Android")
@@ -311,7 +332,14 @@
 # -msse3 flag is not valid for Mips therefore clang gives a warning
 # message with -msse3. But check_c_compiler_flags() checks only for
 # compiler error messages. Therefore COMPILER_RT_HAS_MSSE3_FLAG turns out to be
-# true on Mips. So we make it false here.
+# true on Mips, so we make it false here.
 if("${LLVM_NATIVE_ARCH}" STREQUAL "Mips")
   set(COMPILER_RT_HAS_MSSE3_FLAG FALSE)
 endif()
+
+if (SAFESTACK_SUPPORTED_ARCH AND
+    OS_NAME MATCHES "Darwin|Linux|FreeBSD")
+  set(COMPILER_RT_HAS_SAFESTACK TRUE)
+else()
+  set(COMPILER_RT_HAS_SAFESTACK FALSE)
+endif()
diff --git a/include/sanitizer/dfsan_interface.h b/include/sanitizer/dfsan_interface.h
index 79dbf2f..84ffd49 100644
--- a/include/sanitizer/dfsan_interface.h
+++ b/include/sanitizer/dfsan_interface.h
@@ -91,6 +91,16 @@
 /// <label> <parent label 1> <parent label 2> <label description if any>
 void dfsan_dump_labels(int fd);
 
+/// Whenever a dfsan's custom function is called the corresponding
+/// hook is called it non-zero. The hooks should be defined by the user.
+/// The primary use case is taint-guided fuzzing, where the fuzzer
+/// needs to see the parameters of the function and the labels.
+/// FIXME: implement more hooks.
+
+/// memcmp hook.
+void dfsan_weak_hook_memcmp(void *caller_pc, const void *s1, const void *s2,
+                            size_t n, dfsan_label s1_label,
+                            dfsan_label s2_label, dfsan_label n_label);
 #ifdef __cplusplus
 }  // extern "C"
 
diff --git a/include/sanitizer/lsan_interface.h b/include/sanitizer/lsan_interface.h
index 46d2668..db017c4 100644
--- a/include/sanitizer/lsan_interface.h
+++ b/include/sanitizer/lsan_interface.h
@@ -41,14 +41,25 @@
   void __lsan_register_root_region(const void *p, size_t size);
   void __lsan_unregister_root_region(const void *p, size_t size);
 
-  // Calling this function makes LSan enter the leak checking phase immediately.
-  // Use this if normal end-of-process leak checking happens too late (e.g. if
-  // you have intentional memory leaks in your shutdown code). Calling this
-  // function overrides end-of-process leak checking; it must be called at
-  // most once per process. This function will terminate the process if there
-  // are memory leaks and the exit_code flag is non-zero.
+  // Check for leaks now. This function behaves identically to the default
+  // end-of-process leak check. In particular, it will terminate the process if
+  // leaks are found and the exit_code flag is non-zero.
+  // Subsequent calls to this function will have no effect and end-of-process
+  // leak check will not run. Effectively, end-of-process leak check is moved to
+  // the time of first invocation of this function.
+  // By calling this function early during process shutdown, you can instruct
+  // LSan to ignore shutdown-only leaks which happen later on.
   void __lsan_do_leak_check();
 
+  // Check for leaks now. Returns zero if no leaks have been found or if leak
+  // detection is disabled, non-zero otherwise.
+  // This function may be called repeatedly, e.g. to periodically check a
+  // long-running process. It prints a leak report if appropriate, but does not
+  // terminate the process. It does not affect the behavior of
+  // __lsan_do_leak_check() or the end-of-process leak check, and is not
+  // affected by them.
+  int __lsan_do_recoverable_leak_check();
+
   // The user may optionally provide this function to disallow leak checking
   // for the program it is linked into (if the return value is non-zero). This
   // function must be defined as returning a constant value; any behavior beyond
diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt
index 2b6ae54..3a5d429 100644
--- a/lib/CMakeLists.txt
+++ b/lib/CMakeLists.txt
@@ -34,3 +34,6 @@
   add_subdirectory(tsan/dd)
 endif()
 
+if(COMPILER_RT_HAS_SAFESTACK)
+  add_subdirectory(safestack)
+endif()
diff --git a/lib/asan/Android.mk b/lib/asan/Android.mk
index 81fb3ca..b9e09cd 100644
--- a/lib/asan/Android.mk
+++ b/lib/asan/Android.mk
@@ -321,6 +321,7 @@
 LOCAL_CLANG := true
 LOCAL_CXX_STL := libc++
 LOCAL_MULTILIB := both
+LOCAL_LDLIBS := -lrt
 LOCAL_MODULE_STEM_32 := $(LOCAL_MODULE)32
 LOCAL_MODULE_STEM_64 := $(LOCAL_MODULE)64
 LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
diff --git a/lib/asan/CMakeLists.txt b/lib/asan/CMakeLists.txt
index e09c94d..447ee0b 100644
--- a/lib/asan/CMakeLists.txt
+++ b/lib/asan/CMakeLists.txt
@@ -37,9 +37,22 @@
 set(ASAN_COMMON_DEFINITIONS
   ASAN_HAS_EXCEPTIONS=1)
 
+set(ASAN_DYNAMIC_LINK_FLAGS)
+
 if(ANDROID)
   list(APPEND ASAN_COMMON_DEFINITIONS
     ASAN_LOW_MEMORY=1)
+# On Android, -z global does not do what it is documented to do.
+# On Android, -z global moves the library ahead in the lookup order,
+# placing it right after the LD_PRELOADs. This is used to compensate for the fact
+# that Android linker does not look at the dependencies of the main executable
+# that aren't dependencies of the current DSO when resolving symbols from said DSO.
+# As a net result, this allows running ASan executables without LD_PRELOAD-ing the
+# ASan runtime library.
+# The above is applicable to L MR1 or newer.
+  if (COMPILER_RT_HAS_Z_GLOBAL)
+    list(APPEND ASAN_DYNAMIC_LINK_FLAGS -Wl,-z,global)
+  endif()
 endif()
 
 set(ASAN_DYNAMIC_DEFINITIONS
@@ -53,6 +66,7 @@
 
 append_list_if(COMPILER_RT_HAS_LIBC c ASAN_DYNAMIC_LIBS)
 append_list_if(COMPILER_RT_HAS_LIBDL dl ASAN_DYNAMIC_LIBS)
+append_list_if(COMPILER_RT_HAS_LIBRT rt ASAN_DYNAMIC_LIBS)
 append_list_if(COMPILER_RT_HAS_LIBM m ASAN_DYNAMIC_LIBS)
 append_list_if(COMPILER_RT_HAS_LIBPTHREAD pthread ASAN_DYNAMIC_LIBS)
 append_list_if(COMPILER_RT_HAS_LIBSTDCXX stdc++ ASAN_DYNAMIC_LIBS)
@@ -61,35 +75,43 @@
 
 # Compile ASan sources into an object library.
 if(APPLE)
-  foreach(os ${SANITIZER_COMMON_SUPPORTED_DARWIN_OS})
-    add_compiler_rt_darwin_object_library(RTAsan ${os}
-      ARCH ${ASAN_SUPPORTED_ARCH}
-      SOURCES ${ASAN_SOURCES} ${ASAN_CXX_SOURCES}
-      CFLAGS ${ASAN_DYNAMIC_CFLAGS}
-      DEFS ${ASAN_DYNAMIC_DEFINITIONS})
-  endforeach()
+  add_compiler_rt_object_libraries(RTAsan
+    OS ${SANITIZER_COMMON_SUPPORTED_OS}
+    ARCH ${ASAN_SUPPORTED_ARCH}
+    SOURCES ${ASAN_SOURCES} ${ASAN_CXX_SOURCES}
+    CFLAGS ${ASAN_DYNAMIC_CFLAGS}
+    DEFS ${ASAN_DYNAMIC_DEFINITIONS})
 else()
-  foreach(arch ${ASAN_SUPPORTED_ARCH})
-    add_compiler_rt_object_library(RTAsan ${arch}
-      SOURCES ${ASAN_SOURCES} CFLAGS ${ASAN_CFLAGS}
-      DEFS ${ASAN_COMMON_DEFINITIONS})
-    add_compiler_rt_object_library(RTAsan_cxx ${arch}
-      SOURCES ${ASAN_CXX_SOURCES} CFLAGS ${ASAN_CFLAGS}
-      DEFS ${ASAN_COMMON_DEFINITIONS})
-    add_compiler_rt_object_library(RTAsan_preinit ${arch}
-      SOURCES ${ASAN_PREINIT_SOURCES} CFLAGS ${ASAN_CFLAGS}
-      DEFS ${ASAN_COMMON_DEFINITIONS})
-    add_compiler_rt_object_library(RTAsan_dynamic ${arch}
-      SOURCES ${ASAN_SOURCES} ${ASAN_CXX_SOURCES}
-      CFLAGS ${ASAN_DYNAMIC_CFLAGS}
-      DEFS ${ASAN_DYNAMIC_DEFINITIONS})
-  endforeach()
+  add_compiler_rt_object_libraries(RTAsan 
+    ARCH ${ASAN_SUPPORTED_ARCH}
+    SOURCES ${ASAN_SOURCES} CFLAGS ${ASAN_CFLAGS}
+    DEFS ${ASAN_COMMON_DEFINITIONS})
+  add_compiler_rt_object_libraries(RTAsan_cxx 
+    ARCH ${ASAN_SUPPORTED_ARCH}
+    SOURCES ${ASAN_CXX_SOURCES} CFLAGS ${ASAN_CFLAGS}
+    DEFS ${ASAN_COMMON_DEFINITIONS})
+  add_compiler_rt_object_libraries(RTAsan_preinit 
+    ARCH ${ASAN_SUPPORTED_ARCH}
+    SOURCES ${ASAN_PREINIT_SOURCES} CFLAGS ${ASAN_CFLAGS}
+    DEFS ${ASAN_COMMON_DEFINITIONS})
+  add_compiler_rt_object_libraries(RTAsan_dynamic 
+    ARCH ${ASAN_SUPPORTED_ARCH}
+    SOURCES ${ASAN_SOURCES} ${ASAN_CXX_SOURCES}
+    CFLAGS ${ASAN_DYNAMIC_CFLAGS}
+    DEFS ${ASAN_DYNAMIC_DEFINITIONS})
+
+  file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/dummy.cc "")
+  add_compiler_rt_object_libraries(RTAsan_dynamic_version_script_dummy
+    ARCH ${ASAN_SUPPORTED_ARCH}
+    SOURCES ${CMAKE_CURRENT_BINARY_DIR}/dummy.cc
+    CFLAGS ${ASAN_DYNAMIC_CFLAGS}
+    DEFS ${ASAN_DYNAMIC_DEFINITIONS})
 endif()
 
 # Build ASan runtimes shipped with Clang.
 add_custom_target(asan)
 if(APPLE)
-  foreach (os ${SANITIZER_COMMON_SUPPORTED_DARWIN_OS})
+  foreach (os ${SANITIZER_COMMON_SUPPORTED_OS})
     add_compiler_rt_darwin_dynamic_runtime(clang_rt.asan_${os}_dynamic ${os}
       ARCH ${ASAN_SUPPORTED_ARCH}
       SOURCES $<TARGET_OBJECTS:RTAsan.${os}>
@@ -132,6 +154,20 @@
       DEFS ${ASAN_COMMON_DEFINITIONS})
     add_dependencies(asan clang_rt.asan-preinit-${arch})
 
+    if (UNIX AND NOT ${arch} MATCHES "i386|i686")
+      add_sanitizer_rt_version_list(clang_rt.asan-dynamic-${arch}
+                                    LIB clang_rt.asan-${arch} clang_rt.asan_cxx-${arch}
+                                    EXTRA asan.syms.extra)
+      set(VERSION_SCRIPT_FLAG
+           -Wl,--version-script,${CMAKE_CURRENT_BINARY_DIR}/clang_rt.asan-dynamic-${arch}.vers)
+      set_source_files_properties(
+        ${CMAKE_CURRENT_BINARY_DIR}/dummy.cc
+	PROPERTIES
+	OBJECT_DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/clang_rt.asan-dynamic-${arch}.vers)
+    else()
+      set(VERSION_SCRIPT_FLAG)
+    endif()
+
     if (WIN32)
       set(SHARED_ASAN_NAME clang_rt.asan_dynamic-${arch}${COMPILER_RT_OS_SUFFIX})
     else()
@@ -140,9 +176,16 @@
     add_compiler_rt_runtime(clang_rt.asan-dynamic-${arch} ${arch} SHARED
       OUTPUT_NAME ${SHARED_ASAN_NAME}
       SOURCES $<TARGET_OBJECTS:RTAsan_dynamic.${arch}>
+              # The only purpose of RTAsan_dynamic_version_script_dummy is to carry
+              # a dependency of the shared runtime on the version script. With CMake
+              # 3.1 or later it can be replaced with a straightforward
+              # add_dependencies(clang_rt.asan-dynamic-${arch} clang_rt.asan-dynamic-${arch}-version-list)
+              $<TARGET_OBJECTS:RTAsan_dynamic_version_script_dummy.${arch}>
               $<TARGET_OBJECTS:RTUbsan_cxx.${arch}>
               ${ASAN_COMMON_RUNTIME_OBJECTS}
       CFLAGS ${ASAN_DYNAMIC_CFLAGS}
+      LINKFLAGS ${ASAN_DYNAMIC_LINK_FLAGS}
+                ${VERSION_SCRIPT_FLAG}
       DEFS ${ASAN_DYNAMIC_DEFINITIONS})
     target_link_libraries(clang_rt.asan-dynamic-${arch} ${ASAN_DYNAMIC_LIBS})
     add_dependencies(asan clang_rt.asan-dynamic-${arch})
diff --git a/lib/asan/asan_allocator.cc b/lib/asan/asan_allocator.cc
index fd63ac6..2ead263 100644
--- a/lib/asan/asan_allocator.cc
+++ b/lib/asan/asan_allocator.cc
@@ -223,7 +223,7 @@
 
 struct Allocator {
   static const uptr kMaxAllowedMallocSize =
-      FIRST_32_SECOND_64(3UL << 30, 64UL << 30);
+      FIRST_32_SECOND_64(3UL << 30, 1UL << 40);
   static const uptr kMaxThreadLocalQuarantine =
       FIRST_32_SECOND_64(1 << 18, 1 << 20);
 
@@ -354,7 +354,7 @@
     }
     CHECK(IsAligned(needed_size, min_alignment));
     if (size > kMaxAllowedMallocSize || needed_size > kMaxAllowedMallocSize) {
-      Report("WARNING: AddressSanitizer failed to allocate %p bytes\n",
+      Report("WARNING: AddressSanitizer failed to allocate 0x%zx bytes\n",
              (void*)size);
       return allocator.ReturnNullOrDie();
     }
diff --git a/lib/asan/asan_fake_stack.cc b/lib/asan/asan_fake_stack.cc
index bf4f1eb..d206411 100644
--- a/lib/asan/asan_fake_stack.cc
+++ b/lib/asan/asan_fake_stack.cc
@@ -22,6 +22,9 @@
 static const u64 kMagic4 = (kMagic2 << 16) | kMagic2;
 static const u64 kMagic8 = (kMagic4 << 32) | kMagic4;
 
+static const u64 kAllocaRedzoneSize = 32UL;
+static const u64 kAllocaRedzoneMask = 31UL;
+
 // For small size classes inline PoisonShadow for better performance.
 ALWAYS_INLINE void SetShadow(uptr ptr, uptr size, uptr class_id, u64 magic) {
   CHECK_EQ(SHADOW_SCALE, 3);  // This code expects SHADOW_SCALE=3.
@@ -253,4 +256,24 @@
   if (end) *end = reinterpret_cast<void*>(frame_end);
   return reinterpret_cast<void*>(frame->real_stack);
 }
+
+SANITIZER_INTERFACE_ATTRIBUTE
+void __asan_alloca_poison(uptr addr, uptr size) {
+  uptr LeftRedzoneAddr = addr - kAllocaRedzoneSize;
+  uptr PartialRzAddr = addr + size;
+  uptr RightRzAddr = (PartialRzAddr + kAllocaRedzoneMask) & ~kAllocaRedzoneMask;
+  uptr PartialRzAligned = PartialRzAddr & ~(SHADOW_GRANULARITY - 1);
+  FastPoisonShadow(LeftRedzoneAddr, kAllocaRedzoneSize, kAsanAllocaLeftMagic);
+  FastPoisonShadowPartialRightRedzone(
+      PartialRzAligned, PartialRzAddr % SHADOW_GRANULARITY,
+      RightRzAddr - PartialRzAligned, kAsanAllocaRightMagic);
+  FastPoisonShadow(RightRzAddr, kAllocaRedzoneSize, kAsanAllocaRightMagic);
+}
+
+SANITIZER_INTERFACE_ATTRIBUTE
+void __asan_allocas_unpoison(uptr top, uptr bottom) {
+  if ((!top) || (top > bottom)) return;
+  REAL(memset)(reinterpret_cast<void*>(MemToShadow(top)), 0,
+               (bottom - top) / SHADOW_GRANULARITY);
+}
 }  // extern "C"
diff --git a/lib/asan/asan_globals.cc b/lib/asan/asan_globals.cc
index 8906d1e..c34b1d3 100644
--- a/lib/asan/asan_globals.cc
+++ b/lib/asan/asan_globals.cc
@@ -74,7 +74,7 @@
 
 const uptr kMinimalDistanceFromAnotherGlobal = 64;
 
-bool IsAddressNearGlobal(uptr addr, const __asan_global &g) {
+static bool IsAddressNearGlobal(uptr addr, const __asan_global &g) {
   if (addr <= g.beg - kMinimalDistanceFromAnotherGlobal) return false;
   if (addr >= g.beg + g.size_with_redzone) return false;
   return true;
@@ -91,46 +91,8 @@
   }
 }
 
-static bool DescribeOrGetInfoIfGlobal(uptr addr, uptr size, bool print,
-                                      Global *output_global) {
-  if (!flags()->report_globals) return false;
-  BlockingMutexLock lock(&mu_for_globals);
-  bool res = false;
-  for (ListOfGlobals *l = list_of_all_globals; l; l = l->next) {
-    const Global &g = *l->g;
-    if (print) {
-      if (flags()->report_globals >= 2)
-        ReportGlobal(g, "Search");
-      res |= DescribeAddressRelativeToGlobal(addr, size, g);
-    } else {
-      if (IsAddressNearGlobal(addr, g)) {
-        CHECK(output_global);
-        *output_global = g;
-        return true;
-      }
-    }
-  }
-  return res;
-}
-
-bool DescribeAddressIfGlobal(uptr addr, uptr size) {
-  return DescribeOrGetInfoIfGlobal(addr, size, /* print */ true,
-                                   /* output_global */ nullptr);
-}
-
-bool GetInfoForAddressIfGlobal(uptr addr, AddressDescription *descr) {
-  Global g = {};
-  if (DescribeOrGetInfoIfGlobal(addr, /* size */ 1, /* print */ false, &g)) {
-    internal_strncpy(descr->name, g.name, descr->name_size);
-    descr->region_address = g.beg;
-    descr->region_size = g.size;
-    descr->region_kind = "global";
-    return true;
-  }
-  return false;
-}
-
-u32 FindRegistrationSite(const Global *g) {
+static u32 FindRegistrationSite(const Global *g) {
+  mu_for_globals.CheckLocked();
   CHECK(global_registration_site_vector);
   for (uptr i = 0, n = global_registration_site_vector->size(); i < n; i++) {
     GlobalRegistrationSite &grs = (*global_registration_site_vector)[i];
@@ -140,6 +102,38 @@
   return 0;
 }
 
+int GetGlobalsForAddress(uptr addr, Global *globals, u32 *reg_sites,
+                         int max_globals) {
+  if (!flags()->report_globals) return 0;
+  BlockingMutexLock lock(&mu_for_globals);
+  int res = 0;
+  for (ListOfGlobals *l = list_of_all_globals; l; l = l->next) {
+    const Global &g = *l->g;
+    if (flags()->report_globals >= 2)
+      ReportGlobal(g, "Search");
+    if (IsAddressNearGlobal(addr, g)) {
+      globals[res] = g;
+      if (reg_sites)
+        reg_sites[res] = FindRegistrationSite(&g);
+      res++;
+      if (res == max_globals) break;
+    }
+  }
+  return res;
+}
+
+bool GetInfoForAddressIfGlobal(uptr addr, AddressDescription *descr) {
+  Global g = {};
+  if (GetGlobalsForAddress(addr, &g, nullptr, 1)) {
+    internal_strncpy(descr->name, g.name, descr->name_size);
+    descr->region_address = g.beg;
+    descr->region_size = g.size;
+    descr->region_kind = "global";
+    return true;
+  }
+  return false;
+}
+
 // Register a global variable.
 // This function may be called more than once for every global
 // so we store the globals in a map.
diff --git a/lib/asan/asan_interceptors.cc b/lib/asan/asan_interceptors.cc
index 1318785..d8b48d3 100644
--- a/lib/asan/asan_interceptors.cc
+++ b/lib/asan/asan_interceptors.cc
@@ -182,6 +182,13 @@
   CoverageUpdateMapping()
 #define COMMON_INTERCEPTOR_LIBRARY_UNLOADED() CoverageUpdateMapping()
 #define COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED (!asan_inited)
+#define COMMON_INTERCEPTOR_GET_TLS_RANGE(begin, end)                           \
+  if (AsanThread *t = GetCurrentThread()) {                                    \
+    *begin = t->tls_begin();                                                   \
+    *end = t->tls_end();                                                       \
+  } else {                                                                     \
+    *begin = *end = 0;                                                         \
+  }
 #include "sanitizer_common/sanitizer_common_interceptors.inc"
 
 // Syscall interceptors don't have contexts, we don't support suppressions
diff --git a/lib/asan/asan_interface_internal.h b/lib/asan/asan_interface_internal.h
index 8ed4ee3..ad8ebcd 100644
--- a/lib/asan/asan_interface_internal.h
+++ b/lib/asan/asan_interface_internal.h
@@ -195,6 +195,10 @@
   void __asan_poison_intra_object_redzone(uptr p, uptr size);
   SANITIZER_INTERFACE_ATTRIBUTE
   void __asan_unpoison_intra_object_redzone(uptr p, uptr size);
+  SANITIZER_INTERFACE_ATTRIBUTE
+  void __asan_alloca_poison(uptr addr, uptr size);
+  SANITIZER_INTERFACE_ATTRIBUTE
+  void __asan_allocas_unpoison(uptr top, uptr bottom);
 }  // extern "C"
 
 #endif  // ASAN_INTERFACE_INTERNAL_H
diff --git a/lib/asan/asan_internal.h b/lib/asan/asan_internal.h
index 394e460..107e16e 100644
--- a/lib/asan/asan_internal.h
+++ b/lib/asan/asan_internal.h
@@ -93,7 +93,7 @@
 
 void *AsanDlSymNext(const char *sym);
 
-void ReserveShadowMemoryRange(uptr beg, uptr end);
+void ReserveShadowMemoryRange(uptr beg, uptr end, const char *name);
 
 // Platform-specific options.
 #if SANITIZER_MAC
diff --git a/lib/asan/asan_linux.cc b/lib/asan/asan_linux.cc
index f4f187f..9580fc7 100644
--- a/lib/asan/asan_linux.cc
+++ b/lib/asan/asan_linux.cc
@@ -113,6 +113,9 @@
 }
 
 void AsanCheckDynamicRTPrereqs() {
+  if (!ASAN_DYNAMIC)
+    return;
+
   // Ensure that dynamic RT is the first DSO in the list
   const char *first_dso_name = 0;
   dl_iterate_phdr(FindFirstDSOCallback, &first_dso_name);
diff --git a/lib/asan/asan_poisoning.h b/lib/asan/asan_poisoning.h
index 3fc9464..6344225 100644
--- a/lib/asan/asan_poisoning.h
+++ b/lib/asan/asan_poisoning.h
@@ -64,7 +64,7 @@
       if (page_end != shadow_end) {
         REAL(memset)((void *)page_end, 0, shadow_end - page_end);
       }
-      ReserveShadowMemoryRange(page_beg, page_end - 1);
+      ReserveShadowMemoryRange(page_beg, page_end - 1, nullptr);
     }
   }
 }
diff --git a/lib/asan/asan_report.cc b/lib/asan/asan_report.cc
index 62c814e..c1681e6 100644
--- a/lib/asan/asan_report.cc
+++ b/lib/asan/asan_report.cc
@@ -281,9 +281,8 @@
     str->append(":%d", g.location->column_no);
 }
 
-bool DescribeAddressRelativeToGlobal(uptr addr, uptr size,
-                                     const __asan_global &g) {
-  if (!IsAddressNearGlobal(addr, g)) return false;
+static void DescribeAddressRelativeToGlobal(uptr addr, uptr size,
+                                            const __asan_global &g) {
   InternalScopedString str(4096);
   Decorator d;
   str.append("%s", d.Location());
@@ -306,6 +305,26 @@
   str.append("%s", d.EndLocation());
   PrintGlobalNameIfASCII(&str, g);
   Printf("%s", str.data());
+}
+
+static bool DescribeAddressIfGlobal(uptr addr, uptr size,
+                                    const char *bug_type) {
+  // Assume address is close to at most four globals.
+  const int kMaxGlobalsInReport = 4;
+  __asan_global globals[kMaxGlobalsInReport];
+  u32 reg_sites[kMaxGlobalsInReport];
+  int globals_num =
+      GetGlobalsForAddress(addr, globals, reg_sites, ARRAY_SIZE(globals));
+  if (globals_num == 0)
+    return false;
+  for (int i = 0; i < globals_num; i++) {
+    DescribeAddressRelativeToGlobal(addr, size, globals[i]);
+    if (0 == internal_strcmp(bug_type, "initialization-order-fiasco") &&
+        reg_sites[i]) {
+      Printf("  registered at:\n");
+      StackDepotGet(reg_sites[i]).Print();
+    }
+  }
   return true;
 }
 
@@ -551,12 +570,12 @@
   DescribeThread(alloc_thread);
 }
 
-void DescribeAddress(uptr addr, uptr access_size) {
+static void DescribeAddress(uptr addr, uptr access_size, const char *bug_type) {
   // Check if this is shadow or shadow gap.
   if (DescribeAddressIfShadow(addr))
     return;
   CHECK(AddrIsInMem(addr));
-  if (DescribeAddressIfGlobal(addr, access_size))
+  if (DescribeAddressIfGlobal(addr, access_size, bug_type))
     return;
   if (DescribeAddressIfStack(addr, access_size))
     return;
@@ -810,8 +829,8 @@
              bug_type, offset1, offset1 + length1, offset2, offset2 + length2);
   Printf("%s", d.EndWarning());
   stack->Print();
-  DescribeAddress((uptr)offset1, length1);
-  DescribeAddress((uptr)offset2, length2);
+  DescribeAddress((uptr)offset1, length1, bug_type);
+  DescribeAddress((uptr)offset2, length2, bug_type);
   ReportErrorSummary(bug_type, stack);
 }
 
@@ -824,7 +843,7 @@
   Report("ERROR: AddressSanitizer: %s: (size=%zd)\n", bug_type, size);
   Printf("%s", d.EndWarning());
   stack->Print();
-  DescribeAddress(offset, size);
+  DescribeAddress(offset, size, bug_type);
   ReportErrorSummary(bug_type, stack);
 }
 
@@ -879,15 +898,16 @@
 static NOINLINE void
 ReportInvalidPointerPair(uptr pc, uptr bp, uptr sp, uptr a1, uptr a2) {
   ScopedInErrorReport in_report;
+  const char *bug_type = "invalid-pointer-pair";
   Decorator d;
   Printf("%s", d.Warning());
   Report("ERROR: AddressSanitizer: invalid-pointer-pair: %p %p\n", a1, a2);
   Printf("%s", d.EndWarning());
   GET_STACK_TRACE_FATAL(pc, bp);
   stack.Print();
-  DescribeAddress(a1, 1);
-  DescribeAddress(a2, 1);
-  ReportErrorSummary("invalid-pointer-pair", &stack);
+  DescribeAddress(a1, 1, bug_type);
+  DescribeAddress(a2, 1, bug_type);
+  ReportErrorSummary(bug_type, &stack);
 }
 
 static INLINE void CheckForInvalidPointerPair(void *p1, void *p2) {
@@ -1034,7 +1054,7 @@
   GET_STACK_TRACE_FATAL(pc, bp);
   stack.Print();
 
-  DescribeAddress(addr, access_size);
+  DescribeAddress(addr, access_size, bug_descr);
   ReportErrorSummary(bug_descr, &stack);
   PrintShadowMemoryForAddress(addr);
 }
@@ -1052,7 +1072,7 @@
 void __asan_describe_address(uptr addr) {
   // Thread registry must be locked while we're describing an address.
   asanThreadRegistry().Lock();
-  DescribeAddress(addr, 1);
+  DescribeAddress(addr, 1, "");
   asanThreadRegistry().Unlock();
 }
 
diff --git a/lib/asan/asan_report.h b/lib/asan/asan_report.h
index 029c914..e2786b0 100644
--- a/lib/asan/asan_report.h
+++ b/lib/asan/asan_report.h
@@ -33,22 +33,19 @@
   const char *region_kind;
 };
 
+// Returns the number of globals close to the provided address and copies
+// them to "globals" array.
+int GetGlobalsForAddress(uptr addr, __asan_global *globals, u32 *reg_sites,
+                         int max_globals);
+bool GetInfoForAddressIfGlobal(uptr addr, AddressDescription *descr);
 // The following functions prints address description depending
 // on the memory type (shadow/heap/stack/global).
 void DescribeHeapAddress(uptr addr, uptr access_size);
-bool DescribeAddressIfGlobal(uptr addr, uptr access_size);
-bool DescribeAddressRelativeToGlobal(uptr addr, uptr access_size,
-                                     const __asan_global &g);
-bool IsAddressNearGlobal(uptr addr, const __asan_global &g);
-bool GetInfoForAddressIfGlobal(uptr addr, AddressDescription *descr);
 bool DescribeAddressIfShadow(uptr addr, AddressDescription *descr = nullptr,
                              bool print = true);
 bool ParseFrameDescription(const char *frame_descr,
                            InternalMmapVector<StackVarDescr> *vars);
 bool DescribeAddressIfStack(uptr addr, uptr access_size);
-// Determines memory type on its own.
-void DescribeAddress(uptr addr, uptr access_size);
-
 void DescribeThread(AsanThreadContext *context);
 
 // Different kinds of error reports.
diff --git a/lib/asan/asan_rtl.cc b/lib/asan/asan_rtl.cc
index ce86506..a8d92b9 100644
--- a/lib/asan/asan_rtl.cc
+++ b/lib/asan/asan_rtl.cc
@@ -89,12 +89,12 @@
 // ---------------------- mmap -------------------- {{{1
 // Reserve memory range [beg, end].
 // We need to use inclusive range because end+1 may not be representable.
-void ReserveShadowMemoryRange(uptr beg, uptr end) {
+void ReserveShadowMemoryRange(uptr beg, uptr end, const char *name) {
   CHECK_EQ((beg % GetPageSizeCached()), 0);
   CHECK_EQ(((end + 1) % GetPageSizeCached()), 0);
   uptr size = end - beg + 1;
   DecreaseTotalMmap(size);  // Don't count the shadow against mmap_limit_mb.
-  void *res = MmapFixedNoReserve(beg, size);
+  void *res = MmapFixedNoReserve(beg, size, name);
   if (res != (void*)beg) {
     Report("ReserveShadowMemoryRange failed while trying to map 0x%zx bytes. "
            "Perhaps you're using ulimit -v\n", size);
@@ -298,7 +298,7 @@
 }
 
 static void ProtectGap(uptr addr, uptr size) {
-  void *res = MmapNoAccess(addr, size);
+  void *res = MmapNoAccess(addr, size, "shadow gap");
   if (addr == (uptr)res)
     return;
   Report("ERROR: Failed to protect the shadow gap. "
@@ -347,9 +347,9 @@
   Printf("malloc_context_size=%zu\n",
          (uptr)common_flags()->malloc_context_size);
 
-  Printf("SHADOW_SCALE: %zx\n", (uptr)SHADOW_SCALE);
-  Printf("SHADOW_GRANULARITY: %zx\n", (uptr)SHADOW_GRANULARITY);
-  Printf("SHADOW_OFFSET: %zx\n", (uptr)SHADOW_OFFSET);
+  Printf("SHADOW_SCALE: %d\n", (int)SHADOW_SCALE);
+  Printf("SHADOW_GRANULARITY: %d\n", (int)SHADOW_GRANULARITY);
+  Printf("SHADOW_OFFSET: 0x%zx\n", (uptr)SHADOW_OFFSET);
   CHECK(SHADOW_SCALE >= 3 && SHADOW_SCALE <= 7);
   if (kMidMemBeg)
     CHECK(kMidShadowBeg > kLowShadowEnd &&
@@ -367,6 +367,11 @@
   // initialization steps look at flags().
   InitializeFlags();
 
+  CacheBinaryName();
+
+  AsanCheckIncompatibleRT();
+  AsanCheckDynamicRTPrereqs();
+
   SetCanPoisonMemory(flags()->poison_heap);
   SetMallocContextSize(common_flags()->malloc_context_size);
 
@@ -422,9 +427,9 @@
   if (full_shadow_is_available) {
     // mmap the low shadow plus at least one page at the left.
     if (kLowShadowBeg)
-      ReserveShadowMemoryRange(shadow_start, kLowShadowEnd);
+      ReserveShadowMemoryRange(shadow_start, kLowShadowEnd, "low shadow");
     // mmap the high shadow.
-    ReserveShadowMemoryRange(kHighShadowBeg, kHighShadowEnd);
+    ReserveShadowMemoryRange(kHighShadowBeg, kHighShadowEnd, "high shadow");
     // protect the gap.
     ProtectGap(kShadowGapBeg, kShadowGapEnd - kShadowGapBeg + 1);
     CHECK_EQ(kShadowGapEnd, kHighShadowBeg - 1);
@@ -433,11 +438,11 @@
       MemoryRangeIsAvailable(kMidMemEnd + 1, kHighShadowEnd)) {
     CHECK(kLowShadowBeg != kLowShadowEnd);
     // mmap the low shadow plus at least one page at the left.
-    ReserveShadowMemoryRange(shadow_start, kLowShadowEnd);
+    ReserveShadowMemoryRange(shadow_start, kLowShadowEnd, "low shadow");
     // mmap the mid shadow.
-    ReserveShadowMemoryRange(kMidShadowBeg, kMidShadowEnd);
+    ReserveShadowMemoryRange(kMidShadowBeg, kMidShadowEnd, "mid shadow");
     // mmap the high shadow.
-    ReserveShadowMemoryRange(kHighShadowBeg, kHighShadowEnd);
+    ReserveShadowMemoryRange(kHighShadowBeg, kHighShadowEnd, "high shadow");
     // protect the gaps.
     ProtectGap(kShadowGapBeg, kShadowGapEnd - kShadowGapBeg + 1);
     ProtectGap(kShadowGap2Beg, kShadowGap2End - kShadowGap2Beg + 1);
@@ -514,13 +519,11 @@
 
 #if ASAN_DYNAMIC
 // Initialize runtime in case it's LD_PRELOAD-ed into unsanitized executable
-// (and thus normal initializer from .preinit_array haven't run).
+// (and thus normal initializers from .preinit_array or modules haven't run).
 
 class AsanInitializer {
 public:  // NOLINT
   AsanInitializer() {
-    AsanCheckIncompatibleRT();
-    AsanCheckDynamicRTPrereqs();
     AsanInitFromRtl();
   }
 };
@@ -572,7 +575,6 @@
 // Initialize as requested from instrumented application code.
 // We use this call as a trigger to wake up ASan from deactivated state.
 void __asan_init() {
-  AsanCheckIncompatibleRT();
   AsanActivate();
   AsanInitInternal();
 }
diff --git a/lib/asan/asan_win_dll_thunk.cc b/lib/asan/asan_win_dll_thunk.cc
index 0c363fe..b77f181 100644
--- a/lib/asan/asan_win_dll_thunk.cc
+++ b/lib/asan/asan_win_dll_thunk.cc
@@ -303,6 +303,7 @@
 INTERFACE_FUNCTION(__sanitizer_cov_module_init)
 INTERFACE_FUNCTION(__sanitizer_cov_trace_basic_block)
 INTERFACE_FUNCTION(__sanitizer_cov_trace_func_enter)
+INTERFACE_FUNCTION(__sanitizer_cov_trace_cmp)
 INTERFACE_FUNCTION(__sanitizer_cov_with_check)
 INTERFACE_FUNCTION(__sanitizer_get_allocated_size)
 INTERFACE_FUNCTION(__sanitizer_get_coverage_guards)
@@ -380,11 +381,15 @@
 INTERCEPT_LIBRARY_FUNCTION(strchr);
 INTERCEPT_LIBRARY_FUNCTION(strcmp);
 INTERCEPT_LIBRARY_FUNCTION(strcpy);  // NOLINT
+INTERCEPT_LIBRARY_FUNCTION(strcspn);
 INTERCEPT_LIBRARY_FUNCTION(strlen);
 INTERCEPT_LIBRARY_FUNCTION(strncat);
 INTERCEPT_LIBRARY_FUNCTION(strncmp);
 INTERCEPT_LIBRARY_FUNCTION(strncpy);
 INTERCEPT_LIBRARY_FUNCTION(strnlen);
+INTERCEPT_LIBRARY_FUNCTION(strpbrk);
+INTERCEPT_LIBRARY_FUNCTION(strspn);
+INTERCEPT_LIBRARY_FUNCTION(strstr);
 INTERCEPT_LIBRARY_FUNCTION(strtol);
 INTERCEPT_LIBRARY_FUNCTION(wcslen);
 
diff --git a/lib/asan/tests/CMakeLists.txt b/lib/asan/tests/CMakeLists.txt
index 16baf45..9eeacd8 100644
--- a/lib/asan/tests/CMakeLists.txt
+++ b/lib/asan/tests/CMakeLists.txt
@@ -52,6 +52,11 @@
   list(APPEND ASAN_UNITTEST_COMMON_LINKFLAGS ${DARWIN_osx_LINKFLAGS})
 endif()
 
+if(MSVC)
+  # Disable exceptions on Windows until they work reliably.
+  list(APPEND ASAN_UNITTEST_COMMON_CFLAGS -fno-exceptions -DGTEST_HAS_SEH=0)
+endif()
+
 set(ASAN_BLACKLIST_FILE "${CMAKE_CURRENT_SOURCE_DIR}/asan_test.ignore")
 set(ASAN_UNITTEST_INSTRUMENTED_CFLAGS
   ${ASAN_UNITTEST_COMMON_CFLAGS}
@@ -94,6 +99,7 @@
 set(ASAN_UNITTEST_NOINST_LINKFLAGS ${ASAN_UNITTEST_COMMON_LINKFLAGS})
 append_list_if(COMPILER_RT_HAS_LIBM -lm ASAN_UNITTEST_NOINST_LINKFLAGS)
 append_list_if(COMPILER_RT_HAS_LIBDL -ldl ASAN_UNITTEST_NOINST_LINKFLAGS)
+append_list_if(COMPILER_RT_HAS_LIBRT -lrt ASAN_UNITTEST_NOINST_LINKFLAGS)
 append_list_if(COMPILER_RT_HAS_LIBPTHREAD -pthread ASAN_UNITTEST_NOINST_LINKFLAGS)
 append_list_if(COMPILER_RT_HAS_LIBPTHREAD -pthread
           ASAN_DYNAMIC_UNITTEST_INSTRUMENTED_LINKFLAGS)
@@ -270,6 +276,8 @@
       $<TARGET_OBJECTS:RTInterception.${arch}>
       $<TARGET_OBJECTS:RTSanitizerCommon.${arch}>
       $<TARGET_OBJECTS:RTSanitizerCommonLibc.${arch}>
+      $<TARGET_OBJECTS:RTUbsan.${arch}>
+      $<TARGET_OBJECTS:RTUbsan_cxx.${arch}>
       ${COMPILER_RT_GTEST_SOURCE}
       ${ASAN_NOINST_TEST_SOURCES})
     set_target_compile_flags(AsanNoinstTest ${ASAN_UNITTEST_COMMON_CFLAGS})
diff --git a/lib/builtins/atomic_flag_clear.c b/lib/builtins/atomic_flag_clear.c
new file mode 100644
index 0000000..15984cd
--- /dev/null
+++ b/lib/builtins/atomic_flag_clear.c
@@ -0,0 +1,19 @@
+/*===-- atomic_flag_clear.c -------------------------------------------------===
+ *
+ *                     The LLVM Compiler Infrastructure
+ *
+ * This file is dual licensed under the MIT and the University of Illinois Open
+ * Source Licenses. See LICENSE.TXT for details.
+ *
+ *===------------------------------------------------------------------------===
+ *
+ * This file implements atomic_flag_clear from C11's stdatomic.h.
+ *
+ *===------------------------------------------------------------------------===
+ */
+
+#include <stdatomic.h>
+#undef atomic_flag_clear
+void atomic_flag_clear(volatile atomic_flag *object) {
+  return __c11_atomic_store(&(object)->_Value, 0, __ATOMIC_SEQ_CST);
+}
diff --git a/lib/builtins/atomic_flag_clear_explicit.c b/lib/builtins/atomic_flag_clear_explicit.c
new file mode 100644
index 0000000..0f7859c
--- /dev/null
+++ b/lib/builtins/atomic_flag_clear_explicit.c
@@ -0,0 +1,20 @@
+/*===-- atomic_flag_clear_explicit.c ----------------------------------------===
+ *
+ *                     The LLVM Compiler Infrastructure
+ *
+ * This file is dual licensed under the MIT and the University of Illinois Open
+ * Source Licenses. See LICENSE.TXT for details.
+ *
+ *===------------------------------------------------------------------------===
+ *
+ * This file implements atomic_flag_clear_explicit from C11's stdatomic.h.
+ *
+ *===------------------------------------------------------------------------===
+ */
+
+#include <stdatomic.h>
+#undef atomic_flag_clear_explicit
+void atomic_flag_clear_explicit(volatile atomic_flag *object,
+                                memory_order order) {
+  return __c11_atomic_store(&(object)->_Value, 0, order);
+}
diff --git a/lib/builtins/atomic_flag_test_and_set.c b/lib/builtins/atomic_flag_test_and_set.c
new file mode 100644
index 0000000..07209fc
--- /dev/null
+++ b/lib/builtins/atomic_flag_test_and_set.c
@@ -0,0 +1,19 @@
+/*===-- atomic_flag_test_and_set.c ------------------------------------------===
+ *
+ *                     The LLVM Compiler Infrastructure
+ *
+ * This file is dual licensed under the MIT and the University of Illinois Open
+ * Source Licenses. See LICENSE.TXT for details.
+ *
+ *===------------------------------------------------------------------------===
+ *
+ * This file implements atomic_flag_test_and_set from C11's stdatomic.h.
+ *
+ *===------------------------------------------------------------------------===
+ */
+
+#include <stdatomic.h>
+#undef atomic_flag_test_and_set
+_Bool atomic_flag_test_and_set(volatile atomic_flag *object) {
+  return __c11_atomic_exchange(&(object)->_Value, 1, __ATOMIC_SEQ_CST);
+}
diff --git a/lib/builtins/atomic_flag_test_and_set_explicit.c b/lib/builtins/atomic_flag_test_and_set_explicit.c
new file mode 100644
index 0000000..eaa5be0
--- /dev/null
+++ b/lib/builtins/atomic_flag_test_and_set_explicit.c
@@ -0,0 +1,20 @@
+/*===-- atomic_flag_test_and_set_explicit.c ---------------------------------===
+ *
+ *                     The LLVM Compiler Infrastructure
+ *
+ * This file is dual licensed under the MIT and the University of Illinois Open
+ * Source Licenses. See LICENSE.TXT for details.
+ *
+ *===------------------------------------------------------------------------===
+ *
+ * This file implements atomic_flag_test_and_set_explicit from C11's stdatomic.h
+ *
+ *===------------------------------------------------------------------------===
+ */
+
+#include <stdatomic.h>
+#undef atomic_flag_test_and_set_explicit
+_Bool atomic_flag_test_and_set_explicit(volatile atomic_flag *object,
+                                        memory_order order) {
+  return __c11_atomic_exchange(&(object)->_Value, 1, order);
+}
diff --git a/lib/builtins/atomic_signal_fence.c b/lib/builtins/atomic_signal_fence.c
new file mode 100644
index 0000000..ad292d2
--- /dev/null
+++ b/lib/builtins/atomic_signal_fence.c
@@ -0,0 +1,19 @@
+/*===-- atomic_signal_fence.c -----------------------------------------------===
+ *
+ *                     The LLVM Compiler Infrastructure
+ *
+ * This file is dual licensed under the MIT and the University of Illinois Open
+ * Source Licenses. See LICENSE.TXT for details.
+ *
+ *===------------------------------------------------------------------------===
+ *
+ * This file implements atomic_signal_fence from C11's stdatomic.h.
+ *
+ *===------------------------------------------------------------------------===
+ */
+
+#include <stdatomic.h>
+#undef atomic_signal_fence
+void atomic_signal_fence(memory_order order) {
+  __c11_atomic_signal_fence(order);
+}
diff --git a/lib/builtins/atomic_thread_fence.c b/lib/builtins/atomic_thread_fence.c
new file mode 100644
index 0000000..71f698c
--- /dev/null
+++ b/lib/builtins/atomic_thread_fence.c
@@ -0,0 +1,19 @@
+/*===-- atomic_thread_fence.c -----------------------------------------------===
+ *
+ *                     The LLVM Compiler Infrastructure
+ *
+ * This file is dual licensed under the MIT and the University of Illinois Open
+ * Source Licenses. See LICENSE.TXT for details.
+ *
+ *===------------------------------------------------------------------------===
+ *
+ * This file implements atomic_thread_fence from C11's stdatomic.h.
+ *
+ *===------------------------------------------------------------------------===
+ */
+
+#include <stdatomic.h>
+#undef atomic_thread_fence
+void atomic_thread_fence(memory_order order) {
+  __c11_atomic_thread_fence(order);
+}
diff --git a/lib/builtins/extendhfsf2.c b/lib/builtins/extendhfsf2.c
index f0b3c37..7524e2e 100644
--- a/lib/builtins/extendhfsf2.c
+++ b/lib/builtins/extendhfsf2.c
@@ -12,10 +12,12 @@
 #define DST_SINGLE
 #include "fp_extend_impl.inc"
 
-COMPILER_RT_ABI float __extendhfsf2(uint16_t a) {
+// Use a forwarding definition and noinline to implement a poor man's alias,
+// as there isn't a good cross-platform way of defining one.
+COMPILER_RT_ABI __attribute__((noinline)) float __extendhfsf2(uint16_t a) {
     return __extendXfYf2__(a);
 }
 
 COMPILER_RT_ABI float __gnu_h2f_ieee(uint16_t a) {
-    return __extendXfYf2__(a);
+    return __extendhfsf2(a);
 }
diff --git a/lib/builtins/fixunsdfdi.c b/lib/builtins/fixunsdfdi.c
index b93d1c1..2e0d87e 100644
--- a/lib/builtins/fixunsdfdi.c
+++ b/lib/builtins/fixunsdfdi.c
@@ -21,6 +21,7 @@
 COMPILER_RT_ABI du_int
 __fixunsdfdi(double a)
 {
+    if (a <= 0.0) return 0;
     su_int high = a/0x1p32f;
     su_int low = a - (double)high*0x1p32f;
     return ((du_int)high << 32) | low;
diff --git a/lib/builtins/fixunsdfti.c b/lib/builtins/fixunsdfti.c
index c3d7df9..f8046a0 100644
--- a/lib/builtins/fixunsdfti.c
+++ b/lib/builtins/fixunsdfti.c
@@ -17,7 +17,7 @@
 #include "fp_fixuint_impl.inc"
 
 COMPILER_RT_ABI tu_int
-__fixunsdftti(fp_t a) {
+__fixunsdfti(fp_t a) {
     return __fixuint(a);
 }
 #endif /* CRT_HAS_128BIT */
diff --git a/lib/builtins/fixunssfdi.c b/lib/builtins/fixunssfdi.c
index 374ebbe..5a154e8 100644
--- a/lib/builtins/fixunssfdi.c
+++ b/lib/builtins/fixunssfdi.c
@@ -21,6 +21,7 @@
 COMPILER_RT_ABI du_int
 __fixunssfdi(float a)
 {
+    if (a <= 0.0f) return 0;
     double da = a;
     su_int high = da/0x1p32f;
     su_int low = da - (double)high*0x1p32f;
diff --git a/lib/builtins/int_lib.h b/lib/builtins/int_lib.h
index ff314da..bca5d81 100644
--- a/lib/builtins/int_lib.h
+++ b/lib/builtins/int_lib.h
@@ -28,7 +28,11 @@
 # define COMPILER_RT_ABI __attribute__((pcs("aapcs")))
 #else
 # define ARM_EABI_FNALIAS(aeabi_name, name)
-# define COMPILER_RT_ABI
+# if defined(__arm__) && defined(_WIN32)
+#   define COMPILER_RT_ABI __attribute__((pcs("aapcs")))
+# else
+#   define COMPILER_RT_ABI
+# endif
 #endif
 
 #if defined(__NetBSD__) && (defined(_KERNEL) || defined(_STANDALONE))
diff --git a/lib/builtins/truncsfhf2.c b/lib/builtins/truncsfhf2.c
index a25dd83..381e590 100644
--- a/lib/builtins/truncsfhf2.c
+++ b/lib/builtins/truncsfhf2.c
@@ -11,10 +11,12 @@
 #define DST_HALF
 #include "fp_trunc_impl.inc"
 
-COMPILER_RT_ABI uint16_t __truncsfhf2(float a) {
+// Use a forwarding definition and noinline to implement a poor man's alias,
+// as there isn't a good cross-platform way of defining one.
+COMPILER_RT_ABI __attribute__((noinline)) uint16_t __truncsfhf2(float a) {
     return __truncXfYf2__(a);
 }
 
 COMPILER_RT_ABI uint16_t __gnu_f2h_ieee(float a) {
-    return __truncXfYf2__(a);
+    return __truncsfhf2(a);
 }
diff --git a/lib/dfsan/dfsan_custom.cc b/lib/dfsan/dfsan_custom.cc
index 35f6fb4..c58b471 100644
--- a/lib/dfsan/dfsan_custom.cc
+++ b/lib/dfsan/dfsan_custom.cc
@@ -82,11 +82,20 @@
   }
 }
 
+SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE
+void
+dfsan_weak_hook_memcmp(uptr caller_pc, const void *s1, const void *s2, size_t n,
+                       dfsan_label s1_label, dfsan_label s2_label,
+                       dfsan_label n_label);
+
 SANITIZER_INTERFACE_ATTRIBUTE int __dfsw_memcmp(const void *s1, const void *s2,
                                                 size_t n, dfsan_label s1_label,
                                                 dfsan_label s2_label,
                                                 dfsan_label n_label,
                                                 dfsan_label *ret_label) {
+  if (dfsan_weak_hook_memcmp)
+    dfsan_weak_hook_memcmp(GET_CALLER_PC(), s1, s2, n, s1_label, s2_label,
+                           n_label);
   const char *cs1 = (const char *) s1, *cs2 = (const char *) s2;
   for (size_t i = 0; i != n; ++i) {
     if (cs1[i] != cs2[i]) {
diff --git a/lib/dfsan/done_abilist.txt b/lib/dfsan/done_abilist.txt
index 15c6d1b..e6c077f 100644
--- a/lib/dfsan/done_abilist.txt
+++ b/lib/dfsan/done_abilist.txt
@@ -258,3 +258,18 @@
 fun:reflect.MakeFuncStubGo=discard
 fun:reflect.makeFuncStub=uninstrumented
 fun:reflect.makeFuncStub=discard
+
+
+###############################################################################
+# lib/Fuzzer
+###############################################################################
+# Replaces __sanitizer_cov_trace_cmp with __dfsw___sanitizer_cov_trace_cmp
+fun:__sanitizer_cov_trace_cmp=custom
+fun:__sanitizer_cov_trace_cmp=uninstrumented
+
+# Ignores all other __sanitizer callbacks.
+fun:__sanitizer_*=uninstrumented
+fun:__sanitizer_*=discard
+
+# Don't add extra parameters to the Fuzzer callback.
+fun:LLVMFuzzerTestOneInput=uninstrumented
diff --git a/lib/dfsan/scripts/check_custom_wrappers.sh b/lib/dfsan/scripts/check_custom_wrappers.sh
index 1880882..99bf50c 100755
--- a/lib/dfsan/scripts/check_custom_wrappers.sh
+++ b/lib/dfsan/scripts/check_custom_wrappers.sh
@@ -17,8 +17,10 @@
   rm -f ${DIFF_B} 2> /dev/null
 }
 
+# Ignore __sanitizer_cov_trace* because they are implemented elsewhere.
 trap on_exit EXIT
-grep -E "^fun:.*=custom" ${DFSAN_ABI_LIST} | grep -v "dfsan_get_label" \
+grep -E "^fun:.*=custom" ${DFSAN_ABI_LIST} \
+  | grep -v "dfsan_get_label\|__sanitizer_cov_trace" \
   | sed "s/^fun:\(.*\)=custom.*/\1/" | sort > $DIFF_A
 grep -E "__dfsw.*\(" ${DFSAN_CUSTOM_WRAPPERS} \
   | sed "s/.*__dfsw_\(.*\)(.*/\1/" | sort > $DIFF_B
diff --git a/lib/interception/CMakeLists.txt b/lib/interception/CMakeLists.txt
index b77f2d1..f5ff437 100644
--- a/lib/interception/CMakeLists.txt
+++ b/lib/interception/CMakeLists.txt
@@ -12,18 +12,8 @@
 set(INTERCEPTION_CFLAGS ${SANITIZER_COMMON_CFLAGS})
 append_no_rtti_flag(INTERCEPTION_CFLAGS)
 
-if(APPLE)
-  # Build universal binary on APPLE.
-  foreach(os ${SANITIZER_COMMON_SUPPORTED_DARWIN_OS})
-    add_compiler_rt_darwin_object_library(RTInterception ${os}
-      ARCH ${SANITIZER_COMMON_SUPPORTED_ARCH}
-      SOURCES ${INTERCEPTION_SOURCES}
-      CFLAGS ${INTERCEPTION_CFLAGS})
-  endforeach()
-else()
-  # Otherwise, build separate libraries for each target.
-  foreach(arch ${SANITIZER_COMMON_SUPPORTED_ARCH})
-    add_compiler_rt_object_library(RTInterception ${arch}
-      SOURCES ${INTERCEPTION_SOURCES} CFLAGS ${INTERCEPTION_CFLAGS})
-  endforeach()
-endif()
+add_compiler_rt_object_libraries(RTInterception
+    OS ${SANITIZER_COMMON_SUPPORTED_OS}
+    ARCH ${SANITIZER_COMMON_SUPPORTED_ARCH}
+    SOURCES ${INTERCEPTION_SOURCES}
+    CFLAGS ${INTERCEPTION_CFLAGS})
diff --git a/lib/lsan/CMakeLists.txt b/lib/lsan/CMakeLists.txt
index 2ea765d..d87e9dd 100644
--- a/lib/lsan/CMakeLists.txt
+++ b/lib/lsan/CMakeLists.txt
@@ -18,20 +18,13 @@
 
 add_custom_target(lsan)
 
-if(APPLE)
-  foreach(os ${SANITIZER_COMMON_SUPPORTED_DARWIN_OS})
-    add_compiler_rt_darwin_object_library(RTLSanCommon ${os}
-      ARCH ${LSAN_COMMON_SUPPORTED_ARCH}
-      SOURCES ${LSAN_COMMON_SOURCES}
-      CFLAGS ${LSAN_CFLAGS})
-  endforeach()
-else()
-  foreach(arch ${LSAN_COMMON_SUPPORTED_ARCH})
-    add_compiler_rt_object_library(RTLSanCommon ${arch}
-      SOURCES ${LSAN_COMMON_SOURCES}
-      CFLAGS ${LSAN_CFLAGS})
-  endforeach()
+add_compiler_rt_object_libraries(RTLSanCommon
+    OS ${SANITIZER_COMMON_SUPPORTED_OS}
+    ARCH ${LSAN_COMMON_SUPPORTED_ARCH}
+    SOURCES ${LSAN_COMMON_SOURCES}
+    CFLAGS ${LSAN_CFLAGS})
 
+if(NOT APPLE)
   foreach(arch ${LSAN_SUPPORTED_ARCH})
     add_compiler_rt_runtime(clang_rt.lsan-${arch} ${arch} STATIC
       SOURCES ${LSAN_SOURCES}
diff --git a/lib/lsan/lsan_common.cc b/lib/lsan/lsan_common.cc
index 8ac2ae0..0ffba50 100644
--- a/lib/lsan/lsan_common.cc
+++ b/lib/lsan/lsan_common.cc
@@ -126,13 +126,14 @@
 
 // Scans the memory range, looking for byte patterns that point into allocator
 // chunks. Marks those chunks with |tag| and adds them to |frontier|.
-// There are two usage modes for this function: finding reachable or ignored
-// chunks (|tag| = kReachable or kIgnored) and finding indirectly leaked chunks
+// There are two usage modes for this function: finding reachable chunks
+// (|tag| = kReachable) and finding indirectly leaked chunks
 // (|tag| = kIndirectlyLeaked). In the second case, there's no flood fill,
 // so |frontier| = 0.
 void ScanRangeForPointers(uptr begin, uptr end,
                           Frontier *frontier,
                           const char *region_type, ChunkTag tag) {
+  CHECK(tag == kReachable || tag == kIndirectlyLeaked);
   const uptr alignment = flags()->pointer_alignment();
   LOG_POINTERS("Scanning %s range %p-%p.\n", region_type, begin, end);
   uptr pp = begin;
@@ -146,9 +147,7 @@
     // Pointers to self don't count. This matters when tag == kIndirectlyLeaked.
     if (chunk == begin) continue;
     LsanMetadata m(chunk);
-    // Reachable beats ignored beats leaked.
-    if (m.tag() == kReachable) continue;
-    if (m.tag() == kIgnored && tag != kReachable) continue;
+    if (m.tag() == kReachable || m.tag() == kIgnored) continue;
 
     // Do this check relatively late so we can log only the interesting cases.
     if (!flags()->use_poisoned && WordIsPoisoned(pp)) {
@@ -287,7 +286,7 @@
   LsanMetadata m(chunk);
   if (m.allocated() && m.tag() != kReachable) {
     ScanRangeForPointers(chunk, chunk + m.requested_size(),
-                         /* frontier */ 0, "HEAP", kIndirectlyLeaked);
+                         /* frontier */ nullptr, "HEAP", kIndirectlyLeaked);
   }
 }
 
@@ -297,8 +296,11 @@
   CHECK(arg);
   chunk = GetUserBegin(chunk);
   LsanMetadata m(chunk);
-  if (m.allocated() && m.tag() == kIgnored)
+  if (m.allocated() && m.tag() == kIgnored) {
+    LOG_POINTERS("Ignored: chunk %p-%p of size %zu.\n",
+                 chunk, chunk + m.requested_size(), m.requested_size());
     reinterpret_cast<Frontier *>(arg)->push_back(chunk);
+  }
 }
 
 // Sets the appropriate tag on each chunk.
@@ -306,26 +308,33 @@
   // Holds the flood fill frontier.
   Frontier frontier(1);
 
+  ForEachChunk(CollectIgnoredCb, &frontier);
   ProcessGlobalRegions(&frontier);
   ProcessThreads(suspended_threads, &frontier);
   ProcessRootRegions(&frontier);
   FloodFillTag(&frontier, kReachable);
+
   // The check here is relatively expensive, so we do this in a separate flood
   // fill. That way we can skip the check for chunks that are reachable
   // otherwise.
   LOG_POINTERS("Processing platform-specific allocations.\n");
+  CHECK_EQ(0, frontier.size());
   ProcessPlatformSpecificAllocations(&frontier);
   FloodFillTag(&frontier, kReachable);
 
-  LOG_POINTERS("Scanning ignored chunks.\n");
-  CHECK_EQ(0, frontier.size());
-  ForEachChunk(CollectIgnoredCb, &frontier);
-  FloodFillTag(&frontier, kIgnored);
-
   // Iterate over leaked chunks and mark those that are reachable from other
   // leaked chunks.
   LOG_POINTERS("Scanning leaked chunks.\n");
-  ForEachChunk(MarkIndirectlyLeakedCb, 0 /* arg */);
+  ForEachChunk(MarkIndirectlyLeakedCb, nullptr);
+}
+
+// ForEachChunk callback. Resets the tags to pre-leak-check state.
+static void ResetTagsCb(uptr chunk, void *arg) {
+  (void)arg;
+  chunk = GetUserBegin(chunk);
+  LsanMetadata m(chunk);
+  if (m.allocated() && m.tag() != kIgnored)
+    m.set_tag(kDirectlyLeaked);
 }
 
 static void PrintStackTraceById(u32 stack_trace_id) {
@@ -371,35 +380,33 @@
   Printf("%s\n\n", line);
 }
 
-struct DoLeakCheckParam {
+struct CheckForLeaksParam {
   bool success;
   LeakReport leak_report;
 };
 
-static void DoLeakCheckCallback(const SuspendedThreadsList &suspended_threads,
-                                void *arg) {
-  DoLeakCheckParam *param = reinterpret_cast<DoLeakCheckParam *>(arg);
+static void CheckForLeaksCallback(const SuspendedThreadsList &suspended_threads,
+                                  void *arg) {
+  CheckForLeaksParam *param = reinterpret_cast<CheckForLeaksParam *>(arg);
   CHECK(param);
   CHECK(!param->success);
   ClassifyAllChunks(suspended_threads);
   ForEachChunk(CollectLeaksCb, &param->leak_report);
+  // Clean up for subsequent leak checks. This assumes we did not overwrite any
+  // kIgnored tags.
+  ForEachChunk(ResetTagsCb, nullptr);
   param->success = true;
 }
 
-void DoLeakCheck() {
-  EnsureMainThreadIDIsCorrect();
-  BlockingMutexLock l(&global_mutex);
-  static bool already_done;
-  if (already_done) return;
-  already_done = true;
+static bool CheckForLeaks() {
   if (&__lsan_is_turned_off && __lsan_is_turned_off())
-      return;
-
-  DoLeakCheckParam param;
+      return false;
+  EnsureMainThreadIDIsCorrect();
+  CheckForLeaksParam param;
   param.success = false;
   LockThreadRegistry();
   LockAllocator();
-  DoStopTheWorld(DoLeakCheckCallback, &param);
+  DoStopTheWorld(CheckForLeaksCallback, &param);
   UnlockAllocator();
   UnlockThreadRegistry();
 
@@ -423,12 +430,31 @@
     PrintMatchedSuppressions();
   if (unsuppressed_count > 0) {
     param.leak_report.PrintSummary();
-    if (flags()->exitcode) {
-      if (common_flags()->coverage)
-        __sanitizer_cov_dump();
-      internal__exit(flags()->exitcode);
-    }
+    return true;
   }
+  return false;
+}
+
+void DoLeakCheck() {
+  BlockingMutexLock l(&global_mutex);
+  static bool already_done;
+  if (already_done) return;
+  already_done = true;
+  bool have_leaks = CheckForLeaks();
+  if (!have_leaks) {
+    return;
+  }
+  if (flags()->exitcode) {
+    if (common_flags()->coverage)
+      __sanitizer_cov_dump();
+    internal__exit(flags()->exitcode);
+  }
+}
+
+static int DoRecoverableLeakCheck() {
+  BlockingMutexLock l(&global_mutex);
+  bool have_leaks = CheckForLeaks();
+  return have_leaks ? 1 : 0;
 }
 
 static Suppression *GetSuppressionForAddr(uptr addr) {
@@ -676,6 +702,15 @@
 #endif  // CAN_SANITIZE_LEAKS
 }
 
+SANITIZER_INTERFACE_ATTRIBUTE
+int __lsan_do_recoverable_leak_check() {
+#if CAN_SANITIZE_LEAKS
+  if (common_flags()->detect_leaks)
+    return __lsan::DoRecoverableLeakCheck();
+#endif  // CAN_SANITIZE_LEAKS
+  return 0;
+}
+
 #if !SANITIZER_SUPPORTS_WEAK_HOOKS
 SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE
 int __lsan_is_turned_off() {
diff --git a/lib/lsan/lsan_common_linux.cc b/lib/lsan/lsan_common_linux.cc
index 813e0b7..2955343 100644
--- a/lib/lsan/lsan_common_linux.cc
+++ b/lib/lsan/lsan_common_linux.cc
@@ -110,7 +110,7 @@
       reinterpret_cast<ProcessPlatformAllocParam *>(arg);
   chunk = GetUserBegin(chunk);
   LsanMetadata m(chunk);
-  if (m.allocated() && m.tag() != kReachable) {
+  if (m.allocated() && m.tag() != kReachable && m.tag() != kIgnored) {
     u32 stack_id = m.stack_trace_id();
     uptr caller_pc = 0;
     if (stack_id > 0)
diff --git a/lib/msan/CMakeLists.txt b/lib/msan/CMakeLists.txt
index ccf47fc..de5980e 100644
--- a/lib/msan/CMakeLists.txt
+++ b/lib/msan/CMakeLists.txt
@@ -7,12 +7,15 @@
   msan_chained_origin_depot.cc
   msan_interceptors.cc
   msan_linux.cc
-  msan_new_delete.cc
   msan_report.cc
   msan_thread.cc
   msan_poisoning.cc
   )
 
+set(MSAN_RTL_CXX_SOURCES
+  msan_new_delete.cc)
+
+
 set(MSAN_RTL_CFLAGS ${SANITIZER_COMMON_CFLAGS})
 append_no_rtti_flag(MSAN_RTL_CFLAGS)
 append_list_if(COMPILER_RT_HAS_FPIE_FLAG -fPIE MSAN_RTL_CFLAGS)
@@ -29,12 +32,21 @@
             $<TARGET_OBJECTS:RTInterception.${arch}>
             $<TARGET_OBJECTS:RTSanitizerCommon.${arch}>
             $<TARGET_OBJECTS:RTSanitizerCommonLibc.${arch}>
+            $<TARGET_OBJECTS:RTUbsan.${arch}>
     CFLAGS ${MSAN_RTL_CFLAGS})
-  add_dependencies(msan clang_rt.msan-${arch})
-  list(APPEND MSAN_RUNTIME_LIBRARIES clang_rt.msan-${arch})
+  add_compiler_rt_runtime(clang_rt.msan_cxx-${arch} ${arch} STATIC
+    SOURCES ${MSAN_RTL_CXX_SOURCES}
+            $<TARGET_OBJECTS:RTUbsan_cxx.${arch}>
+    CFLAGS ${MSAN_RTL_CFLAGS})
+  add_dependencies(msan clang_rt.msan-${arch}
+                        clang_rt.msan_cxx-${arch})
+  list(APPEND MSAN_RUNTIME_LIBRARIES clang_rt.msan-${arch}
+                                     clang_rt.msan_cxx-${arch})
   if(UNIX)
     add_sanitizer_rt_symbols(clang_rt.msan-${arch} msan.syms.extra)
-    add_dependencies(msan clang_rt.msan-${arch}-symbols)
+    add_sanitizer_rt_symbols(clang_rt.msan_cxx-${arch} msan.syms.extra)
+    add_dependencies(msan clang_rt.msan-${arch}-symbols
+                          clang_rt.msan_cxx-${arch}-symbols)
   endif()
 endforeach()
 
diff --git a/lib/msan/msan.cc b/lib/msan/msan.cc
index caa7736..163d59d 100644
--- a/lib/msan/msan.cc
+++ b/lib/msan/msan.cc
@@ -26,6 +26,8 @@
 #include "sanitizer_common/sanitizer_stacktrace.h"
 #include "sanitizer_common/sanitizer_symbolizer.h"
 #include "sanitizer_common/sanitizer_stackdepot.h"
+#include "ubsan/ubsan_flags.h"
+#include "ubsan/ubsan_init.h"
 
 // ACHTUNG! No system header includes in this file.
 
@@ -133,11 +135,6 @@
 }
 
 static void InitializeFlags() {
-  Flags *f = flags();
-  FlagParser parser;
-  RegisterMsanFlags(&parser, f);
-  RegisterCommonFlags(&parser);
-
   SetCommonFlagsDefaults();
   {
     CommonFlags cf;
@@ -151,14 +148,35 @@
     OverrideCommonFlags(cf);
   }
 
+  Flags *f = flags();
   f->SetDefaults();
 
+  FlagParser parser;
+  RegisterMsanFlags(&parser, f);
+  RegisterCommonFlags(&parser);
+
+#if MSAN_CONTAINS_UBSAN
+  __ubsan::Flags *uf = __ubsan::flags();
+  uf->SetDefaults();
+
+  FlagParser ubsan_parser;
+  __ubsan::RegisterUbsanFlags(&ubsan_parser, uf);
+  RegisterCommonFlags(&ubsan_parser);
+#endif
+
   // Override from user-specified string.
   if (__msan_default_options)
     parser.ParseString(__msan_default_options());
+#if MSAN_CONTAINS_UBSAN
+  const char *ubsan_default_options = __ubsan::MaybeCallUbsanDefaultOptions();
+  ubsan_parser.ParseString(ubsan_default_options);
+#endif
 
   const char *msan_options = GetEnv("MSAN_OPTIONS");
   parser.ParseString(msan_options);
+#if MSAN_CONTAINS_UBSAN
+  ubsan_parser.ParseString(GetEnv("UBSAN_OPTIONS"));
+#endif
   VPrintf(1, "MSAN_OPTIONS: %s\n", msan_options ? msan_options : "<empty>");
 
   SetVerbosity(common_flags()->verbosity);
@@ -355,13 +373,12 @@
   InitTlsSize();
 
   InitializeFlags();
+  CacheBinaryName();
   __sanitizer_set_report_path(common_flags()->log_path);
 
   InitializeInterceptors();
   InstallAtExitHandler(); // Needs __cxa_atexit interceptor.
 
-  if (MSAN_REPLACE_OPERATORS_NEW_AND_DELETE)
-    ReplaceOperatorsNewAndDelete();
   DisableCoreDumperIfNecessary();
   if (StackSizeIsUnlimited()) {
     VPrintf(1, "Unlimited stack, doing reexec\n");
@@ -374,7 +391,7 @@
   __msan_clear_on_return();
   if (__msan_get_track_origins())
     VPrintf(1, "msan_track_origins\n");
-  if (!InitShadow(/* map_shadow */ true, __msan_get_track_origins())) {
+  if (!InitShadow(__msan_get_track_origins())) {
     Printf("FATAL: MemorySanitizer can not mmap the shadow memory.\n");
     Printf("FATAL: Make sure to compile with -fPIE and to link with -pie.\n");
     Printf("FATAL: Disabling ASLR is known to cause this error.\n");
@@ -394,6 +411,10 @@
   SetCurrentThread(main_thread);
   main_thread->ThreadStart();
 
+#if MSAN_CONTAINS_UBSAN
+  __ubsan::InitAsPlugin();
+#endif
+
   VPrintf(1, "MemorySanitizer init done\n");
 
   msan_init_is_running = 0;
diff --git a/lib/msan/msan.h b/lib/msan/msan.h
index ed18f21..0adbeb6 100644
--- a/lib/msan/msan.h
+++ b/lib/msan/msan.h
@@ -20,11 +20,16 @@
 #include "sanitizer_common/sanitizer_stacktrace.h"
 #include "msan_interface_internal.h"
 #include "msan_flags.h"
+#include "ubsan/ubsan_platform.h"
 
 #ifndef MSAN_REPLACE_OPERATORS_NEW_AND_DELETE
 # define MSAN_REPLACE_OPERATORS_NEW_AND_DELETE 1
 #endif
 
+#ifndef MSAN_CONTAINS_UBSAN
+# define MSAN_CONTAINS_UBSAN CAN_SANITIZE_UB
+#endif
+
 struct MappingDesc {
   uptr start;
   uptr end;
@@ -120,7 +125,7 @@
 extern int msan_report_count;
 
 bool ProtectRange(uptr beg, uptr end);
-bool InitShadow(bool map_shadow, bool init_origins);
+bool InitShadow(bool init_origins);
 char *GetProcSelfMaps();
 void InitializeInterceptors();
 
@@ -131,7 +136,6 @@
 void MsanDeallocate(StackTrace *stack, void *ptr);
 void InstallTrapHandler();
 void InstallAtExitHandler();
-void ReplaceOperatorsNewAndDelete();
 
 const char *GetStackOriginDescr(u32 id, uptr *pc);
 
diff --git a/lib/msan/msan.syms.extra b/lib/msan/msan.syms.extra
index aad41cf..950e6f4 100644
--- a/lib/msan/msan.syms.extra
+++ b/lib/msan/msan.syms.extra
@@ -1 +1,2 @@
 __msan_*
+__ubsan_*
diff --git a/lib/msan/msan_interceptors.cc b/lib/msan/msan_interceptors.cc
index a1e8193..ffae221 100644
--- a/lib/msan/msan_interceptors.cc
+++ b/lib/msan/msan_interceptors.cc
@@ -1397,6 +1397,14 @@
     if (map) ForEachMappedRegion(map, __msan_unpoison);      \
   } while (false)
 
+#define COMMON_INTERCEPTOR_GET_TLS_RANGE(begin, end)                           \
+  if (MsanThread *t = GetCurrentThread()) {                                    \
+    *begin = t->tls_begin();                                                   \
+    *end = t->tls_end();                                                       \
+  } else {                                                                     \
+    *begin = *end = 0;                                                         \
+  }
+
 #include "sanitizer_common/sanitizer_common_interceptors.inc"
 
 #define COMMON_SYSCALL_PRE_READ_RANGE(p, s) CHECK_UNPOISONED(p, s)
diff --git a/lib/msan/msan_linux.cc b/lib/msan/msan_linux.cc
index 26ba82b..7025ef6 100644
--- a/lib/msan/msan_linux.cc
+++ b/lib/msan/msan_linux.cc
@@ -53,10 +53,19 @@
   return true;
 }
 
-static bool ProtectMemoryRange(uptr beg, uptr size) {
+static bool ProtectMemoryRange(uptr beg, uptr size, const char *name) {
   if (size > 0) {
-    uptr end = beg + size - 1;
-    if (!MmapNoAccess(beg, size)) {
+    void *addr = MmapNoAccess(beg, size, name);
+    if (beg == 0 && addr != 0) {
+      // Depending on the kernel configuration, we may not be able to protect
+      // the page at address zero.
+      uptr gap = 16 * GetPageSizeCached();
+      beg += gap;
+      size -= gap;
+      addr = MmapNoAccess(beg, size, name);
+    }
+    if ((uptr)addr != beg) {
+      uptr end = beg + size - 1;
       Printf("FATAL: Cannot protect memory range %p - %p.\n", beg, end);
       return false;
     }
@@ -95,7 +104,7 @@
   }
 }
 
-bool InitShadow(bool map_shadow, bool init_origins) {
+bool InitShadow(bool init_origins) {
   // Let user know mapping parameters first.
   VPrintf(1, "__msan_init %p\n", &__msan_init);
   for (unsigned i = 0; i < kMemoryLayoutSize; ++i)
@@ -115,15 +124,27 @@
     uptr end = kMemoryLayout[i].end;
     uptr size= end - start;
     MappingDesc::Type type = kMemoryLayout[i].type;
-    if ((map_shadow && type == MappingDesc::SHADOW) ||
-        (init_origins && type == MappingDesc::ORIGIN)) {
-      if (!CheckMemoryRangeAvailability(start, size)) return false;
-      if ((uptr)MmapFixedNoReserve(start, size) != start) return false;
+
+    bool map = type == MappingDesc::SHADOW ||
+               (init_origins && type == MappingDesc::ORIGIN);
+    bool protect = type == MappingDesc::INVALID ||
+                   (!init_origins && type == MappingDesc::ORIGIN);
+    CHECK(!(map && protect));
+    if (!map && !protect)
+      CHECK(type == MappingDesc::APP);
+    if (map) {
+      if (!CheckMemoryRangeAvailability(start, size))
+        return false;
+      if ((uptr)MmapFixedNoReserve(start, size, kMemoryLayout[i].name) != start)
+        return false;
       if (common_flags()->use_madv_dontdump)
         DontDumpShadowMemory(start, size);
-    } else if (type == MappingDesc::INVALID) {
-      if (!CheckMemoryRangeAvailability(start, size)) return false;
-      if (!ProtectMemoryRange(start, size)) return false;
+    }
+    if (protect) {
+      if (!CheckMemoryRangeAvailability(start, size))
+        return false;
+      if (!ProtectMemoryRange(start, size, kMemoryLayout[i].name))
+        return false;
     }
   }
 
diff --git a/lib/msan/msan_new_delete.cc b/lib/msan/msan_new_delete.cc
index 9a8e56e..c8bc065 100644
--- a/lib/msan/msan_new_delete.cc
+++ b/lib/msan/msan_new_delete.cc
@@ -19,13 +19,6 @@
 
 #include <stddef.h>
 
-namespace __msan {
-// This function is a no-op. We need it to make sure that object file
-// with our replacements will actually be loaded from static MSan
-// run-time library at link-time.
-void ReplaceOperatorsNewAndDelete() { }
-}
-
 using namespace __msan;  // NOLINT
 
 // Fake std::nothrow_t to avoid including <new>.
diff --git a/lib/profile/InstrProfiling.h b/lib/profile/InstrProfiling.h
index 2b1bd00..84b673c 100644
--- a/lib/profile/InstrProfiling.h
+++ b/lib/profile/InstrProfiling.h
@@ -62,7 +62,9 @@
  *
  * Writes to the file with the last name given to \a __llvm_profile_set_filename(),
  * or if it hasn't been called, the \c LLVM_PROFILE_FILE environment variable,
- * or if that's not set, \c "default.profdata".
+ * or if that's not set, the last name given to
+ * \a __llvm_profile_override_default_filename(), or if that's not set,
+ * \c "default.profdata".
  */
 int __llvm_profile_write_file(void);
 
@@ -77,6 +79,19 @@
  */
 void __llvm_profile_set_filename(const char *Name);
 
+/*!
+ * \brief Set the filename for writing instrumentation data, unless the
+ * \c LLVM_PROFILE_FILE environment variable was set.
+ *
+ * Unless overridden, sets the filename to be used for subsequent calls to
+ * \a __llvm_profile_write_file().
+ *
+ * \c Name is not copied, so it must remain valid.  Passing NULL resets the
+ * filename logic to the default behaviour (unless the \c LLVM_PROFILE_FILE
+ * was set in which case it has no effect).
+ */
+void __llvm_profile_override_default_filename(const char *Name);
+
 /*! \brief Register to write instrumentation data to file at exit. */
 int __llvm_profile_register_write_file_atexit(void);
 
diff --git a/lib/profile/InstrProfilingFile.c b/lib/profile/InstrProfilingFile.c
index d9acbbe..0102a25 100644
--- a/lib/profile/InstrProfilingFile.c
+++ b/lib/profile/InstrProfilingFile.c
@@ -76,14 +76,6 @@
 __attribute__((weak)) int __llvm_profile_OwnsFilename = 0;
 __attribute__((weak)) const char *__llvm_profile_CurrentFilename = NULL;
 
-static void setFilename(const char *Filename, int OwnsFilename) {
-  if (__llvm_profile_OwnsFilename)
-    free(UNCONST(__llvm_profile_CurrentFilename));
-
-  __llvm_profile_CurrentFilename = Filename;
-  __llvm_profile_OwnsFilename = OwnsFilename;
-}
-
 static void truncateCurrentFile(void) {
   const char *Filename;
   FILE *File;
@@ -99,19 +91,36 @@
   fclose(File);
 }
 
-static void setDefaultFilename(void) { setFilename("default.profraw", 0); }
+static void setFilename(const char *Filename, int OwnsFilename) {
+  /* Check if this is a new filename and therefore needs truncation. */
+  int NewFile = !__llvm_profile_CurrentFilename ||
+      (Filename && strcmp(Filename, __llvm_profile_CurrentFilename));
+  if (__llvm_profile_OwnsFilename)
+    free(UNCONST(__llvm_profile_CurrentFilename));
+
+  __llvm_profile_CurrentFilename = Filename;
+  __llvm_profile_OwnsFilename = OwnsFilename;
+
+  /* If not a new file, append to support profiling multiple shared objects. */
+  if (NewFile)
+    truncateCurrentFile();
+}
+
+static void resetFilenameToDefault(void) { setFilename("default.profraw", 0); }
 
 int getpid(void);
-static int setFilenameFromEnvironment(void) {
-  const char *Filename = getenv("LLVM_PROFILE_FILE");
+static int setFilenamePossiblyWithPid(const char *Filename) {
 #define MAX_PID_SIZE 16
   char PidChars[MAX_PID_SIZE] = {0};
   int NumPids = 0, PidLength = 0;
   char *Allocated;
   int I, J;
 
-  if (!Filename || !Filename[0])
-    return -1;
+  /* Reset filename on NULL, except with env var which is checked by caller. */
+  if (!Filename) {
+    resetFilenameToDefault();
+    return 0;
+  }
 
   /* Check the filename for "%p", which indicates a pid-substitution. */
   for (I = 0; Filename[I]; ++I)
@@ -148,11 +157,20 @@
   return 0;
 }
 
+static int setFilenameFromEnvironment(void) {
+  const char *Filename = getenv("LLVM_PROFILE_FILE");
+
+  if (!Filename || !Filename[0])
+    return -1;
+
+  return setFilenamePossiblyWithPid(Filename);
+}
+
 static void setFilenameAutomatically(void) {
   if (!setFilenameFromEnvironment())
     return;
 
-  setDefaultFilename();
+  resetFilenameToDefault();
 }
 
 __attribute__((visibility("hidden")))
@@ -163,13 +181,20 @@
 
   /* Detect the filename and truncate. */
   setFilenameAutomatically();
-  truncateCurrentFile();
 }
 
 __attribute__((visibility("hidden")))
 void __llvm_profile_set_filename(const char *Filename) {
-  setFilename(Filename, 0);
-  truncateCurrentFile();
+  setFilenamePossiblyWithPid(Filename);
+}
+
+__attribute__((visibility("hidden")))
+void __llvm_profile_override_default_filename(const char *Filename) {
+  /* If the env var is set, skip setting filename from argument. */
+  const char *Env_Filename = getenv("LLVM_PROFILE_FILE");
+  if (Env_Filename && Env_Filename[0])
+    return;
+  setFilenamePossiblyWithPid(Filename);
 }
 
 __attribute__((visibility("hidden")))
diff --git a/lib/safestack/CMakeLists.txt b/lib/safestack/CMakeLists.txt
new file mode 100644
index 0000000..1c15d07
--- /dev/null
+++ b/lib/safestack/CMakeLists.txt
@@ -0,0 +1,28 @@
+add_custom_target(safestack)
+
+set(SAFESTACK_SOURCES safestack.cc)
+
+include_directories(..)
+
+set(SAFESTACK_CFLAGS ${SANITIZER_COMMON_CFLAGS})
+
+if(APPLE)
+  # Build universal binary on APPLE.
+  add_compiler_rt_osx_static_runtime(clang_rt.safestack_osx
+    ARCH ${SAFESTACK_SUPPORTED_ARCH}
+    SOURCES ${SAFESTACK_SOURCES}
+            $<TARGET_OBJECTS:RTInterception.osx>
+            $<TARGET_OBJECTS:RTSanitizerCommon.osx>
+    CFLAGS ${SAFESTACK_CFLAGS})
+  add_dependencies(safestack clang_rt.safestack_osx)
+else()
+  # Otherwise, build separate libraries for each target.
+  foreach(arch ${SAFESTACK_SUPPORTED_ARCH})
+    add_compiler_rt_runtime(clang_rt.safestack-${arch} ${arch} STATIC
+      SOURCES ${SAFESTACK_SOURCES}
+              $<TARGET_OBJECTS:RTInterception.${arch}>
+              $<TARGET_OBJECTS:RTSanitizerCommon.${arch}>
+      CFLAGS ${SAFESTACK_CFLAGS})
+    add_dependencies(safestack clang_rt.safestack-${arch})
+  endforeach()
+endif()
diff --git a/lib/safestack/safestack.cc b/lib/safestack/safestack.cc
new file mode 100644
index 0000000..43366fd
--- /dev/null
+++ b/lib/safestack/safestack.cc
@@ -0,0 +1,236 @@
+//===-- safestack.cc ------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the runtime support for the safe stack protection
+// mechanism. The runtime manages allocation/deallocation of the unsafe stack
+// for the main thread, as well as all pthreads that are created/destroyed
+// during program execution.
+//
+//===----------------------------------------------------------------------===//
+
+#include <limits.h>
+#include <pthread.h>
+#include <stddef.h>
+#include <sys/resource.h>
+#include <sys/user.h>
+
+#include "interception/interception.h"
+#include "sanitizer_common/sanitizer_common.h"
+
+// TODO: The runtime library does not currently protect the safe stack. The
+// protection of the (safe) stack can be provided by two alternative features
+// that requires C library support:
+//
+// 1) Protection via hardware segmentation on x32 architectures: the (safe)
+// stack segment (implicitly accessed via the %ss segment register) can be
+// separated from the data segment (implicitly accessed via the %ds segment
+// register). Dereferencing a pointer to the safe segment would result in a
+// segmentation fault.
+//
+// 2) Protection via information hiding on 64 bit architectures: the location of
+// the safe stack can be randomized through secure mechanisms, and the leakage
+// of the stack pointer can be prevented. Currently, libc can leak the stack
+// pointer in several ways (e.g. in longjmp, signal handling, user-level context
+// switching related functions, etc.). These can be fixed in libc and in other
+// low-level libraries, by either eliminating the escaping/dumping of the stack
+// pointer (i.e., %rsp) when that's possible, or by using encryption/PTR_MANGLE
+// (XOR-ing the dumped stack pointer with another secret we control and protect
+// better). (This is already done for setjmp in glibc.) Furthermore, a static
+// machine code level verifier can be ran after code generation to make sure
+// that the stack pointer is never written to memory, or if it is, its written
+// on the safe stack.
+//
+// Finally, while the Unsafe Stack pointer is currently stored in a thread local
+// variable, with libc support it could be stored in the TCB (thread control
+// block) as well, eliminating another level of indirection. Alternatively,
+// dedicating a separate register for storing it would also be possible.
+
+/// Minimum stack alignment for the unsafe stack.
+const unsigned kStackAlign = 16;
+
+/// Default size of the unsafe stack. This value is only used if the stack
+/// size rlimit is set to infinity.
+const unsigned kDefaultUnsafeStackSize = 0x2800000;
+
+// TODO: To make accessing the unsafe stack pointer faster, we plan to
+// eventually store it directly in the thread control block data structure on
+// platforms where this structure is pointed to by %fs or %gs. This is exactly
+// the same mechanism as currently being used by the traditional stack
+// protector pass to store the stack guard (see getStackCookieLocation()
+// function above). Doing so requires changing the tcbhead_t struct in glibc
+// on Linux and tcb struct in libc on FreeBSD.
+//
+// For now, store it in a thread-local variable.
+extern "C" {
+__attribute__((visibility(
+    "default"))) __thread void *__safestack_unsafe_stack_ptr = nullptr;
+}
+
+// Per-thread unsafe stack information. It's not frequently accessed, so there
+// it can be kept out of the tcb in normal thread-local variables.
+static __thread void *unsafe_stack_start = nullptr;
+static __thread size_t unsafe_stack_size = 0;
+static __thread size_t unsafe_stack_guard = 0;
+
+static inline void *unsafe_stack_alloc(size_t size, size_t guard) {
+  CHECK_GE(size + guard, size);
+  void *addr = MmapOrDie(size + guard, "unsafe_stack_alloc");
+  MprotectNoAccess((uptr)addr, (uptr)guard);
+  return (char *)addr + guard;
+}
+
+static inline void unsafe_stack_setup(void *start, size_t size, size_t guard) {
+  CHECK_GE((char *)start + size, (char *)start);
+  CHECK_GE((char *)start + guard, (char *)start);
+  void *stack_ptr = (char *)start + size;
+  CHECK_EQ((((size_t)stack_ptr) & (kStackAlign - 1)), 0);
+
+  __safestack_unsafe_stack_ptr = stack_ptr;
+  unsafe_stack_start = start;
+  unsafe_stack_size = size;
+  unsafe_stack_guard = guard;
+}
+
+static void unsafe_stack_free() {
+  if (unsafe_stack_start) {
+    UnmapOrDie((char *)unsafe_stack_start - unsafe_stack_guard,
+               unsafe_stack_size + unsafe_stack_guard);
+  }
+  unsafe_stack_start = nullptr;
+}
+
+/// Thread data for the cleanup handler
+static pthread_key_t thread_cleanup_key;
+
+/// Safe stack per-thread information passed to the thread_start function
+struct tinfo {
+  void *(*start_routine)(void *);
+  void *start_routine_arg;
+
+  void *unsafe_stack_start;
+  size_t unsafe_stack_size;
+  size_t unsafe_stack_guard;
+};
+
+/// Wrap the thread function in order to deallocate the unsafe stack when the
+/// thread terminates by returning from its main function.
+static void *thread_start(void *arg) {
+  struct tinfo *tinfo = (struct tinfo *)arg;
+
+  void *(*start_routine)(void *) = tinfo->start_routine;
+  void *start_routine_arg = tinfo->start_routine_arg;
+
+  // Setup the unsafe stack; this will destroy tinfo content
+  unsafe_stack_setup(tinfo->unsafe_stack_start, tinfo->unsafe_stack_size,
+                     tinfo->unsafe_stack_guard);
+
+  // Make sure out thread-specific destructor will be called
+  // FIXME: we can do this only any other specific key is set by
+  // intercepting the pthread_setspecific function itself
+  pthread_setspecific(thread_cleanup_key, (void *)1);
+
+  return start_routine(start_routine_arg);
+}
+
+/// Thread-specific data destructor
+static void thread_cleanup_handler(void *_iter) {
+  // We want to free the unsafe stack only after all other destructors
+  // have already run. We force this function to be called multiple times.
+  // User destructors that might run more then PTHREAD_DESTRUCTOR_ITERATIONS-1
+  // times might still end up executing after the unsafe stack is deallocated.
+  size_t iter = (size_t)_iter;
+  if (iter < PTHREAD_DESTRUCTOR_ITERATIONS) {
+    pthread_setspecific(thread_cleanup_key, (void *)(iter + 1));
+  } else {
+    // This is the last iteration
+    unsafe_stack_free();
+  }
+}
+
+/// Intercept thread creation operation to allocate and setup the unsafe stack
+INTERCEPTOR(int, pthread_create, pthread_t *thread,
+            const pthread_attr_t *attr,
+            void *(*start_routine)(void*), void *arg) {
+
+  size_t size = 0;
+  size_t guard = 0;
+
+  if (attr != NULL) {
+    pthread_attr_getstacksize(attr, &size);
+    pthread_attr_getguardsize(attr, &guard);
+  } else {
+    // get pthread default stack size
+    pthread_attr_t tmpattr;
+    pthread_attr_init(&tmpattr);
+    pthread_attr_getstacksize(&tmpattr, &size);
+    pthread_attr_getguardsize(&tmpattr, &guard);
+    pthread_attr_destroy(&tmpattr);
+  }
+
+  CHECK_NE(size, 0);
+  CHECK_EQ((size & (kStackAlign - 1)), 0);
+  CHECK_EQ((guard & (PAGE_SIZE - 1)), 0);
+
+  void *addr = unsafe_stack_alloc(size, guard);
+  struct tinfo *tinfo =
+      (struct tinfo *)(((char *)addr) + size - sizeof(struct tinfo));
+  tinfo->start_routine = start_routine;
+  tinfo->start_routine_arg = arg;
+  tinfo->unsafe_stack_start = addr;
+  tinfo->unsafe_stack_size = size;
+  tinfo->unsafe_stack_guard = guard;
+
+  return REAL(pthread_create)(thread, attr, thread_start, tinfo);
+}
+
+extern "C" __attribute__((visibility("default")))
+#if !SANITIZER_CAN_USE_PREINIT_ARRAY
+// On ELF platforms, the constructor is invoked using .preinit_array (see below)
+__attribute__((constructor(0)))
+#endif
+void __safestack_init() {
+  // Determine the stack size for the main thread.
+  size_t size = kDefaultUnsafeStackSize;
+  size_t guard = 4096;
+
+  struct rlimit limit;
+  if (getrlimit(RLIMIT_STACK, &limit) == 0 && limit.rlim_cur != RLIM_INFINITY)
+    size = limit.rlim_cur;
+
+  // Allocate unsafe stack for main thread
+  void *addr = unsafe_stack_alloc(size, guard);
+
+  unsafe_stack_setup(addr, size, guard);
+
+  // Initialize pthread interceptors for thread allocation
+  INTERCEPT_FUNCTION(pthread_create);
+
+  // Setup the cleanup handler
+  pthread_key_create(&thread_cleanup_key, thread_cleanup_handler);
+}
+
+#if SANITIZER_CAN_USE_PREINIT_ARRAY
+// On ELF platforms, run safestack initialization before any other constructors.
+// On other platforms we use the constructor attribute to arrange to run our
+// initialization early.
+extern "C" {
+__attribute__((section(".preinit_array"),
+               used)) void (*__safestack_preinit)(void) = __safestack_init;
+}
+#endif
+
+extern "C"
+    __attribute__((visibility("default"))) void *__get_unsafe_stack_start() {
+  return unsafe_stack_start;
+}
+
+extern "C"
+    __attribute__((visibility("default"))) void *__get_unsafe_stack_ptr() {
+  return __safestack_unsafe_stack_ptr;
+}
diff --git a/lib/sanitizer_common/CMakeLists.txt b/lib/sanitizer_common/CMakeLists.txt
index d213953..e4aa29c 100644
--- a/lib/sanitizer_common/CMakeLists.txt
+++ b/lib/sanitizer_common/CMakeLists.txt
@@ -119,7 +119,7 @@
 set(SANITIZER_CFLAGS ${SANITIZER_COMMON_CFLAGS})
 append_no_rtti_flag(SANITIZER_CFLAGS)
 
-append_list_if(SANITIZER_LIMIT_FRAME_SIZE -Wframe-larger-than=512
+append_list_if(SANITIZER_LIMIT_FRAME_SIZE -Wframe-larger-than=570
                SANITIZER_CFLAGS)
 append_list_if(COMPILER_RT_HAS_WGLOBAL_CONSTRUCTORS_FLAG -Wglobal-constructors
                SANITIZER_CFLAGS)
@@ -128,23 +128,28 @@
 set(SANITIZER_RUNTIME_LIBRARIES)
 if(APPLE)
   # Build universal binary on APPLE.
-  foreach(os ${SANITIZER_COMMON_SUPPORTED_DARWIN_OS})
-    add_compiler_rt_darwin_object_library(RTSanitizerCommon ${os}
-      ARCH ${SANITIZER_COMMON_SUPPORTED_ARCH}
-      SOURCES ${SANITIZER_SOURCES} ${SANITIZER_LIBCDEP_SOURCES}
-      CFLAGS ${SANITIZER_CFLAGS}
-      DEFS ${SANITIZER_COMMON_DEFINITIONS})
+
+  add_compiler_rt_object_libraries(RTSanitizerCommon
+    OS ${SANITIZER_COMMON_SUPPORTED_OS}
+    ARCH ${SANITIZER_COMMON_SUPPORTED_ARCH}
+    SOURCES ${SANITIZER_SOURCES} ${SANITIZER_LIBCDEP_SOURCES}
+    CFLAGS ${SANITIZER_CFLAGS}
+    DEFS ${SANITIZER_COMMON_DEFINITIONS})
+  foreach(os ${SANITIZER_COMMON_SUPPORTED_OS})
     list(APPEND SANITIZER_RUNTIME_LIBRARIES RTSanitizerCommon.${os})
   endforeach()
 else()
   # Otherwise, build separate libraries for each target.
+  
+  add_compiler_rt_object_libraries(RTSanitizerCommon
+    ARCH ${SANITIZER_COMMON_SUPPORTED_ARCH}
+    SOURCES ${SANITIZER_SOURCES} CFLAGS ${SANITIZER_CFLAGS}
+    DEFS ${SANITIZER_COMMON_DEFINITIONS})
+  add_compiler_rt_object_libraries(RTSanitizerCommonLibc
+    ARCH ${SANITIZER_COMMON_SUPPORTED_ARCH}
+    SOURCES ${SANITIZER_LIBCDEP_SOURCES} CFLAGS ${SANITIZER_CFLAGS}
+    DEFS ${SANITIZER_COMMON_DEFINITIONS})
   foreach(arch ${SANITIZER_COMMON_SUPPORTED_ARCH})
-    add_compiler_rt_object_library(RTSanitizerCommon ${arch}
-      SOURCES ${SANITIZER_SOURCES} CFLAGS ${SANITIZER_CFLAGS}
-      DEFS ${SANITIZER_COMMON_DEFINITIONS})
-    add_compiler_rt_object_library(RTSanitizerCommonLibc ${arch}
-      SOURCES ${SANITIZER_LIBCDEP_SOURCES} CFLAGS ${SANITIZER_CFLAGS}
-      DEFS ${SANITIZER_COMMON_DEFINITIONS})
     list(APPEND SANITIZER_RUNTIME_LIBRARIES RTSanitizerCommon.${arch}
                                             RTSanitizerCommonLibc.${arch})
   endforeach()
diff --git a/lib/sanitizer_common/sanitizer_atomic.h b/lib/sanitizer_common/sanitizer_atomic.h
index 6643c54..7e3374a 100644
--- a/lib/sanitizer_common/sanitizer_atomic.h
+++ b/lib/sanitizer_common/sanitizer_atomic.h
@@ -55,7 +55,7 @@
 
 }  // namespace __sanitizer
 
-#if defined(__GNUC__)
+#if defined(__clang__) || defined(__GNUC__)
 # include "sanitizer_atomic_clang.h"
 #elif defined(_MSC_VER)
 # include "sanitizer_atomic_msvc.h"
diff --git a/lib/sanitizer_common/sanitizer_common.cc b/lib/sanitizer_common/sanitizer_common.cc
index 8185c81..14871a1 100644
--- a/lib/sanitizer_common/sanitizer_common.cc
+++ b/lib/sanitizer_common/sanitizer_common.cc
@@ -57,7 +57,13 @@
       CloseFile(fd);
   }
 
-  internal_snprintf(full_path, kMaxPathLength, "%s.%zu", path_prefix, pid);
+  const char *exe_name = GetBinaryBasename();
+  if (common_flags()->log_exe_name && exe_name) {
+    internal_snprintf(full_path, kMaxPathLength, "%s.%s.%zu", path_prefix,
+                      exe_name, pid);
+  } else {
+    internal_snprintf(full_path, kMaxPathLength, "%s.%zu", path_prefix, pid);
+  }
   fd = OpenFile(full_path, WrOnly);
   if (fd == kInvalidFd) {
     const char *ErrorMsgPrefix = "ERROR: Can't open file: ";
@@ -243,7 +249,8 @@
     return;
   InternalScopedString buff(kMaxSummaryLength);
   buff.append("%s ", error_type);
-  RenderFrame(&buff, "%L %F", 0, info, common_flags()->strip_path_prefix);
+  RenderFrame(&buff, "%L %F", 0, info, common_flags()->symbolize_vs_style,
+              common_flags()->strip_path_prefix);
   ReportErrorSummary(buff.data());
 }
 #endif
@@ -337,6 +344,24 @@
   return true;
 }
 
+static char binary_name_cache_str[kMaxPathLength];
+static const char *binary_basename_cache_str;
+
+const char *GetBinaryName() {
+  return binary_name_cache_str;
+}
+
+const char *GetBinaryBasename() {
+  return binary_basename_cache_str;
+}
+
+// Call once to make sure that binary_name_cache_str is initialized
+void CacheBinaryName() {
+  CHECK_EQ('\0', binary_name_cache_str[0]);
+  ReadBinaryName(binary_name_cache_str, sizeof(binary_name_cache_str));
+  binary_basename_cache_str = StripModuleName(binary_name_cache_str);
+}
+
 }  // namespace __sanitizer
 
 using namespace __sanitizer;  // NOLINT
diff --git a/lib/sanitizer_common/sanitizer_common.h b/lib/sanitizer_common/sanitizer_common.h
index 2e920c8..8ca3992 100644
--- a/lib/sanitizer_common/sanitizer_common.h
+++ b/lib/sanitizer_common/sanitizer_common.h
@@ -69,10 +69,11 @@
 // Memory management
 void *MmapOrDie(uptr size, const char *mem_type);
 void UnmapOrDie(void *addr, uptr size);
-void *MmapFixedNoReserve(uptr fixed_addr, uptr size);
+void *MmapFixedNoReserve(uptr fixed_addr, uptr size,
+                         const char *name = nullptr);
 void *MmapNoReserveOrDie(uptr size, const char *mem_type);
 void *MmapFixedOrDie(uptr fixed_addr, uptr size);
-void *MmapNoAccess(uptr fixed_addr, uptr size);
+void *MmapNoAccess(uptr fixed_addr, uptr size, const char *name = nullptr);
 // Map aligned chunk of address space; size and alignment are powers of two.
 void *MmapAlignedOrDie(uptr size, uptr alignment, const char *mem_type);
 // Disallow access to a memory range.  Use MmapNoAccess to allocate an
@@ -237,6 +238,10 @@
 const char *StripModuleName(const char *module);
 
 // OS
+uptr ReadBinaryName(/*out*/char *buf, uptr buf_len);
+const char *GetBinaryName();
+const char *GetBinaryBasename();
+void CacheBinaryName();
 void DisableCoreDumperIfNecessary();
 void DumpProcessMap();
 bool FileExists(const char *filename);
@@ -247,8 +252,6 @@
 bool IsPathSeparator(const char c);
 bool IsAbsolutePath(const char *path);
 
-// Returns the path to the main executable.
-uptr ReadBinaryName(/*out*/char *buf, uptr buf_len);
 u32 GetUid();
 void ReExec();
 bool StackSizeIsUnlimited();
@@ -622,11 +625,13 @@
 void AndroidLogWrite(const char *buffer);
 void GetExtraActivationFlags(char *buf, uptr size);
 void SanitizerInitializeUnwinder();
+u32 AndroidGetApiLevel();
 #else
 INLINE void AndroidLogInit() {}
 INLINE void AndroidLogWrite(const char *buffer_unused) {}
 INLINE void GetExtraActivationFlags(char *buf, uptr size) { *buf = '\0'; }
 INLINE void SanitizerInitializeUnwinder() {}
+INLINE u32 AndroidGetApiLevel() { return 0; }
 #endif
 
 void *internal_start_thread(void(*func)(void*), void *arg);
diff --git a/lib/sanitizer_common/sanitizer_common_interceptors.inc b/lib/sanitizer_common/sanitizer_common_interceptors.inc
index 69c1cf8..ee21ccf 100644
--- a/lib/sanitizer_common/sanitizer_common_interceptors.inc
+++ b/lib/sanitizer_common/sanitizer_common_interceptors.inc
@@ -47,6 +47,7 @@
 #define pthread_setname_np pthread_set_name_np
 #define inet_aton __inet_aton
 #define inet_pton __inet_pton
+#define iconv __bsd_iconv
 #endif
 
 #ifndef COMMON_INTERCEPTOR_INITIALIZE_RANGE
@@ -113,6 +114,10 @@
 #define COMMON_INTERCEPTOR_ON_DLOPEN(filename, flag) {}
 #endif
 
+#ifndef COMMON_INTERCEPTOR_GET_TLS_RANGE
+#define COMMON_INTERCEPTOR_GET_TLS_RANGE(begin, end) *begin = *end = 0;
+#endif
+
 struct FileMetadata {
   // For open_memstream().
   char **addr;
@@ -266,6 +271,97 @@
 #define INIT_STRNCASECMP
 #endif
 
+#if SANITIZER_INTERCEPT_STRSTR || SANITIZER_INTERCEPT_STRCASESTR
+static inline void StrstrCheck(void *ctx, char *r, const char *s1,
+                               const char *s2) {
+    uptr len1 = REAL(strlen)(s1);
+    uptr len2 = REAL(strlen)(s2);
+    COMMON_INTERCEPTOR_READ_STRING_OF_LEN(ctx, s1, len1,
+                                          r ? r - s1 + len2 : len1 + 1);
+    COMMON_INTERCEPTOR_READ_RANGE(ctx, s2, len2 + 1);
+}
+#endif
+
+#if SANITIZER_INTERCEPT_STRSTR
+INTERCEPTOR(char*, strstr, const char *s1, const char *s2) {
+  if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED)
+    return internal_strstr(s1, s2);
+  void *ctx;
+  COMMON_INTERCEPTOR_ENTER(ctx, strstr, s1, s2);
+  char *r = REAL(strstr)(s1, s2);
+  if (common_flags()->intercept_strstr)
+    StrstrCheck(ctx, r, s1, s2);
+  return r;
+}
+
+#define INIT_STRSTR COMMON_INTERCEPT_FUNCTION(strstr);
+#else
+#define INIT_STRSTR
+#endif
+
+#if SANITIZER_INTERCEPT_STRCASESTR
+INTERCEPTOR(char*, strcasestr, const char *s1, const char *s2) {
+  void *ctx;
+  COMMON_INTERCEPTOR_ENTER(ctx, strcasestr, s1, s2);
+  char *r = REAL(strcasestr)(s1, s2);
+  if (common_flags()->intercept_strstr)
+    StrstrCheck(ctx, r, s1, s2);
+  return r;
+}
+
+#define INIT_STRCASESTR COMMON_INTERCEPT_FUNCTION(strcasestr);
+#else
+#define INIT_STRCASESTR
+#endif
+
+#if SANITIZER_INTERCEPT_STRSPN
+INTERCEPTOR(SIZE_T, strspn, const char *s1, const char *s2) {
+  void *ctx;
+  COMMON_INTERCEPTOR_ENTER(ctx, strspn, s1, s2);
+  SIZE_T r = REAL(strspn)(s1, s2);
+  if (common_flags()->intercept_strspn) {
+    COMMON_INTERCEPTOR_READ_RANGE(ctx, s2, REAL(strlen)(s2) + 1);
+    COMMON_INTERCEPTOR_READ_STRING(ctx, s1, r + 1);
+  }
+  return r;
+}
+
+INTERCEPTOR(SIZE_T, strcspn, const char *s1, const char *s2) {
+  void *ctx;
+  COMMON_INTERCEPTOR_ENTER(ctx, strcspn, s1, s2);
+  SIZE_T r = REAL(strcspn)(s1, s2);
+  if (common_flags()->intercept_strspn) {
+    COMMON_INTERCEPTOR_READ_RANGE(ctx, s2, REAL(strlen)(s2) + 1);
+    COMMON_INTERCEPTOR_READ_STRING(ctx, s1, r + 1);
+  }
+  return r;
+}
+
+#define INIT_STRSPN \
+  COMMON_INTERCEPT_FUNCTION(strspn); \
+  COMMON_INTERCEPT_FUNCTION(strcspn);
+#else
+#define INIT_STRSPN
+#endif
+
+#if SANITIZER_INTERCEPT_STRPBRK
+INTERCEPTOR(char *, strpbrk, const char *s1, const char *s2) {
+  void *ctx;
+  COMMON_INTERCEPTOR_ENTER(ctx, strpbrk, s1, s2);
+  char *r = REAL(strpbrk)(s1, s2);
+  if (common_flags()->intercept_strpbrk) {
+    COMMON_INTERCEPTOR_READ_RANGE(ctx, s2, REAL(strlen)(s2) + 1);
+    COMMON_INTERCEPTOR_READ_STRING(ctx, s1,
+        r ? r - s1 + 1 : REAL(strlen)(s1) + 1);
+  }
+  return r;
+}
+
+#define INIT_STRPBRK COMMON_INTERCEPT_FUNCTION(strpbrk);
+#else
+#define INIT_STRPBRK
+#endif
+
 #if SANITIZER_INTERCEPT_MEMCHR
 INTERCEPTOR(void*, memchr, const void *s, int c, SIZE_T n) {
   void *ctx;
@@ -3903,25 +3999,33 @@
   }
   return res;
 }
-INTERCEPTOR(SSIZE_T, __getdelim, char **lineptr, SIZE_T *n, int delim,
-            void *stream) {
-  void *ctx;
-  COMMON_INTERCEPTOR_ENTER(ctx, __getdelim, lineptr, n, delim, stream);
-  // FIXME: under ASan the call below may write to freed memory and corrupt
-  // its metadata. See
-  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
-  SSIZE_T res = REAL(__getdelim)(lineptr, n, delim, stream);
-  if (res > 0) {
-    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, lineptr, sizeof(*lineptr));
-    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, n, sizeof(*n));
-    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *lineptr, res + 1);
+
+// FIXME: under ASan the call below may write to freed memory and corrupt its
+// metadata. See
+// https://code.google.com/p/address-sanitizer/issues/detail?id=321.
+#define GETDELIM_INTERCEPTOR_IMPL(vname)                                       \
+  {                                                                            \
+    void *ctx;                                                                 \
+    COMMON_INTERCEPTOR_ENTER(ctx, vname, lineptr, n, delim, stream);           \
+    SSIZE_T res = REAL(vname)(lineptr, n, delim, stream);                      \
+    if (res > 0) {                                                             \
+      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, lineptr, sizeof(*lineptr));          \
+      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, n, sizeof(*n));                      \
+      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *lineptr, res + 1);                  \
+    }                                                                          \
+    return res;                                                                \
   }
-  return res;
-}
+
+INTERCEPTOR(SSIZE_T, __getdelim, char **lineptr, SIZE_T *n, int delim,
+            void *stream)
+GETDELIM_INTERCEPTOR_IMPL(__getdelim)
+
+// There's no __getdelim() on FreeBSD so we supply the getdelim() interceptor
+// with its own body.
 INTERCEPTOR(SSIZE_T, getdelim, char **lineptr, SIZE_T *n, int delim,
-            void *stream) {
-  return __getdelim(lineptr, n, delim, stream);
-}
+            void *stream)
+GETDELIM_INTERCEPTOR_IMPL(getdelim)
+
 #define INIT_GETLINE                     \
   COMMON_INTERCEPT_FUNCTION(getline);    \
   COMMON_INTERCEPT_FUNCTION(__getdelim); \
@@ -3987,7 +4091,9 @@
   void *ctx;
   COMMON_INTERCEPTOR_ENTER(ctx, __tls_get_addr, arg);
   void *res = REAL(__tls_get_addr)(arg);
-  DTLS::DTV *dtv = DTLS_on_tls_get_addr(arg, res);
+  uptr tls_begin, tls_end;
+  COMMON_INTERCEPTOR_GET_TLS_RANGE(&tls_begin, &tls_end);
+  DTLS::DTV *dtv = DTLS_on_tls_get_addr(arg, res, tls_begin, tls_end);
   if (dtv) {
     // New DTLS block has been allocated.
     COMMON_INTERCEPTOR_INITIALIZE_RANGE((void *)dtv->beg, dtv->size);
@@ -4859,6 +4965,10 @@
   INIT_STRNCMP;
   INIT_STRCASECMP;
   INIT_STRNCASECMP;
+  INIT_STRSTR;
+  INIT_STRCASESTR;
+  INIT_STRSPN;
+  INIT_STRPBRK;
   INIT_MEMCHR;
   INIT_MEMRCHR;
   INIT_READ;
diff --git a/lib/sanitizer_common/sanitizer_common_interceptors_ioctl.inc b/lib/sanitizer_common/sanitizer_common_interceptors_ioctl.inc
index 69b7ca9..b94c21c 100644
--- a/lib/sanitizer_common/sanitizer_common_interceptors_ioctl.inc
+++ b/lib/sanitizer_common/sanitizer_common_interceptors_ioctl.inc
@@ -578,14 +578,10 @@
   }
   if (desc->type != ioctl_desc::CUSTOM)
     return;
-  switch (request) {
-    case 0x00008912: {  // SIOCGIFCONF
-      struct __sanitizer_ifconf *ifc = (__sanitizer_ifconf *)arg;
-      COMMON_INTERCEPTOR_READ_RANGE(ctx, &ifc->ifc_len, sizeof(ifc->ifc_len));
-      break;
-    }
+  if (request == IOCTL_SIOCGIFCONF) {
+    struct __sanitizer_ifconf *ifc = (__sanitizer_ifconf *)arg;
+    COMMON_INTERCEPTOR_READ_RANGE(ctx, &ifc->ifc_len, sizeof(ifc->ifc_len));
   }
-  return;
 }
 
 static void ioctl_common_post(void *ctx, const ioctl_desc *desc, int res, int d,
@@ -597,12 +593,8 @@
   }
   if (desc->type != ioctl_desc::CUSTOM)
     return;
-  switch (request) {
-    case 0x00008912: {  // SIOCGIFCONF
-      struct __sanitizer_ifconf *ifc = (__sanitizer_ifconf *)arg;
-      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ifc->ifc_ifcu.ifcu_req, ifc->ifc_len);
-      break;
-    }
+  if (request == IOCTL_SIOCGIFCONF) {
+    struct __sanitizer_ifconf *ifc = (__sanitizer_ifconf *)arg;
+    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ifc->ifc_ifcu.ifcu_req, ifc->ifc_len);
   }
-  return;
 }
diff --git a/lib/sanitizer_common/sanitizer_coverage_libcdep.cc b/lib/sanitizer_common/sanitizer_coverage_libcdep.cc
index 2c7c7e0..f511c99 100644
--- a/lib/sanitizer_common/sanitizer_coverage_libcdep.cc
+++ b/lib/sanitizer_common/sanitizer_coverage_libcdep.cc
@@ -109,8 +109,9 @@
 
   // Maximal size pc array may ever grow.
   // We MmapNoReserve this space to ensure that the array is contiguous.
-  static const uptr kPcArrayMaxSize =
-      FIRST_32_SECOND_64(1 << (SANITIZER_ANDROID ? 24 : 26), 1 << 27);
+  static const uptr kPcArrayMaxSize = FIRST_32_SECOND_64(
+      1 << (SANITIZER_ANDROID ? 24 : (SANITIZER_WINDOWS ? 27 : 26)),
+      1 << 27);
   // The amount file mapping for the pc array is grown by.
   static const uptr kPcArrayMmapSize = 64 * 1024;
 
@@ -265,8 +266,9 @@
       // In memory-mapped mode we must extend the new file to the known array
       // size.
       uptr size = atomic_load(&pc_array_size, memory_order_relaxed);
+      uptr npcs = size / sizeof(uptr);
       Enable();
-      if (size) Extend(size);
+      if (size) Extend(npcs);
       if (coverage_enabled) CovUpdateMapping(coverage_dir);
     } else {
       Enable();
@@ -571,9 +573,11 @@
     else
       path->append("%s/%s.%s.packed", coverage_dir, name, extension);
   }
-  fd_t fd = OpenFile(path->data(), WrOnly);
+  error_t err;
+  fd_t fd = OpenFile(path->data(), WrOnly, &err);
   if (fd == kInvalidFd)
-    Report("SanitizerCoverage: failed to open %s for writing\n", path->data());
+    Report("SanitizerCoverage: failed to open %s for writing (reason: %d)\n",
+           path->data(), err);
   return fd;
 }
 
@@ -927,4 +931,7 @@
 uptr __sanitizer_update_counter_bitset_and_clear_counters(u8 *bitset) {
   return coverage_data.Update8bitCounterBitsetAndClearCounters(bitset);
 }
+// Default empty implementation (weak). Users should redefine it.
+SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE
+void __sanitizer_cov_trace_cmp() {}
 }  // extern "C"
diff --git a/lib/sanitizer_common/sanitizer_flags.inc b/lib/sanitizer_common/sanitizer_flags.inc
index 80c30ac..bbb39c7 100644
--- a/lib/sanitizer_common/sanitizer_flags.inc
+++ b/lib/sanitizer_common/sanitizer_flags.inc
@@ -51,6 +51,10 @@
     "Write logs to \"log_path.pid\". The special values are \"stdout\" and "
     "\"stderr\". The default is \"stderr\".")
 COMMON_FLAG(
+    bool, log_exe_name, false,
+    "Mention name of executable when reporting error and "
+    "append executable name to logs (as in \"log_path.exe_name.pid\").")
+COMMON_FLAG(
     int, verbosity, 0,
     "Verbosity level (0 - silent, 1 - a bit of output, 2+ - more output).")
 COMMON_FLAG(bool, detect_leaks, true, "Enable memory leak detection.")
@@ -67,8 +71,9 @@
             "reports.")
 COMMON_FLAG(bool, check_printf, true, "Check printf arguments.")
 COMMON_FLAG(bool, handle_segv, SANITIZER_NEEDS_SEGV,
-            "If set, registers the tool's custom SEGV handler (both SIGBUS and "
-            "SIGSEGV on OSX).")
+            "If set, registers the tool's custom SIGSEGV/SIGBUS handler.")
+COMMON_FLAG(bool, handle_abort, false,
+            "If set, registers the tool's custom SIGABRT handler.")
 COMMON_FLAG(bool, allow_user_segv_handler, false,
             "If set, allows user to register a SEGV handler even if the tool "
             "registers one.")
@@ -145,6 +150,9 @@
           "in core file.")
 COMMON_FLAG(bool, symbolize_inline_frames, true,
             "Print inlined frames in stacktraces. Defaults to true.")
+COMMON_FLAG(bool, symbolize_vs_style, false,
+            "Print file locations in Visual Studio style (e.g: "
+            " file(10,42): ...")
 COMMON_FLAG(const char *, stack_trace_format, "DEFAULT",
             "Format string used to render stack frames. "
             "See sanitizer_stacktrace_printer.h for the format description. "
@@ -153,3 +161,15 @@
             "If true, the shadow is not allowed to use huge pages. ")
 COMMON_FLAG(bool, strict_string_checks, false,
             "If set check that string arguments are properly null-terminated")
+COMMON_FLAG(bool, intercept_strstr, true,
+            "If set, uses custom wrappers for strstr and strcasestr functions "
+            "to find more errors.")
+COMMON_FLAG(bool, intercept_strspn, true,
+            "If set, uses custom wrappers for strspn and strcspn function "
+            "to find more errors.")
+COMMON_FLAG(bool, intercept_strpbrk, true,
+            "If set, uses custom wrappers for strpbrk function "
+            "to find more errors.")
+COMMON_FLAG(bool, decorate_proc_maps, false, "If set, decorate sanitizer "
+                                             "mappings in /proc/self/maps with "
+                                             "user-readable names")
diff --git a/lib/sanitizer_common/sanitizer_linux.cc b/lib/sanitizer_common/sanitizer_linux.cc
index 11a6fe6..7ba690e 100644
--- a/lib/sanitizer_common/sanitizer_linux.cc
+++ b/lib/sanitizer_common/sanitizer_linux.cc
@@ -36,6 +36,7 @@
 // access stat from asm/stat.h, without conflicting with definition in
 // sys/stat.h, we use this trick.
 #if defined(__mips64)
+#include <asm/unistd.h>
 #include <sys/types.h>
 #define stat kernel_stat
 #include <asm/stat.h>
@@ -45,9 +46,7 @@
 #include <dlfcn.h>
 #include <errno.h>
 #include <fcntl.h>
-#if !SANITIZER_ANDROID
 #include <link.h>
-#endif
 #include <pthread.h>
 #include <sched.h>
 #include <sys/mman.h>
@@ -707,47 +706,32 @@
 #endif
 }
 
-static char proc_self_exe_cache_str[kMaxPathLength];
-static uptr proc_self_exe_cache_len = 0;
-
 uptr ReadBinaryName(/*out*/char *buf, uptr buf_len) {
-  if (proc_self_exe_cache_len > 0) {
-    // If available, use the cached module name.
-    uptr module_name_len =
-        internal_snprintf(buf, buf_len, "%s", proc_self_exe_cache_str);
-    CHECK_LT(module_name_len, buf_len);
-    return module_name_len;
-  }
 #if SANITIZER_FREEBSD
-  const int Mib[4] = { CTL_KERN, KERN_PROC, KERN_PROC_PATHNAME, -1 };
+  const int Mib[] = { CTL_KERN, KERN_PROC, KERN_PROC_PATHNAME, -1 };
+  const char *default_module_name = "kern.proc.pathname";
   size_t Size = buf_len;
-  bool IsErr = (sysctl(Mib, 4, buf, &Size, NULL, 0) != 0);
+  bool IsErr = (sysctl(Mib, ARRAY_SIZE(Mib), buf, &Size, NULL, 0) != 0);
   int readlink_error = IsErr ? errno : 0;
   uptr module_name_len = Size;
 #else
+  const char *default_module_name = "/proc/self/exe";
   uptr module_name_len = internal_readlink(
-      "/proc/self/exe", buf, buf_len);
+      default_module_name, buf, buf_len);
   int readlink_error;
   bool IsErr = internal_iserror(module_name_len, &readlink_error);
 #endif
   if (IsErr) {
-    // We can't read /proc/self/exe for some reason, assume the name of the
-    // binary is unknown.
-    Report("WARNING: readlink(\"/proc/self/exe\") failed with errno %d, "
+    // We can't read binary name for some reason, assume it's unknown.
+    Report("WARNING: reading executable name failed with errno %d, "
            "some stack frames may not be symbolized\n", readlink_error);
-    module_name_len = internal_snprintf(buf, buf_len, "/proc/self/exe");
+    module_name_len = internal_snprintf(buf, buf_len, "%s",
+                                        default_module_name);
     CHECK_LT(module_name_len, buf_len);
   }
   return module_name_len;
 }
 
-void CacheBinaryName() {
-  if (!proc_self_exe_cache_len) {
-    proc_self_exe_cache_len =
-        ReadBinaryName(proc_self_exe_cache_str, kMaxPathLength);
-  }
-}
-
 // Match full names of the form /path/to/base_name{-,.}*
 bool LibraryNameIs(const char *full_name, const char *base_name) {
   const char *name = full_name;
@@ -864,11 +848,70 @@
   return res;
 }
 #elif defined(__mips__)
-// TODO(sagarthakur): clone function is to be rewritten in assembly.
 uptr internal_clone(int (*fn)(void *), void *child_stack, int flags, void *arg,
                     int *parent_tidptr, void *newtls, int *child_tidptr) {
-  return clone(fn, child_stack, flags, arg, parent_tidptr,
-               newtls, child_tidptr);
+  long long res;
+  if (!fn || !child_stack)
+    return -EINVAL;
+  CHECK_EQ(0, (uptr)child_stack % 16);
+  child_stack = (char *)child_stack - 2 * sizeof(unsigned long long);
+  ((unsigned long long *)child_stack)[0] = (uptr)fn;
+  ((unsigned long long *)child_stack)[1] = (uptr)arg;
+  register void *a3 __asm__("$7") = newtls;
+  register int *a4 __asm__("$8") = child_tidptr;
+  // We don't have proper CFI directives here because it requires alot of code
+  // for very marginal benefits.
+  __asm__ __volatile__(
+                       /* $v0 = syscall($v0 = __NR_clone,
+                        * $a0 = flags,
+                        * $a1 = child_stack,
+                        * $a2 = parent_tidptr,
+                        * $a3 = new_tls,
+                        * $a4 = child_tidptr)
+                        */
+                       ".cprestore 16;\n"
+                       "move $4,%1;\n"
+                       "move $5,%2;\n"
+                       "move $6,%3;\n"
+                       "move $7,%4;\n"
+                       /* Store the fifth argument on stack
+                        * if we are using 32-bit abi.
+                        */
+#if SANITIZER_WORDSIZE == 32
+                       "lw %5,16($29);\n"
+#else
+                       "move $8,%5;\n"
+#endif
+                       "li $2,%6;\n"
+                       "syscall;\n"
+
+                       /* if ($v0 != 0)
+                        * return;
+                        */
+                       "bnez $2,1f;\n"
+
+                       /* Call "fn(arg)". */
+                       "ld $25,0($29);\n"
+                       "ld $4,8($29);\n"
+                       "jal $25;\n"
+
+                       /* Call _exit($v0). */
+                       "move $4,$2;\n"
+                       "li $2,%7;\n"
+                       "syscall;\n"
+
+                       /* Return to parent. */
+                     "1:\n"
+                       : "=r" (res)
+                       : "r"(flags),
+                         "r"(child_stack),
+                         "r"(parent_tidptr),
+                         "r"(a3),
+                         "r"(a4),
+                         "i"(__NR_clone),
+                         "i"(__NR_exit)
+                       : "memory", "$29" );
+  return res;
 }
 #endif  // defined(__x86_64__) && SANITIZER_LINUX
 
@@ -904,9 +947,51 @@
   CHECK(size > PROP_VALUE_MAX);
   __system_property_get("asan.options", buf);
 }
+
+#if __ANDROID_API__ < 21
+extern "C" __attribute__((weak)) int dl_iterate_phdr(
+    int (*)(struct dl_phdr_info *, size_t, void *), void *);
+#endif
+
+static int dl_iterate_phdr_test_cb(struct dl_phdr_info *info, size_t size,
+                                   void *data) {
+  // Any name starting with "lib" indicated a bug in L where library base names
+  // are returned instead of paths.
+  if (info->dlpi_name && info->dlpi_name[0] == 'l' &&
+      info->dlpi_name[1] == 'i' && info->dlpi_name[2] == 'b') {
+    *(bool *)data = true;
+    return 1;
+  }
+  return 0;
+}
+
+static atomic_uint32_t android_api_level;
+
+static u32 AndroidDetectApiLevel() {
+  if (!&dl_iterate_phdr)
+    return 19; // K or lower
+  bool base_name_seen = false;
+  dl_iterate_phdr(dl_iterate_phdr_test_cb, &base_name_seen);
+  if (base_name_seen)
+    return 22; // L MR1
+  return 23;   // post-L
+  // Plain L (API level 21) is completely broken wrt ASan and not very
+  // interesting to detect.
+}
+
+u32 AndroidGetApiLevel() {
+  u32 level = atomic_load(&android_api_level, memory_order_relaxed);
+  if (level) return level;
+  level = AndroidDetectApiLevel();
+  atomic_store(&android_api_level, level, memory_order_relaxed);
+  return level;
+}
+
 #endif
 
 bool IsDeadlySignal(int signum) {
+  if (common_flags()->handle_abort && signum == SIGABRT)
+    return true;
   return (signum == SIGSEGV || signum == SIGBUS) && common_flags()->handle_segv;
 }
 
@@ -915,6 +1000,11 @@
   // Start the thread with signals blocked, otherwise it can steal user signals.
   __sanitizer_sigset_t set, old;
   internal_sigfillset(&set);
+#if SANITIZER_LINUX
+  // Glibc uses SIGSETXID signal during setuid call. If this signal is blocked
+  // on any thread, setuid call hangs (see test/tsan/setuid.c).
+  internal_sigdelset(&set, 33);
+#endif
   internal_sigprocmask(SIG_SETMASK, &set, &old);
   void *th;
   real_pthread_create(&th, 0, (void*(*)(void *arg))func, arg);
@@ -995,7 +1085,7 @@
 # endif
 #elif defined(__mips__)
   ucontext_t *ucontext = (ucontext_t*)context;
-  *pc = ucontext->uc_mcontext.gregs[31];
+  *pc = ucontext->uc_mcontext.pc;
   *bp = ucontext->uc_mcontext.gregs[30];
   *sp = ucontext->uc_mcontext.gregs[29];
 #else
diff --git a/lib/sanitizer_common/sanitizer_linux.h b/lib/sanitizer_common/sanitizer_linux.h
index fd3c134..e9fc4ad 100644
--- a/lib/sanitizer_common/sanitizer_linux.h
+++ b/lib/sanitizer_common/sanitizer_linux.h
@@ -81,9 +81,6 @@
 // information).
 bool LibraryNameIs(const char *full_name, const char *base_name);
 
-// Cache the value of /proc/self/exe.
-void CacheBinaryName();
-
 // Call cb for each region mapped by map.
 void ForEachMappedRegion(link_map *map, void (*cb)(const void *, uptr));
 }  // namespace __sanitizer
diff --git a/lib/sanitizer_common/sanitizer_linux_libcdep.cc b/lib/sanitizer_common/sanitizer_linux_libcdep.cc
index ab9f0ab..ba844be 100644
--- a/lib/sanitizer_common/sanitizer_linux_libcdep.cc
+++ b/lib/sanitizer_common/sanitizer_linux_libcdep.cc
@@ -28,6 +28,7 @@
 #include <dlfcn.h>  // for dlsym()
 #endif
 
+#include <link.h>
 #include <pthread.h>
 #include <signal.h>
 #include <sys/resource.h>
@@ -42,9 +43,12 @@
 #include <sys/prctl.h>
 #endif
 
+#if SANITIZER_ANDROID
+#include <android/api-level.h>
+#endif
+
 #if !SANITIZER_ANDROID
 #include <elf.h>
-#include <link.h>
 #include <unistd.h>
 #endif
 
@@ -397,13 +401,6 @@
   }
 }
 
-#if SANITIZER_ANDROID
-uptr GetListOfModules(LoadedModule *modules, uptr max_modules,
-                      string_predicate_t filter) {
-  MemoryMappingLayout memory_mapping(false);
-  return memory_mapping.DumpListOfModules(modules, max_modules, filter);
-}
-#else  // SANITIZER_ANDROID
 # if !SANITIZER_FREEBSD
 typedef ElfW(Phdr) Elf_Phdr;
 # elif SANITIZER_WORDSIZE == 32 && __FreeBSD_version <= 902001  // v9.2
@@ -451,14 +448,28 @@
   return 0;
 }
 
+#if SANITIZER_ANDROID && __ANDROID_API__ < 21
+extern "C" __attribute__((weak)) int dl_iterate_phdr(
+    int (*)(struct dl_phdr_info *, size_t, void *), void *);
+#endif
+
 uptr GetListOfModules(LoadedModule *modules, uptr max_modules,
                       string_predicate_t filter) {
+#if SANITIZER_ANDROID && __ANDROID_API__ < 21
+  u32 api_level = AndroidGetApiLevel();
+  // Fall back to /proc/maps if dl_iterate_phdr is unavailable or broken.
+  // The runtime check allows the same library to work with
+  // both K and L (and future) Android releases.
+  if (api_level <= 22) { // L or earlier
+    MemoryMappingLayout memory_mapping(false);
+    return memory_mapping.DumpListOfModules(modules, max_modules, filter);
+  }
+#endif
   CHECK(modules);
   DlIteratePhdrData data = {modules, 0, true, max_modules, filter};
   dl_iterate_phdr(dl_iterate_phdr_cb, &data);
   return data.current_n;
 }
-#endif  // SANITIZER_ANDROID
 
 // getrusage does not give us the current RSS, only the max RSS.
 // Still, this is better than nothing if /proc/self/statm is not available
diff --git a/lib/sanitizer_common/sanitizer_mac.cc b/lib/sanitizer_common/sanitizer_mac.cc
index 4c5b409..4615105 100644
--- a/lib/sanitizer_common/sanitizer_mac.cc
+++ b/lib/sanitizer_common/sanitizer_mac.cc
@@ -27,11 +27,15 @@
 #include "sanitizer_libc.h"
 #include "sanitizer_mac.h"
 #include "sanitizer_placement_new.h"
+#include "sanitizer_platform_limits_posix.h"
 #include "sanitizer_procmaps.h"
 
 #include <crt_externs.h>  // for _NSGetEnviron
+#include <errno.h>
 #include <fcntl.h>
+#include <libkern/OSAtomic.h>
 #include <mach-o/dyld.h>
+#include <mach/mach.h>
 #include <pthread.h>
 #include <sched.h>
 #include <signal.h>
@@ -42,8 +46,6 @@
 #include <sys/sysctl.h>
 #include <sys/types.h>
 #include <unistd.h>
-#include <libkern/OSAtomic.h>
-#include <errno.h>
 
 namespace __sanitizer {
 
@@ -131,6 +133,13 @@
                    (struct sigaction *)act, (struct sigaction *)oldact);
 }
 
+void internal_sigfillset(__sanitizer_sigset_t *set) { sigfillset(set); }
+
+uptr internal_sigprocmask(int how, __sanitizer_sigset_t *set,
+                          __sanitizer_sigset_t *oldset) {
+  return sigprocmask(how, set, oldset);
+}
+
 int internal_fork() {
   // TODO(glider): this may call user's pthread_atfork() handlers which is bad.
   return fork();
@@ -333,7 +342,15 @@
 }
 
 uptr GetRSS() {
-  return 0;
+  struct task_basic_info info;
+  unsigned count = TASK_BASIC_INFO_COUNT;
+  kern_return_t result =
+      task_info(mach_task_self(), TASK_BASIC_INFO, (task_info_t)&info, &count);
+  if (UNLIKELY(result != KERN_SUCCESS)) {
+    Report("Cannot get task info. Error: %d\n", result);
+    Die();
+  }
+  return info.resident_size;
 }
 
 void *internal_start_thread(void (*func)(void *arg), void *arg) { return 0; }
diff --git a/lib/sanitizer_common/sanitizer_platform_interceptors.h b/lib/sanitizer_common/sanitizer_platform_interceptors.h
index 438ecba..8142be5 100644
--- a/lib/sanitizer_common/sanitizer_platform_interceptors.h
+++ b/lib/sanitizer_common/sanitizer_platform_interceptors.h
@@ -54,6 +54,10 @@
 #endif
 
 #define SANITIZER_INTERCEPT_STRCMP 1
+#define SANITIZER_INTERCEPT_STRSTR 1
+#define SANITIZER_INTERCEPT_STRCASESTR SI_NOT_WINDOWS
+#define SANITIZER_INTERCEPT_STRSPN 1
+#define SANITIZER_INTERCEPT_STRPBRK 1
 #define SANITIZER_INTERCEPT_TEXTDOMAIN SI_LINUX_NOT_ANDROID
 #define SANITIZER_INTERCEPT_STRCASECMP SI_NOT_WINDOWS
 #define SANITIZER_INTERCEPT_MEMCHR 1
@@ -147,7 +151,8 @@
 #define SANITIZER_INTERCEPT_STRERROR SI_NOT_WINDOWS
 #define SANITIZER_INTERCEPT_STRERROR_R SI_NOT_WINDOWS
 #define SANITIZER_INTERCEPT_XPG_STRERROR_R SI_LINUX_NOT_ANDROID
-#define SANITIZER_INTERCEPT_SCANDIR SI_LINUX_NOT_ANDROID
+#define SANITIZER_INTERCEPT_SCANDIR \
+  SI_FREEBSD || SI_LINUX_NOT_ANDROID
 #define SANITIZER_INTERCEPT_SCANDIR64 SI_LINUX_NOT_ANDROID
 #define SANITIZER_INTERCEPT_GETGROUPS SI_NOT_WINDOWS
 #define SANITIZER_INTERCEPT_POLL SI_NOT_WINDOWS
@@ -161,7 +166,7 @@
   SI_FREEBSD || SI_MAC || SI_LINUX_NOT_ANDROID
 #define SANITIZER_INTERCEPT_SIGPENDING SI_NOT_WINDOWS
 #define SANITIZER_INTERCEPT_SIGPROCMASK SI_NOT_WINDOWS
-#define SANITIZER_INTERCEPT_BACKTRACE SI_LINUX_NOT_ANDROID
+#define SANITIZER_INTERCEPT_BACKTRACE SI_FREEBSD || SI_LINUX_NOT_ANDROID
 #define SANITIZER_INTERCEPT_GETMNTENT SI_LINUX
 #define SANITIZER_INTERCEPT_GETMNTENT_R SI_LINUX_NOT_ANDROID
 #define SANITIZER_INTERCEPT_STATFS SI_FREEBSD || SI_MAC || SI_LINUX_NOT_ANDROID
@@ -203,12 +208,13 @@
 #define SANITIZER_INTERCEPT_LGAMMA_R SI_FREEBSD || SI_LINUX
 #define SANITIZER_INTERCEPT_LGAMMAL_R SI_LINUX_NOT_ANDROID
 #define SANITIZER_INTERCEPT_DRAND48_R SI_LINUX_NOT_ANDROID
-#define SANITIZER_INTERCEPT_RAND_R SI_MAC || SI_LINUX_NOT_ANDROID
-#define SANITIZER_INTERCEPT_ICONV SI_LINUX_NOT_ANDROID
+#define SANITIZER_INTERCEPT_RAND_R \
+  SI_FREEBSD || SI_MAC || SI_LINUX_NOT_ANDROID
+#define SANITIZER_INTERCEPT_ICONV SI_FREEBSD || SI_LINUX_NOT_ANDROID
 #define SANITIZER_INTERCEPT_TIMES SI_NOT_WINDOWS
 
 // FIXME: getline seems to be available on OSX 10.7
-#define SANITIZER_INTERCEPT_GETLINE SI_LINUX_NOT_ANDROID
+#define SANITIZER_INTERCEPT_GETLINE SI_FREEBSD || SI_LINUX_NOT_ANDROID
 
 #define SANITIZER_INTERCEPT__EXIT SI_LINUX || SI_FREEBSD
 
@@ -222,12 +228,14 @@
 #define SANITIZER_INTERCEPT_LISTXATTR SI_LINUX
 #define SANITIZER_INTERCEPT_GETXATTR SI_LINUX
 #define SANITIZER_INTERCEPT_GETRESID SI_LINUX
-#define SANITIZER_INTERCEPT_GETIFADDRS SI_LINUX_NOT_ANDROID || SI_MAC
-#define SANITIZER_INTERCEPT_IF_INDEXTONAME SI_LINUX_NOT_ANDROID || SI_MAC
+#define SANITIZER_INTERCEPT_GETIFADDRS \
+  SI_FREEBSD || SI_LINUX_NOT_ANDROID || SI_MAC
+#define SANITIZER_INTERCEPT_IF_INDEXTONAME \
+  SI_FREEBSD || SI_LINUX_NOT_ANDROID || SI_MAC
 #define SANITIZER_INTERCEPT_CAPGET SI_LINUX_NOT_ANDROID
 #define SANITIZER_INTERCEPT_AEABI_MEM SI_LINUX && defined(__arm__)
 #define SANITIZER_INTERCEPT___BZERO SI_MAC
-#define SANITIZER_INTERCEPT_FTIME SI_NOT_WINDOWS
+#define SANITIZER_INTERCEPT_FTIME !SI_FREEBSD && SI_NOT_WINDOWS
 #define SANITIZER_INTERCEPT_XDR SI_LINUX_NOT_ANDROID
 #define SANITIZER_INTERCEPT_TSEARCH SI_LINUX_NOT_ANDROID || SI_MAC
 #define SANITIZER_INTERCEPT_LIBIO_INTERNALS SI_LINUX_NOT_ANDROID
diff --git a/lib/sanitizer_common/sanitizer_platform_limits_posix.h b/lib/sanitizer_common/sanitizer_platform_limits_posix.h
index bd20bea..77bbdb1 100644
--- a/lib/sanitizer_common/sanitizer_platform_limits_posix.h
+++ b/lib/sanitizer_common/sanitizer_platform_limits_posix.h
@@ -321,7 +321,7 @@
     long pw_change;
     char *pw_class;
 #endif
-#if !SANITIZER_ANDROID
+#if !(SANITIZER_ANDROID && (SANITIZER_WORDSIZE == 32))
     char *pw_gecos;
 #endif
     char *pw_dir;
@@ -383,7 +383,7 @@
   };
 #endif
 
-#if SANITIZER_ANDROID || SANITIZER_MAC || SANITIZER_FREEBSD
+#if SANITIZER_MAC || SANITIZER_FREEBSD
   struct __sanitizer_msghdr {
     void *msg_name;
     unsigned msg_namelen;
@@ -520,6 +520,27 @@
 #endif
 
   // Linux system headers define the 'sa_handler' and 'sa_sigaction' macros.
+#if SANITIZER_ANDROID && (SANITIZER_WORDSIZE == 64)
+  struct __sanitizer_sigaction {
+    unsigned sa_flags;
+    union {
+      void (*sigaction)(int sig, void *siginfo, void *uctx);
+      void (*handler)(int sig);
+    };
+    __sanitizer_sigset_t sa_mask;
+    void (*sa_restorer)();
+  };
+#elif SANITIZER_ANDROID && (SANITIZER_WORDSIZE == 32)
+  struct __sanitizer_sigaction {
+    union {
+      void (*sigaction)(int sig, void *siginfo, void *uctx);
+      void (*handler)(int sig);
+    };
+    __sanitizer_sigset_t sa_mask;
+    uptr sa_flags;
+    void (*sa_restorer)();
+  };
+#else // !SANITIZER_ANDROID
   struct __sanitizer_sigaction {
 #if defined(__mips__) && !SANITIZER_FREEBSD
     unsigned int sa_flags;
@@ -544,6 +565,7 @@
     int sa_resv[1];
 #endif
   };
+#endif // !SANITIZER_ANDROID
 
 #if SANITIZER_FREEBSD
   typedef __sanitizer_sigset_t __sanitizer_kernel_sigset_t;
diff --git a/lib/sanitizer_common/sanitizer_posix.cc b/lib/sanitizer_common/sanitizer_posix.cc
index 0b6d35e..de4b8d1 100644
--- a/lib/sanitizer_common/sanitizer_posix.cc
+++ b/lib/sanitizer_common/sanitizer_posix.cc
@@ -165,22 +165,6 @@
   return (void *)p;
 }
 
-void *MmapFixedNoReserve(uptr fixed_addr, uptr size) {
-  uptr PageSize = GetPageSizeCached();
-  uptr p = internal_mmap((void*)(fixed_addr & ~(PageSize - 1)),
-      RoundUpTo(size, PageSize),
-      PROT_READ | PROT_WRITE,
-      MAP_PRIVATE | MAP_ANON | MAP_FIXED | MAP_NORESERVE,
-      -1, 0);
-  int reserrno;
-  if (internal_iserror(p, &reserrno))
-    Report("ERROR: %s failed to "
-           "allocate 0x%zx (%zd) bytes at address %zx (errno: %d)\n",
-           SanitizerToolName, size, size, fixed_addr, reserrno);
-  IncreaseTotalMmap(size);
-  return (void *)p;
-}
-
 void *MmapFixedOrDie(uptr fixed_addr, uptr size) {
   uptr PageSize = GetPageSizeCached();
   uptr p = internal_mmap((void*)(fixed_addr & ~(PageSize - 1)),
@@ -199,13 +183,6 @@
   return (void *)p;
 }
 
-void *MmapNoAccess(uptr fixed_addr, uptr size) {
-  return (void *)internal_mmap((void*)fixed_addr, size,
-                               PROT_NONE,
-                               MAP_PRIVATE | MAP_ANON | MAP_FIXED |
-                               MAP_NORESERVE, -1, 0);
-}
-
 bool MprotectNoAccess(uptr addr, uptr size) {
   return 0 == internal_mprotect((void*)addr, size, PROT_NONE);
 }
diff --git a/lib/sanitizer_common/sanitizer_posix_libcdep.cc b/lib/sanitizer_common/sanitizer_posix_libcdep.cc
index 9eb28c6..3f0a4f4 100644
--- a/lib/sanitizer_common/sanitizer_posix_libcdep.cc
+++ b/lib/sanitizer_common/sanitizer_posix_libcdep.cc
@@ -24,6 +24,7 @@
 #include "sanitizer_symbolizer.h"
 
 #include <errno.h>
+#include <fcntl.h>
 #include <pthread.h>
 #include <signal.h>
 #include <stdlib.h>
@@ -31,8 +32,16 @@
 #include <sys/resource.h>
 #include <sys/time.h>
 #include <sys/types.h>
+#include <sys/stat.h>
 #include <unistd.h>
 
+#if SANITIZER_FREEBSD
+// The MAP_NORESERVE define has been removed in FreeBSD 11.x, and even before
+// that, it was never implemented.  So just define it to zero.
+#undef  MAP_NORESERVE
+#define MAP_NORESERVE 0
+#endif
+
 namespace __sanitizer {
 
 u32 GetUid() {
@@ -178,6 +187,7 @@
   if (common_flags()->use_sigaltstack) SetAlternateSignalStack();
   MaybeInstallSigaction(SIGSEGV, handler);
   MaybeInstallSigaction(SIGBUS, handler);
+  MaybeInstallSigaction(SIGABRT, handler);
 }
 #endif  // SANITIZER_GO
 
@@ -216,6 +226,55 @@
 #endif
 }
 
+#if SANITIZER_ANDROID
+int GetNamedMappingFd(const char *name, uptr size) {
+  return -1;
+}
+#else
+int GetNamedMappingFd(const char *name, uptr size) {
+  if (!common_flags()->decorate_proc_maps)
+    return -1;
+  char shmname[200];
+  CHECK(internal_strlen(name) < sizeof(shmname) - 10);
+  internal_snprintf(shmname, sizeof(shmname), "%zu [%s]", internal_getpid(),
+                    name);
+  int fd = shm_open(shmname, O_RDWR | O_CREAT | O_TRUNC, S_IRWXU);
+  CHECK_GE(fd, 0);
+  int res = internal_ftruncate(fd, size);
+  CHECK_EQ(0, res);
+  res = shm_unlink(shmname);
+  CHECK_EQ(0, res);
+  return fd;
+}
+#endif
+
+void *MmapFixedNoReserve(uptr fixed_addr, uptr size, const char *name) {
+  int fd = name ? GetNamedMappingFd(name, size) : -1;
+  unsigned flags = MAP_PRIVATE | MAP_FIXED | MAP_NORESERVE;
+  if (fd == -1) flags |= MAP_ANON;
+
+  uptr PageSize = GetPageSizeCached();
+  uptr p = internal_mmap((void *)(fixed_addr & ~(PageSize - 1)),
+                         RoundUpTo(size, PageSize), PROT_READ | PROT_WRITE,
+                         flags, fd, 0);
+  int reserrno;
+  if (internal_iserror(p, &reserrno))
+    Report("ERROR: %s failed to "
+           "allocate 0x%zx (%zd) bytes at address %zx (errno: %d)\n",
+           SanitizerToolName, size, size, fixed_addr, reserrno);
+  IncreaseTotalMmap(size);
+  return (void *)p;
+}
+
+void *MmapNoAccess(uptr fixed_addr, uptr size, const char *name) {
+  int fd = name ? GetNamedMappingFd(name, size) : -1;
+  unsigned flags = MAP_PRIVATE | MAP_FIXED | MAP_NORESERVE;
+  if (fd == -1) flags |= MAP_ANON;
+
+  return (void *)internal_mmap((void *)fixed_addr, size, PROT_NONE, flags, fd,
+                               0);
+}
+
 }  // namespace __sanitizer
 
 #endif  // SANITIZER_POSIX
diff --git a/lib/sanitizer_common/sanitizer_printf.cc b/lib/sanitizer_common/sanitizer_printf.cc
index 3be6723..e4f67f5 100644
--- a/lib/sanitizer_common/sanitizer_printf.cc
+++ b/lib/sanitizer_common/sanitizer_printf.cc
@@ -251,26 +251,32 @@
       buffer_size = kLen;
     }
     needed_length = 0;
+    // Check that data fits into the current buffer.
+#   define CHECK_NEEDED_LENGTH \
+      if (needed_length >= buffer_size) { \
+        if (!use_mmap) continue; \
+        RAW_CHECK_MSG(needed_length < kLen, \
+                      "Buffer in Report is too short!\n"); \
+      }
     if (append_pid) {
       int pid = internal_getpid();
-      needed_length += internal_snprintf(buffer, buffer_size, "==%d==", pid);
-      if (needed_length >= buffer_size) {
-        // The pid doesn't fit into the current buffer.
-        if (!use_mmap)
-          continue;
-        RAW_CHECK_MSG(needed_length < kLen, "Buffer in Report is too short!\n");
+      const char *exe_name = GetBinaryBasename();
+      if (common_flags()->log_exe_name && exe_name) {
+        needed_length += internal_snprintf(buffer, buffer_size,
+                                           "==%s", exe_name);
+        CHECK_NEEDED_LENGTH
       }
+      needed_length += internal_snprintf(buffer + needed_length,
+                                         buffer_size - needed_length,
+                                         "==%d==", pid);
+      CHECK_NEEDED_LENGTH
     }
     needed_length += VSNPrintf(buffer + needed_length,
                                buffer_size - needed_length, format, args);
-    if (needed_length >= buffer_size) {
-      // The message doesn't fit into the current buffer.
-      if (!use_mmap)
-        continue;
-      RAW_CHECK_MSG(needed_length < kLen, "Buffer in Report is too short!\n");
-    }
+    CHECK_NEEDED_LENGTH
     // If the message fit into the buffer, print it and exit.
     break;
+#   undef CHECK_NEEDED_LENGTH
   }
   RawWrite(buffer);
   AndroidLogWrite(buffer);
diff --git a/lib/sanitizer_common/sanitizer_stacktrace_libcdep.cc b/lib/sanitizer_common/sanitizer_stacktrace_libcdep.cc
index 0f98c7d..b55d4dd 100644
--- a/lib/sanitizer_common/sanitizer_stacktrace_libcdep.cc
+++ b/lib/sanitizer_common/sanitizer_stacktrace_libcdep.cc
@@ -35,7 +35,8 @@
     for (SymbolizedStack *cur = frames; cur; cur = cur->next) {
       frame_desc.clear();
       RenderFrame(&frame_desc, common_flags()->stack_trace_format, frame_num++,
-                  cur->info, common_flags()->strip_path_prefix);
+                  cur->info, common_flags()->symbolize_vs_style,
+                  common_flags()->strip_path_prefix);
       Printf("%s\n", frame_desc.data());
     }
     frames->ClearAll();
diff --git a/lib/sanitizer_common/sanitizer_stacktrace_printer.cc b/lib/sanitizer_common/sanitizer_stacktrace_printer.cc
index 7b37dbc..d56e47e 100644
--- a/lib/sanitizer_common/sanitizer_stacktrace_printer.cc
+++ b/lib/sanitizer_common/sanitizer_stacktrace_printer.cc
@@ -26,8 +26,8 @@
 static const char kDefaultFormat[] = "    #%n %p %F %L";
 
 void RenderFrame(InternalScopedString *buffer, const char *format, int frame_no,
-                 const AddressInfo &info, const char *strip_path_prefix,
-                 const char *strip_func_prefix) {
+                 const AddressInfo &info, bool vs_style,
+                 const char *strip_path_prefix, const char *strip_func_prefix) {
   if (0 == internal_strcmp(format, "DEFAULT"))
     format = kDefaultFormat;
   for (const char *p = format; *p != '\0'; p++) {
@@ -82,14 +82,14 @@
       break;
     case 'S':
       // File/line information.
-      RenderSourceLocation(buffer, info.file, info.line, info.column,
+      RenderSourceLocation(buffer, info.file, info.line, info.column, vs_style,
                            strip_path_prefix);
       break;
     case 'L':
       // Source location, or module location.
       if (info.file) {
         RenderSourceLocation(buffer, info.file, info.line, info.column,
-                             strip_path_prefix);
+                             vs_style, strip_path_prefix);
       } else if (info.module) {
         RenderModuleLocation(buffer, info.module, info.module_offset,
                              strip_path_prefix);
@@ -106,15 +106,24 @@
         buffer->append("(%p)", (void *)info.address);
       break;
     default:
-      Report("Unsupported specifier in stack frame format: %c (0x%zx)!\n",
-             *p, *p);
+      Report("Unsupported specifier in stack frame format: %c (0x%zx)!\n", *p,
+             *p);
       Die();
     }
   }
 }
 
 void RenderSourceLocation(InternalScopedString *buffer, const char *file,
-                          int line, int column, const char *strip_path_prefix) {
+                          int line, int column, bool vs_style,
+                          const char *strip_path_prefix) {
+  if (vs_style && line > 0) {
+    buffer->append("%s(%d", StripPathPrefix(file, strip_path_prefix), line);
+    if (column > 0)
+      buffer->append(",%d", column);
+    buffer->append(")");
+    return;
+  }
+
   buffer->append("%s", StripPathPrefix(file, strip_path_prefix));
   if (line > 0) {
     buffer->append(":%d", line);
diff --git a/lib/sanitizer_common/sanitizer_stacktrace_printer.h b/lib/sanitizer_common/sanitizer_stacktrace_printer.h
index 9356988..7f6c5c7 100644
--- a/lib/sanitizer_common/sanitizer_stacktrace_printer.h
+++ b/lib/sanitizer_common/sanitizer_stacktrace_printer.h
@@ -48,11 +48,13 @@
 //        module+offset if it is known, or (<unknown module>) string.
 //   %M - prints module basename and offset, if it is known, or PC.
 void RenderFrame(InternalScopedString *buffer, const char *format, int frame_no,
-                 const AddressInfo &info, const char *strip_path_prefix = "",
+                 const AddressInfo &info, bool vs_style,
+                 const char *strip_path_prefix = "",
                  const char *strip_func_prefix = "");
 
 void RenderSourceLocation(InternalScopedString *buffer, const char *file,
-                          int line, int column, const char *strip_path_prefix);
+                          int line, int column, bool vs_style,
+                          const char *strip_path_prefix);
 
 void RenderModuleLocation(InternalScopedString *buffer, const char *module,
                           uptr offset, const char *strip_path_prefix);
diff --git a/lib/sanitizer_common/sanitizer_symbolizer_posix_libcdep.cc b/lib/sanitizer_common/sanitizer_symbolizer_posix_libcdep.cc
index 6e714c7..eae9b57 100644
--- a/lib/sanitizer_common/sanitizer_symbolizer_posix_libcdep.cc
+++ b/lib/sanitizer_common/sanitizer_symbolizer_posix_libcdep.cc
@@ -67,6 +67,7 @@
     CHECK(function_name);
     if (function_name[0] == '\0') {
       // There are no more frames.
+      InternalFree(function_name);
       break;
     }
     SymbolizedStack *cur;
@@ -353,12 +354,7 @@
   return DemangleCXXABI(name);
 }
 
-void Symbolizer::PlatformPrepareForSandboxing() {
-#if SANITIZER_LINUX && !SANITIZER_ANDROID
-  // Cache /proc/self/exe on Linux.
-  CacheBinaryName();
-#endif
-}
+void Symbolizer::PlatformPrepareForSandboxing() {}
 
 static SymbolizerTool *ChooseExternalSymbolizer(LowLevelAllocator *allocator) {
   const char *path = common_flags()->external_symbolizer_path;
diff --git a/lib/sanitizer_common/sanitizer_tls_get_addr.cc b/lib/sanitizer_common/sanitizer_tls_get_addr.cc
index 6142ce5..ea03715 100644
--- a/lib/sanitizer_common/sanitizer_tls_get_addr.cc
+++ b/lib/sanitizer_common/sanitizer_tls_get_addr.cc
@@ -78,7 +78,8 @@
   DTLS_Deallocate(dtls.dtv, s);
 }
 
-DTLS::DTV *DTLS_on_tls_get_addr(void *arg_void, void *res) {
+DTLS::DTV *DTLS_on_tls_get_addr(void *arg_void, void *res,
+                                uptr static_tls_begin, uptr static_tls_end) {
   if (!common_flags()->intercept_tls_get_addr) return 0;
   TlsGetAddrParam *arg = reinterpret_cast<TlsGetAddrParam *>(arg_void);
   uptr dso_id = arg->dso_id;
@@ -95,6 +96,11 @@
     tls_size = dtls.last_memalign_size;
     VPrintf(2, "__tls_get_addr: glibc <=2.18 suspected; tls={%p,%p}\n",
         tls_beg, tls_size);
+  } else if (tls_beg >= static_tls_begin && tls_beg < static_tls_end) {
+    // This is the static TLS block which was initialized / unpoisoned at thread
+    // creation.
+    VPrintf(2, "__tls_get_addr: static tls: %p\n", tls_beg);
+    tls_size = 0;
   } else if ((tls_beg % 4096) == sizeof(Glibc_2_19_tls_header)) {
     // We may want to check gnu_get_libc_version().
     Glibc_2_19_tls_header *header = (Glibc_2_19_tls_header *)tls_beg - 1;
diff --git a/lib/sanitizer_common/sanitizer_tls_get_addr.h b/lib/sanitizer_common/sanitizer_tls_get_addr.h
index 0fc9a22..58d4763 100644
--- a/lib/sanitizer_common/sanitizer_tls_get_addr.h
+++ b/lib/sanitizer_common/sanitizer_tls_get_addr.h
@@ -50,7 +50,8 @@
 
 // Returns pointer and size of a linker-allocated TLS block.
 // Each block is returned exactly once.
-DTLS::DTV *DTLS_on_tls_get_addr(void *arg, void *res);
+DTLS::DTV *DTLS_on_tls_get_addr(void *arg, void *res, uptr static_tls_begin,
+                                uptr static_tls_end);
 void DTLS_on_libc_memalign(void *ptr, uptr size);
 DTLS *DTLS_Get();
 void DTLS_Destroy();  // Make sure to call this before the thread is destroyed.
diff --git a/lib/sanitizer_common/sanitizer_win.cc b/lib/sanitizer_common/sanitizer_win.cc
index e5e2f64..94393c4 100644
--- a/lib/sanitizer_common/sanitizer_win.cc
+++ b/lib/sanitizer_common/sanitizer_win.cc
@@ -104,9 +104,10 @@
   }
 }
 
-void *MmapFixedNoReserve(uptr fixed_addr, uptr size) {
+void *MmapFixedNoReserve(uptr fixed_addr, uptr size, const char *name) {
   // FIXME: is this really "NoReserve"? On Win32 this does not matter much,
   // but on Win64 it does.
+  (void)name; // unsupported
   void *p = VirtualAlloc((LPVOID)fixed_addr, size,
       MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
   if (p == 0)
@@ -125,7 +126,8 @@
   return MmapOrDie(size, mem_type);
 }
 
-void *MmapNoAccess(uptr fixed_addr, uptr size) {
+void *MmapNoAccess(uptr fixed_addr, uptr size, const char *name) {
+  (void)name; // unsupported
   void *res = VirtualAlloc((LPVOID)fixed_addr, size,
                            MEM_RESERVE | MEM_COMMIT, PAGE_NOACCESS);
   if (res == 0)
@@ -267,8 +269,9 @@
 }
 
 void PrepareForSandboxing(__sanitizer_sandbox_arguments *args) {
-  (void)args;
-  // Nothing here for now.
+#if !SANITIZER_GO
+  CovPrepareForSandboxing(args);
+#endif
 }
 
 bool StackSizeIsUnlimited() {
@@ -292,11 +295,6 @@
   return 0;
 }
 
-uptr ReadBinaryName(/*out*/char *buf, uptr buf_len) {
-  // Nothing here for now.
-  return 0;
-}
-
 bool IsPathSeparator(const char c) {
   return c == '\\' || c == '/';
 }
@@ -408,6 +406,8 @@
                         FILE_ATTRIBUTE_NORMAL, nullptr);
   CHECK(res != kStdoutFd || kStdoutFd == kInvalidFd);
   CHECK(res != kStderrFd || kStderrFd == kInvalidFd);
+  if (res == kInvalidFd && last_error)
+    *last_error = GetLastError();
   return res;
 }
 
@@ -636,6 +636,13 @@
   return SignalContext(context, access_addr, pc, sp, bp);
 }
 
+uptr ReadBinaryName(/*out*/char *buf, uptr buf_len) {
+  // FIXME: Actually implement this function.
+  CHECK_GT(buf_len, 0);
+  buf[0] = 0;
+  return 0;
+}
+
 }  // namespace __sanitizer
 
 #endif  // _WIN32
diff --git a/lib/sanitizer_common/scripts/cpplint.py b/lib/sanitizer_common/scripts/cpplint.py
index 742459a..d45c47f 100755
--- a/lib/sanitizer_common/scripts/cpplint.py
+++ b/lib/sanitizer_common/scripts/cpplint.py
@@ -1,4 +1,4 @@
-#!/usr/bin/python
+#!/usr/bin/env python
 #
 # Copyright (c) 2009 Google Inc. All rights reserved.
 #
diff --git a/lib/sanitizer_common/scripts/gen_dynamic_list.py b/lib/sanitizer_common/scripts/gen_dynamic_list.py
index 7bab230..f055bb4 100755
--- a/lib/sanitizer_common/scripts/gen_dynamic_list.py
+++ b/lib/sanitizer_common/scripts/gen_dynamic_list.py
@@ -14,15 +14,24 @@
 #   gen_dynamic_list.py libclang_rt.*san*.a [ files ... ]
 #
 #===------------------------------------------------------------------------===#
+import argparse
 import os
 import re
 import subprocess
 import sys
 
-new_delete = set(['_ZdaPv', '_ZdaPvRKSt9nothrow_t',
-                  '_ZdlPv', '_ZdlPvRKSt9nothrow_t',
-                  '_Znam', '_ZnamRKSt9nothrow_t',
-                  '_Znwm', '_ZnwmRKSt9nothrow_t'])
+new_delete = set([
+                  '_Znam', '_ZnamRKSt9nothrow_t',    # operator new[](unsigned long)
+                  '_Znwm', '_ZnwmRKSt9nothrow_t',    # operator new(unsigned long)
+                  '_Znaj', '_ZnajRKSt9nothrow_t',    # operator new[](unsigned int)
+                  '_Znwj', '_ZnwjRKSt9nothrow_t',    # operator new(unsigned int)
+                  '_ZdaPv', '_ZdaPvRKSt9nothrow_t',  # operator delete[](void *)
+                  '_ZdlPv', '_ZdlPvRKSt9nothrow_t',  # operator delete(void *)
+                  '_ZdaPvm',                         # operator delete[](void*, unsigned long)
+                  '_ZdlPvm',                         # operator delete(void*, unsigned long)
+                  '_ZdaPvj',                         # operator delete[](void*, unsigned int)
+                  '_ZdlPvj',                         # operator delete(void*, unsigned int)
+                  ])
 
 versioned_functions = set(['memcpy', 'pthread_attr_getaffinity_np',
                            'pthread_cond_broadcast',
@@ -49,10 +58,17 @@
   return functions
 
 def main(argv):
+  parser = argparse.ArgumentParser()
+  parser.add_argument('--version-list', action='store_true')
+  parser.add_argument('--extra', default=[], action='append')
+  parser.add_argument('libraries', default=[], nargs='+')
+  args = parser.parse_args()
+
   result = []
 
-  library = argv[1]
-  all_functions = get_global_functions(library)
+  all_functions = []
+  for library in args.libraries:
+    all_functions.extend(get_global_functions(library))
   function_set = set(all_functions)
   for func in all_functions:
     # Export new/delete operators.
@@ -66,7 +82,7 @@
       # We have to avoid exporting the interceptors for versioned library
       # functions due to gold internal error.
       orig_name = match.group(1)
-      if orig_name in function_set and orig_name not in versioned_functions:
+      if orig_name in function_set and (args.version_list or orig_name not in versioned_functions):
         result.append(orig_name)
       continue
     # Export sanitizer interface functions.
@@ -74,15 +90,20 @@
       result.append(func)
 
   # Additional exported functions from files.
-  for fname in argv[2:]:
+  for fname in args.extra:
     f = open(fname, 'r')
     for line in f:
       result.append(line.rstrip())
   # Print the resulting list in the format recognized by ld.
   print('{')
+  if args.version_list:
+    print('global:')
   result.sort()
   for f in result:
-    print('  ' + f + ';')
+    print('  ' + f.encode('utf-8') + ';')
+  if args.version_list:
+    print('local:')
+    print('  *;')
   print('};')
 
 if __name__ == '__main__':
diff --git a/lib/sanitizer_common/scripts/litlint.py b/lib/sanitizer_common/scripts/litlint.py
index 1e78448..81b89c2 100755
--- a/lib/sanitizer_common/scripts/litlint.py
+++ b/lib/sanitizer_common/scripts/litlint.py
@@ -1,4 +1,4 @@
-#!/usr/bin/python
+#!/usr/bin/env python
 #
 # litlint
 #
diff --git a/lib/sanitizer_common/scripts/sancov.py b/lib/sanitizer_common/scripts/sancov.py
index 776b8d9..a5ae957 100755
--- a/lib/sanitizer_common/scripts/sancov.py
+++ b/lib/sanitizer_common/scripts/sancov.py
@@ -8,16 +8,18 @@
 import glob
 import os.path
 import struct
+import subprocess
 import sys
 
 prog_name = ""
 
 def Usage():
   print >> sys.stderr, "Usage: \n" + \
-      " " + prog_name + " [32|64] merge file1 [file2 ...]  > output\n" \
-      " " + prog_name + " [32|64] print file1 [file2 ...]\n" \
-      " " + prog_name + " [32|64] unpack file1 [file2 ...]\n" \
-      " " + prog_name + " [32|64] rawunpack file1 [file2 ...]\n"
+      " " + prog_name + " merge FILE [FILE...] > OUTPUT\n" \
+      " " + prog_name + " print FILE [FILE...]\n" \
+      " " + prog_name + " unpack FILE [FILE...]\n" \
+      " " + prog_name + " rawunpack FILE [FILE ...]\n" \
+      " " + prog_name + " missing BINARY < LIST_OF_PCS\n"
   exit(1)
 
 def CheckBits(bits):
@@ -177,11 +179,50 @@
     f_map = f[:-3] + 'map'
     UnpackOneRawFile(f, f_map)
 
+def GetInstrumentedPCs(binary):
+  # This looks scary, but all it does is extract all offsets where we call:
+  # - __sanitizer_cov() or __sanitizer_cov_with_check(),
+  # - with call or callq,
+  # - directly or via PLT.
+  cmd = "objdump -d %s | " \
+        "grep '^\s\+[0-9a-f]\+:.*\scall\(q\|\)\s\+[0-9a-f]\+ <__sanitizer_cov\(_with_check\|\)\(@plt\|\)>' | " \
+        "grep '^\s\+[0-9a-f]\+' -o" % binary
+  proc = subprocess.Popen(cmd, stdin=subprocess.PIPE, stdout=subprocess.PIPE,
+                          shell=True)
+  proc.stdin.close()
+  # The PCs we get from objdump are off by 4 bytes, as they point to the
+  # beginning of the callq instruction. Empirically this is true on x86 and
+  # x86_64.
+  return set(int(line.strip(), 16) + 4 for line in proc.stdout)
+
+def PrintMissing(binary):
+  if not os.path.isfile(binary):
+    raise Exception('File not found: %s' % binary)
+  instrumented = GetInstrumentedPCs(binary)
+  print >> sys.stderr, "%s: found %d instrumented PCs in %s" % (prog_name,
+                                                                len(instrumented),
+                                                                binary)
+  covered = set(int(line, 16) for line in sys.stdin)
+  print >> sys.stderr, "%s: read %d PCs from stdin" % (prog_name, len(covered))
+  missing = instrumented - covered
+  print >> sys.stderr, "%s: %d PCs missing from coverage" % (prog_name, len(missing))
+  if (len(missing) > len(instrumented) - len(covered)):
+    print >> sys.stderr, \
+        "%s: WARNING: stdin contains PCs not found in binary" % prog_name
+  for pc in sorted(missing):
+    print "0x%x" % pc
+
 if __name__ == '__main__':
   prog_name = sys.argv[0]
   if len(sys.argv) <= 2:
     Usage();
 
+  if sys.argv[1] == "missing":
+    if len(sys.argv) != 3:
+      Usage()
+    PrintMissing(sys.argv[2])
+    exit(0)
+
   file_list = []
   for f in sys.argv[2:]:
     file_list += glob.glob(f)
diff --git a/lib/sanitizer_common/tests/Android.mk b/lib/sanitizer_common/tests/Android.mk
index f282ead..5129c00 100644
--- a/lib/sanitizer_common/tests/Android.mk
+++ b/lib/sanitizer_common/tests/Android.mk
@@ -65,7 +65,7 @@
 LOCAL_CPPFLAGS := $(san_test_cppflags)
 LOCAL_SRC_FILES := $(san_test_files)
 LOCAL_STATIC_LIBRARIES := libsan
-LOCAL_LDLIBS := -ldl
+LOCAL_LDLIBS := -ldl -lrt
 LOCAL_SANITIZE := never
 include $(BUILD_HOST_NATIVE_TEST)
 
diff --git a/lib/sanitizer_common/tests/CMakeLists.txt b/lib/sanitizer_common/tests/CMakeLists.txt
index b062c5a..540d506 100644
--- a/lib/sanitizer_common/tests/CMakeLists.txt
+++ b/lib/sanitizer_common/tests/CMakeLists.txt
@@ -51,11 +51,16 @@
   -Werror=sign-compare
   -Wno-non-virtual-dtor)
 
+if(MSVC)
+  # Disable exceptions on Windows until they work reliably.
+  list(APPEND SANITIZER_TEST_CFLAGS_COMMON -fno-exceptions -DGTEST_HAS_SEH=0)
+endif()
+
 # -gline-tables-only must be enough for these tests, so use it if possible.
 if(COMPILER_RT_TEST_COMPILER_ID MATCHES "Clang")
-  list(APPEND ASAN_UNITTEST_COMMON_CFLAGS -gline-tables-only)
+  list(APPEND SANITIZER_TEST_CFLAGS_COMMON -gline-tables-only)
 else()
-  list(APPEND ASAN_UNITTEST_COMMON_CFLAGS -g)
+  list(APPEND SANITIZER_TEST_CFLAGS_COMMON -g)
 endif()
 
 if(NOT MSVC)
@@ -68,6 +73,7 @@
 append_list_if(ANDROID atomic SANITIZER_TEST_LINK_LIBS)
 
 append_list_if(COMPILER_RT_HAS_LIBDL -ldl SANITIZER_TEST_LINK_FLAGS_COMMON)
+append_list_if(COMPILER_RT_HAS_LIBRT -lrt SANITIZER_TEST_LINK_FLAGS_COMMON)
 append_list_if(COMPILER_RT_HAS_LIBPTHREAD -pthread SANITIZER_TEST_LINK_FLAGS_COMMON)
 # x86_64 FreeBSD 9.2 additionally requires libc++ to build the tests. Also,
 # 'libm' shall be specified explicitly to build i386 tests.
diff --git a/lib/sanitizer_common/tests/sanitizer_stacktrace_printer_test.cc b/lib/sanitizer_common/tests/sanitizer_stacktrace_printer_test.cc
index cc9a9ed..05796fc 100644
--- a/lib/sanitizer_common/tests/sanitizer_stacktrace_printer_test.cc
+++ b/lib/sanitizer_common/tests/sanitizer_stacktrace_printer_test.cc
@@ -18,20 +18,36 @@
 
 TEST(SanitizerStacktracePrinter, RenderSourceLocation) {
   InternalScopedString str(128);
-  RenderSourceLocation(&str, "/dir/file.cc", 10, 5, "");
+  RenderSourceLocation(&str, "/dir/file.cc", 10, 5, false, "");
   EXPECT_STREQ("/dir/file.cc:10:5", str.data());
 
   str.clear();
-  RenderSourceLocation(&str, "/dir/file.cc", 11, 0, "");
+  RenderSourceLocation(&str, "/dir/file.cc", 11, 0, false, "");
   EXPECT_STREQ("/dir/file.cc:11", str.data());
 
   str.clear();
-  RenderSourceLocation(&str, "/dir/file.cc", 0, 0, "");
+  RenderSourceLocation(&str, "/dir/file.cc", 0, 0, false, "");
   EXPECT_STREQ("/dir/file.cc", str.data());
 
   str.clear();
-  RenderSourceLocation(&str, "/dir/file.cc", 10, 5, "/dir/");
+  RenderSourceLocation(&str, "/dir/file.cc", 10, 5, false, "/dir/");
   EXPECT_STREQ("file.cc:10:5", str.data());
+
+  str.clear();
+  RenderSourceLocation(&str, "/dir/file.cc", 10, 5, true, "");
+  EXPECT_STREQ("/dir/file.cc(10,5)", str.data());
+
+  str.clear();
+  RenderSourceLocation(&str, "/dir/file.cc", 11, 0, true, "");
+  EXPECT_STREQ("/dir/file.cc(11)", str.data());
+
+  str.clear();
+  RenderSourceLocation(&str, "/dir/file.cc", 0, 0, true, "");
+  EXPECT_STREQ("/dir/file.cc", str.data());
+
+  str.clear();
+  RenderSourceLocation(&str, "/dir/file.cc", 10, 5, true, "/dir/");
+  EXPECT_STREQ("file.cc(10,5)", str.data());
 }
 
 TEST(SanitizerStacktracePrinter, RenderModuleLocation) {
@@ -62,7 +78,7 @@
   RenderFrame(&str, "%% Frame:%n PC:%p Module:%m ModuleOffset:%o "
                     "Function:%f FunctionOffset:%q Source:%s Line:%l "
                     "Column:%c",
-              frame_no, info, "/path/to/", "function_");
+              frame_no, info, false, "/path/to/", "function_");
   EXPECT_STREQ("% Frame:42 PC:0x400000 Module:my/module ModuleOffset:0x200 "
                "Function:foo FunctionOffset:0x100 Source:my/source Line:10 "
                "Column:5",
@@ -72,50 +88,64 @@
 
   // Test special format specifiers.
   info.address = 0x400000;
-  RenderFrame(&str, "%M", frame_no, info);
+  RenderFrame(&str, "%M", frame_no, info, false);
   EXPECT_NE(nullptr, internal_strstr(str.data(), "400000"));
   str.clear();
 
-  RenderFrame(&str, "%L", frame_no, info);
+  RenderFrame(&str, "%L", frame_no, info, false);
   EXPECT_STREQ("(<unknown module>)", str.data());
   str.clear();
 
   info.module = internal_strdup("/path/to/module");
   info.module_offset = 0x200;
-  RenderFrame(&str, "%M", frame_no, info);
+  RenderFrame(&str, "%M", frame_no, info, false);
   EXPECT_NE(nullptr, internal_strstr(str.data(), "(module+0x"));
   EXPECT_NE(nullptr, internal_strstr(str.data(), "200"));
   str.clear();
 
-  RenderFrame(&str, "%L", frame_no, info);
+  RenderFrame(&str, "%L", frame_no, info, false);
   EXPECT_STREQ("(/path/to/module+0x200)", str.data());
   str.clear();
 
   info.function = internal_strdup("my_function");
-  RenderFrame(&str, "%F", frame_no, info);
+  RenderFrame(&str, "%F", frame_no, info, false);
   EXPECT_STREQ("in my_function", str.data());
   str.clear();
 
   info.function_offset = 0x100;
-  RenderFrame(&str, "%F %S", frame_no, info);
+  RenderFrame(&str, "%F %S", frame_no, info, false);
   EXPECT_STREQ("in my_function+0x100 <null>", str.data());
   str.clear();
 
   info.file = internal_strdup("my_file");
-  RenderFrame(&str, "%F %S", frame_no, info);
+  RenderFrame(&str, "%F %S", frame_no, info, false);
   EXPECT_STREQ("in my_function my_file", str.data());
   str.clear();
 
   info.line = 10;
-  RenderFrame(&str, "%F %S", frame_no, info);
+  RenderFrame(&str, "%F %S", frame_no, info, false);
   EXPECT_STREQ("in my_function my_file:10", str.data());
   str.clear();
 
   info.column = 5;
-  RenderFrame(&str, "%S %L", frame_no, info);
+  RenderFrame(&str, "%S %L", frame_no, info, false);
   EXPECT_STREQ("my_file:10:5 my_file:10:5", str.data());
   str.clear();
 
+  RenderFrame(&str, "%S %L", frame_no, info, true);
+  EXPECT_STREQ("my_file(10,5) my_file(10,5)", str.data());
+  str.clear();
+
+  info.column = 0;
+  RenderFrame(&str, "%F %S", frame_no, info, true);
+  EXPECT_STREQ("in my_function my_file(10)", str.data());
+  str.clear();
+
+  info.line = 0;
+  RenderFrame(&str, "%F %S", frame_no, info, true);
+  EXPECT_STREQ("in my_function my_file", str.data());
+  str.clear();
+
   info.Clear();
 }
 
diff --git a/lib/tsan/CMakeLists.txt b/lib/tsan/CMakeLists.txt
index 68862f4..e091f1a 100644
--- a/lib/tsan/CMakeLists.txt
+++ b/lib/tsan/CMakeLists.txt
@@ -41,6 +41,9 @@
   rtl/tsan_symbolize.cc
   rtl/tsan_sync.cc)
 
+set(TSAN_CXX_SOURCES
+  rtl/tsan_new_delete.cc)
+
 if(APPLE)
   list(APPEND TSAN_SOURCES rtl/tsan_platform_mac.cc)
 elseif(UNIX)
@@ -57,6 +60,7 @@
   rtl/tsan_flags.h
   rtl/tsan_flags.inc
   rtl/tsan_ignoreset.h
+  rtl/tsan_interceptors.h
   rtl/tsan_interface_ann.h
   rtl/tsan_interface.h
   rtl/tsan_interface_inl.h
@@ -103,12 +107,20 @@
               $<TARGET_OBJECTS:RTInterception.${arch}>
               $<TARGET_OBJECTS:RTSanitizerCommon.${arch}>
               $<TARGET_OBJECTS:RTSanitizerCommonLibc.${arch}>
-      CFLAGS ${TSAN_RTL_CFLAGS}
-      DEFS ${TSAN_COMMON_DEFINITIONS})
-    list(APPEND TSAN_RUNTIME_LIBRARIES clang_rt.tsan-${arch})
+              $<TARGET_OBJECTS:RTUbsan.${arch}>
+      CFLAGS ${TSAN_RTL_CFLAGS})
+    add_compiler_rt_runtime(clang_rt.tsan_cxx-${arch} ${arch} STATIC
+      SOURCES ${TSAN_CXX_SOURCES}
+              $<TARGET_OBJECTS:RTUbsan_cxx.${arch}>
+      CFLAGS ${TSAN_RTL_CFLAGS})
+    list(APPEND TSAN_RUNTIME_LIBRARIES clang_rt.tsan-${arch}
+                                       clang_rt.tsan_cxx-${arch})
     add_sanitizer_rt_symbols(clang_rt.tsan-${arch} rtl/tsan.syms.extra)
+    add_sanitizer_rt_symbols(clang_rt.tsan_cxx-${arch} rtl/tsan.syms.extra)
     add_dependencies(tsan clang_rt.tsan-${arch}
-      clang_rt.tsan-${arch}-symbols)
+                          clang_rt.tsan_cxx-${arch}
+                          clang_rt.tsan-${arch}-symbols
+                          clang_rt.tsan_cxx-${arch}-symbols)
   endforeach()
 endif()
 
diff --git a/lib/tsan/Makefile.old b/lib/tsan/Makefile.old
index fbdb9dd..b2ac912 100644
--- a/lib/tsan/Makefile.old
+++ b/lib/tsan/Makefile.old
@@ -1,7 +1,8 @@
 DEBUG=0
 LDFLAGS=-ldl -lrt -lpthread -pie
 CXXFLAGS = -std=c++11 -fPIE -fno-rtti -g -Wall -Werror \
-					 -DGTEST_HAS_RTTI=0 -DSANITIZER_DEBUG=$(DEBUG)
+					 -DGTEST_HAS_RTTI=0 -DSANITIZER_DEBUG=$(DEBUG) \
+					 -DTSAN_CONTAINS_UBSAN=0
 CLANG=clang
 FILECHECK=FileCheck
 # Silence warnings that Clang produces for gtest code.
diff --git a/lib/tsan/dd/CMakeLists.txt b/lib/tsan/dd/CMakeLists.txt
index 981c1fb..d7c6041 100644
--- a/lib/tsan/dd/CMakeLists.txt
+++ b/lib/tsan/dd/CMakeLists.txt
@@ -12,6 +12,7 @@
 
 set(DD_LINKLIBS)
 append_list_if(COMPILER_RT_HAS_LIBDL dl DD_LINKLIBS)
+append_list_if(COMPILER_RT_HAS_LIBRT rt DD_LINKLIBS)
 append_list_if(COMPILER_RT_HAS_LIBPTHREAD pthread DD_LINKLIBS)
 
 add_custom_target(dd)
@@ -26,7 +27,8 @@
     CFLAGS ${DD_CFLAGS})
   add_dependencies(dd clang_rt.dd-${arch})
 
-  add_compiler_rt_object_library(RTDD ${arch}
+  add_compiler_rt_object_libraries(RTDD
+    ARCH ${arch}
     SOURCES ${DD_SOURCES} CFLAGS ${DD_CFLAGS})
 
   add_compiler_rt_runtime(clang_rt.dyndd-${arch} ${arch} SHARED
diff --git a/lib/tsan/go/buildgo.sh b/lib/tsan/go/buildgo.sh
index 5ac6034..7193b57 100755
--- a/lib/tsan/go/buildgo.sh
+++ b/lib/tsan/go/buildgo.sh
@@ -36,7 +36,7 @@
 if [ "`uname -a | grep Linux`" != "" ]; then
 	SUFFIX="linux_amd64"
 	OSCFLAGS="-fPIC -ffreestanding -Wno-maybe-uninitialized -Wno-unused-const-variable -Werror -Wno-unknown-warning-option"
-	OSLDFLAGS="-lpthread -fPIC -fpie"
+	OSLDFLAGS="-lpthread -lrt -fPIC -fpie"
 	SRCS="
 		$SRCS
 		../rtl/tsan_platform_linux.cc
diff --git a/lib/tsan/rtl/Makefile.old b/lib/tsan/rtl/Makefile.old
index 627e03b..ee7095e 100644
--- a/lib/tsan/rtl/Makefile.old
+++ b/lib/tsan/rtl/Makefile.old
@@ -1,4 +1,4 @@
-CXXFLAGS = -std=c++11 -fPIE -g -Wall -Werror -fno-builtin -msse3 -DSANITIZER_DEBUG=$(DEBUG)
+CXXFLAGS = -std=c++11 -fPIE -g -Wall -Werror -fno-builtin -msse3 -DSANITIZER_DEBUG=$(DEBUG) -DTSAN_CONTAINS_UBSAN=0
 CLANG=clang
 ifeq ($(DEBUG), 0)
   CXXFLAGS += -O3
diff --git a/lib/tsan/rtl/tsan.syms.extra b/lib/tsan/rtl/tsan.syms.extra
index 49ed6b4..1bc1d93 100644
--- a/lib/tsan/rtl/tsan.syms.extra
+++ b/lib/tsan/rtl/tsan.syms.extra
@@ -8,6 +8,7 @@
 __tsan_unaligned*
 __tsan_release
 __tsan_acquire
+__ubsan_*
 Annotate*
 WTFAnnotate*
 RunningOnValgrind
diff --git a/lib/tsan/rtl/tsan_defs.h b/lib/tsan/rtl/tsan_defs.h
index 910a483..d869d95 100644
--- a/lib/tsan/rtl/tsan_defs.h
+++ b/lib/tsan/rtl/tsan_defs.h
@@ -17,6 +17,7 @@
 #include "sanitizer_common/sanitizer_internal_defs.h"
 #include "sanitizer_common/sanitizer_libc.h"
 #include "tsan_stat.h"
+#include "ubsan/ubsan_platform.h"
 
 // Setup defaults for compile definitions.
 #ifndef TSAN_NO_HISTORY
@@ -27,6 +28,10 @@
 # define TSAN_COLLECT_STATS 0
 #endif
 
+#ifndef TSAN_CONTAINS_UBSAN
+# define TSAN_CONTAINS_UBSAN (CAN_SANITIZE_UB && !defined(SANITIZER_GO))
+#endif
+
 namespace __tsan {
 
 #ifdef SANITIZER_GO
diff --git a/lib/tsan/rtl/tsan_flags.cc b/lib/tsan/rtl/tsan_flags.cc
index 4c06600..5de227a 100644
--- a/lib/tsan/rtl/tsan_flags.cc
+++ b/lib/tsan/rtl/tsan_flags.cc
@@ -17,6 +17,7 @@
 #include "tsan_flags.h"
 #include "tsan_rtl.h"
 #include "tsan_mman.h"
+#include "ubsan/ubsan_flags.h"
 
 namespace __tsan {
 
@@ -54,12 +55,6 @@
 }
 
 void InitializeFlags(Flags *f, const char *env) {
-  FlagParser parser;
-  RegisterTsanFlags(&parser, f);
-  RegisterCommonFlags(&parser);
-
-  f->SetDefaults();
-
   SetCommonFlagsDefaults();
   {
     // Override some common flags defaults.
@@ -74,10 +69,32 @@
     OverrideCommonFlags(cf);
   }
 
+  f->SetDefaults();
+
+  FlagParser parser;
+  RegisterTsanFlags(&parser, f);
+  RegisterCommonFlags(&parser);
+
+#if TSAN_CONTAINS_UBSAN
+  __ubsan::Flags *uf = __ubsan::flags();
+  uf->SetDefaults();
+
+  FlagParser ubsan_parser;
+  __ubsan::RegisterUbsanFlags(&ubsan_parser, uf);
+  RegisterCommonFlags(&ubsan_parser);
+#endif
+
   // Let a frontend override.
   parser.ParseString(__tsan_default_options());
+#if TSAN_CONTAINS_UBSAN
+  const char *ubsan_default_options = __ubsan::MaybeCallUbsanDefaultOptions();
+  ubsan_parser.ParseString(ubsan_default_options);
+#endif
   // Override from command line.
   parser.ParseString(env);
+#if TSAN_CONTAINS_UBSAN
+  ubsan_parser.ParseString(GetEnv("UBSAN_OPTIONS"));
+#endif
 
   // Sanity check.
   if (!f->report_bugs) {
diff --git a/lib/tsan/rtl/tsan_interceptors.cc b/lib/tsan/rtl/tsan_interceptors.cc
index df4d5fd..ca3be64 100644
--- a/lib/tsan/rtl/tsan_interceptors.cc
+++ b/lib/tsan/rtl/tsan_interceptors.cc
@@ -20,6 +20,7 @@
 #include "sanitizer_common/sanitizer_placement_new.h"
 #include "sanitizer_common/sanitizer_stacktrace.h"
 #include "interception/interception.h"
+#include "tsan_interceptors.h"
 #include "tsan_interface.h"
 #include "tsan_platform.h"
 #include "tsan_suppressions.h"
@@ -31,10 +32,8 @@
 
 #if SANITIZER_FREEBSD
 #define __errno_location __error
-#define __libc_malloc __malloc
 #define __libc_realloc __realloc
 #define __libc_calloc __calloc
-#define __libc_free __free
 #define stdout __stdoutp
 #define stderr __stderrp
 #endif
@@ -78,10 +77,8 @@
 extern "C" void _exit(int status);
 extern "C" int *__errno_location();
 extern "C" int fileno_unlocked(void *stream);
-extern "C" void *__libc_malloc(uptr size);
 extern "C" void *__libc_calloc(uptr size, uptr n);
 extern "C" void *__libc_realloc(void *ptr, uptr size);
-extern "C" void __libc_free(void *ptr);
 extern "C" int dirfd(void *dirp);
 #if !SANITIZER_FREEBSD
 extern "C" int mallopt(int param, int value);
@@ -159,10 +156,6 @@
 #define COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED \
   (!cur_thread()->is_inited)
 
-namespace std {
-struct nothrow_t {};
-}  // namespace std
-
 static sigaction_t sigactions[kSigCount];
 
 namespace __tsan {
@@ -212,16 +205,6 @@
 
 static unsigned g_thread_finalize_key;
 
-class ScopedInterceptor {
- public:
-  ScopedInterceptor(ThreadState *thr, const char *fname, uptr pc);
-  ~ScopedInterceptor();
- private:
-  ThreadState *const thr_;
-  const uptr pc_;
-  bool in_ignored_lib_;
-};
-
 ScopedInterceptor::ScopedInterceptor(ThreadState *thr, const char *fname,
                                      uptr pc)
     : thr_(thr)
@@ -251,14 +234,6 @@
   }
 }
 
-#define SCOPED_INTERCEPTOR_RAW(func, ...) \
-    ThreadState *thr = cur_thread(); \
-    const uptr caller_pc = GET_CALLER_PC(); \
-    ScopedInterceptor si(thr, #func, caller_pc); \
-    const uptr pc = StackTrace::GetCurrentPc(); \
-    (void)pc; \
-/**/
-
 #define SCOPED_TSAN_INTERCEPTOR(func, ...) \
     SCOPED_INTERCEPTOR_RAW(func, __VA_ARGS__); \
     if (REAL(func) == 0) { \
@@ -598,73 +573,6 @@
   return user_alloc_usable_size(p);
 }
 
-#define OPERATOR_NEW_BODY(mangled_name) \
-  if (cur_thread()->in_symbolizer) \
-    return __libc_malloc(size); \
-  void *p = 0; \
-  {  \
-    SCOPED_INTERCEPTOR_RAW(mangled_name, size); \
-    p = user_alloc(thr, pc, size); \
-  }  \
-  invoke_malloc_hook(p, size);  \
-  return p;
-
-SANITIZER_INTERFACE_ATTRIBUTE
-void *operator new(__sanitizer::uptr size);
-void *operator new(__sanitizer::uptr size) {
-  OPERATOR_NEW_BODY(_Znwm);
-}
-
-SANITIZER_INTERFACE_ATTRIBUTE
-void *operator new[](__sanitizer::uptr size);
-void *operator new[](__sanitizer::uptr size) {
-  OPERATOR_NEW_BODY(_Znam);
-}
-
-SANITIZER_INTERFACE_ATTRIBUTE
-void *operator new(__sanitizer::uptr size, std::nothrow_t const&);
-void *operator new(__sanitizer::uptr size, std::nothrow_t const&) {
-  OPERATOR_NEW_BODY(_ZnwmRKSt9nothrow_t);
-}
-
-SANITIZER_INTERFACE_ATTRIBUTE
-void *operator new[](__sanitizer::uptr size, std::nothrow_t const&);
-void *operator new[](__sanitizer::uptr size, std::nothrow_t const&) {
-  OPERATOR_NEW_BODY(_ZnamRKSt9nothrow_t);
-}
-
-#define OPERATOR_DELETE_BODY(mangled_name) \
-  if (ptr == 0) return;  \
-  if (cur_thread()->in_symbolizer) \
-    return __libc_free(ptr); \
-  invoke_free_hook(ptr);  \
-  SCOPED_INTERCEPTOR_RAW(mangled_name, ptr);  \
-  user_free(thr, pc, ptr);
-
-SANITIZER_INTERFACE_ATTRIBUTE
-void operator delete(void *ptr) throw();
-void operator delete(void *ptr) throw() {
-  OPERATOR_DELETE_BODY(_ZdlPv);
-}
-
-SANITIZER_INTERFACE_ATTRIBUTE
-void operator delete[](void *ptr) throw();
-void operator delete[](void *ptr) throw() {
-  OPERATOR_DELETE_BODY(_ZdaPv);
-}
-
-SANITIZER_INTERFACE_ATTRIBUTE
-void operator delete(void *ptr, std::nothrow_t const&);
-void operator delete(void *ptr, std::nothrow_t const&) {
-  OPERATOR_DELETE_BODY(_ZdlPvRKSt9nothrow_t);
-}
-
-SANITIZER_INTERFACE_ATTRIBUTE
-void operator delete[](void *ptr, std::nothrow_t const&);
-void operator delete[](void *ptr, std::nothrow_t const&) {
-  OPERATOR_DELETE_BODY(_ZdaPvRKSt9nothrow_t);
-}
-
 TSAN_INTERCEPTOR(uptr, strlen, const char *s) {
   SCOPED_TSAN_INTERCEPTOR(strlen, s);
   uptr len = internal_strlen(s);
@@ -751,16 +659,6 @@
   return REAL(strncpy)(dst, src, n);
 }
 
-TSAN_INTERCEPTOR(const char*, strstr, const char *s1, const char *s2) {
-  SCOPED_TSAN_INTERCEPTOR(strstr, s1, s2);
-  const char *res = REAL(strstr)(s1, s2);
-  uptr len1 = internal_strlen(s1);
-  uptr len2 = internal_strlen(s2);
-  MemoryAccessRange(thr, pc, (uptr)s1, len1 + 1, false);
-  MemoryAccessRange(thr, pc, (uptr)s2, len2 + 1, false);
-  return res;
-}
-
 TSAN_INTERCEPTOR(char*, strdup, const char *str) {
   SCOPED_TSAN_INTERCEPTOR(strdup, str);
   // strdup will call malloc, so no instrumentation is required here.
@@ -935,8 +833,8 @@
     ThreadIgnoreEnd(thr, 0);
     while ((tid = atomic_load(&p->tid, memory_order_acquire)) == 0)
       pthread_yield();
-    atomic_store(&p->tid, 0, memory_order_release);
     ThreadStart(thr, tid, GetTid());
+    atomic_store(&p->tid, 0, memory_order_release);
   }
   void *res = callback(param);
   // Prevent the callback from being tail called,
@@ -984,6 +882,13 @@
   if (res == 0) {
     int tid = ThreadCreate(thr, pc, *(uptr*)th, detached);
     CHECK_NE(tid, 0);
+    // Synchronization on p.tid serves two purposes:
+    // 1. ThreadCreate must finish before the new thread starts.
+    //    Otherwise the new thread can call pthread_detach, but the pthread_t
+    //    identifier is not yet registered in ThreadRegistry by ThreadCreate.
+    // 2. ThreadStart must finish before this thread continues.
+    //    Otherwise, this thread can call pthread_detach and reset thr->sync
+    //    before the new thread got a chance to acquire from it in ThreadStart.
     atomic_store(&p.tid, tid, memory_order_release);
     while (atomic_load(&p.tid, memory_order_acquire) != 0)
       pthread_yield();
@@ -2370,6 +2275,14 @@
   HandleRecvmsg(((TsanInterceptorContext *)ctx)->thr, \
       ((TsanInterceptorContext *)ctx)->pc, msg)
 
+#define COMMON_INTERCEPTOR_GET_TLS_RANGE(begin, end)                           \
+  if (TsanThread *t = GetCurrentThread()) {                                    \
+    *begin = t->tls_begin();                                                   \
+    *end = t->tls_end();                                                       \
+  } else {                                                                     \
+    *begin = *end = 0;                                                         \
+  }
+
 #include "sanitizer_common/sanitizer_common_interceptors.inc"
 
 #define TSAN_SYSCALL() \
@@ -2549,7 +2462,6 @@
   TSAN_INTERCEPT(strrchr);
   TSAN_INTERCEPT(strcpy);  // NOLINT
   TSAN_INTERCEPT(strncpy);
-  TSAN_INTERCEPT(strstr);
   TSAN_INTERCEPT(strdup);
 
   TSAN_INTERCEPT(pthread_create);
diff --git a/lib/tsan/rtl/tsan_interceptors.h b/lib/tsan/rtl/tsan_interceptors.h
new file mode 100644
index 0000000..49b79a7
--- /dev/null
+++ b/lib/tsan/rtl/tsan_interceptors.h
@@ -0,0 +1,37 @@
+#ifndef TSAN_INTERCEPTORS_H
+#define TSAN_INTERCEPTORS_H
+
+#include "sanitizer_common/sanitizer_stacktrace.h"
+#include "tsan_rtl.h"
+
+namespace __tsan {
+
+class ScopedInterceptor {
+ public:
+  ScopedInterceptor(ThreadState *thr, const char *fname, uptr pc);
+  ~ScopedInterceptor();
+ private:
+  ThreadState *const thr_;
+  const uptr pc_;
+  bool in_ignored_lib_;
+};
+
+}  // namespace __tsan
+
+#define SCOPED_INTERCEPTOR_RAW(func, ...) \
+    ThreadState *thr = cur_thread(); \
+    const uptr caller_pc = GET_CALLER_PC(); \
+    ScopedInterceptor si(thr, #func, caller_pc); \
+    const uptr pc = StackTrace::GetCurrentPc(); \
+    (void)pc; \
+/**/
+
+#if SANITIZER_FREEBSD
+#define __libc_free __free
+#define __libc_malloc __malloc
+#endif
+
+extern "C" void __libc_free(void *ptr);
+extern "C" void *__libc_malloc(uptr size);
+
+#endif  // TSAN_INTERCEPTORS_H
diff --git a/lib/tsan/rtl/tsan_interface.cc b/lib/tsan/rtl/tsan_interface.cc
index 9bc9a69..809d2ab 100644
--- a/lib/tsan/rtl/tsan_interface.cc
+++ b/lib/tsan/rtl/tsan_interface.cc
@@ -38,6 +38,16 @@
   MemoryWrite(cur_thread(), CALLERPC, (uptr)addr + 8, kSizeLog8);
 }
 
+void __tsan_read16_pc(void *addr, void *pc) {
+  MemoryRead(cur_thread(), (uptr)pc, (uptr)addr, kSizeLog8);
+  MemoryRead(cur_thread(), (uptr)pc, (uptr)addr + 8, kSizeLog8);
+}
+
+void __tsan_write16_pc(void *addr, void *pc) {
+  MemoryWrite(cur_thread(), (uptr)pc, (uptr)addr, kSizeLog8);
+  MemoryWrite(cur_thread(), (uptr)pc, (uptr)addr + 8, kSizeLog8);
+}
+
 // __tsan_unaligned_read/write calls are emitted by compiler.
 
 void __tsan_unaligned_read2(const void *addr) {
diff --git a/lib/tsan/rtl/tsan_interface.h b/lib/tsan/rtl/tsan_interface.h
index a05e6f0..41e084b 100644
--- a/lib/tsan/rtl/tsan_interface.h
+++ b/lib/tsan/rtl/tsan_interface.h
@@ -51,6 +51,18 @@
 SANITIZER_INTERFACE_ATTRIBUTE void __tsan_unaligned_write8(void *addr);
 SANITIZER_INTERFACE_ATTRIBUTE void __tsan_unaligned_write16(void *addr);
 
+SANITIZER_INTERFACE_ATTRIBUTE void __tsan_read1_pc(void *addr, void *pc);
+SANITIZER_INTERFACE_ATTRIBUTE void __tsan_read2_pc(void *addr, void *pc);
+SANITIZER_INTERFACE_ATTRIBUTE void __tsan_read4_pc(void *addr, void *pc);
+SANITIZER_INTERFACE_ATTRIBUTE void __tsan_read8_pc(void *addr, void *pc);
+SANITIZER_INTERFACE_ATTRIBUTE void __tsan_read16_pc(void *addr, void *pc);
+
+SANITIZER_INTERFACE_ATTRIBUTE void __tsan_write1_pc(void *addr, void *pc);
+SANITIZER_INTERFACE_ATTRIBUTE void __tsan_write2_pc(void *addr, void *pc);
+SANITIZER_INTERFACE_ATTRIBUTE void __tsan_write4_pc(void *addr, void *pc);
+SANITIZER_INTERFACE_ATTRIBUTE void __tsan_write8_pc(void *addr, void *pc);
+SANITIZER_INTERFACE_ATTRIBUTE void __tsan_write16_pc(void *addr, void *pc);
+
 SANITIZER_INTERFACE_ATTRIBUTE void __tsan_vptr_read(void **vptr_p);
 SANITIZER_INTERFACE_ATTRIBUTE
 void __tsan_vptr_update(void **vptr_p, void *new_val);
diff --git a/lib/tsan/rtl/tsan_interface_inl.h b/lib/tsan/rtl/tsan_interface_inl.h
index 0187e49..8852aa3 100644
--- a/lib/tsan/rtl/tsan_interface_inl.h
+++ b/lib/tsan/rtl/tsan_interface_inl.h
@@ -50,6 +50,38 @@
   MemoryWrite(cur_thread(), CALLERPC, (uptr)addr, kSizeLog8);
 }
 
+void __tsan_read1_pc(void *addr, void *pc) {
+  MemoryRead(cur_thread(), (uptr)pc, (uptr)addr, kSizeLog1);
+}
+
+void __tsan_read2_pc(void *addr, void *pc) {
+  MemoryRead(cur_thread(), (uptr)pc, (uptr)addr, kSizeLog2);
+}
+
+void __tsan_read4_pc(void *addr, void *pc) {
+  MemoryRead(cur_thread(), (uptr)pc, (uptr)addr, kSizeLog4);
+}
+
+void __tsan_read8_pc(void *addr, void *pc) {
+  MemoryRead(cur_thread(), (uptr)pc, (uptr)addr, kSizeLog8);
+}
+
+void __tsan_write1_pc(void *addr, void *pc) {
+  MemoryWrite(cur_thread(), (uptr)pc, (uptr)addr, kSizeLog1);
+}
+
+void __tsan_write2_pc(void *addr, void *pc) {
+  MemoryWrite(cur_thread(), (uptr)pc, (uptr)addr, kSizeLog2);
+}
+
+void __tsan_write4_pc(void *addr, void *pc) {
+  MemoryWrite(cur_thread(), (uptr)pc, (uptr)addr, kSizeLog4);
+}
+
+void __tsan_write8_pc(void *addr, void *pc) {
+  MemoryWrite(cur_thread(), (uptr)pc, (uptr)addr, kSizeLog8);
+}
+
 void __tsan_vptr_update(void **vptr_p, void *new_val) {
   CHECK_EQ(sizeof(vptr_p), 8);
   if (*vptr_p != new_val) {
diff --git a/lib/tsan/rtl/tsan_new_delete.cc b/lib/tsan/rtl/tsan_new_delete.cc
new file mode 100644
index 0000000..2d9d044
--- /dev/null
+++ b/lib/tsan/rtl/tsan_new_delete.cc
@@ -0,0 +1,88 @@
+//===-- tsan_new_delete.cc ----------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file is a part of ThreadSanitizer (TSan), a race detector.
+//
+// Interceptors for operators new and delete.
+//===----------------------------------------------------------------------===//
+#include "sanitizer_common/sanitizer_internal_defs.h"
+#include "tsan_interceptors.h"
+
+using namespace __tsan;  // NOLINT
+
+namespace std {
+struct nothrow_t {};
+}  // namespace std
+
+#define OPERATOR_NEW_BODY(mangled_name) \
+  if (cur_thread()->in_symbolizer) \
+    return __libc_malloc(size); \
+  void *p = 0; \
+  {  \
+    SCOPED_INTERCEPTOR_RAW(mangled_name, size); \
+    p = user_alloc(thr, pc, size); \
+  }  \
+  invoke_malloc_hook(p, size);  \
+  return p;
+
+SANITIZER_INTERFACE_ATTRIBUTE
+void *operator new(__sanitizer::uptr size);
+void *operator new(__sanitizer::uptr size) {
+  OPERATOR_NEW_BODY(_Znwm);
+}
+
+SANITIZER_INTERFACE_ATTRIBUTE
+void *operator new[](__sanitizer::uptr size);
+void *operator new[](__sanitizer::uptr size) {
+  OPERATOR_NEW_BODY(_Znam);
+}
+
+SANITIZER_INTERFACE_ATTRIBUTE
+void *operator new(__sanitizer::uptr size, std::nothrow_t const&);
+void *operator new(__sanitizer::uptr size, std::nothrow_t const&) {
+  OPERATOR_NEW_BODY(_ZnwmRKSt9nothrow_t);
+}
+
+SANITIZER_INTERFACE_ATTRIBUTE
+void *operator new[](__sanitizer::uptr size, std::nothrow_t const&);
+void *operator new[](__sanitizer::uptr size, std::nothrow_t const&) {
+  OPERATOR_NEW_BODY(_ZnamRKSt9nothrow_t);
+}
+
+#define OPERATOR_DELETE_BODY(mangled_name) \
+  if (ptr == 0) return;  \
+  if (cur_thread()->in_symbolizer) \
+    return __libc_free(ptr); \
+  invoke_free_hook(ptr);  \
+  SCOPED_INTERCEPTOR_RAW(mangled_name, ptr);  \
+  user_free(thr, pc, ptr);
+
+SANITIZER_INTERFACE_ATTRIBUTE
+void operator delete(void *ptr) throw();
+void operator delete(void *ptr) throw() {
+  OPERATOR_DELETE_BODY(_ZdlPv);
+}
+
+SANITIZER_INTERFACE_ATTRIBUTE
+void operator delete[](void *ptr) throw();
+void operator delete[](void *ptr) throw() {
+  OPERATOR_DELETE_BODY(_ZdaPv);
+}
+
+SANITIZER_INTERFACE_ATTRIBUTE
+void operator delete(void *ptr, std::nothrow_t const&);
+void operator delete(void *ptr, std::nothrow_t const&) {
+  OPERATOR_DELETE_BODY(_ZdlPvRKSt9nothrow_t);
+}
+
+SANITIZER_INTERFACE_ATTRIBUTE
+void operator delete[](void *ptr, std::nothrow_t const&);
+void operator delete[](void *ptr, std::nothrow_t const&) {
+  OPERATOR_DELETE_BODY(_ZdaPvRKSt9nothrow_t);
+}
diff --git a/lib/tsan/rtl/tsan_platform_linux.cc b/lib/tsan/rtl/tsan_platform_linux.cc
index e408ba1..0359f5e 100644
--- a/lib/tsan/rtl/tsan_platform_linux.cc
+++ b/lib/tsan/rtl/tsan_platform_linux.cc
@@ -202,8 +202,8 @@
 
 void InitializeShadowMemory() {
   // Map memory shadow.
-  uptr shadow = (uptr)MmapFixedNoReserve(kShadowBeg,
-    kShadowEnd - kShadowBeg);
+  uptr shadow =
+      (uptr)MmapFixedNoReserve(kShadowBeg, kShadowEnd - kShadowBeg, "shadow");
   if (shadow != kShadowBeg) {
     Printf("FATAL: ThreadSanitizer can not mmap the shadow memory\n");
     Printf("FATAL: Make sure to compile with -fPIE and "
@@ -232,7 +232,8 @@
 
   // Map meta shadow.
   uptr meta_size = kMetaShadowEnd - kMetaShadowBeg;
-  uptr meta = (uptr)MmapFixedNoReserve(kMetaShadowBeg, meta_size);
+  uptr meta =
+      (uptr)MmapFixedNoReserve(kMetaShadowBeg, meta_size, "meta shadow");
   if (meta != kMetaShadowBeg) {
     Printf("FATAL: ThreadSanitizer can not mmap the shadow memory\n");
     Printf("FATAL: Make sure to compile with -fPIE and "
diff --git a/lib/tsan/rtl/tsan_report.cc b/lib/tsan/rtl/tsan_report.cc
index 18bad14..f4b0687 100644
--- a/lib/tsan/rtl/tsan_report.cc
+++ b/lib/tsan/rtl/tsan_report.cc
@@ -120,6 +120,7 @@
   for (int i = 0; frame && frame->info.address; frame = frame->next, i++) {
     InternalScopedString res(2 * GetPageSizeCached());
     RenderFrame(&res, common_flags()->stack_trace_format, i, frame->info,
+                common_flags()->symbolize_vs_style,
                 common_flags()->strip_path_prefix, "__interceptor_");
     Printf("%s\n", res.data());
   }
diff --git a/lib/tsan/rtl/tsan_rtl.cc b/lib/tsan/rtl/tsan_rtl.cc
index ee279a3..63c356b 100644
--- a/lib/tsan/rtl/tsan_rtl.cc
+++ b/lib/tsan/rtl/tsan_rtl.cc
@@ -24,6 +24,7 @@
 #include "tsan_mman.h"
 #include "tsan_suppressions.h"
 #include "tsan_symbolize.h"
+#include "ubsan/ubsan_init.h"
 
 #ifdef __SSE3__
 // <emmintrin.h> transitively includes <stdlib.h>,
@@ -66,9 +67,12 @@
 
 static ThreadContextBase *CreateThreadContext(u32 tid) {
   // Map thread trace when context is created.
-  MapThreadTrace(GetThreadTrace(tid), TraceSize() * sizeof(Event));
+  char name[50];
+  internal_snprintf(name, sizeof(name), "trace %u", tid);
+  MapThreadTrace(GetThreadTrace(tid), TraceSize() * sizeof(Event), name);
   const uptr hdr = GetThreadTraceHeader(tid);
-  MapThreadTrace(hdr, sizeof(Trace));
+  internal_snprintf(name, sizeof(name), "trace header %u", tid);
+  MapThreadTrace(hdr, sizeof(Trace), name);
   new((void*)hdr) Trace();
   // We are going to use only a small part of the trace with the default
   // value of history_size. However, the constructor writes to the whole trace.
@@ -236,7 +240,7 @@
   // Global data is not 64K aligned, but there are no adjacent mappings,
   // so we can get away with unaligned mapping.
   // CHECK_EQ(addr, addr & ~((64 << 10) - 1));  // windows wants 64K alignment
-  MmapFixedNoReserve(MemToShadow(addr), size * kShadowMultiplier);
+  MmapFixedNoReserve(MemToShadow(addr), size * kShadowMultiplier, "shadow");
 
   // Meta shadow is 2:1, so tread carefully.
   static bool data_mapped = false;
@@ -248,7 +252,7 @@
   if (!data_mapped) {
     // First call maps data+bss.
     data_mapped = true;
-    MmapFixedNoReserve(meta_begin, meta_end - meta_begin);
+    MmapFixedNoReserve(meta_begin, meta_end - meta_begin, "meta shadow");
   } else {
     // Mapping continous heap.
     // Windows wants 64K alignment.
@@ -258,19 +262,19 @@
       return;
     if (meta_begin < mapped_meta_end)
       meta_begin = mapped_meta_end;
-    MmapFixedNoReserve(meta_begin, meta_end - meta_begin);
+    MmapFixedNoReserve(meta_begin, meta_end - meta_begin, "meta shadow");
     mapped_meta_end = meta_end;
   }
   VPrintf(2, "mapped meta shadow for (%p-%p) at (%p-%p)\n",
       addr, addr+size, meta_begin, meta_end);
 }
 
-void MapThreadTrace(uptr addr, uptr size) {
+void MapThreadTrace(uptr addr, uptr size, const char *name) {
   DPrintf("#0: Mapping trace at %p-%p(0x%zx)\n", addr, addr + size, size);
   CHECK_GE(addr, kTraceMemBeg);
   CHECK_LE(addr + size, kTraceMemEnd);
   CHECK_EQ(addr, addr & ~((64 << 10) - 1));  // windows wants 64K alignment
-  uptr addr1 = (uptr)MmapFixedNoReserve(addr, size);
+  uptr addr1 = (uptr)MmapFixedNoReserve(addr, size, name);
   if (addr1 != addr) {
     Printf("FATAL: ThreadSanitizer can not mmap thread trace (%p/%p->%p)\n",
         addr, size, addr1);
@@ -315,6 +319,7 @@
   ctx = new(ctx_placeholder) Context;
   const char *options = GetEnv(kTsanOptionsEnv);
   InitializeFlags(&ctx->flags, options);
+  CacheBinaryName();
 #ifndef SANITIZER_GO
   InitializeAllocator();
 #endif
@@ -350,6 +355,9 @@
   int tid = ThreadCreate(thr, 0, 0, true);
   CHECK_EQ(tid, 0);
   ThreadStart(thr, tid, internal_getpid());
+#if TSAN_CONTAINS_UBSAN
+  __ubsan::InitAsPlugin();
+#endif
   ctx->initialized = true;
 
   if (flags()->stop_on_start) {
diff --git a/lib/tsan/rtl/tsan_rtl.h b/lib/tsan/rtl/tsan_rtl.h
index dde908a..a13e4b6 100644
--- a/lib/tsan/rtl/tsan_rtl.h
+++ b/lib/tsan/rtl/tsan_rtl.h
@@ -574,7 +574,7 @@
 }
 
 void MapShadow(uptr addr, uptr size);
-void MapThreadTrace(uptr addr, uptr size);
+void MapThreadTrace(uptr addr, uptr size, const char *name);
 void DontNeedShadowFor(uptr addr, uptr size);
 void InitializeShadowMemory();
 void InitializeInterceptors();
diff --git a/lib/tsan/rtl/tsan_update_shadow_word_inl.h b/lib/tsan/rtl/tsan_update_shadow_word_inl.h
index c80e0a8..6e3ac2f 100644
--- a/lib/tsan/rtl/tsan_update_shadow_word_inl.h
+++ b/lib/tsan/rtl/tsan_update_shadow_word_inl.h
@@ -38,7 +38,8 @@
     }
     StatInc(thr, StatShadowAnotherThread);
     if (HappensBefore(old, thr)) {
-      StoreIfNotYetStored(sp, &store_word);
+      if (old.IsRWWeakerOrEqual(kAccessIsWrite, kIsAtomic))
+        StoreIfNotYetStored(sp, &store_word);
       break;
     }
     if (old.IsBothReadsOrAtomic(kAccessIsWrite, kIsAtomic))
diff --git a/lib/ubsan/CMakeLists.txt b/lib/ubsan/CMakeLists.txt
index 08bb739..5314b57 100644
--- a/lib/ubsan/CMakeLists.txt
+++ b/lib/ubsan/CMakeLists.txt
@@ -28,20 +28,21 @@
 add_custom_target(ubsan)
 
 if(APPLE)
-  foreach(os ${SANITIZER_COMMON_SUPPORTED_DARWIN_OS})
-    # Common parts of UBSan runtime.
-    add_compiler_rt_darwin_object_library(RTUbsan ${os}
-      ARCH ${UBSAN_COMMON_SUPPORTED_ARCH}
-      SOURCES ${UBSAN_SOURCES} ${UBSAN_CXX_SOURCES}
-      CFLAGS ${UBSAN_CXXFLAGS})
+  # Common parts of UBSan runtime.
+  add_compiler_rt_object_libraries(RTUbsan
+    OS ${SANITIZER_COMMON_SUPPORTED_OS}
+    ARCH ${UBSAN_COMMON_SUPPORTED_ARCH}
+    SOURCES ${UBSAN_SOURCES} ${UBSAN_CXX_SOURCES}
+    CFLAGS ${UBSAN_CXXFLAGS})
 
-    if(COMPILER_RT_HAS_UBSAN)
-      # Initializer of standalone UBSan runtime.
-      add_compiler_rt_darwin_object_library(RTUbsan_standalone ${os}
-        ARCH ${UBSAN_SUPPORTED_ARCH}
-        SOURCES ${UBSAN_STANDALONE_SOURCES}
-        CFLAGS ${UBSAN_STANDALONE_CFLAGS})
-
+  if(COMPILER_RT_HAS_UBSAN)
+    # Initializer of standalone UBSan runtime.
+    add_compiler_rt_object_libraries(RTUbsan_standalone
+      OS ${SANITIZER_COMMON_SUPPORTED_OS}
+      ARCH ${UBSAN_SUPPORTED_ARCH}
+      SOURCES ${UBSAN_STANDALONE_SOURCES}
+      CFLAGS ${UBSAN_STANDALONE_CFLAGS})
+    foreach(os ${SANITIZER_COMMON_SUPPORTED_OS})
       add_compiler_rt_darwin_dynamic_runtime(clang_rt.ubsan_${os}_dynamic ${os}
         ARCH ${UBSAN_SUPPORTED_ARCH}
         SOURCES $<TARGET_OBJECTS:RTUbsan.${os}>
@@ -49,24 +50,26 @@
                 $<TARGET_OBJECTS:RTSanitizerCommon.${os}>)
 
       add_dependencies(ubsan clang_rt.ubsan_${os}_dynamic)
-    endif()
-  endforeach()
+    endforeach()
+  endif()
+
 else()
   # Common parts of UBSan runtime.
-  foreach(arch ${UBSAN_COMMON_SUPPORTED_ARCH})
-    add_compiler_rt_object_library(RTUbsan ${arch}
-      SOURCES ${UBSAN_SOURCES} CFLAGS ${UBSAN_CFLAGS})
-    # C++-specific parts of UBSan runtime. Requires a C++ ABI library.
-    add_compiler_rt_object_library(RTUbsan_cxx ${arch}
-      SOURCES ${UBSAN_CXX_SOURCES} CFLAGS ${UBSAN_CXXFLAGS})
-  endforeach()
+  add_compiler_rt_object_libraries(RTUbsan
+    ARCH ${UBSAN_COMMON_SUPPORTED_ARCH}
+    SOURCES ${UBSAN_SOURCES} CFLAGS ${UBSAN_CFLAGS})
+  # C++-specific parts of UBSan runtime. Requires a C++ ABI library.
+  add_compiler_rt_object_libraries(RTUbsan_cxx
+    ARCH ${UBSAN_COMMON_SUPPORTED_ARCH}
+    SOURCES ${UBSAN_CXX_SOURCES} CFLAGS ${UBSAN_CXXFLAGS})
 
   if(COMPILER_RT_HAS_UBSAN)
+    # Initializer of standalone UBSan runtime.
+    add_compiler_rt_object_libraries(RTUbsan_standalone
+      ARCH ${UBSAN_SUPPORTED_ARCH}
+      SOURCES ${UBSAN_STANDALONE_SOURCES} CFLAGS ${UBSAN_STANDALONE_CFLAGS})
+    
     foreach(arch ${UBSAN_SUPPORTED_ARCH})
-      # Initializer of standalone UBSan runtime.
-      add_compiler_rt_object_library(RTUbsan_standalone ${arch}
-        SOURCES ${UBSAN_STANDALONE_SOURCES} CFLAGS ${UBSAN_STANDALONE_CFLAGS})
-
       # Standalone UBSan runtimes.
       add_compiler_rt_runtime(clang_rt.ubsan_standalone-${arch} ${arch} STATIC
         SOURCES $<TARGET_OBJECTS:RTSanitizerCommon.${arch}>
diff --git a/lib/ubsan/ubsan_diag.cc b/lib/ubsan/ubsan_diag.cc
index 6f76c6a..a4c9e30 100644
--- a/lib/ubsan/ubsan_diag.cc
+++ b/lib/ubsan/ubsan_diag.cc
@@ -46,8 +46,7 @@
 static void MaybeReportErrorSummary(Location Loc) {
   if (!common_flags()->print_summary)
     return;
-  // Don't try to unwind the stack trace in UBSan summaries: just use the
-  // provided location.
+  const char *ErrorType = "undefined-behavior";
   if (Loc.isSourceLocation()) {
     SourceLocation SLoc = Loc.getSourceLocation();
     if (!SLoc.isInvalid()) {
@@ -56,12 +55,16 @@
       AI.line = SLoc.getLine();
       AI.column = SLoc.getColumn();
       AI.function = internal_strdup("");  // Avoid printing ?? as function name.
-      ReportErrorSummary("undefined-behavior", AI);
+      ReportErrorSummary(ErrorType, AI);
       AI.Clear();
       return;
     }
+  } else if (Loc.isSymbolizedStack()) {
+    const AddressInfo &AI = Loc.getSymbolizedStack()->info;
+    ReportErrorSummary(ErrorType, AI);
+    return;
   }
-  ReportErrorSummary("undefined-behavior");
+  ReportErrorSummary(ErrorType);
 }
 
 namespace {
@@ -118,7 +121,8 @@
       LocBuffer.append("<unknown>");
     else
       RenderSourceLocation(&LocBuffer, SLoc.getFilename(), SLoc.getLine(),
-                           SLoc.getColumn(), common_flags()->strip_path_prefix);
+                           SLoc.getColumn(), common_flags()->symbolize_vs_style,
+                           common_flags()->strip_path_prefix);
     break;
   }
   case Location::LK_Memory:
@@ -128,6 +132,7 @@
     const AddressInfo &Info = Loc.getSymbolizedStack()->info;
     if (Info.file) {
       RenderSourceLocation(&LocBuffer, Info.file, Info.line, Info.column,
+                           common_flags()->symbolize_vs_style,
                            common_flags()->strip_path_prefix);
     } else if (Info.module) {
       RenderModuleLocation(&LocBuffer, Info.module, Info.module_offset,
diff --git a/lib/ubsan/ubsan_init.cc b/lib/ubsan/ubsan_init.cc
index c3b8b6c..73398ce 100644
--- a/lib/ubsan/ubsan_init.cc
+++ b/lib/ubsan/ubsan_init.cc
@@ -37,6 +37,8 @@
 static void CommonStandaloneInit() {
   SanitizerToolName = "UndefinedBehaviorSanitizer";
   InitializeFlags();
+  CacheBinaryName();
+  __sanitizer_set_report_path(common_flags()->log_path);
   InitializeCoverage(common_flags()->coverage, common_flags()->coverage_dir);
   CommonInit();
   ubsan_mode = UBSAN_MODE_STANDALONE;
diff --git a/lib/ubsan/ubsan_init_standalone.cc b/lib/ubsan/ubsan_init_standalone.cc
index 47899a5..ff1a20e 100644
--- a/lib/ubsan/ubsan_init_standalone.cc
+++ b/lib/ubsan/ubsan_init_standalone.cc
@@ -16,6 +16,7 @@
 # error "UBSan is not supported on this platform!"
 #endif
 
+#include "sanitizer_common/sanitizer_internal_defs.h"
 #include "ubsan_init.h"
 
 #if SANITIZER_CAN_USE_PREINIT_ARRAY
diff --git a/make/platform/clang_darwin.mk b/make/platform/clang_darwin.mk
index 61250c7..e8349db 100644
--- a/make/platform/clang_darwin.mk
+++ b/make/platform/clang_darwin.mk
@@ -255,17 +255,31 @@
 LDFLAGS.ubsan_osx_dynamic += -isysroot $(OSX_SDK)
 endif
 
+ATOMIC_FUNCTIONS := \
+	atomic_flag_clear \
+	atomic_flag_clear_explicit \
+	atomic_flag_test_and_set \
+	atomic_flag_test_and_set_explicit \
+	atomic_signal_fence \
+	atomic_thread_fence
+
+FP16_FUNCTIONS := \
+	extendhfsf2 \
+	truncdfhf2 \
+	truncsfhf2
+
 FUNCTIONS.eprintf := eprintf
 FUNCTIONS.10.4 := eprintf floatundidf floatundisf floatundixf
 
-FUNCTIONS.ios	    := divmodsi4 udivmodsi4 mulosi4 mulodi4 muloti4
+FUNCTIONS.ios	    := divmodsi4 udivmodsi4 mulosi4 mulodi4 muloti4 \
+                       $(ATOMIC_FUNCTIONS) $(FP16_FUNCTIONS)
 # On x86, the divmod functions reference divsi.
 FUNCTIONS.ios.i386    := $(FUNCTIONS.ios) \
                          divsi3 udivsi3
 FUNCTIONS.ios.x86_64  := $(FUNCTIONS.ios.i386)
-FUNCTIONS.ios.arm64   := mulsc3 muldc3 divsc3 divdc3
+FUNCTIONS.ios.arm64   := mulsc3 muldc3 divsc3 divdc3 $(ATOMIC_FUNCTIONS)
 
-FUNCTIONS.osx	:= mulosi4 mulodi4 muloti4
+FUNCTIONS.osx	:= mulosi4 mulodi4 muloti4 $(ATOMIC_FUNCTIONS) $(FP16_FUNCTIONS)
 
 FUNCTIONS.profile_osx := GCDAProfiling InstrProfiling InstrProfilingBuffer \
                          InstrProfilingFile InstrProfilingPlatformDarwin \
@@ -319,6 +333,7 @@
 	udivmodsi4 \
 	do_global_dtors \
 	eprintf \
+	extendhfsf2 \
 	ffsdi2 \
 	fixdfdi \
 	fixsfdi \
@@ -349,6 +364,8 @@
 	powisf2 \
 	subvdi3 \
 	subvsi3 \
+	truncdfhf2 \
+	truncsfhf2 \
 	ucmpdi2 \
 	udiv_w_sdiv \
 	udivdi3 \
@@ -395,6 +412,7 @@
 	modsi3 \
 	muldf3 \
 	mulsf3 \
+	mulodi4 \
 	negdf2 \
 	negsf2 \
 	subdf3 \
diff --git a/make/platform/clang_macho_embedded.mk b/make/platform/clang_macho_embedded.mk
index 76e43e6..d7870d4 100644
--- a/make/platform/clang_macho_embedded.mk
+++ b/make/platform/clang_macho_embedded.mk
@@ -156,6 +156,7 @@
 	divsf3 \
 	divsi3 \
 	extendsfdf2 \
+	extendhfsf2 \
 	ffssi2 \
 	fixdfsi \
 	fixsfsi \
@@ -172,11 +173,19 @@
 	negsf2 \
 	subdf3 \
 	subsf3 \
+	truncdfhf2 \
 	truncdfsf2 \
+	truncsfhf2 \
 	udivsi3 \
 	umodsi3 \
 	unorddf2 \
-	unordsf2
+	unordsf2 \
+	atomic_flag_clear \
+	atomic_flag_clear_explicit \
+	atomic_flag_test_and_set \
+	atomic_flag_test_and_set_explicit \
+	atomic_signal_fence \
+	atomic_thread_fence
 
 ARM_FUNCTIONS := \
 	aeabi_cdcmpeq \
diff --git a/make/platform/darwin_bni.mk b/make/platform/darwin_bni.mk
index 2fd5089..8e066e8 100644
--- a/make/platform/darwin_bni.mk
+++ b/make/platform/darwin_bni.mk
@@ -32,7 +32,7 @@
 CFLAGS := -Wall -Os -fomit-frame-pointer -g $(DEPLOYMENT_FLAGS)
 CFLAGS.Static := $(CFLAGS) -static  
 DYLIB_FLAGS := $(DEPLOYMENT_FLAGS) \
-		-Xarch_arm -Wl,-alias_list,$(SRCROOT)/lib/arm/softfloat-alias.list
+		-Xarch_arm -Wl,-alias_list,$(SRCROOT)/lib/builtins/arm/softfloat-alias.list
 
 VISIBILITY_HIDDEN := 0
 VISIBILITY_HIDDEN.Static  := 1
@@ -47,7 +47,11 @@
              mulodi4 muloti4 mulsc3 mulvdi3 mulvsi3 negdi2 negvdi2 negvsi2 \
              paritydi2 paritysi2 popcountdi2 popcountsi2 powidf2 \
              powisf2 subvdi3 subvsi3 ucmpdi2 udivdi3 \
-             udivmoddi4 umoddi3 apple_versioning eprintf atomic
+             udivmoddi4 umoddi3 apple_versioning eprintf atomic \
+             atomic_flag_clear atomic_flag_clear_explicit \
+             atomic_flag_test_and_set atomic_flag_test_and_set_explicit \
+             atomic_signal_fence atomic_thread_fence \
+             extendhfsf2 truncdfhf2 truncsfhf2 
 
 FUNCTIONS.i386 := $(FUNCTIONS) \
                 divxc3 fixunsxfdi fixunsxfsi fixxfdi floatdixf \
@@ -124,5 +128,8 @@
 					fixdfti fixsfti \
 					fixunsdfti fixunssfti fixunssfti \
 					floattidf floattisf floatuntidf floatuntisf \
-					gcc_personality_v0 atomic
-
+					gcc_personality_v0 atomic \
+					atomic_flag_clear atomic_flag_clear_explicit \
+					atomic_flag_test_and_set \
+					atomic_flag_test_and_set_explicit \
+					atomic_signal_fence atomic_thread_fence
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
index 85a1735..ce715bb 100644
--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -58,6 +58,9 @@
     add_subdirectory(ubsan)
   endif()
   add_subdirectory(cfi)
+  if(COMPILER_RT_HAS_SAFESTACK)
+    add_subdirectory(safestack)
+  endif()
 endif()
 
 if(COMPILER_RT_STANDALONE_BUILD)
diff --git a/test/asan/CMakeLists.txt b/test/asan/CMakeLists.txt
index 08c1689..aff54db 100644
--- a/test/asan/CMakeLists.txt
+++ b/test/asan/CMakeLists.txt
@@ -28,6 +28,7 @@
     set(ASAN_TEST_TARGET_CFLAGS ${COMPILER_RT_TEST_COMPILER_CFLAGS})
   else()
     get_target_flags_for_arch(${arch} ASAN_TEST_TARGET_CFLAGS)
+    string(REPLACE ";" " " ASAN_TEST_TARGET_CFLAGS "${ASAN_TEST_TARGET_CFLAGS}")
   endif()
   if(ANDROID)
     set(ASAN_TEST_DYNAMIC True)
diff --git a/test/asan/TestCases/Android/coverage-android.cc b/test/asan/TestCases/Android/coverage-android.cc
index e243059..5f26316 100644
--- a/test/asan/TestCases/Android/coverage-android.cc
+++ b/test/asan/TestCases/Android/coverage-android.cc
@@ -1,15 +1,15 @@
 // Test for direct coverage writing with dlopen.
 
 // Test normal exit, coverage level 1.
-// RUN: %clangxx_asan -fsanitize-coverage=1 -DSHARED %s -shared -o %T/libcoverage_android_test_1.so -fPIC
-// RUN: %clangxx_asan -fsanitize-coverage=1 -DSO_DIR=\"%device\" %s -o %t
+// RUN: %clangxx_asan -fsanitize-coverage=func -DSHARED %s -shared -o %T/libcoverage_android_test_1.so -fPIC
+// RUN: %clangxx_asan -fsanitize-coverage=func -DSO_DIR=\"%device\" %s -o %t
 
 // RUN: adb shell rm -rf %device/coverage-android
 // RUN: rm -rf %T/coverage-android
 
 // RUN: adb shell mkdir -p %device/coverage-android/direct
 // RUN: mkdir -p %T/coverage-android/direct
-// RUN: ASAN_OPTIONS=coverage=1:coverage_direct=1:coverage_dir=%device/coverage-android/direct:verbosity=1 %run %t
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:coverage=1:coverage_direct=1:coverage_dir=%device/coverage-android/direct:verbosity=1 %run %t
 // RUN: adb pull %device/coverage-android/direct %T/coverage-android/direct
 // RUN: ls; pwd
 // RUN: cd %T/coverage-android/direct
@@ -18,15 +18,15 @@
 
 
 // Test sudden death, coverage level 1.
-// RUN: %clangxx_asan -fsanitize-coverage=1 -DSHARED -DKILL %s -shared -o %T/libcoverage_android_test_1.so -fPIC
-// RUN: %clangxx_asan -fsanitize-coverage=1 -DSO_DIR=\"%device\" %s -o %t
+// RUN: %clangxx_asan -fsanitize-coverage=func -DSHARED -DKILL %s -shared -o %T/libcoverage_android_test_1.so -fPIC
+// RUN: %clangxx_asan -fsanitize-coverage=func -DSO_DIR=\"%device\" %s -o %t
 
 // RUN: adb shell rm -rf %device/coverage-android-kill
 // RUN: rm -rf %T/coverage-android-kill
 
 // RUN: adb shell mkdir -p %device/coverage-android-kill/direct
 // RUN: mkdir -p %T/coverage-android-kill/direct
-// RUN: ASAN_OPTIONS=coverage=1:coverage_direct=1:coverage_dir=%device/coverage-android-kill/direct:verbosity=1 not %run %t
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:coverage=1:coverage_direct=1:coverage_dir=%device/coverage-android-kill/direct:verbosity=1 not %run %t
 // RUN: adb pull %device/coverage-android-kill/direct %T/coverage-android-kill/direct
 // RUN: ls; pwd
 // RUN: cd %T/coverage-android-kill/direct
@@ -35,15 +35,15 @@
 
 
 // Test normal exit, coverage level 2.
-// RUN: %clangxx_asan -fsanitize-coverage=2 -DSHARED %s -shared -o %T/libcoverage_android_test_1.so -fPIC
-// RUN: %clangxx_asan -fsanitize-coverage=2 -DSO_DIR=\"%device\" %s -o %t
+// RUN: %clangxx_asan -fsanitize-coverage=bb -DSHARED %s -shared -o %T/libcoverage_android_test_1.so -fPIC
+// RUN: %clangxx_asan -fsanitize-coverage=bb -DSO_DIR=\"%device\" %s -o %t
 
 // RUN: adb shell rm -rf %device/coverage-android
 // RUN: rm -rf %T/coverage-android
 
 // RUN: adb shell mkdir -p %device/coverage-android/direct
 // RUN: mkdir -p %T/coverage-android/direct
-// RUN: ASAN_OPTIONS=coverage=1:coverage_direct=1:coverage_dir=%device/coverage-android/direct:verbosity=1 %run %t
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:coverage=1:coverage_direct=1:coverage_dir=%device/coverage-android/direct:verbosity=1 %run %t
 // RUN: adb pull %device/coverage-android/direct %T/coverage-android/direct
 // RUN: ls; pwd
 // RUN: cd %T/coverage-android/direct
@@ -52,15 +52,15 @@
 
 
 // Test sudden death, coverage level 2.
-// RUN: %clangxx_asan -fsanitize-coverage=2 -DSHARED -DKILL %s -shared -o %T/libcoverage_android_test_1.so -fPIC
-// RUN: %clangxx_asan -fsanitize-coverage=2 -DSO_DIR=\"%device\" %s -o %t
+// RUN: %clangxx_asan -fsanitize-coverage=bb -DSHARED -DKILL %s -shared -o %T/libcoverage_android_test_1.so -fPIC
+// RUN: %clangxx_asan -fsanitize-coverage=bb -DSO_DIR=\"%device\" %s -o %t
 
 // RUN: adb shell rm -rf %device/coverage-android-kill
 // RUN: rm -rf %T/coverage-android-kill
 
 // RUN: adb shell mkdir -p %device/coverage-android-kill/direct
 // RUN: mkdir -p %T/coverage-android-kill/direct
-// RUN: ASAN_OPTIONS=coverage=1:coverage_direct=1:coverage_dir=%device/coverage-android-kill/direct:verbosity=1 not %run %t
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:coverage=1:coverage_direct=1:coverage_dir=%device/coverage-android-kill/direct:verbosity=1 not %run %t
 // RUN: adb pull %device/coverage-android-kill/direct %T/coverage-android-kill/direct
 // RUN: ls; pwd
 // RUN: cd %T/coverage-android-kill/direct
@@ -69,15 +69,15 @@
 
 
 // Test normal exit, coverage level 3.
-// RUN: %clangxx_asan -fsanitize-coverage=3 -DSHARED %s -shared -o %T/libcoverage_android_test_1.so -fPIC
-// RUN: %clangxx_asan -fsanitize-coverage=3 -DSO_DIR=\"%device\" %s -o %t
+// RUN: %clangxx_asan -fsanitize-coverage=edge -DSHARED %s -shared -o %T/libcoverage_android_test_1.so -fPIC
+// RUN: %clangxx_asan -fsanitize-coverage=edge -DSO_DIR=\"%device\" %s -o %t
 
 // RUN: adb shell rm -rf %device/coverage-android
 // RUN: rm -rf %T/coverage-android
 
 // RUN: adb shell mkdir -p %device/coverage-android/direct
 // RUN: mkdir -p %T/coverage-android/direct
-// RUN: ASAN_OPTIONS=coverage=1:coverage_direct=1:coverage_dir=%device/coverage-android/direct:verbosity=1 %run %t
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:coverage=1:coverage_direct=1:coverage_dir=%device/coverage-android/direct:verbosity=1 %run %t
 // RUN: adb pull %device/coverage-android/direct %T/coverage-android/direct
 // RUN: ls; pwd
 // RUN: cd %T/coverage-android/direct
@@ -86,15 +86,15 @@
 
 
 // Test sudden death, coverage level 3.
-// RUN: %clangxx_asan -fsanitize-coverage=3 -DSHARED -DKILL %s -shared -o %T/libcoverage_android_test_1.so -fPIC
-// RUN: %clangxx_asan -fsanitize-coverage=3 -DSO_DIR=\"%device\" %s -o %t
+// RUN: %clangxx_asan -fsanitize-coverage=edge -DSHARED -DKILL %s -shared -o %T/libcoverage_android_test_1.so -fPIC
+// RUN: %clangxx_asan -fsanitize-coverage=edge -DSO_DIR=\"%device\" %s -o %t
 
 // RUN: adb shell rm -rf %device/coverage-android-kill
 // RUN: rm -rf %T/coverage-android-kill
 
 // RUN: adb shell mkdir -p %device/coverage-android-kill/direct
 // RUN: mkdir -p %T/coverage-android-kill/direct
-// RUN: ASAN_OPTIONS=coverage=1:coverage_direct=1:coverage_dir=%device/coverage-android-kill/direct:verbosity=1 not %run %t
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:coverage=1:coverage_direct=1:coverage_dir=%device/coverage-android-kill/direct:verbosity=1 not %run %t
 // RUN: adb pull %device/coverage-android-kill/direct %T/coverage-android-kill/direct
 // RUN: ls; pwd
 // RUN: cd %T/coverage-android-kill/direct
diff --git a/test/asan/TestCases/Darwin/atos-symbolizer.cc b/test/asan/TestCases/Darwin/atos-symbolizer.cc
index a4df3a2..8da8422 100644
--- a/test/asan/TestCases/Darwin/atos-symbolizer.cc
+++ b/test/asan/TestCases/Darwin/atos-symbolizer.cc
@@ -1,10 +1,10 @@
 // Check that the `atos` symbolizer works.
 
 // RUN: %clangxx_asan -O0 %s -o %t 
-// RUN: ASAN_OPTIONS=verbosity=2 ASAN_SYMBOLIZER_PATH=$(which atos) not %run %t 2>&1 | FileCheck %s
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:verbosity=2 ASAN_SYMBOLIZER_PATH=$(which atos) not %run %t 2>&1 | FileCheck %s
 
 // Check that when having a DYLD_ROOT_PATH set, the symbolizer still works.
-// RUN: DYLD_ROOT_PATH="/" ASAN_OPTIONS=verbosity=2 ASAN_SYMBOLIZER_PATH=$(which atos) \
+// RUN: env DYLD_ROOT_PATH="/" ASAN_OPTIONS=$ASAN_OPTIONS:verbosity=2 ASAN_SYMBOLIZER_PATH=$(which atos) \
 // RUN:   not %run %t 2>&1 | FileCheck %s
 
 #include <stdlib.h>
diff --git a/test/asan/TestCases/Darwin/dladdr-demangling.cc b/test/asan/TestCases/Darwin/dladdr-demangling.cc
index 494007f..3d36c4f 100644
--- a/test/asan/TestCases/Darwin/dladdr-demangling.cc
+++ b/test/asan/TestCases/Darwin/dladdr-demangling.cc
@@ -3,7 +3,7 @@
 
 // RUN: %clangxx_asan -O0 %s -o %t 
 // RUN: not %run %t 2>&1 | FileCheck %s
-// RUN: ASAN_OPTIONS=verbosity=2 not %run sandbox-exec -p '(version 1)(allow default)(deny process-fork)' %t 2>&1 | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-DLADDR
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:verbosity=2 not %run sandbox-exec -p '(version 1)(allow default)(deny process-fork)' %t 2>&1 | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-DLADDR
 
 #include <stdlib.h>
 
diff --git a/test/asan/TestCases/Darwin/dyld_insert_libraries_reexec.cc b/test/asan/TestCases/Darwin/dyld_insert_libraries_reexec.cc
index 0bd4170..9210baf 100644
--- a/test/asan/TestCases/Darwin/dyld_insert_libraries_reexec.cc
+++ b/test/asan/TestCases/Darwin/dyld_insert_libraries_reexec.cc
@@ -7,10 +7,10 @@
 // RUN:   | sed -e 's/.*"\(.*libclang_rt.asan_osx_dynamic.dylib\)".*/\1/'` \
 // RUN:   %T/dyld_insert_libraries_reexec/libclang_rt.asan_osx_dynamic.dylib
 // RUN: %clangxx_asan %s -o %T/dyld_insert_libraries_reexec/a.out
-// RUN: DYLD_INSERT_LIBRARIES=@executable_path/libclang_rt.asan_osx_dynamic.dylib \
-// RUN:   ASAN_OPTIONS=verbosity=1 %run %T/dyld_insert_libraries_reexec/a.out 2>&1 \
+// RUN: env DYLD_INSERT_LIBRARIES=@executable_path/libclang_rt.asan_osx_dynamic.dylib \
+// RUN:   ASAN_OPTIONS=$ASAN_OPTIONS:verbosity=1 %run %T/dyld_insert_libraries_reexec/a.out 2>&1 \
 // RUN:   | FileCheck %s
-// RUN: ASAN_OPTIONS=verbosity=1 %run %T/dyld_insert_libraries_reexec/a.out 2>&1 \
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:verbosity=1 %run %T/dyld_insert_libraries_reexec/a.out 2>&1 \
 // RUN:   | FileCheck --check-prefix=CHECK-NOINSERT %s
 
 #include <stdio.h>
diff --git a/test/asan/TestCases/Darwin/reexec-insert-libraries-env.cc b/test/asan/TestCases/Darwin/reexec-insert-libraries-env.cc
index 59ddd63..aa4d92b 100644
--- a/test/asan/TestCases/Darwin/reexec-insert-libraries-env.cc
+++ b/test/asan/TestCases/Darwin/reexec-insert-libraries-env.cc
@@ -7,7 +7,7 @@
 // RUN:     -dynamiclib -o darwin-dummy-shared-lib-so.dylib
 
 // FIXME: the following command line may hang in the case of a regression.
-// RUN: DYLD_INSERT_LIBRARIES=darwin-dummy-shared-lib-so.dylib \
+// RUN: env DYLD_INSERT_LIBRARIES=darwin-dummy-shared-lib-so.dylib \
 // RUN:     %run %t 2>&1 | FileCheck %s || exit 1
 
 #if !defined(SHARED_LIB)
diff --git a/test/asan/TestCases/Darwin/sandbox-symbolizer.cc b/test/asan/TestCases/Darwin/sandbox-symbolizer.cc
index 4313371..4310f9c 100644
--- a/test/asan/TestCases/Darwin/sandbox-symbolizer.cc
+++ b/test/asan/TestCases/Darwin/sandbox-symbolizer.cc
@@ -6,11 +6,11 @@
 // RUN: %clangxx_asan -O0 %s -o %t 
 // RUN: not %run sandbox-exec -p '(version 1)(allow default)(deny process-fork)' %t 2>&1 | FileCheck %s
 // RUN: not %run sandbox-exec -p '(version 1)(allow default)(deny mach-priv-task-port)' %t 2>&1 | FileCheck %s
-// RUN: ASAN_SYMBOLIZER_PATH="" not %run sandbox-exec -p '(version 1)(allow default)(deny mach-priv-task-port)' %t 2>&1 | FileCheck %s
+// RUN: env ASAN_SYMBOLIZER_PATH="" not %run sandbox-exec -p '(version 1)(allow default)(deny mach-priv-task-port)' %t 2>&1 | FileCheck %s
 // RUN: %clangxx_asan -O3 %s -o %t 
 // RUN: not %run sandbox-exec -p '(version 1)(allow default)(deny process-fork)' %t 2>&1 | FileCheck %s
 // RUN: not %run sandbox-exec -p '(version 1)(allow default)(deny mach-priv-task-port)' %t 2>&1 | FileCheck %s
-// RUN: ASAN_SYMBOLIZER_PATH="" not %run sandbox-exec -p '(version 1)(allow default)(deny mach-priv-task-port)' %t 2>&1 | FileCheck %s
+// RUN: env ASAN_SYMBOLIZER_PATH="" not %run sandbox-exec -p '(version 1)(allow default)(deny mach-priv-task-port)' %t 2>&1 | FileCheck %s
 
 #include <stdlib.h>
 int main() {
diff --git a/test/asan/TestCases/Darwin/suppressions-darwin.cc b/test/asan/TestCases/Darwin/suppressions-darwin.cc
index fb37296..488bff1 100644
--- a/test/asan/TestCases/Darwin/suppressions-darwin.cc
+++ b/test/asan/TestCases/Darwin/suppressions-darwin.cc
@@ -4,17 +4,17 @@
 
 // Check that suppressing the interceptor by name works.
 // RUN: echo "interceptor_name:memmove" > %t.supp
-// RUN: ASAN_OPTIONS="suppressions='%t.supp'" %run %t 2>&1 | FileCheck --check-prefix=CHECK-IGNORE %s
+// RUN: env ASAN_OPTIONS="$ASAN_OPTIONS:suppressions='%t.supp'" %run %t 2>&1 | FileCheck --check-prefix=CHECK-IGNORE %s
 
 // Check that suppressing by interceptor name works even without the symbolizer
-// RUN: ASAN_OPTIONS="suppressions='%t.supp':symbolize=false" %run %t 2>&1 | FileCheck --check-prefix=CHECK-IGNORE %s
+// RUN: env ASAN_OPTIONS="$ASAN_OPTIONS:suppressions='%t.supp':symbolize=false" %run %t 2>&1 | FileCheck --check-prefix=CHECK-IGNORE %s
 
 // Check that suppressing all reports from a library works.
 // RUN: echo "interceptor_via_lib:CoreFoundation" > %t.supp
-// RUN: ASAN_OPTIONS="suppressions='%t.supp'" %run %t 2>&1 | FileCheck --check-prefix=CHECK-IGNORE %s
+// RUN: env ASAN_OPTIONS="$ASAN_OPTIONS:suppressions='%t.supp'" %run %t 2>&1 | FileCheck --check-prefix=CHECK-IGNORE %s
 
 // Check that suppressing library works even without the symbolizer.
-// RUN: ASAN_OPTIONS="suppressions='%t.supp':symbolize=false" %run %t 2>&1 | FileCheck --check-prefix=CHECK-IGNORE %s
+// RUN: env ASAN_OPTIONS="$ASAN_OPTIONS:suppressions='%t.supp':symbolize=false" %run %t 2>&1 | FileCheck --check-prefix=CHECK-IGNORE %s
 
 #include <CoreFoundation/CoreFoundation.h>
 
diff --git a/test/asan/TestCases/Darwin/suppressions-sandbox.cc b/test/asan/TestCases/Darwin/suppressions-sandbox.cc
index 59fe475..47d80f8 100644
--- a/test/asan/TestCases/Darwin/suppressions-sandbox.cc
+++ b/test/asan/TestCases/Darwin/suppressions-sandbox.cc
@@ -4,7 +4,7 @@
 
 // Check that suppressing a function name works within a no-fork sandbox
 // RUN: echo "interceptor_via_fun:CFStringCreateWithBytes" > %t.supp
-// RUN: ASAN_OPTIONS=suppressions=%t.supp \
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:suppressions=%t.supp \
 // RUN:   sandbox-exec -p '(version 1)(allow default)(deny process-fork)' \
 // RUN:   %run %t 2>&1 | FileCheck --check-prefix=CHECK-IGNORE %s
 
diff --git a/test/asan/TestCases/Darwin/unset-insert-libraries-on-exec.cc b/test/asan/TestCases/Darwin/unset-insert-libraries-on-exec.cc
index ed476b2..f8a330a 100644
--- a/test/asan/TestCases/Darwin/unset-insert-libraries-on-exec.cc
+++ b/test/asan/TestCases/Darwin/unset-insert-libraries-on-exec.cc
@@ -10,7 +10,7 @@
 // execl().
 
 // RUN: %run %t %T/echo-env >/dev/null 2>&1
-// RUN: DYLD_INSERT_LIBRARIES=%t-darwin-dummy-shared-lib-so.dylib \
+// RUN: env DYLD_INSERT_LIBRARIES=%t-darwin-dummy-shared-lib-so.dylib \
 // RUN:     %run %t %T/echo-env 2>&1 | FileCheck %s || exit 1
 
 #if !defined(SHARED_LIB)
diff --git a/test/asan/TestCases/Linux/asan_prelink_test.cc b/test/asan/TestCases/Linux/asan_prelink_test.cc
index 6145c01..9e58f83 100644
--- a/test/asan/TestCases/Linux/asan_prelink_test.cc
+++ b/test/asan/TestCases/Linux/asan_prelink_test.cc
@@ -7,7 +7,7 @@
 // RUN: %clangxx_asan -DBUILD_SO=1 -fPIC -shared %s -o %t.so -Wl,-Ttext-segment=0x3600000000 ||\
 // RUN: %clangxx_asan -DBUILD_SO=1 -fPIC -shared %s -o %t.so -Wl,-Ttext=0x3600000000
 // RUN: %clangxx_asan %t.o %t.so -Wl,-R. -o %t
-// RUN: ASAN_OPTIONS=verbosity=1 %run %t 2>&1 | FileCheck %s
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:verbosity=1 %run %t 2>&1 | FileCheck %s
 
 // GNU driver doesn't handle .so files properly.
 // REQUIRES: x86_64-supported-target, asan-64-bits, Clang
diff --git a/test/asan/TestCases/Linux/asan_preload_test-1.cc b/test/asan/TestCases/Linux/asan_preload_test-1.cc
index e5eab55..4e365b5 100644
--- a/test/asan/TestCases/Linux/asan_preload_test-1.cc
+++ b/test/asan/TestCases/Linux/asan_preload_test-1.cc
@@ -5,7 +5,7 @@
 // RUN: %clangxx %s %t.so -o %t
 //
 // RUN: %clangxx_asan -DBUILD_SO=1 -fPIC -shared %s -o %t.so
-// RUN: LD_PRELOAD=%shared_libasan not %run %t 2>&1 | FileCheck %s
+// RUN: env LD_PRELOAD=%shared_libasan not %run %t 2>&1 | FileCheck %s
 
 // REQUIRES: asan-dynamic-runtime
 
diff --git a/test/asan/TestCases/Linux/asan_preload_test-2.cc b/test/asan/TestCases/Linux/asan_preload_test-2.cc
index 0f22264..488fd52 100644
--- a/test/asan/TestCases/Linux/asan_preload_test-2.cc
+++ b/test/asan/TestCases/Linux/asan_preload_test-2.cc
@@ -1,7 +1,7 @@
 // Test that preloaded runtime works with unsanitized executables.
 //
 // RUN: %clangxx %s -o %t
-// RUN: LD_PRELOAD=%shared_libasan not %run %t 2>&1 | FileCheck %s
+// RUN: env LD_PRELOAD=%shared_libasan not %run %t 2>&1 | FileCheck %s
 
 // REQUIRES: asan-dynamic-runtime
 
diff --git a/test/asan/TestCases/Linux/asan_rt_confict_test-1.cc b/test/asan/TestCases/Linux/asan_rt_confict_test-1.cc
index 30f1c17..8cf761c 100644
--- a/test/asan/TestCases/Linux/asan_rt_confict_test-1.cc
+++ b/test/asan/TestCases/Linux/asan_rt_confict_test-1.cc
@@ -2,7 +2,7 @@
 // executable is prohibited.
 //
 // RUN: %clangxx_asan_static %s -o %t
-// RUN: LD_PRELOAD=%shared_libasan not %run %t 2>&1 | FileCheck %s
+// RUN: env LD_PRELOAD=%shared_libasan not %run %t 2>&1 | FileCheck %s
 
 // REQUIRES: asan-dynamic-runtime
 // XFAIL: android
diff --git a/test/asan/TestCases/Linux/coverage-missing.cc b/test/asan/TestCases/Linux/coverage-missing.cc
new file mode 100644
index 0000000..4c6ba26
--- /dev/null
+++ b/test/asan/TestCases/Linux/coverage-missing.cc
@@ -0,0 +1,84 @@
+// Test for "sancov.py missing ...".
+
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:coverage=1:coverage_dir=%T/coverage-missing
+
+// First case: coverage from executable. main() is called on every code path.
+// RUN: %clangxx_asan -fsanitize-coverage=func %s -o %t -DFOOBAR -DMAIN
+// RUN: rm -rf %T/coverage-missing
+// RUN: mkdir -p %T/coverage-missing
+// RUN: cd %T/coverage-missing
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS %t
+// RUN: %sancov print *.sancov > main.txt
+// RUN: rm *.sancov
+// RUN: [ $(cat main.txt | wc -l) == 1 ]
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS %t x
+// RUN: %sancov print *.sancov > foo.txt
+// RUN: rm *.sancov
+// RUN: [ $(cat foo.txt | wc -l) == 3 ]
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS %t x x
+// RUN: %sancov print *.sancov > bar.txt
+// RUN: rm *.sancov
+// RUN: [ $(cat bar.txt | wc -l) == 4 ]
+// RUN: %sancov missing %t < foo.txt > foo-missing.txt
+// RUN: sort main.txt foo-missing.txt -o foo-missing-with-main.txt
+// The "missing from foo" set may contain a few bogus PCs from the sanitizer
+// runtime, but it must include the entire "bar" code path as a subset. Sorted
+// lists can be tested for set inclusion with diff + grep.
+// RUN: ( diff bar.txt foo-missing-with-main.txt || true ) | not grep "^<"
+
+// Second case: coverage from DSO.
+// cd %T
+// RUN: %clangxx_asan -fsanitize-coverage=func %s -o %dynamiclib -DFOOBAR -shared -fPIC
+// RUN: %clangxx_asan -fsanitize-coverage=func %s %dynamiclib -o %t -DMAIN
+// RUN: env LIBNAME=`basename %dynamiclib`
+// RUN: rm -rf %T/coverage-missing
+// RUN: mkdir -p %T/coverage-missing
+// RUN: cd %T/coverage-missing
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS %t x
+// RUN: %sancov print $LIBNAME.*.sancov > foo.txt
+// RUN: rm *.sancov
+// RUN: [ $(cat foo.txt | wc -l) == 2 ]
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS %t x x
+// RUN: %sancov print $LIBNAME.*.sancov > bar.txt
+// RUN: rm *.sancov
+// RUN: [ $(cat bar.txt | wc -l) == 3 ]
+// RUN: %sancov missing %dynamiclib < foo.txt > foo-missing.txt
+// RUN: ( diff bar.txt foo-missing.txt || true ) | not grep "^<"
+
+// REQUIRES: x86_64-supported-target, i386-supported-target
+// XFAIL: android
+
+#include <stdio.h>
+
+void foo1();
+void foo2();
+void bar1();
+void bar2();
+void bar3();
+
+#if defined(FOOBAR)
+void foo1() { fprintf(stderr, "foo1\n"); }
+void foo2() { fprintf(stderr, "foo2\n"); }
+
+void bar1() { fprintf(stderr, "bar1\n"); }
+void bar2() { fprintf(stderr, "bar2\n"); }
+void bar3() { fprintf(stderr, "bar3\n"); }
+#endif
+
+#if defined(MAIN)
+int main(int argc, char **argv) {
+  switch (argc) {
+    case 1:
+      break;
+    case 2:
+      foo1();
+      foo2();
+      break;
+    case 3:
+      bar1();
+      bar2();
+      bar3();
+      break;
+  }
+}
+#endif
diff --git a/test/asan/TestCases/Linux/init-order-dlopen.cc b/test/asan/TestCases/Linux/init-order-dlopen.cc
index 17ba9d0..a04a84e 100644
--- a/test/asan/TestCases/Linux/init-order-dlopen.cc
+++ b/test/asan/TestCases/Linux/init-order-dlopen.cc
@@ -3,7 +3,7 @@
 
 // RUN: %clangxx_asan -O0 -DSHARED_LIB %s -fPIC -shared -o %t-so.so
 // RUN: %clangxx_asan -O0 %s %libdl -Wl,--export-dynamic -o %t
-// RUN: env ASAN_OPTIONS=strict_init_order=true %run %t 2>&1
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:strict_init_order=true %run %t 2>&1
 
 #if defined(SHARED_LIB)
 #include <stdio.h>
diff --git a/test/asan/TestCases/Linux/initialization-bug-any-order.cc b/test/asan/TestCases/Linux/initialization-bug-any-order.cc
index a462f4a..0f2fcca 100644
--- a/test/asan/TestCases/Linux/initialization-bug-any-order.cc
+++ b/test/asan/TestCases/Linux/initialization-bug-any-order.cc
@@ -4,9 +4,9 @@
 // strict init-order checking).
 
 // RUN: %clangxx_asan -O0 %s %p/../Helpers/initialization-bug-extra.cc -o %t
-// RUN: ASAN_OPTIONS=strict_init_order=true not %run %t 2>&1 | FileCheck %s
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:strict_init_order=true not %run %t 2>&1 | FileCheck %s
 // RUN: %clangxx_asan -O0 %p/../Helpers/initialization-bug-extra.cc %s -o %t
-// RUN: ASAN_OPTIONS=strict_init_order=true not %run %t 2>&1 | FileCheck %s
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:strict_init_order=true not %run %t 2>&1 | FileCheck %s
 
 // Do not test with optimization -- the error may be optimized away.
 
diff --git a/test/asan/TestCases/Linux/interface_symbols_linux.c b/test/asan/TestCases/Linux/interface_symbols_linux.c
index bec501b..9e87679 100644
--- a/test/asan/TestCases/Linux/interface_symbols_linux.c
+++ b/test/asan/TestCases/Linux/interface_symbols_linux.c
@@ -38,6 +38,8 @@
 // RUN: echo __asan_report_exp_store_n >> %t.interface
 // RUN: echo __asan_get_current_fake_stack >> %t.interface
 // RUN: echo __asan_addr_is_in_fake_stack >> %t.interface
+// RUN: echo __asan_alloca_poison >> %t.interface
+// RUN: echo __asan_allocas_unpoison >> %t.interface
 // RUN: cat %t.interface | sort -u | diff %t.symbols -
 
 // FIXME: nm -D on powerpc somewhy shows ASan interface symbols residing
diff --git a/test/asan/TestCases/Linux/kernel-area.cc b/test/asan/TestCases/Linux/kernel-area.cc
index 8dd509f..1b3fe07 100644
--- a/test/asan/TestCases/Linux/kernel-area.cc
+++ b/test/asan/TestCases/Linux/kernel-area.cc
@@ -4,17 +4,17 @@
 // Test that kernel area is not sanitized on 32-bit machines.
 //
 // RUN: %clangxx_asan %s -o %t
-// RUN: ASAN_OPTIONS=verbosity=1 %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-%kernel_bits
-// RUN: ASAN_OPTIONS=verbosity=1:full_address_space=0 %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-%kernel_bits
-// RUN: ASAN_OPTIONS=verbosity=1:full_address_space=1 %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-kernel-64-bits
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:verbosity=1 %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-%kernel_bits
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:verbosity=1:full_address_space=0 %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-%kernel_bits
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:verbosity=1:full_address_space=1 %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-kernel-64-bits
 //
-// CHECK-kernel-32-bits: || `[0x38000000, 0xbfffffff]` || HighMem    ||
-// CHECK-kernel-32-bits: || `[0x27000000, 0x37ffffff]` || HighShadow ||
-// CHECK-kernel-32-bits: || `[0x24000000, 0x26ffffff]` || ShadowGap  ||
+// CHECK-kernel-32-bits: || `[0x38{{0+}}, 0xb{{f+}}]` || HighMem    ||
+// CHECK-kernel-32-bits: || `[0x27{{0+}}, 0x37{{f+}}]` || HighShadow ||
+// CHECK-kernel-32-bits: || `[0x24{{0+}}, 0x26{{f+}}]` || ShadowGap  ||
 //
-// CHECK-kernel-64-bits: || `[0x40000000, 0xffffffff]` || HighMem    ||
-// CHECK-kernel-64-bits: || `[0x28000000, 0x3fffffff]` || HighShadow ||
-// CHECK-kernel-64-bits: || `[0x24000000, 0x27ffffff]` || ShadowGap  ||
+// CHECK-kernel-64-bits: || `[0x4{{0+}}, 0x{{f+}}]` || HighMem    ||
+// CHECK-kernel-64-bits: || `[0x28{{0+}}, 0x3{{f+}}]` || HighShadow ||
+// CHECK-kernel-64-bits: || `[0x24{{0+}}, 0x27{{f+}}]` || ShadowGap  ||
 //
 // REQUIRES: asan-32-bits
 
diff --git a/test/asan/TestCases/Linux/leak.cc b/test/asan/TestCases/Linux/leak.cc
index 36dc6dd..15c03b4 100644
--- a/test/asan/TestCases/Linux/leak.cc
+++ b/test/asan/TestCases/Linux/leak.cc
@@ -2,9 +2,9 @@
 // REQUIRES: leak-detection
 //
 // RUN: %clangxx_asan  %s -o %t
-// RUN: ASAN_OPTIONS=detect_leaks=1 not %run %t  2>&1 | FileCheck %s
-// RUN: ASAN_OPTIONS=""             not %run %t  2>&1 | FileCheck %s
-// RUN: ASAN_OPTIONS=detect_leaks=0     %run %t
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:detect_leaks=1 not %run %t  2>&1 | FileCheck %s
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS                not %run %t  2>&1 | FileCheck %s
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:detect_leaks=0     %run %t
 #include <stdio.h>
 int *t;
 
diff --git a/test/asan/TestCases/Linux/malloc-in-qsort.cc b/test/asan/TestCases/Linux/malloc-in-qsort.cc
index 80af409..f7c7c5f 100644
--- a/test/asan/TestCases/Linux/malloc-in-qsort.cc
+++ b/test/asan/TestCases/Linux/malloc-in-qsort.cc
@@ -1,6 +1,6 @@
 // RUN: %clangxx_asan -O2 %s -o %t
-// RUN: ASAN_OPTIONS=fast_unwind_on_malloc=1 not %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-FAST
-// RUN: ASAN_OPTIONS=fast_unwind_on_malloc=0 not %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-SLOW
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:fast_unwind_on_malloc=1 not %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-FAST
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:fast_unwind_on_malloc=0 not %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-SLOW
 
 // Test how well we unwind in presence of qsort in the stack
 // (i.e. if we can unwind through a function compiled w/o frame pointers).
diff --git a/test/asan/TestCases/Linux/malloc_delete_mismatch.cc b/test/asan/TestCases/Linux/malloc_delete_mismatch.cc
index 18d65ce..33d0ede 100644
--- a/test/asan/TestCases/Linux/malloc_delete_mismatch.cc
+++ b/test/asan/TestCases/Linux/malloc_delete_mismatch.cc
@@ -4,14 +4,14 @@
 // RUN: %clangxx_asan -g %s -o %t 2>&1
 
 // Find error and provide malloc context.
-// RUN: ASAN_OPTIONS=alloc_dealloc_mismatch=1 not %run %t 2>&1 | FileCheck %s --check-prefix=CHECK --check-prefix=ALLOC-STACK
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:alloc_dealloc_mismatch=1 not %run %t 2>&1 | FileCheck %s --check-prefix=CHECK --check-prefix=ALLOC-STACK
 
 // No error here.
-// RUN: ASAN_OPTIONS=alloc_dealloc_mismatch=0 %run %t
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:alloc_dealloc_mismatch=0 %run %t
 
 // Also works if no malloc context is available.
-// RUN: ASAN_OPTIONS=alloc_dealloc_mismatch=1:malloc_context_size=0:fast_unwind_on_malloc=0 not %run %t 2>&1 | FileCheck %s
-// RUN: ASAN_OPTIONS=alloc_dealloc_mismatch=1:malloc_context_size=0:fast_unwind_on_malloc=1 not %run %t 2>&1 | FileCheck %s
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:alloc_dealloc_mismatch=1:malloc_context_size=0:fast_unwind_on_malloc=0 not %run %t 2>&1 | FileCheck %s
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:alloc_dealloc_mismatch=1:malloc_context_size=0:fast_unwind_on_malloc=1 not %run %t 2>&1 | FileCheck %s
 // XFAIL: arm-linux-gnueabi
 // XFAIL: armv7l-unknown-linux-gnueabihf
 #include <stdlib.h>
diff --git a/test/asan/TestCases/Linux/nohugepage_test.cc b/test/asan/TestCases/Linux/nohugepage_test.cc
index 337b95d..aeb70c9 100644
--- a/test/asan/TestCases/Linux/nohugepage_test.cc
+++ b/test/asan/TestCases/Linux/nohugepage_test.cc
@@ -3,8 +3,8 @@
 // where asan consumed too much RAM due to transparent hugetables.
 //
 // RUN: %clangxx_asan -g %s -o %t
-// RUN: ASAN_OPTIONS=no_huge_pages_for_shadow=1 %run %t 2>&1 | FileCheck %s
-// RUN:                                         %run %t 2>&1 | FileCheck %s
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:no_huge_pages_for_shadow=1 %run %t 2>&1 | FileCheck %s
+// RUN:                                                                  %run %t 2>&1 | FileCheck %s
 //
 // Would be great to run the test with no_huge_pages_for_shadow=0, but
 // the result will depend on the OS version and settings...
diff --git a/test/asan/TestCases/Linux/odr-violation.cc b/test/asan/TestCases/Linux/odr-violation.cc
index ba13cdf..e9311d1 100644
--- a/test/asan/TestCases/Linux/odr-violation.cc
+++ b/test/asan/TestCases/Linux/odr-violation.cc
@@ -7,20 +7,20 @@
 // Different size: detect a bug if detect_odr_violation>=1
 // RUN: %clangxx_asan -DBUILD_SO=1 -fPIC -shared %s -o %t-ODR-SO.so
 // RUN: %clangxx_asan %s %t-ODR-SO.so -Wl,-R. -o %t-ODR-EXE
-// RUN: ASAN_OPTIONS=fast_unwind_on_malloc=0:detect_odr_violation=1 not %run %t-ODR-EXE 2>&1 | FileCheck %s
-// RUN: ASAN_OPTIONS=fast_unwind_on_malloc=0:detect_odr_violation=2 not %run %t-ODR-EXE 2>&1 | FileCheck %s
-// RUN: ASAN_OPTIONS=fast_unwind_on_malloc=0:detect_odr_violation=0     %run %t-ODR-EXE 2>&1 | FileCheck %s --check-prefix=DISABLED
-// RUN: ASAN_OPTIONS=fast_unwind_on_malloc=0                        not %run %t-ODR-EXE 2>&1 | FileCheck %s
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:fast_unwind_on_malloc=0:detect_odr_violation=1 not %run %t-ODR-EXE 2>&1 | FileCheck %s
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:fast_unwind_on_malloc=0:detect_odr_violation=2 not %run %t-ODR-EXE 2>&1 | FileCheck %s
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:fast_unwind_on_malloc=0:detect_odr_violation=0     %run %t-ODR-EXE 2>&1 | FileCheck %s --check-prefix=DISABLED
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:fast_unwind_on_malloc=0                        not %run %t-ODR-EXE 2>&1 | FileCheck %s
 //
 // Same size: report a bug only if detect_odr_violation>=2.
 // RUN: %clangxx_asan -DBUILD_SO=1 -fPIC -shared %s -o %t-ODR-SO.so -DSZ=100
-// RUN: ASAN_OPTIONS=fast_unwind_on_malloc=0:detect_odr_violation=1     %run %t-ODR-EXE 2>&1 | FileCheck %s --check-prefix=DISABLED
-// RUN: ASAN_OPTIONS=fast_unwind_on_malloc=0:detect_odr_violation=2 not %run %t-ODR-EXE 2>&1 | FileCheck %s
-// RUN: ASAN_OPTIONS=fast_unwind_on_malloc=0                        not %run %t-ODR-EXE 2>&1 | FileCheck %s
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:fast_unwind_on_malloc=0:detect_odr_violation=1     %run %t-ODR-EXE 2>&1 | FileCheck %s --check-prefix=DISABLED
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:fast_unwind_on_malloc=0:detect_odr_violation=2 not %run %t-ODR-EXE 2>&1 | FileCheck %s
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:fast_unwind_on_malloc=0                        not %run %t-ODR-EXE 2>&1 | FileCheck %s
 // RUN: echo "odr_violation:foo::ZZZ" > %t.supp
-// RUN: ASAN_OPTIONS=fast_unwind_on_malloc=0:detect_odr_violation=2:suppressions=%t.supp  not %run %t-ODR-EXE 2>&1 | FileCheck %s
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:fast_unwind_on_malloc=0:detect_odr_violation=2:suppressions=%t.supp  not %run %t-ODR-EXE 2>&1 | FileCheck %s
 // RUN: echo "odr_violation:foo::G" > %t.supp
-// RUN: ASAN_OPTIONS=fast_unwind_on_malloc=0:detect_odr_violation=2:suppressions=%t.supp      %run %t-ODR-EXE 2>&1 | FileCheck %s --check-prefix=DISABLED
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:fast_unwind_on_malloc=0:detect_odr_violation=2:suppressions=%t.supp      %run %t-ODR-EXE 2>&1 | FileCheck %s --check-prefix=DISABLED
 // RUN: rm -f %t.supp
 
 // GNU driver doesn't handle .so files properly.
diff --git a/test/asan/TestCases/Linux/overflow-in-qsort.cc b/test/asan/TestCases/Linux/overflow-in-qsort.cc
index 21bdff6..26fe67d 100644
--- a/test/asan/TestCases/Linux/overflow-in-qsort.cc
+++ b/test/asan/TestCases/Linux/overflow-in-qsort.cc
@@ -1,6 +1,6 @@
 // RUN: %clangxx_asan -O2 %s -o %t
-// RUN: ASAN_OPTIONS=fast_unwind_on_fatal=1 not %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-FAST
-// RUN: ASAN_OPTIONS=fast_unwind_on_fatal=0 not %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-SLOW
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:fast_unwind_on_fatal=1 not %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-FAST
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:fast_unwind_on_fatal=0 not %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-SLOW
 
 // Test how well we unwind in presence of qsort in the stack
 // (i.e. if we can unwind through a function compiled w/o frame pointers).
diff --git a/test/asan/TestCases/Linux/quarantine_size_mb.cc b/test/asan/TestCases/Linux/quarantine_size_mb.cc
index 4499992..1820cb9 100644
--- a/test/asan/TestCases/Linux/quarantine_size_mb.cc
+++ b/test/asan/TestCases/Linux/quarantine_size_mb.cc
@@ -1,10 +1,10 @@
 // Test quarantine_size_mb (and the deprecated quarantine_size)
 // RUN: %clangxx_asan  %s -o %t
-// RUN: ASAN_OPTIONS=quarantine_size=10485760:verbosity=1:hard_rss_limit_mb=50 %run %t  2>&1  | FileCheck %s  --check-prefix=Q10
-// RUN: ASAN_OPTIONS=quarantine_size_mb=10:verbosity=1:hard_rss_limit_mb=50    %run %t  2>&1  | FileCheck %s  --check-prefix=Q10
-// RUN: ASAN_OPTIONS=quarantine_size_mb=10:quarantine_size=20:verbosity=1  not  %run %t  2>&1 | FileCheck %s  --check-prefix=BOTH
-// RUN: ASAN_OPTIONS=quarantine_size_mb=1000:hard_rss_limit_mb=50 not  %run %t           2>&1 | FileCheck %s  --check-prefix=RSS_LIMIT
-// RUN: ASAN_OPTIONS=hard_rss_limit_mb=50                         not  %run %t           2>&1 | FileCheck %s  --check-prefix=RSS_LIMIT
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:quarantine_size=10485760:verbosity=1:hard_rss_limit_mb=50 %run %t  2>&1 | FileCheck %s  --check-prefix=Q10
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:quarantine_size_mb=10:verbosity=1:hard_rss_limit_mb=50    %run %t  2>&1 | FileCheck %s  --check-prefix=Q10
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:quarantine_size_mb=10:quarantine_size=20:verbosity=1  not %run %t  2>&1 | FileCheck %s  --check-prefix=BOTH
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:quarantine_size_mb=1000:hard_rss_limit_mb=50 not  %run %t          2>&1 | FileCheck %s  --check-prefix=RSS_LIMIT
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:hard_rss_limit_mb=50                         not  %run %t          2>&1 | FileCheck %s  --check-prefix=RSS_LIMIT
 #include <string.h>
 char *g;
 
diff --git a/test/asan/TestCases/Linux/sized_delete_test.cc b/test/asan/TestCases/Linux/sized_delete_test.cc
index 1401644..7dc8018 100644
--- a/test/asan/TestCases/Linux/sized_delete_test.cc
+++ b/test/asan/TestCases/Linux/sized_delete_test.cc
@@ -1,10 +1,10 @@
 // RUN: %clangxx_asan -fsized-deallocation -O0 %s -o %t
-// RUN:                                         not %run %t scalar 2>&1 | FileCheck %s -check-prefix=SCALAR
-// RUN: ASAN_OPTIONS=new_delete_type_mismatch=1 not %run %t scalar 2>&1 | FileCheck %s -check-prefix=SCALAR
-// RUN:                                         not %run %t array  2>&1 | FileCheck %s -check-prefix=ARRAY
-// RUN: ASAN_OPTIONS=new_delete_type_mismatch=1 not %run %t array  2>&1 | FileCheck %s -check-prefix=ARRAY
-// RUN: ASAN_OPTIONS=new_delete_type_mismatch=0     %run %t scalar
-// RUN: ASAN_OPTIONS=new_delete_type_mismatch=0     %run %t array
+// RUN:                                                                  not %run %t scalar 2>&1 | FileCheck %s -check-prefix=SCALAR
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:new_delete_type_mismatch=1 not %run %t scalar 2>&1 | FileCheck %s -check-prefix=SCALAR
+// RUN:                                                                  not %run %t array  2>&1 | FileCheck %s -check-prefix=ARRAY
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:new_delete_type_mismatch=1 not %run %t array  2>&1 | FileCheck %s -check-prefix=ARRAY
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:new_delete_type_mismatch=0     %run %t scalar
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:new_delete_type_mismatch=0     %run %t array
 
 // FIXME: the following two lines are not true after r232788.
 // Sized-delete is implemented with a weak delete() definition.
diff --git a/test/asan/TestCases/Linux/stack-overflow-sigbus.cc b/test/asan/TestCases/Linux/stack-overflow-sigbus.cc
index 5f597e9..23c4d23 100644
--- a/test/asan/TestCases/Linux/stack-overflow-sigbus.cc
+++ b/test/asan/TestCases/Linux/stack-overflow-sigbus.cc
@@ -1,6 +1,6 @@
 // Test ASan detection of stack-overflow condition when Linux sends SIGBUS.
 
-// RUN: %clangxx_asan -O0 %s -o %t && env ASAN_OPTIONS=use_sigaltstack=1 not %run %t 2>&1 | FileCheck %s
+// RUN: %clangxx_asan -O0 %s -o %t && env ASAN_OPTIONS=$ASAN_OPTIONS:use_sigaltstack=1 not %run %t 2>&1 | FileCheck %s
 
 #include <assert.h>
 #include <stdio.h>
diff --git a/test/asan/TestCases/Linux/stack-trace-dlclose.cc b/test/asan/TestCases/Linux/stack-trace-dlclose.cc
index b3bd9f7..66b57d4 100644
--- a/test/asan/TestCases/Linux/stack-trace-dlclose.cc
+++ b/test/asan/TestCases/Linux/stack-trace-dlclose.cc
@@ -3,7 +3,7 @@
 //
 // RUN: %clangxx_asan -DSHARED %s -shared -o %T/stack_trace_dlclose.so -fPIC
 // RUN: %clangxx_asan -DSO_DIR=\"%T\" %s %libdl -o %t
-// RUN: ASAN_OPTIONS=exitcode=0 %run %t 2>&1 | FileCheck %s
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:exitcode=0 %run %t 2>&1 | FileCheck %s
 // XFAIL: arm-linux-gnueabi
 // XFAIL: armv7l-unknown-linux-gnueabihf
 
diff --git a/test/asan/TestCases/Linux/static_tls.cc b/test/asan/TestCases/Linux/static_tls.cc
new file mode 100644
index 0000000..785228b
--- /dev/null
+++ b/test/asan/TestCases/Linux/static_tls.cc
@@ -0,0 +1,29 @@
+// REQUIRES: asan-64-bits
+// Regression test: __tls_get_addr interceptor must recognize static TLS.
+//
+// RUN: %clangxx_asan -DSHARED %s -shared -o %t-so.so -fPIC
+// RUN: %clangxx_asan %s -ldl -pthread -o %t %t-so.so
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:verbosity=2 %run %t 2>&1 | FileCheck %s
+
+// CHECK: before
+// CHECK: __tls_get_addr: static tls
+// CHECK: after
+
+// XFAIL: powerpc64
+
+#ifndef SHARED
+#include <stdio.h>
+
+unsigned *f();
+int main(int argc, char *argv[]) {
+  fprintf(stderr, "before\n");
+  f();
+  fprintf(stderr, "after\n");
+  return 0;
+}
+#else  // SHARED
+static __thread unsigned ThreadLocal;
+unsigned *f() {
+  return &ThreadLocal;
+}
+#endif
diff --git a/test/asan/TestCases/Linux/stress_dtls.c b/test/asan/TestCases/Linux/stress_dtls.c
index cb901ee..7af33b9 100644
--- a/test/asan/TestCases/Linux/stress_dtls.c
+++ b/test/asan/TestCases/Linux/stress_dtls.c
@@ -12,9 +12,9 @@
 // RUN: %clangxx_asan %s -ldl -pthread -o %t
 // RUN: %run %t 0 3
 // RUN: %run %t 2 3
-// RUN: ASAN_OPTIONS=verbosity=2 %run %t 10 2 2>&1 | FileCheck %s
-// RUN: ASAN_OPTIONS=verbosity=2:intercept_tls_get_addr=1 %run %t 10 2 2>&1 | FileCheck %s
-// RUN: ASAN_OPTIONS=verbosity=2:intercept_tls_get_addr=0 %run %t 10 2 2>&1 | FileCheck %s --check-prefix=CHECK0
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:verbosity=2 %run %t 10 2 2>&1 | FileCheck %s
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:verbosity=2:intercept_tls_get_addr=1 %run %t 10 2 2>&1 | FileCheck %s
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:verbosity=2:intercept_tls_get_addr=0 %run %t 10 2 2>&1 | FileCheck %s --check-prefix=CHECK0
 // CHECK: __tls_get_addr
 // CHECK: Creating thread 0
 // CHECK: __tls_get_addr
diff --git a/test/asan/TestCases/Posix/allow_user_segv.cc b/test/asan/TestCases/Posix/allow_user_segv.cc
index b6443fa..b299ae8 100644
--- a/test/asan/TestCases/Posix/allow_user_segv.cc
+++ b/test/asan/TestCases/Posix/allow_user_segv.cc
@@ -1,8 +1,8 @@
 // Regression test for
 // https://code.google.com/p/address-sanitizer/issues/detail?id=180
 
-// RUN: %clangxx_asan -O0 %s -o %t && ASAN_OPTIONS=allow_user_segv_handler=true not %run %t 2>&1 | FileCheck %s
-// RUN: %clangxx_asan -O2 %s -o %t && ASAN_OPTIONS=allow_user_segv_handler=true not %run %t 2>&1 | FileCheck %s
+// RUN: %clangxx_asan -O0 %s -o %t && ASAN_OPTIONS=$ASAN_OPTIONS:allow_user_segv_handler=true not %run %t 2>&1 | FileCheck %s
+// RUN: %clangxx_asan -O2 %s -o %t && ASAN_OPTIONS=$ASAN_OPTIONS:allow_user_segv_handler=true not %run %t 2>&1 | FileCheck %s
 
 #include <signal.h>
 #include <stdio.h>
diff --git a/test/asan/TestCases/Posix/asan-symbolize-sanity-test.cc b/test/asan/TestCases/Posix/asan-symbolize-sanity-test.cc
index 3ce6446..043130f 100644
--- a/test/asan/TestCases/Posix/asan-symbolize-sanity-test.cc
+++ b/test/asan/TestCases/Posix/asan-symbolize-sanity-test.cc
@@ -6,7 +6,7 @@
 
 // RUN: %clangxx_asan -O0 -DSHARED_LIB %s -fPIC -shared -o %t-so.so
 // RUN: %clangxx_asan -O0 %s %libdl -o %t
-// RUN: env ASAN_OPTIONS=symbolize=0 not %run %t 2>&1 | %asan_symbolize | FileCheck %s
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:symbolize=0 not %run %t 2>&1 | %asan_symbolize | FileCheck %s
 // XFAIL: arm-linux-gnueabi
 // XFAIL: armv7l-unknown-linux-gnueabihf
 
diff --git a/test/asan/TestCases/Posix/coverage-direct-activation.cc b/test/asan/TestCases/Posix/coverage-direct-activation.cc
index 05dc557..af73f5d 100644
--- a/test/asan/TestCases/Posix/coverage-direct-activation.cc
+++ b/test/asan/TestCases/Posix/coverage-direct-activation.cc
@@ -1,17 +1,17 @@
 // Test for direct coverage writing enabled at activation time.
 
-// RUN: %clangxx_asan -fsanitize-coverage=1 -DSHARED %s -shared -o %dynamiclib -fPIC
+// RUN: %clangxx_asan -fsanitize-coverage=func -DSHARED %s -shared -o %dynamiclib -fPIC
 // RUN: %clangxx -c -DSO_DIR=\"%T\" %s -o %t.o
-// RUN: %clangxx_asan -fsanitize-coverage=1 %t.o %libdl -o %t
+// RUN: %clangxx_asan -fsanitize-coverage=func %t.o %libdl -o %t
 
 // RUN: rm -rf %T/coverage-direct-activation
 
 // RUN: mkdir -p %T/coverage-direct-activation/normal
-// RUN: ASAN_OPTIONS=coverage=1,coverage_direct=0,coverage_dir=%T/coverage-direct-activation/normal:verbosity=1 %run %t %dynamiclib
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:coverage=1,coverage_direct=0,coverage_dir=%T/coverage-direct-activation/normal:verbosity=1 %run %t %dynamiclib
 // RUN: %sancov print %T/coverage-direct-activation/normal/*.sancov >%T/coverage-direct-activation/normal/out.txt
 
 // RUN: mkdir -p %T/coverage-direct-activation/direct
-// RUN: ASAN_OPTIONS=start_deactivated=1,coverage_direct=1,verbosity=1 \
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:start_deactivated=1,coverage_direct=1,verbosity=1 \
 // RUN:   ASAN_ACTIVATION_OPTIONS=coverage=1,coverage_dir=%T/coverage-direct-activation/direct %run %t %dynamiclib
 // RUN: cd %T/coverage-direct-activation/direct
 // RUN: %sancov rawunpack *.sancov.raw
@@ -23,7 +23,7 @@
 // RUN: diff -u coverage-direct-activation/normal/out.txt coverage-direct-activation/direct/out.txt
 
 // RUN: mkdir -p %T/coverage-direct-activation/direct2
-// RUN: ASAN_OPTIONS=start_deactivated=1,coverage=1,coverage_direct=1,verbosity=1 \
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:start_deactivated=1,coverage=1,coverage_direct=1,verbosity=1 \
 // RUN:   ASAN_ACTIVATION_OPTIONS=coverage_dir=%T/coverage-direct-activation/direct2 %run %t %dynamiclib
 // RUN: cd %T/coverage-direct-activation/direct2
 // RUN: %sancov rawunpack *.sancov.raw
diff --git a/test/asan/TestCases/Posix/coverage-direct-large.cc b/test/asan/TestCases/Posix/coverage-direct-large.cc
index cf7351d..2769172 100644
--- a/test/asan/TestCases/Posix/coverage-direct-large.cc
+++ b/test/asan/TestCases/Posix/coverage-direct-large.cc
@@ -2,18 +2,18 @@
 // Current implementation maps output file in chunks of 64K. This test overflows
 // 1 chunk.
 
-// RUN: %clangxx_asan -fsanitize-coverage=1 -O0 -DSHARED %s -shared -o %dynamiclib -fPIC
-// RUN: %clangxx_asan -fsanitize-coverage=1 -O0 %s %libdl -o %t
+// RUN: %clangxx_asan -fsanitize-coverage=func -O0 -DSHARED %s -shared -o %dynamiclib -fPIC
+// RUN: %clangxx_asan -fsanitize-coverage=func -O0 %s %libdl -o %t
 
 // RUN: rm -rf %T/coverage-direct-large
 
 // RUN: mkdir -p %T/coverage-direct-large/normal && cd %T/coverage-direct-large/normal
-// RUN: ASAN_OPTIONS=coverage=1:coverage_direct=0:verbosity=1 %run %t %dynamiclib
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:coverage=1:coverage_direct=0:verbosity=1 %run %t %dynamiclib
 // RUN: %sancov print *.sancov >out.txt
 // RUN: cd ../..
 
 // RUN: mkdir -p %T/coverage-direct-large/direct && cd %T/coverage-direct-large/direct
-// RUN: ASAN_OPTIONS=coverage=1:coverage_direct=1:verbosity=1 %run %t %dynamiclib
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:coverage=1:coverage_direct=1:verbosity=1 %run %t %dynamiclib
 // RUN: %sancov rawunpack *.sancov.raw
 // RUN: %sancov print *.sancov >out.txt
 // RUN: cd ../..
diff --git a/test/asan/TestCases/Posix/coverage-direct.cc b/test/asan/TestCases/Posix/coverage-direct.cc
index 60acbb7..5371a85 100644
--- a/test/asan/TestCases/Posix/coverage-direct.cc
+++ b/test/asan/TestCases/Posix/coverage-direct.cc
@@ -1,16 +1,16 @@
 // Test for direct coverage writing with dlopen at coverage level 1 to 3.
 
-// RUN: %clangxx_asan -fsanitize-coverage=1 -DSHARED %s -shared -o %dynamiclib -fPIC
-// RUN: %clangxx_asan -fsanitize-coverage=1 %s %libdl -o %t
+// RUN: %clangxx_asan -fsanitize-coverage=func -DSHARED %s -shared -o %dynamiclib -fPIC
+// RUN: %clangxx_asan -fsanitize-coverage=func %s %libdl -o %t
 
 // RUN: rm -rf %T/coverage-direct
 
 // RUN: mkdir -p %T/coverage-direct/normal
-// RUN: ASAN_OPTIONS=coverage=1:coverage_direct=0:coverage_dir=%T/coverage-direct/normal:verbosity=1 %run %t %dynamiclib
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:coverage=1:coverage_direct=0:coverage_dir=%T/coverage-direct/normal:verbosity=1 %run %t %dynamiclib
 // RUN: %sancov print %T/coverage-direct/normal/*.sancov >%T/coverage-direct/normal/out.txt
 
 // RUN: mkdir -p %T/coverage-direct/direct
-// RUN: ASAN_OPTIONS=coverage=1:coverage_direct=1:coverage_dir=%T/coverage-direct/direct:verbosity=1 %run %t %dynamiclib
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:coverage=1:coverage_direct=1:coverage_dir=%T/coverage-direct/direct:verbosity=1 %run %t %dynamiclib
 // RUN: cd %T/coverage-direct/direct
 // RUN: %sancov rawunpack *.sancov.raw
 // RUN: %sancov print *.sancov >out.txt
@@ -19,17 +19,17 @@
 // RUN: diff -u coverage-direct/normal/out.txt coverage-direct/direct/out.txt
 
 
-// RUN: %clangxx_asan -fsanitize-coverage=2 -DSHARED %s -shared -o %dynamiclib -fPIC
-// RUN: %clangxx_asan -fsanitize-coverage=2 -DSO_DIR=\"%T\" %s %libdl -o %t
+// RUN: %clangxx_asan -fsanitize-coverage=bb -DSHARED %s -shared -o %dynamiclib -fPIC
+// RUN: %clangxx_asan -fsanitize-coverage=bb -DSO_DIR=\"%T\" %s %libdl -o %t
 
 // RUN: rm -rf %T/coverage-direct
 
 // RUN: mkdir -p %T/coverage-direct/normal
-// RUN: ASAN_OPTIONS=coverage=1:coverage_direct=0:coverage_dir=%T/coverage-direct/normal:verbosity=1 %run %t %dynamiclib
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:coverage=1:coverage_direct=0:coverage_dir=%T/coverage-direct/normal:verbosity=1 %run %t %dynamiclib
 // RUN: %sancov print %T/coverage-direct/normal/*.sancov >%T/coverage-direct/normal/out.txt
 
 // RUN: mkdir -p %T/coverage-direct/direct
-// RUN: ASAN_OPTIONS=coverage=1:coverage_direct=1:coverage_dir=%T/coverage-direct/direct:verbosity=1 %run %t %dynamiclib
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:coverage=1:coverage_direct=1:coverage_dir=%T/coverage-direct/direct:verbosity=1 %run %t %dynamiclib
 // RUN: cd %T/coverage-direct/direct
 // RUN: %sancov rawunpack *.sancov.raw
 // RUN: %sancov print *.sancov >out.txt
@@ -38,17 +38,17 @@
 // RUN: diff -u coverage-direct/normal/out.txt coverage-direct/direct/out.txt
 
 
-// RUN: %clangxx_asan -fsanitize-coverage=3 -DSHARED %s -shared -o %dynamiclib -fPIC
-// RUN: %clangxx_asan -fsanitize-coverage=3 -DSO_DIR=\"%T\" %s %libdl -o %t
+// RUN: %clangxx_asan -fsanitize-coverage=edge -DSHARED %s -shared -o %dynamiclib -fPIC
+// RUN: %clangxx_asan -fsanitize-coverage=edge -DSO_DIR=\"%T\" %s %libdl -o %t
 
 // RUN: rm -rf %T/coverage-direct
 
 // RUN: mkdir -p %T/coverage-direct/normal
-// RUN: ASAN_OPTIONS=coverage=1:coverage_direct=0:coverage_dir=%T/coverage-direct/normal:verbosity=1 %run %t %dynamiclib
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:coverage=1:coverage_direct=0:coverage_dir=%T/coverage-direct/normal:verbosity=1 %run %t %dynamiclib
 // RUN: %sancov print %T/coverage-direct/normal/*.sancov >%T/coverage-direct/normal/out.txt
 
 // RUN: mkdir -p %T/coverage-direct/direct
-// RUN: ASAN_OPTIONS=coverage=1:coverage_direct=1:coverage_dir=%T/coverage-direct/direct:verbosity=1 %run %t %dynamiclib
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:coverage=1:coverage_direct=1:coverage_dir=%T/coverage-direct/direct:verbosity=1 %run %t %dynamiclib
 // RUN: cd %T/coverage-direct/direct
 // RUN: %sancov rawunpack *.sancov.raw
 // RUN: %sancov print *.sancov >out.txt
diff --git a/test/asan/TestCases/Posix/coverage-fork-direct.cc b/test/asan/TestCases/Posix/coverage-fork-direct.cc
index 51cbbd8..3936391 100644
--- a/test/asan/TestCases/Posix/coverage-fork-direct.cc
+++ b/test/asan/TestCases/Posix/coverage-fork-direct.cc
@@ -1,7 +1,7 @@
-// RUN: %clangxx_asan -fsanitize-coverage=1 %s -o %t
+// RUN: %clangxx_asan -fsanitize-coverage=func %s -o %t
 // RUN: rm -rf %T/coverage-fork-direct
 // RUN: mkdir -p %T/coverage-fork-direct && cd %T/coverage-fork-direct
-// RUN: (ASAN_OPTIONS=coverage=1:coverage_direct=1:verbosity=1 %run %t; \
+// RUN: (ASAN_OPTIONS=$ASAN_OPTIONS:coverage=1:coverage_direct=1:verbosity=1 %run %t; \
 // RUN:  %sancov rawunpack *.sancov.raw; %sancov print *.sancov) 2>&1
 //
 // XFAIL: android
diff --git a/test/asan/TestCases/Posix/coverage-fork.cc b/test/asan/TestCases/Posix/coverage-fork.cc
index 38c2009..c1f0fc3 100644
--- a/test/asan/TestCases/Posix/coverage-fork.cc
+++ b/test/asan/TestCases/Posix/coverage-fork.cc
@@ -1,5 +1,5 @@
-// RUN: %clangxx_asan -fsanitize-coverage=1 %s -o %t
-// RUN: export ASAN_OPTIONS=coverage=1:coverage_direct=0:verbosity=1
+// RUN: %clangxx_asan -fsanitize-coverage=func %s -o %t
+// RUN: export ASAN_OPTIONS=$ASAN_OPTIONS:coverage=1:coverage_direct=0:verbosity=1
 // RUN: rm -rf %T/coverage-fork
 // RUN: mkdir -p %T/coverage-fork && cd %T/coverage-fork
 // RUN: %run %t 2>&1 | FileCheck %s
diff --git a/test/asan/TestCases/Posix/coverage-module-unloaded.cc b/test/asan/TestCases/Posix/coverage-module-unloaded.cc
index 26ef479..fe08bdd 100644
--- a/test/asan/TestCases/Posix/coverage-module-unloaded.cc
+++ b/test/asan/TestCases/Posix/coverage-module-unloaded.cc
@@ -1,9 +1,9 @@
 // Check that unloading a module doesn't break coverage dumping for remaining
 // modules.
-// RUN: %clangxx_asan -fsanitize-coverage=1 -DSHARED %s -shared -o %dynamiclib1 -fPIC
-// RUN: %clangxx_asan -fsanitize-coverage=1 -DSHARED %s -shared -o %dynamiclib2 -fPIC
-// RUN: %clangxx_asan -fsanitize-coverage=1 %s %libdl -o %t
-// RUN: export ASAN_OPTIONS=coverage=1:verbosity=1
+// RUN: %clangxx_asan -fsanitize-coverage=func -DSHARED %s -shared -o %dynamiclib1 -fPIC
+// RUN: %clangxx_asan -fsanitize-coverage=func -DSHARED %s -shared -o %dynamiclib2 -fPIC
+// RUN: %clangxx_asan -fsanitize-coverage=func %s %libdl -o %t
+// RUN: export ASAN_OPTIONS=$ASAN_OPTIONS:coverage=1:verbosity=1
 // RUN: mkdir -p %T/coverage-module-unloaded && cd %T/coverage-module-unloaded
 // RUN: %run %t %dynamiclib1 %dynamiclib2 2>&1        | FileCheck %s
 // RUN: %run %t %dynamiclib1 %dynamiclib2 foo 2>&1    | FileCheck %s
diff --git a/test/asan/TestCases/Posix/coverage-sandboxing.cc b/test/asan/TestCases/Posix/coverage-sandboxing.cc
index 8f1c1ee..dd2c1ec 100644
--- a/test/asan/TestCases/Posix/coverage-sandboxing.cc
+++ b/test/asan/TestCases/Posix/coverage-sandboxing.cc
@@ -1,6 +1,6 @@
-// RUN: %clangxx_asan -fsanitize-coverage=2 -DSHARED %s -shared -o %dynamiclib -fPIC %ld_flags_rpath_so
-// RUN: %clangxx_asan -fsanitize-coverage=1 %s -o %t %ld_flags_rpath_exe
-// RUN: export ASAN_OPTIONS=coverage=1:verbosity=1
+// RUN: %clangxx_asan -fsanitize-coverage=bb -DSHARED %s -shared -o %dynamiclib -fPIC %ld_flags_rpath_so
+// RUN: %clangxx_asan -fsanitize-coverage=func %s -o %t %ld_flags_rpath_exe
+// RUN: export ASAN_OPTIONS=$ASAN_OPTIONS:coverage=1:verbosity=1
 // RUN: rm -rf %T/coverage_sandboxing_test
 // RUN: mkdir %T/coverage_sandboxing_test && cd %T/coverage_sandboxing_test
 // RUN: mkdir vanilla && cd vanilla
diff --git a/test/asan/TestCases/Posix/coverage.cc b/test/asan/TestCases/Posix/coverage.cc
index 7b59015..99e348f 100644
--- a/test/asan/TestCases/Posix/coverage.cc
+++ b/test/asan/TestCases/Posix/coverage.cc
@@ -1,6 +1,6 @@
-// RUN: %clangxx_asan -fsanitize-coverage=1 -DSHARED %s -shared -o %dynamiclib -fPIC %ld_flags_rpath_so
-// RUN: %clangxx_asan -fsanitize-coverage=1 %s %ld_flags_rpath_exe -o %t
-// RUN: export ASAN_OPTIONS=coverage=1:verbosity=1
+// RUN: %clangxx_asan -fsanitize-coverage=func -DSHARED %s -shared -o %dynamiclib -fPIC %ld_flags_rpath_so
+// RUN: %clangxx_asan -fsanitize-coverage=func %s %ld_flags_rpath_exe -o %t
+// RUN: export ASAN_OPTIONS=$ASAN_OPTIONS:coverage=1:verbosity=1
 // RUN: rm -rf %T/coverage && mkdir -p %T/coverage && cd %T/coverage
 // RUN: %run %t 2>&1         | FileCheck %s --check-prefix=CHECK-main
 // RUN: %sancov print `ls coverage.*sancov | grep -v '.so'` 2>&1 | FileCheck %s --check-prefix=CHECK-SANCOV1
diff --git a/test/asan/TestCases/Posix/ioctl.cc b/test/asan/TestCases/Posix/ioctl.cc
index 78f152f..d25f6ec 100644
--- a/test/asan/TestCases/Posix/ioctl.cc
+++ b/test/asan/TestCases/Posix/ioctl.cc
@@ -1,5 +1,5 @@
-// RUN: %clangxx_asan -O0 -g %s -o %t && ASAN_OPTIONS=handle_ioctl=1 not %run %t 2>&1 | FileCheck %s
-// RUN: %clangxx_asan -O3 -g %s -o %t && ASAN_OPTIONS=handle_ioctl=1 not %run %t 2>&1 | FileCheck %s
+// RUN: %clangxx_asan -O0 -g %s -o %t && ASAN_OPTIONS=$ASAN_OPTIONS:handle_ioctl=1 not %run %t 2>&1 | FileCheck %s
+// RUN: %clangxx_asan -O3 -g %s -o %t && ASAN_OPTIONS=$ASAN_OPTIONS:handle_ioctl=1 not %run %t 2>&1 | FileCheck %s
 
 // RUN: %clangxx_asan -O0 -g %s -o %t && %run %t
 // RUN: %clangxx_asan -O3 -g %s -o %t && %run %t
diff --git a/test/asan/TestCases/Posix/large_allocator_unpoisons_on_free.cc b/test/asan/TestCases/Posix/large_allocator_unpoisons_on_free.cc
index f852a62..b1c9943 100644
--- a/test/asan/TestCases/Posix/large_allocator_unpoisons_on_free.cc
+++ b/test/asan/TestCases/Posix/large_allocator_unpoisons_on_free.cc
@@ -2,7 +2,7 @@
 // RUN: %clangxx_asan %s -o %t
 // The memory is released only when the deallocated chunk leaves the quarantine,
 // otherwise the mmap(p, ...) call overwrites the malloc header.
-// RUN: ASAN_OPTIONS=quarantine_size_mb=0 %run %t
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:quarantine_size_mb=0 %run %t
 
 #include <assert.h>
 #include <string.h>
diff --git a/test/asan/TestCases/Posix/log_path_fork_test.cc.disabled b/test/asan/TestCases/Posix/log_path_fork_test.cc.disabled
index cfe90df..9f09b78 100644
--- a/test/asan/TestCases/Posix/log_path_fork_test.cc.disabled
+++ b/test/asan/TestCases/Posix/log_path_fork_test.cc.disabled
@@ -1,7 +1,7 @@
 // RUN: %clangxx_asan  %s -o %t
 // RUN: rm -f %t.log.*
 // Set verbosity to 1 so that the log files are opened prior to fork().
-// RUN: env ASAN_OPTIONS="log_path=%t.log verbosity=1" not %run %t 2> %t.out
+// RUN: env ASAN_OPTIONS="$ASAN_OPTIONS:log_path=%t.log verbosity=1" not %run %t 2> %t.out
 // RUN: for f in %t.log.* ; do FileCheck %s < $f; done
 // RUN: [ `ls %t.log.* | wc -l` == 2 ]
 
diff --git a/test/asan/TestCases/Posix/new_array_cookie_test.cc b/test/asan/TestCases/Posix/new_array_cookie_test.cc
index 85d51f3..bc68185 100644
--- a/test/asan/TestCases/Posix/new_array_cookie_test.cc
+++ b/test/asan/TestCases/Posix/new_array_cookie_test.cc
@@ -1,8 +1,8 @@
 // REQUIRES: asan-64-bits
 // RUN: %clangxx_asan -O3 %s -o %t
 // RUN:                                    not %run %t 2>&1  | FileCheck %s
-// RUN: ASAN_OPTIONS=poison_array_cookie=1 not %run %t 2>&1  | FileCheck %s
-// RUN: ASAN_OPTIONS=poison_array_cookie=0 not %run %t 2>&1  | FileCheck %s --check-prefix=NO_COOKIE
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:poison_array_cookie=1 not %run %t 2>&1  | FileCheck %s
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:poison_array_cookie=0 not %run %t 2>&1  | FileCheck %s --check-prefix=NO_COOKIE
 #include <stdio.h>
 #include <stdlib.h>
 struct C {
diff --git a/test/asan/TestCases/Posix/new_array_cookie_uaf_test.cc b/test/asan/TestCases/Posix/new_array_cookie_uaf_test.cc
index c35cceb..5998d06 100644
--- a/test/asan/TestCases/Posix/new_array_cookie_uaf_test.cc
+++ b/test/asan/TestCases/Posix/new_array_cookie_uaf_test.cc
@@ -1,7 +1,7 @@
 // REQUIRES: asan-64-bits
 // RUN: %clangxx_asan -O3 %s -o %t
-// RUN: ASAN_OPTIONS=poison_array_cookie=1 not %run %t 2>&1  | FileCheck %s --check-prefix=COOKIE
-// RUN: ASAN_OPTIONS=poison_array_cookie=0 not %run %t 2>&1  | FileCheck %s --check-prefix=NO_COOKIE
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:poison_array_cookie=1 not %run %t 2>&1  | FileCheck %s --check-prefix=COOKIE
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:poison_array_cookie=0 not %run %t 2>&1  | FileCheck %s --check-prefix=NO_COOKIE
 #include <stdio.h>
 #include <stdlib.h>
 #include <assert.h>
diff --git a/test/asan/TestCases/Posix/start-deactivated.cc b/test/asan/TestCases/Posix/start-deactivated.cc
index 2eb02df..2ca8015 100644
--- a/test/asan/TestCases/Posix/start-deactivated.cc
+++ b/test/asan/TestCases/Posix/start-deactivated.cc
@@ -5,17 +5,17 @@
 // RUN: %clangxx_asan -O0 -DSHARED_LIB %s -fPIC -shared -o %t-so.so
 // RUN: %clangxx -O0 %s -c -o %t.o
 // RUN: %clangxx_asan -O0 %t.o %libdl -o %t
-// RUN: ASAN_OPTIONS=start_deactivated=1,allocator_may_return_null=0 \
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:start_deactivated=1,allocator_may_return_null=0 \
 // RUN:   ASAN_ACTIVATION_OPTIONS=allocator_may_return_null=1 not %run %t 2>&1 | FileCheck %s --check-prefix=CHECK
-// RUN: ASAN_OPTIONS=start_deactivated=1 \
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:start_deactivated=1 \
 // RUN:   ASAN_ACTIVATION_OPTIONS=help=1 not %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-HELP
-// RUN: ASAN_OPTIONS=start_deactivated=1,verbosity=1 \
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:start_deactivated=1,verbosity=1 \
 // RUN:   ASAN_ACTIVATION_OPTIONS=help=1,handle_segv=0 not %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-UNSUPPORTED
-// RUN: ASAN_OPTIONS=start_deactivated=1 \
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:start_deactivated=1 \
 // RUN:   ASAN_ACTIVATION_OPTIONS=help=1,handle_segv=0 not %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-UNSUPPORTED-V0
 
 // Check that verbosity=1 in activation flags affects reporting of unrecognized activation flags.
-// RUN: ASAN_OPTIONS=start_deactivated=1 \
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:start_deactivated=1 \
 // RUN:   ASAN_ACTIVATION_OPTIONS=help=1,handle_segv=0,verbosity=1 not %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-UNSUPPORTED
 
 // XFAIL: arm-linux-gnueabi
diff --git a/test/asan/TestCases/Posix/tsd_dtor_leak.cc b/test/asan/TestCases/Posix/tsd_dtor_leak.cc
index 6952245..69d2819 100644
--- a/test/asan/TestCases/Posix/tsd_dtor_leak.cc
+++ b/test/asan/TestCases/Posix/tsd_dtor_leak.cc
@@ -1,7 +1,7 @@
 // Regression test for a leak in tsd:
 // https://code.google.com/p/address-sanitizer/issues/detail?id=233
 // RUN: %clangxx_asan -O1 %s -pthread -o %t
-// RUN: ASAN_OPTIONS=quarantine_size_mb=0 %run %t
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:quarantine_size_mb=0 %run %t
 #include <pthread.h>
 #include <stdio.h>
 #include <stdlib.h>
diff --git a/test/asan/TestCases/Windows/coverage-basic.cc b/test/asan/TestCases/Windows/coverage-basic.cc
index 3081d7c..a249999 100644
--- a/test/asan/TestCases/Windows/coverage-basic.cc
+++ b/test/asan/TestCases/Windows/coverage-basic.cc
@@ -1,7 +1,7 @@
 // RUN: rm -rf %T/coverage-basic
 // RUN: mkdir %T/coverage-basic && cd %T/coverage-basic
-// RUN: %clangxx_asan -fsanitize-coverage=1 %s -o test.exe
-// RUN: env ASAN_OPTIONS=coverage=1 %run test.exe
+// RUN: %clangxx_asan -fsanitize-coverage=func %s -o test.exe
+// RUN: env ASAN_OPTIONS=%ASAN_OPTIONS%:coverage=1 %run ./test.exe
 //
 // RUN: %sancov print *.sancov | FileCheck %s
 #include <stdio.h>
diff --git a/test/asan/TestCases/Windows/dll_report_globals_symbolization_at_startup.cc b/test/asan/TestCases/Windows/dll_report_globals_symbolization_at_startup.cc
index fbdb1c1..3fea308 100644
--- a/test/asan/TestCases/Windows/dll_report_globals_symbolization_at_startup.cc
+++ b/test/asan/TestCases/Windows/dll_report_globals_symbolization_at_startup.cc
@@ -1,6 +1,6 @@
 // RUN: %clang_cl_asan -LD -O0 -DDLL %s -Fe%t.dll
 // RUN: %clang_cl_asan -O0 -DEXE %s %t.lib -Fe%te.exe
-// RUN: env ASAN_OPTIONS=report_globals=2 %run %te.exe 2>&1 | FileCheck %s
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:report_globals=2 %run %te.exe 2>&1 | FileCheck %s
 
 // FIXME: Currently, the MT runtime build crashes on startup due to dbghelp.dll
 // initialization failure.
diff --git a/test/asan/TestCases/Windows/dll_stack_use_after_return.cc b/test/asan/TestCases/Windows/dll_stack_use_after_return.cc
index 6cd74c2..1a6ff2a 100644
--- a/test/asan/TestCases/Windows/dll_stack_use_after_return.cc
+++ b/test/asan/TestCases/Windows/dll_stack_use_after_return.cc
@@ -1,6 +1,6 @@
 // RUN: %clang_cl_asan -O0 %p/dll_host.cc -Fe%t
 // RUN: %clang_cl_asan -LD -O0 %s -Fe%t.dll
-// RUN: env ASAN_OPTIONS=detect_stack_use_after_return=1 not %run %t %t.dll 2>&1 | FileCheck %s
+// RUN: env ASAN_OPTIONS=%ASAN_OPTIONS%:detect_stack_use_after_return=1 not %run %t %t.dll 2>&1 | FileCheck %s
 
 #include <malloc.h>
 
diff --git a/test/asan/TestCases/Windows/report_globals_reload_dll.cc b/test/asan/TestCases/Windows/report_globals_reload_dll.cc
index 8b05097..182b0d2 100644
--- a/test/asan/TestCases/Windows/report_globals_reload_dll.cc
+++ b/test/asan/TestCases/Windows/report_globals_reload_dll.cc
@@ -1,7 +1,7 @@
 // Make sure we can handle reloading the same DLL multiple times.
 // RUN: %clang_cl_asan -LD -O0 -DDLL %s -Fe%t.dll
 // RUN: %clang_cl_asan -O0 -DEXE %s -Fe%te.exe
-// RUN: env ASAN_OPTIONS=report_globals=1 %run %te.exe %t.dll 2>&1 | FileCheck %s
+// RUN: env ASAN_OPTIONS=%ASAN_OPTIONS%:report_globals=1 %run %te.exe %t.dll 2>&1 | FileCheck %s
 
 #include <windows.h>
 #include <stdio.h>
diff --git a/test/asan/TestCases/Windows/report_globals_vs_freelibrary.cc b/test/asan/TestCases/Windows/report_globals_vs_freelibrary.cc
index 72bf36a..e0eee4a 100644
--- a/test/asan/TestCases/Windows/report_globals_vs_freelibrary.cc
+++ b/test/asan/TestCases/Windows/report_globals_vs_freelibrary.cc
@@ -1,6 +1,6 @@
 // RUN: %clang_cl_asan -LD -O0 -DDLL %s -Fe%t.dll
 // RUN: %clang_cl_asan -O0 -DEXE %s -Fe%te.exe
-// RUN: env ASAN_OPTIONS=report_globals=2 %run %te.exe %t.dll 2>&1 | FileCheck %s
+// RUN: env ASAN_OPTIONS=%ASAN_OPTIONS%:report_globals=2 %run %te.exe %t.dll 2>&1 | FileCheck %s
 
 #include <windows.h>
 #include <stdio.h>
diff --git a/test/asan/TestCases/Windows/stack_use_after_return.cc b/test/asan/TestCases/Windows/stack_use_after_return.cc
index 7955f26..282d3f2 100644
--- a/test/asan/TestCases/Windows/stack_use_after_return.cc
+++ b/test/asan/TestCases/Windows/stack_use_after_return.cc
@@ -1,5 +1,5 @@
 // RUN: %clang_cl_asan -O0 %s -Fe%t
-// RUN: env ASAN_OPTIONS=detect_stack_use_after_return=1 not %run %t 2>&1 | FileCheck %s
+// RUN: env ASAN_OPTIONS=%ASAN_OPTIONS%:detect_stack_use_after_return=1 not %run %t 2>&1 | FileCheck %s
 
 char *x;
 
diff --git a/test/asan/TestCases/alloca_loop_unpoisoning.cc b/test/asan/TestCases/alloca_loop_unpoisoning.cc
new file mode 100644
index 0000000..3621a09
--- /dev/null
+++ b/test/asan/TestCases/alloca_loop_unpoisoning.cc
@@ -0,0 +1,33 @@
+// RUN: %clangxx_asan -O0 -mllvm -asan-instrument-allocas %s -o %t
+// RUN: %run %t 2>&1
+//
+// REQUIRES: stable-runtime
+
+// This testcase checks that allocas and VLAs inside loop are correctly unpoisoned.
+
+#include <assert.h>
+#include <alloca.h>
+#include <stdint.h>
+#include "sanitizer/asan_interface.h"
+
+void *top, *bot;
+
+__attribute__((noinline)) void foo(int len) {
+  char x;
+  top = &x;
+  char array[len];  // NOLINT
+  assert(!(reinterpret_cast<uintptr_t>(array) & 31L));
+  alloca(len);
+  for (int i = 0; i < 32; ++i) {
+    char array[i];  // NOLINT
+    bot = alloca(i);
+    assert(!(reinterpret_cast<uintptr_t>(bot) & 31L));
+  }
+}
+
+int main(int argc, char **argv) {
+  foo(32);
+  void *q = __asan_region_is_poisoned(bot, (char *)top - (char *)bot);
+  assert(!q);
+  return 0;
+}
diff --git a/test/asan/TestCases/alloca_vla_interact.cc b/test/asan/TestCases/alloca_vla_interact.cc
new file mode 100644
index 0000000..531cc24
--- /dev/null
+++ b/test/asan/TestCases/alloca_vla_interact.cc
@@ -0,0 +1,41 @@
+// RUN: %clangxx_asan -O0 -mllvm -asan-instrument-allocas %s -o %t
+// RUN: %run %t 2>&1
+//
+// REQUIRES: stable-runtime
+// XFAIL: powerpc64
+
+// This testcase checks correct interaction between VLAs and allocas.
+
+#include <assert.h>
+#include <alloca.h>
+#include <stdint.h>
+#include "sanitizer/asan_interface.h"
+
+#define RZ 32
+
+__attribute__((noinline)) void foo(int len) {
+  char *top, *bot;
+  // This alloca call should live until the end of foo.
+  char *alloca1 = (char *)alloca(len);
+  assert(!(reinterpret_cast<uintptr_t>(alloca1) & 31L));
+  // This should be first poisoned address after loop.
+  top = alloca1 - RZ;
+  for (int i = 0; i < 32; ++i) {
+    // Check that previous alloca was unpoisoned at the end of iteration.
+    if (i) assert(!__asan_region_is_poisoned(bot, 96));
+    // VLA is unpoisoned at the end of iteration.
+    volatile char array[i];
+    assert(!(reinterpret_cast<uintptr_t>(array) & 31L));
+    // Alloca is unpoisoned at the end of iteration,
+    // because dominated by VLA.
+    bot = (char *)alloca(i) - RZ;
+  }
+  // Check that all allocas from loop were unpoisoned correctly.
+  void *q = __asan_region_is_poisoned(bot, (char *)top - (char *)bot + 1);
+  assert(q == top);
+}
+
+int main(int argc, char **argv) {
+  foo(32);
+  return 0;
+}
diff --git a/test/asan/TestCases/allocator_returns_null.cc b/test/asan/TestCases/allocator_returns_null.cc
index da6fbd4..bc6cd20 100644
--- a/test/asan/TestCases/allocator_returns_null.cc
+++ b/test/asan/TestCases/allocator_returns_null.cc
@@ -4,16 +4,16 @@
 //
 // RUN: %clangxx_asan -O0 %s -o %t
 // RUN: not %run %t malloc 2>&1 | FileCheck %s --check-prefix=CHECK-mCRASH
-// RUN: env ASAN_OPTIONS=allocator_may_return_null=0 not %run %t malloc 2>&1 | FileCheck %s --check-prefix=CHECK-mCRASH
-// RUN: env ASAN_OPTIONS=allocator_may_return_null=1     %run %t malloc 2>&1 | FileCheck %s --check-prefix=CHECK-mNULL
-// RUN: env ASAN_OPTIONS=allocator_may_return_null=0 not %run %t calloc 2>&1 | FileCheck %s --check-prefix=CHECK-cCRASH
-// RUN: env ASAN_OPTIONS=allocator_may_return_null=1     %run %t calloc 2>&1 | FileCheck %s --check-prefix=CHECK-cNULL
-// RUN: env ASAN_OPTIONS=allocator_may_return_null=0 not %run %t calloc-overflow 2>&1 | FileCheck %s --check-prefix=CHECK-coCRASH
-// RUN: env ASAN_OPTIONS=allocator_may_return_null=1     %run %t calloc-overflow 2>&1 | FileCheck %s --check-prefix=CHECK-coNULL
-// RUN: env ASAN_OPTIONS=allocator_may_return_null=0 not %run %t realloc 2>&1 | FileCheck %s --check-prefix=CHECK-rCRASH
-// RUN: env ASAN_OPTIONS=allocator_may_return_null=1     %run %t realloc 2>&1 | FileCheck %s --check-prefix=CHECK-rNULL
-// RUN: env ASAN_OPTIONS=allocator_may_return_null=0 not %run %t realloc-after-malloc 2>&1 | FileCheck %s --check-prefix=CHECK-mrCRASH
-// RUN: env ASAN_OPTIONS=allocator_may_return_null=1     %run %t realloc-after-malloc 2>&1 | FileCheck %s --check-prefix=CHECK-mrNULL
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:allocator_may_return_null=0 not %run %t malloc 2>&1 | FileCheck %s --check-prefix=CHECK-mCRASH
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:allocator_may_return_null=1     %run %t malloc 2>&1 | FileCheck %s --check-prefix=CHECK-mNULL
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:allocator_may_return_null=0 not %run %t calloc 2>&1 | FileCheck %s --check-prefix=CHECK-cCRASH
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:allocator_may_return_null=1     %run %t calloc 2>&1 | FileCheck %s --check-prefix=CHECK-cNULL
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:allocator_may_return_null=0 not %run %t calloc-overflow 2>&1 | FileCheck %s --check-prefix=CHECK-coCRASH
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:allocator_may_return_null=1     %run %t calloc-overflow 2>&1 | FileCheck %s --check-prefix=CHECK-coNULL
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:allocator_may_return_null=0 not %run %t realloc 2>&1 | FileCheck %s --check-prefix=CHECK-rCRASH
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:allocator_may_return_null=1     %run %t realloc 2>&1 | FileCheck %s --check-prefix=CHECK-rNULL
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:allocator_may_return_null=0 not %run %t realloc-after-malloc 2>&1 | FileCheck %s --check-prefix=CHECK-mrCRASH
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:allocator_may_return_null=1     %run %t realloc-after-malloc 2>&1 | FileCheck %s --check-prefix=CHECK-mrNULL
 
 #include <limits.h>
 #include <stdlib.h>
diff --git a/test/asan/TestCases/asan_and_llvm_coverage_test.cc b/test/asan/TestCases/asan_and_llvm_coverage_test.cc
index 35bdfcb..05de12b 100644
--- a/test/asan/TestCases/asan_and_llvm_coverage_test.cc
+++ b/test/asan/TestCases/asan_and_llvm_coverage_test.cc
@@ -1,5 +1,5 @@
 // RUN: %clangxx_asan -coverage -O0 %s -o %t
-// RUN: env ASAN_OPTIONS=check_initialization_order=1 %run %t 2>&1 | FileCheck %s
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:check_initialization_order=1 %run %t 2>&1 | FileCheck %s
 // XFAIL: android
 #include <stdio.h>
 int foo() { return 1; }
diff --git a/test/asan/TestCases/asan_options-help.cc b/test/asan/TestCases/asan_options-help.cc
index f10830f..a5e19e0 100644
--- a/test/asan/TestCases/asan_options-help.cc
+++ b/test/asan/TestCases/asan_options-help.cc
@@ -1,5 +1,5 @@
 // RUN: %clangxx_asan -O0 %s -o %t
-// RUN: ASAN_OPTIONS=help=1 %run %t 2>&1 | FileCheck %s
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:help=1 %run %t 2>&1 | FileCheck %s
 
 int main() {
 }
diff --git a/test/asan/TestCases/atexit_stats.cc b/test/asan/TestCases/atexit_stats.cc
index be65344..596bfda 100644
--- a/test/asan/TestCases/atexit_stats.cc
+++ b/test/asan/TestCases/atexit_stats.cc
@@ -1,6 +1,6 @@
 // Make sure we report atexit stats.
 // RUN: %clangxx_asan -O3 %s -o %t
-// RUN: env ASAN_OPTIONS=atexit=1:print_stats=1 %run %t 2>&1 | FileCheck %s
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:atexit=1:print_stats=1 %run %t 2>&1 | FileCheck %s
 //
 // No atexit output on Android due to
 // https://code.google.com/p/address-sanitizer/issues/detail?id=263
diff --git a/test/asan/TestCases/atoi_strict.c b/test/asan/TestCases/atoi_strict.c
index d60af6f..f373950 100644
--- a/test/asan/TestCases/atoi_strict.c
+++ b/test/asan/TestCases/atoi_strict.c
@@ -1,14 +1,14 @@
 // Test strict_string_checks option in atoi function
 // RUN: %clang_asan %s -o %t
 // RUN: %run %t test1 2>&1
-// RUN: ASAN_OPTIONS=strict_string_checks=false %run %t test1 2>&1
-// RUN: ASAN_OPTIONS=strict_string_checks=true not %run %t test1 2>&1 | FileCheck %s --check-prefix=CHECK1
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:strict_string_checks=false %run %t test1 2>&1
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:strict_string_checks=true not %run %t test1 2>&1 | FileCheck %s --check-prefix=CHECK1
 // RUN: %run %t test2 2>&1
-// RUN: ASAN_OPTIONS=strict_string_checks=false %run %t test2 2>&1
-// RUN: ASAN_OPTIONS=strict_string_checks=true not %run %t test2 2>&1 | FileCheck %s --check-prefix=CHECK2
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:strict_string_checks=false %run %t test2 2>&1
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:strict_string_checks=true not %run %t test2 2>&1 | FileCheck %s --check-prefix=CHECK2
 // RUN: %run %t test3 2>&1
-// RUN: ASAN_OPTIONS=strict_string_checks=false %run %t test3 2>&1
-// RUN: ASAN_OPTIONS=strict_string_checks=true not %run %t test3 2>&1 | FileCheck %s --check-prefix=CHECK3
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:strict_string_checks=false %run %t test3 2>&1
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:strict_string_checks=true not %run %t test3 2>&1 | FileCheck %s --check-prefix=CHECK3
 
 #include <assert.h>
 #include <stdlib.h>
diff --git a/test/asan/TestCases/atol_strict.c b/test/asan/TestCases/atol_strict.c
index 97ec5ba..f106150 100644
--- a/test/asan/TestCases/atol_strict.c
+++ b/test/asan/TestCases/atol_strict.c
@@ -1,14 +1,14 @@
 // Test strict_string_checks option in atol function
 // RUN: %clang_asan %s -o %t
 // RUN: %run %t test1 2>&1
-// RUN: ASAN_OPTIONS=strict_string_checks=false %run %t test1 2>&1
-// RUN: ASAN_OPTIONS=strict_string_checks=true not %run %t test1 2>&1 | FileCheck %s --check-prefix=CHECK1
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:strict_string_checks=false %run %t test1 2>&1
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:strict_string_checks=true not %run %t test1 2>&1 | FileCheck %s --check-prefix=CHECK1
 // RUN: %run %t test2 2>&1
-// RUN: ASAN_OPTIONS=strict_string_checks=false %run %t test2 2>&1
-// RUN: ASAN_OPTIONS=strict_string_checks=true not %run %t test2 2>&1 | FileCheck %s --check-prefix=CHECK2
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:strict_string_checks=false %run %t test2 2>&1
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:strict_string_checks=true not %run %t test2 2>&1 | FileCheck %s --check-prefix=CHECK2
 // RUN: %run %t test3 2>&1
-// RUN: ASAN_OPTIONS=strict_string_checks=false %run %t test3 2>&1
-// RUN: ASAN_OPTIONS=strict_string_checks=true not %run %t test3 2>&1 | FileCheck %s --check-prefix=CHECK3
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:strict_string_checks=false %run %t test3 2>&1
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:strict_string_checks=true not %run %t test3 2>&1 | FileCheck %s --check-prefix=CHECK3
 
 #include <assert.h>
 #include <stdlib.h>
diff --git a/test/asan/TestCases/atoll_strict.c b/test/asan/TestCases/atoll_strict.c
index cd0ef69..23405d2 100644
--- a/test/asan/TestCases/atoll_strict.c
+++ b/test/asan/TestCases/atoll_strict.c
@@ -1,14 +1,14 @@
 // Test strict_string_checks option in atoll function
 // RUN: %clang_asan %s -o %t
 // RUN: %run %t test1 2>&1
-// RUN: ASAN_OPTIONS=strict_string_checks=false %run %t test1 2>&1
-// RUN: ASAN_OPTIONS=strict_string_checks=true not %run %t test1 2>&1 | FileCheck %s --check-prefix=CHECK1
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:strict_string_checks=false %run %t test1 2>&1
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:strict_string_checks=true not %run %t test1 2>&1 | FileCheck %s --check-prefix=CHECK1
 // RUN: %run %t test2 2>&1
-// RUN: ASAN_OPTIONS=strict_string_checks=false %run %t test2 2>&1
-// RUN: ASAN_OPTIONS=strict_string_checks=true not %run %t test2 2>&1 | FileCheck %s --check-prefix=CHECK2
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:strict_string_checks=false %run %t test2 2>&1
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:strict_string_checks=true not %run %t test2 2>&1 | FileCheck %s --check-prefix=CHECK2
 // RUN: %run %t test3 2>&1
-// RUN: ASAN_OPTIONS=strict_string_checks=false %run %t test3 2>&1
-// RUN: ASAN_OPTIONS=strict_string_checks=true not %run %t test3 2>&1 | FileCheck %s --check-prefix=CHECK3
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:strict_string_checks=false %run %t test3 2>&1
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:strict_string_checks=true not %run %t test3 2>&1 | FileCheck %s --check-prefix=CHECK3
 
 #include <assert.h>
 #include <stdlib.h>
diff --git a/test/asan/TestCases/closed-fds.cc b/test/asan/TestCases/closed-fds.cc
index 604bf8b..56799e4 100644
--- a/test/asan/TestCases/closed-fds.cc
+++ b/test/asan/TestCases/closed-fds.cc
@@ -2,7 +2,7 @@
 // symbolizer still works.
 
 // RUN: rm -f %t.log.*
-// RUN: %clangxx_asan -O0 %s -o %t 2>&1 && ASAN_OPTIONS=log_path=%t.log:verbosity=2 not %run %t 2>&1
+// RUN: %clangxx_asan -O0 %s -o %t 2>&1 && ASAN_OPTIONS=$ASAN_OPTIONS:log_path=%t.log:verbosity=2 not %run %t 2>&1
 // RUN: FileCheck %s --check-prefix=CHECK-FILE < %t.log.*
 
 #include <assert.h>
diff --git a/test/asan/TestCases/contiguous_container_crash.cc b/test/asan/TestCases/contiguous_container_crash.cc
index 9bea177..1ae1ff1 100644
--- a/test/asan/TestCases/contiguous_container_crash.cc
+++ b/test/asan/TestCases/contiguous_container_crash.cc
@@ -2,7 +2,7 @@
 // RUN: not %run %t crash 2>&1 | FileCheck --check-prefix=CHECK-CRASH %s
 // RUN: not %run %t bad-bounds 2>&1 | FileCheck --check-prefix=CHECK-BAD-BOUNDS %s
 // RUN: not %run %t bad-alignment 2>&1 | FileCheck --check-prefix=CHECK-BAD-ALIGNMENT %s
-// RUN: env ASAN_OPTIONS=detect_container_overflow=0 %run %t crash
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:detect_container_overflow=0 %run %t crash
 //
 // Test crash due to __sanitizer_annotate_contiguous_container.
 
diff --git a/test/asan/TestCases/coverage-and-lsan.cc b/test/asan/TestCases/coverage-and-lsan.cc
index 4cb8e2a..f65889c 100644
--- a/test/asan/TestCases/coverage-and-lsan.cc
+++ b/test/asan/TestCases/coverage-and-lsan.cc
@@ -1,11 +1,11 @@
 // Make sure coverage is dumped even if there are reported leaks.
 //
-// RUN: %clangxx_asan -fsanitize-coverage=1 %s -o %t
+// RUN: %clangxx_asan -fsanitize-coverage=func %s -o %t
 //
 // RUN: rm -rf %T/coverage-and-lsan
 //
 // RUN: mkdir -p %T/coverage-and-lsan/normal
-// RUN: ASAN_OPTIONS=coverage=1:coverage_dir=%T/coverage-and-lsan:verbosity=1 not %run %t 2>&1 | FileCheck %s
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:coverage=1:coverage_dir=%T/coverage-and-lsan:verbosity=1 not %run %t 2>&1 | FileCheck %s
 // RUN: %sancov print %T/coverage-and-lsan/*.sancov 2>&1
 //
 // REQUIRES: leak-detection
diff --git a/test/asan/TestCases/coverage-caller-callee-total-count.cc b/test/asan/TestCases/coverage-caller-callee-total-count.cc
index 7598f6b..ac6d248 100644
--- a/test/asan/TestCases/coverage-caller-callee-total-count.cc
+++ b/test/asan/TestCases/coverage-caller-callee-total-count.cc
@@ -1,7 +1,7 @@
 // Test __sanitizer_get_total_unique_coverage for caller-callee coverage
 
-// RUN: %clangxx_asan -fsanitize-coverage=4 %s -o %t
-// RUN: ASAN_OPTIONS=coverage=1 %run %t
+// RUN: %clangxx_asan -fsanitize-coverage=edge,indirect-calls %s -o %t
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:coverage=1 %run %t
 // RUN: rm -f caller-callee*.sancov
 //
 // REQUIRES: asan-64-bits
diff --git a/test/asan/TestCases/coverage-caller-callee.cc b/test/asan/TestCases/coverage-caller-callee.cc
index cd31896..9c42817 100644
--- a/test/asan/TestCases/coverage-caller-callee.cc
+++ b/test/asan/TestCases/coverage-caller-callee.cc
@@ -1,13 +1,13 @@
 // Test caller-callee coverage with large number of threads
 // and various numbers of callers and callees.
 
-// RUN: %clangxx_asan -fsanitize-coverage=4 %s -o %t
-// RUN: ASAN_OPTIONS=coverage=1:verbosity=1 %run %t 10 1 2>&1 | FileCheck %s --check-prefix=CHECK-10-1
-// RUN: ASAN_OPTIONS=coverage=1:verbosity=1 %run %t 9  2 2>&1 | FileCheck %s --check-prefix=CHECK-9-2
-// RUN: ASAN_OPTIONS=coverage=1:verbosity=1 %run %t 7  3 2>&1 | FileCheck %s --check-prefix=CHECK-7-3
-// RUN: ASAN_OPTIONS=coverage=1:verbosity=1 %run %t 17 1 2>&1 | FileCheck %s --check-prefix=CHECK-17-1
-// RUN: ASAN_OPTIONS=coverage=1:verbosity=1 %run %t 15 2 2>&1 | FileCheck %s --check-prefix=CHECK-15-2
-// RUN: ASAN_OPTIONS=coverage=1:verbosity=1 %run %t 18 3 2>&1 | FileCheck %s --check-prefix=CHECK-18-3
+// RUN: %clangxx_asan -fsanitize-coverage=edge,indirect-calls %s -o %t
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:coverage=1:verbosity=1 %run %t 10 1 2>&1 | FileCheck %s --check-prefix=CHECK-10-1
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:coverage=1:verbosity=1 %run %t 9  2 2>&1 | FileCheck %s --check-prefix=CHECK-9-2
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:coverage=1:verbosity=1 %run %t 7  3 2>&1 | FileCheck %s --check-prefix=CHECK-7-3
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:coverage=1:verbosity=1 %run %t 17 1 2>&1 | FileCheck %s --check-prefix=CHECK-17-1
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:coverage=1:verbosity=1 %run %t 15 2 2>&1 | FileCheck %s --check-prefix=CHECK-15-2
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:coverage=1:verbosity=1 %run %t 18 3 2>&1 | FileCheck %s --check-prefix=CHECK-18-3
 // RUN: rm -f caller-callee*.sancov
 //
 // REQUIRES: asan-64-bits
diff --git a/test/asan/TestCases/coverage-disabled.cc b/test/asan/TestCases/coverage-disabled.cc
index cb33542..605bd10 100644
--- a/test/asan/TestCases/coverage-disabled.cc
+++ b/test/asan/TestCases/coverage-disabled.cc
@@ -1,15 +1,15 @@
 // Test that no data is collected without a runtime flag.
 //
-// RUN: %clangxx_asan -fsanitize-coverage=1 %s -o %t
+// RUN: %clangxx_asan -fsanitize-coverage=func %s -o %t
 //
 // RUN: rm -rf %T/coverage-disabled
 //
 // RUN: mkdir -p %T/coverage-disabled/normal
-// RUN: ASAN_OPTIONS=coverage_direct=0:coverage_dir=%T/coverage-disabled/normal:verbosity=1 %run %t
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:coverage_direct=0:coverage_dir=%T/coverage-disabled/normal:verbosity=1 %run %t
 // RUN: not %sancov print %T/coverage-disabled/normal/*.sancov 2>&1
 //
 // RUN: mkdir -p %T/coverage-disabled/direct
-// RUN: ASAN_OPTIONS=coverage_direct=1:coverage_dir=%T/coverage-disabled/direct:verbosity=1 %run %t
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:coverage_direct=1:coverage_dir=%T/coverage-disabled/direct:verbosity=1 %run %t
 // RUN: cd %T/coverage-disabled/direct
 // RUN: not %sancov rawunpack *.sancov
 //
diff --git a/test/asan/TestCases/coverage-levels.cc b/test/asan/TestCases/coverage-levels.cc
index 63bed65..aa36419 100644
--- a/test/asan/TestCases/coverage-levels.cc
+++ b/test/asan/TestCases/coverage-levels.cc
@@ -1,19 +1,19 @@
 // Test various levels of coverage
 //
-// RUN: %clangxx_asan -O1 -fsanitize-coverage=1  %s -o %t
-// RUN: ASAN_OPTIONS=coverage=1:coverage_bitset=1:verbosity=1 %run %t 2>&1 | FileCheck %s --check-prefix=CHECK1
-// RUN: %clangxx_asan -O1 -fsanitize-coverage=2  %s -o %t
-// RUN: ASAN_OPTIONS=coverage=1:coverage_bitset=1:verbosity=1 %run %t 2>&1 | FileCheck %s --check-prefix=CHECK2
-// RUN: %clangxx_asan -O1 -fsanitize-coverage=3  %s -o %t
-// RUN: ASAN_OPTIONS=coverage=1:coverage_bitset=1:verbosity=1 %run %t 2>&1 | FileCheck %s --check-prefix=CHECK3
-// RUN: %clangxx_asan -O1 -fsanitize-coverage=3 -mllvm -sanitizer-coverage-block-threshold=0 %s -o %t
-// RUN: ASAN_OPTIONS=coverage=1:coverage_bitset=1:verbosity=1 %run %t 2>&1 | FileCheck %s --check-prefix=CHECK3
-// RUN: %clangxx_asan -O1 -fsanitize-coverage=3 -mllvm -sanitizer-coverage-8bit-counters=1 %s -o %t
-// RUN: ASAN_OPTIONS=coverage=1:coverage_counters=1:verbosity=1 %run %t 2>&1 | FileCheck %s --check-prefix=CHECK_COUNTERS
+// RUN: %clangxx_asan -O1 -fsanitize-coverage=func  %s -o %t
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:coverage=1:coverage_bitset=1:verbosity=1 %run %t 2>&1 | FileCheck %s --check-prefix=CHECK1
+// RUN: %clangxx_asan -O1 -fsanitize-coverage=bb  %s -o %t
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:coverage=1:coverage_bitset=1:verbosity=1 %run %t 2>&1 | FileCheck %s --check-prefix=CHECK2
+// RUN: %clangxx_asan -O1 -fsanitize-coverage=edge  %s -o %t
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:coverage=1:coverage_bitset=1:verbosity=1 %run %t 2>&1 | FileCheck %s --check-prefix=CHECK3
+// RUN: %clangxx_asan -O1 -fsanitize-coverage=edge -mllvm -sanitizer-coverage-block-threshold=0 %s -o %t
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:coverage=1:coverage_bitset=1:verbosity=1 %run %t 2>&1 | FileCheck %s --check-prefix=CHECK3
+// RUN: %clangxx_asan -O1 -fsanitize-coverage=edge,8bit-counters %s -o %t
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:coverage=1:coverage_counters=1:verbosity=1 %run %t 2>&1 | FileCheck %s --check-prefix=CHECK_COUNTERS
 
-// RUN: ASAN_OPTIONS=coverage=1:coverage_bitset=0:verbosity=1 %run %t 2>&1 | FileCheck %s --check-prefix=CHECK3_NOBITSET
-// RUN: ASAN_OPTIONS=coverage=1:verbosity=1 %run %t 2>&1 | FileCheck %s --check-prefix=CHECK3_NOBITSET
-// RUN: ASAN_OPTIONS=coverage=1:coverage_pcs=0:verbosity=1 %run %t 2>&1 | FileCheck %s --check-prefix=CHECK3_NOPCS
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:coverage=1:coverage_bitset=0:verbosity=1 %run %t 2>&1 | FileCheck %s --check-prefix=CHECK3_NOBITSET
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:coverage=1:verbosity=1 %run %t 2>&1 | FileCheck %s --check-prefix=CHECK3_NOBITSET
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:coverage=1:coverage_pcs=0:verbosity=1 %run %t 2>&1 | FileCheck %s --check-prefix=CHECK3_NOPCS
 //
 // REQUIRES: asan-64-bits
 
diff --git a/test/asan/TestCases/coverage-maybe-open-file.cc b/test/asan/TestCases/coverage-maybe-open-file.cc
index ca3f92e..b261fb0 100644
--- a/test/asan/TestCases/coverage-maybe-open-file.cc
+++ b/test/asan/TestCases/coverage-maybe-open-file.cc
@@ -1,11 +1,11 @@
 // FIXME: https://code.google.com/p/address-sanitizer/issues/detail?id=316
 // XFAIL: android
 //
-// RUN: %clangxx_asan -fsanitize-coverage=1 %s -o %t
+// RUN: %clangxx_asan -fsanitize-coverage=func %s -o %t
 // RUN: rm -rf %T/coverage-maybe-open-file
 // RUN: mkdir -p %T/coverage-maybe-open-file && cd %T/coverage-maybe-open-file
-// RUN: ASAN_OPTIONS=coverage=1 %run %t | FileCheck %s --check-prefix=CHECK-success
-// RUN: ASAN_OPTIONS=coverage=0 %run %t | FileCheck %s --check-prefix=CHECK-fail
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:coverage=1 %run %t | FileCheck %s --check-prefix=CHECK-success
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:coverage=0 %run %t | FileCheck %s --check-prefix=CHECK-fail
 // RUN: [ "$(cat test.sancov.packed)" == "test" ]
 // RUN: cd .. && rm -rf %T/coverage-maybe-open-file
 
diff --git a/test/asan/TestCases/coverage-order-pcs.cc b/test/asan/TestCases/coverage-order-pcs.cc
index 076fe1b..3f56354 100644
--- a/test/asan/TestCases/coverage-order-pcs.cc
+++ b/test/asan/TestCases/coverage-order-pcs.cc
@@ -2,17 +2,17 @@
 // RUN: DIR=%T/coverage-order-pcs
 // RUN: rm -rf $DIR
 // RUN: mkdir $DIR
-// RUN: %clangxx_asan -fsanitize-coverage=1 %s -o %t
-// RUN: ASAN_OPTIONS=coverage_dir=$DIR:coverage=1:coverage_order_pcs=0 %run %t
+// RUN: %clangxx_asan -fsanitize-coverage=func %s -o %t
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:coverage_dir=$DIR:coverage=1:coverage_order_pcs=0 %run %t
 // RUN: mv $DIR/*sancov $DIR/A
 
-// RUN: ASAN_OPTIONS=coverage_dir=$DIR:coverage=1:coverage_order_pcs=0 %run %t 1
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:coverage_dir=$DIR:coverage=1:coverage_order_pcs=0 %run %t 1
 // RUN: mv $DIR/*sancov $DIR/B
 
-// RUN: ASAN_OPTIONS=coverage_dir=$DIR:coverage=1:coverage_order_pcs=1 %run %t
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:coverage_dir=$DIR:coverage=1:coverage_order_pcs=1 %run %t
 // RUN: mv $DIR/*sancov $DIR/C
 
-// RUN: ASAN_OPTIONS=coverage_dir=$DIR:coverage=1:coverage_order_pcs=1 %run %t 1
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:coverage_dir=$DIR:coverage=1:coverage_order_pcs=1 %run %t 1
 // RUN: mv $DIR/*sancov $DIR/D
 //
 // RUN: (%sancov print $DIR/A; %sancov print $DIR/B; %sancov print $DIR/C; %sancov print $DIR/D) | FileCheck %s
diff --git a/test/asan/TestCases/coverage-reset.cc b/test/asan/TestCases/coverage-reset.cc
index d3d35e2..8e02560 100644
--- a/test/asan/TestCases/coverage-reset.cc
+++ b/test/asan/TestCases/coverage-reset.cc
@@ -1,7 +1,7 @@
 // Test __sanitizer_reset_coverage().
 
-// RUN: %clangxx_asan -fsanitize-coverage=1 %s -o %t
-// RUN: ASAN_OPTIONS=coverage=1 %run %t
+// RUN: %clangxx_asan -fsanitize-coverage=func %s -o %t
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:coverage=1 %run %t
 
 #include <sanitizer/coverage_interface.h>
 #include <stdio.h>
diff --git a/test/asan/TestCases/coverage-tracing.cc b/test/asan/TestCases/coverage-tracing.cc
index 49dbb5e..21a9851 100644
--- a/test/asan/TestCases/coverage-tracing.cc
+++ b/test/asan/TestCases/coverage-tracing.cc
@@ -1,17 +1,17 @@
-// Test -mllvm -sanitizer-coverage-experimental-tracing
+// Test -fsanitize-coverage=trace-bb
 //
-// RUN: %clangxx_asan -O1 -fsanitize-coverage=1 -mllvm -sanitizer-coverage-experimental-tracing %s -o %t
+// RUN: %clangxx_asan -O1 -fsanitize-coverage=func,trace-bb %s -o %t
 // RUN: rm -rf   %T/coverage-tracing
 // RUN: mkdir %T/coverage-tracing
 // RUN: cd %T/coverage-tracing
-// RUN:  A=x;   ASAN_OPTIONS=coverage=1:verbosity=1 %run %t $A 1   2>&1 | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK1; mv trace-points.*.sancov $A.points
-// RUN:  A=f;   ASAN_OPTIONS=coverage=1:verbosity=1 %run %t $A 1   2>&1 | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK2; mv trace-points.*.sancov $A.points
-// RUN:  A=b;   ASAN_OPTIONS=coverage=1:verbosity=1 %run %t $A 1   2>&1 | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK2; mv trace-points.*.sancov $A.points
-// RUN:  A=bf;  ASAN_OPTIONS=coverage=1:verbosity=1 %run %t $A 1   2>&1 | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK3; mv trace-points.*.sancov $A.points
-// RUN:  A=fb;  ASAN_OPTIONS=coverage=1:verbosity=1 %run %t $A 1   2>&1 | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK3; mv trace-points.*.sancov $A.points
-// RUN:  A=ffb; ASAN_OPTIONS=coverage=1:verbosity=1 %run %t $A 1   2>&1 | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK4; mv trace-points.*.sancov $A.points
-// RUN:  A=fff; ASAN_OPTIONS=coverage=1:verbosity=1 %run %t $A 1   2>&1 | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK4; mv trace-points.*.sancov $A.points
-// RUN:  A=bbf; ASAN_OPTIONS=coverage=1:verbosity=1 %run %t $A 100 2>&1 | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK301; mv trace-points.*.sancov $A.points
+// RUN:  A=x;   ASAN_OPTIONS=$ASAN_OPTIONS:coverage=1:verbosity=1 %run %t $A 1   2>&1 | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK1; mv trace-points.*.sancov $A.points
+// RUN:  A=f;   ASAN_OPTIONS=$ASAN_OPTIONS:coverage=1:verbosity=1 %run %t $A 1   2>&1 | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK2; mv trace-points.*.sancov $A.points
+// RUN:  A=b;   ASAN_OPTIONS=$ASAN_OPTIONS:coverage=1:verbosity=1 %run %t $A 1   2>&1 | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK2; mv trace-points.*.sancov $A.points
+// RUN:  A=bf;  ASAN_OPTIONS=$ASAN_OPTIONS:coverage=1:verbosity=1 %run %t $A 1   2>&1 | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK3; mv trace-points.*.sancov $A.points
+// RUN:  A=fb;  ASAN_OPTIONS=$ASAN_OPTIONS:coverage=1:verbosity=1 %run %t $A 1   2>&1 | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK3; mv trace-points.*.sancov $A.points
+// RUN:  A=ffb; ASAN_OPTIONS=$ASAN_OPTIONS:coverage=1:verbosity=1 %run %t $A 1   2>&1 | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK4; mv trace-points.*.sancov $A.points
+// RUN:  A=fff; ASAN_OPTIONS=$ASAN_OPTIONS:coverage=1:verbosity=1 %run %t $A 1   2>&1 | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK4; mv trace-points.*.sancov $A.points
+// RUN:  A=bbf; ASAN_OPTIONS=$ASAN_OPTIONS:coverage=1:verbosity=1 %run %t $A 100 2>&1 | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK301; mv trace-points.*.sancov $A.points
 // RUN: diff f.points fff.points
 // RUN: diff bf.points fb.points
 // RUN: diff bf.points ffb.points
diff --git a/test/asan/TestCases/debug_mapping.cc b/test/asan/TestCases/debug_mapping.cc
index f96abf6..04de975 100644
--- a/test/asan/TestCases/debug_mapping.cc
+++ b/test/asan/TestCases/debug_mapping.cc
@@ -1,6 +1,6 @@
 // Checks that the debugging API returns correct shadow scale and offset.
 // RUN: %clangxx_asan -O %s -o %t
-// RUN: env ASAN_OPTIONS=verbosity=1 %run %t 2>&1 | FileCheck %s
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:verbosity=1 %run %t 2>&1 | FileCheck %s
 
 #include <sanitizer/asan_interface.h>
 #include <stdio.h>
@@ -8,14 +8,14 @@
 
 // printed because of verbosity=1
 // CHECK: SHADOW_SCALE: [[SCALE:[0-9]+]]
-// CHECK: SHADOW_OFFSET: [[OFFSET:[0-9]+]]
+// CHECK: SHADOW_OFFSET: [[OFFSET:0x[0-9a-f]+]]
 
 int main() {
   size_t scale, offset;
   __asan_get_shadow_mapping(&scale, &offset);
 
-  fprintf(stderr, "scale: %lx\n", scale);
-  fprintf(stderr, "offset: %lx\n", offset);
+  fprintf(stderr, "scale: %d\n", (int)scale);
+  fprintf(stderr, "offset: 0x%lx\n", offset);
 
   // CHECK: scale: [[SCALE]]
   // CHECK: offset: [[OFFSET]]
diff --git a/test/asan/TestCases/debug_ppc64_mapping.cc b/test/asan/TestCases/debug_ppc64_mapping.cc
index 3ddd3e1..ad7e25c 100644
--- a/test/asan/TestCases/debug_ppc64_mapping.cc
+++ b/test/asan/TestCases/debug_ppc64_mapping.cc
@@ -1,6 +1,6 @@
 // RUN: %clang_asan -O0 %s -o %t
-// RUN: env ASAN_OPTIONS=verbosity=0 %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-PPC64-V0
-// RUN: env ASAN_OPTIONS=verbosity=2 %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-PPC64
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:verbosity=0 %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-PPC64-V0
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:verbosity=2 %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-PPC64
 // REQUIRES: powerpc64-supported-target
 
 #include <stdio.h>
diff --git a/test/asan/TestCases/deep_call_stack.cc b/test/asan/TestCases/deep_call_stack.cc
index a5b846e..0a26a80 100644
--- a/test/asan/TestCases/deep_call_stack.cc
+++ b/test/asan/TestCases/deep_call_stack.cc
@@ -1,10 +1,10 @@
 // Check that UAR mode can handle very deep recusrion.
-// RUN: export ASAN_OPTIONS=detect_stack_use_after_return=1
+// RUN: export ASAN_OPTIONS=$ASAN_OPTIONS:detect_stack_use_after_return=1
 // RUN: %clangxx_asan -O2 %s -o %t && \
 // RUN:   (ulimit -s 4096; %run %t) 2>&1 | FileCheck %s
 
 // Also check that use_sigaltstack+verbosity doesn't crash.
-// RUN: env ASAN_OPTIONS=verbosity=1:use_sigaltstack=1 %run %t  | FileCheck %s
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:verbosity=1:use_sigaltstack=1 %run %t  | FileCheck %s
 #include <stdio.h>
 
 __attribute__((noinline))
diff --git a/test/asan/TestCases/deep_stack_uaf.cc b/test/asan/TestCases/deep_stack_uaf.cc
index 3e88d69..7b0f56e 100644
--- a/test/asan/TestCases/deep_stack_uaf.cc
+++ b/test/asan/TestCases/deep_stack_uaf.cc
@@ -1,7 +1,7 @@
 // Check that we can store lots of stack frames if asked to.
 
 // RUN: %clangxx_asan -O0 %s -o %t 2>&1
-// RUN: env ASAN_OPTIONS=malloc_context_size=120:redzone=512 not %run %t 2>&1 | FileCheck %s
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:malloc_context_size=120:redzone=512 not %run %t 2>&1 | FileCheck %s
 // XFAIL: arm-linux-gnueabi
 // XFAIL: armv7l-unknown-linux-gnueabihf
 #include <stdlib.h>
diff --git a/test/asan/TestCases/double-free.cc b/test/asan/TestCases/double-free.cc
index f0dd291..2966aad 100644
--- a/test/asan/TestCases/double-free.cc
+++ b/test/asan/TestCases/double-free.cc
@@ -2,8 +2,8 @@
 // RUN: not %run %t 2>&1 | FileCheck %s --check-prefix=CHECK --check-prefix=MALLOC-CTX
 
 // Also works if no malloc context is available.
-// RUN: env ASAN_OPTIONS=malloc_context_size=0:fast_unwind_on_malloc=0 not %run %t 2>&1 | FileCheck %s
-// RUN: env ASAN_OPTIONS=malloc_context_size=0:fast_unwind_on_malloc=1 not %run %t 2>&1 | FileCheck %s
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:malloc_context_size=0:fast_unwind_on_malloc=0 not %run %t 2>&1 | FileCheck %s
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:malloc_context_size=0:fast_unwind_on_malloc=1 not %run %t 2>&1 | FileCheck %s
 // XFAIL: arm-linux-gnueabi
 // XFAIL: armv7l-unknown-linux-gnueabihf
 
diff --git a/test/asan/TestCases/dump_instruction_bytes.cc b/test/asan/TestCases/dump_instruction_bytes.cc
index 981e3c3..33f382c 100644
--- a/test/asan/TestCases/dump_instruction_bytes.cc
+++ b/test/asan/TestCases/dump_instruction_bytes.cc
@@ -1,7 +1,7 @@
 // Check that ASan prints the faulting instruction bytes on
 // dump_instruction_bytes=1
 // RUN: %clangxx_asan  %s -o %t
-// RUN: env ASAN_OPTIONS=dump_instruction_bytes=1 not %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-DUMP
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:dump_instruction_bytes=1 not %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-DUMP
 // RUN: not %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-NODUMP
 //
 // REQUIRES: x86_64-supported-target,i386-supported-target
diff --git a/test/asan/TestCases/gc-test.cc b/test/asan/TestCases/gc-test.cc
index 4ffa51d..3fedd6a 100644
--- a/test/asan/TestCases/gc-test.cc
+++ b/test/asan/TestCases/gc-test.cc
@@ -1,9 +1,9 @@
 // RUN: %clangxx_asan %s -pthread -o %t
-// RUN: env ASAN_OPTIONS=detect_stack_use_after_return=1 %run %t 2>&1 | FileCheck %s --check-prefix=CHECK1
-// RUN: env ASAN_OPTIONS=detect_stack_use_after_return=0 %run %t 2>&1 | FileCheck %s --check-prefix=CHECK0
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:detect_stack_use_after_return=1 %run %t 2>&1 | FileCheck %s --check-prefix=CHECK1
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:detect_stack_use_after_return=0 %run %t 2>&1 | FileCheck %s --check-prefix=CHECK0
 // RUN: %clangxx_asan -O3 %s -pthread -o %t
-// RUN: env ASAN_OPTIONS=detect_stack_use_after_return=1 %run %t 2>&1 | FileCheck %s --check-prefix=CHECK1
-// RUN: env ASAN_OPTIONS=detect_stack_use_after_return=0 %run %t 2>&1 | FileCheck %s --check-prefix=CHECK0
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:detect_stack_use_after_return=1 %run %t 2>&1 | FileCheck %s --check-prefix=CHECK1
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:detect_stack_use_after_return=0 %run %t 2>&1 | FileCheck %s --check-prefix=CHECK0
 // REQUIRES: stable-runtime
 
 #include <assert.h>
diff --git a/test/asan/TestCases/heap-overflow.cc b/test/asan/TestCases/heap-overflow.cc
index 70a1203..caecea7 100644
--- a/test/asan/TestCases/heap-overflow.cc
+++ b/test/asan/TestCases/heap-overflow.cc
@@ -2,7 +2,7 @@
 // RUN: %clangxx_asan -O1 %s -o %t && not %run %t 2>&1 | FileCheck %s
 // RUN: %clangxx_asan -O2 %s -o %t && not %run %t 2>&1 | FileCheck %s
 // RUN: %clangxx_asan -O3 %s -o %t && not %run %t 2>&1 | FileCheck %s
-// RUN: env ASAN_OPTIONS=print_stats=1 not %run %t 2>&1 | FileCheck %s
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:print_stats=1 not %run %t 2>&1 | FileCheck %s
 
 // FIXME: Fix this test under GCC.
 // REQUIRES: Clang
diff --git a/test/asan/TestCases/heavy_uar_test.cc b/test/asan/TestCases/heavy_uar_test.cc
index 1f8caea..a70dcef 100644
--- a/test/asan/TestCases/heavy_uar_test.cc
+++ b/test/asan/TestCases/heavy_uar_test.cc
@@ -1,4 +1,4 @@
-// RUN: export ASAN_OPTIONS=detect_stack_use_after_return=1
+// RUN: export ASAN_OPTIONS=$ASAN_OPTIONS:detect_stack_use_after_return=1
 // RUN: %clangxx_asan -O0 %s -o %t && not %run %t 2>&1 | FileCheck %s
 // RUN: %clangxx_asan -O2 %s -o %t && not %run %t 2>&1 | FileCheck %s
 // XFAIL: arm-linux-gnueabi
diff --git a/test/asan/TestCases/init-order-atexit.cc b/test/asan/TestCases/init-order-atexit.cc
index e0dac32..1beeb33 100644
--- a/test/asan/TestCases/init-order-atexit.cc
+++ b/test/asan/TestCases/init-order-atexit.cc
@@ -8,7 +8,7 @@
 // We do *not* want to report init-order bug in this case.
 
 // RUN: %clangxx_asan -O0 %s %p/Helpers/init-order-atexit-extra.cc -o %t
-// RUN: env ASAN_OPTIONS=strict_init_order=true not %run %t 2>&1 | FileCheck %s
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:strict_init_order=true not %run %t 2>&1 | FileCheck %s
 
 #include <stdio.h>
 #include <stdlib.h>
diff --git a/test/asan/TestCases/init-order-pthread-create.cc b/test/asan/TestCases/init-order-pthread-create.cc
index b8bc93e..12362fc 100644
--- a/test/asan/TestCases/init-order-pthread-create.cc
+++ b/test/asan/TestCases/init-order-pthread-create.cc
@@ -2,7 +2,7 @@
 // called.
 
 // RUN: %clangxx_asan %s %p/Helpers/init-order-pthread-create-extra.cc -pthread -o %t
-// RUN: env ASAN_OPTIONS=strict_init_order=true %run %t
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:strict_init_order=true %run %t
 
 #include <stdio.h>
 #include <pthread.h>
diff --git a/test/asan/TestCases/initialization-blacklist.cc b/test/asan/TestCases/initialization-blacklist.cc
index 8ea6b46..bcdb111 100644
--- a/test/asan/TestCases/initialization-blacklist.cc
+++ b/test/asan/TestCases/initialization-blacklist.cc
@@ -3,15 +3,15 @@
 // RUN: %clangxx_asan -O0 %s %p/Helpers/initialization-blacklist-extra.cc\
 // RUN:   %p/Helpers/initialization-blacklist-extra2.cc \
 // RUN:   -fsanitize-blacklist=%p/Helpers/initialization-blacklist.txt -o %t
-// RUN: env ASAN_OPTIONS=check_initialization_order=true %run %t 2>&1
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:check_initialization_order=true %run %t 2>&1
 // RUN: %clangxx_asan -O1 %s %p/Helpers/initialization-blacklist-extra.cc\
 // RUN:   %p/Helpers/initialization-blacklist-extra2.cc \
 // RUN:   -fsanitize-blacklist=%p/Helpers/initialization-blacklist.txt -o %t
-// RUN: env ASAN_OPTIONS=check_initialization_order=true %run %t 2>&1
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:check_initialization_order=true %run %t 2>&1
 // RUN: %clangxx_asan -O2 %s %p/Helpers/initialization-blacklist-extra.cc\
 // RUN:   %p/Helpers/initialization-blacklist-extra2.cc \
 // RUN:   -fsanitize-blacklist=%p/Helpers/initialization-blacklist.txt -o %t
-// RUN: env ASAN_OPTIONS=check_initialization_order=true %run %t 2>&1
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:check_initialization_order=true %run %t 2>&1
 
 // Function is defined in another TU.
 int readBadGlobal();
diff --git a/test/asan/TestCases/initialization-bug.cc b/test/asan/TestCases/initialization-bug.cc
index badc6d1..6257d67 100644
--- a/test/asan/TestCases/initialization-bug.cc
+++ b/test/asan/TestCases/initialization-bug.cc
@@ -1,7 +1,7 @@
 // Test to make sure basic initialization order errors are caught.
 
-// RUN: %clangxx_asan -O0 %s %p/Helpers/initialization-bug-extra2.cc -o %t
-// RUN: env ASAN_OPTIONS=check_initialization_order=true not %run %t 2>&1 | FileCheck %s
+// RUN: %clangxx_asan -O0 %s %p/Helpers/initialization-bug-extra2.cc -o %t-INIT-ORDER-EXE
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:check_initialization_order=true not %run %t-INIT-ORDER-EXE 2>&1 | FileCheck %s
 
 // Do not test with optimization -- the error may be optimized away.
 
@@ -32,6 +32,8 @@
   // CHECK: {{AddressSanitizer: initialization-order-fiasco}}
   // CHECK: {{READ of size .* at 0x.* thread T0}}
   // CHECK: {{0x.* is located 0 bytes inside of global variable .*(y|z).*}}
+  // CHECK: registered at:
+  // CHECK: 0x{{.*}} in __asan_register_globals
 }
 
 // This initializer begins our initialization order problems.
diff --git a/test/asan/TestCases/initialization-constexpr.cc b/test/asan/TestCases/initialization-constexpr.cc
index 6442461..1188766 100644
--- a/test/asan/TestCases/initialization-constexpr.cc
+++ b/test/asan/TestCases/initialization-constexpr.cc
@@ -5,13 +5,13 @@
 // not dynamic initialization).
 
 // RUN: %clangxx_asan -O0 %s %p/Helpers/initialization-constexpr-extra.cc --std=c++11 -o %t
-// RUN: env ASAN_OPTIONS=check_initialization_order=true %run %t 2>&1
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:check_initialization_order=true %run %t 2>&1
 // RUN: %clangxx_asan -O1 %s %p/Helpers/initialization-constexpr-extra.cc --std=c++11 -o %t
-// RUN: env ASAN_OPTIONS=check_initialization_order=true %run %t 2>&1
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:check_initialization_order=true %run %t 2>&1
 // RUN: %clangxx_asan -O2 %s %p/Helpers/initialization-constexpr-extra.cc --std=c++11 -o %t
-// RUN: env ASAN_OPTIONS=check_initialization_order=true %run %t 2>&1
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:check_initialization_order=true %run %t 2>&1
 // RUN: %clangxx_asan -O3 %s %p/Helpers/initialization-constexpr-extra.cc --std=c++11 -o %t
-// RUN: env ASAN_OPTIONS=check_initialization_order=true %run %t 2>&1
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:check_initialization_order=true %run %t 2>&1
 
 class Integer {
   private:
diff --git a/test/asan/TestCases/initialization-nobug.cc b/test/asan/TestCases/initialization-nobug.cc
index 1249deb..3890edf 100644
--- a/test/asan/TestCases/initialization-nobug.cc
+++ b/test/asan/TestCases/initialization-nobug.cc
@@ -2,13 +2,13 @@
 // order checking.  If successful, this will just return 0.
 
 // RUN: %clangxx_asan -O0 %s %p/Helpers/initialization-nobug-extra.cc -o %t
-// RUN: env ASAN_OPTIONS=check_initialization_order=true %run %t 2>&1
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:check_initialization_order=true %run %t 2>&1
 // RUN: %clangxx_asan -O1 %s %p/Helpers/initialization-nobug-extra.cc -o %t
-// RUN: env ASAN_OPTIONS=check_initialization_order=true %run %t 2>&1
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:check_initialization_order=true %run %t 2>&1
 // RUN: %clangxx_asan -O2 %s %p/Helpers/initialization-nobug-extra.cc -o %t
-// RUN: env ASAN_OPTIONS=check_initialization_order=true %run %t 2>&1
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:check_initialization_order=true %run %t 2>&1
 // RUN: %clangxx_asan -O3 %s %p/Helpers/initialization-nobug-extra.cc -o %t
-// RUN: env ASAN_OPTIONS=check_initialization_order=true %run %t 2>&1
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:check_initialization_order=true %run %t 2>&1
 
 // Simple access:
 // Make sure that accessing a global in the same TU is safe
diff --git a/test/asan/TestCases/invalid-free.cc b/test/asan/TestCases/invalid-free.cc
index cb545cc..c6f7b84 100644
--- a/test/asan/TestCases/invalid-free.cc
+++ b/test/asan/TestCases/invalid-free.cc
@@ -2,8 +2,8 @@
 // RUN: not %run %t 2>&1 | FileCheck %s --check-prefix=CHECK --check-prefix=MALLOC-CTX
 
 // Also works if no malloc context is available.
-// RUN: env ASAN_OPTIONS=malloc_context_size=0:fast_unwind_on_malloc=0 not %run %t 2>&1 | FileCheck %s
-// RUN: env ASAN_OPTIONS=malloc_context_size=0:fast_unwind_on_malloc=1 not %run %t 2>&1 | FileCheck %s
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:malloc_context_size=0:fast_unwind_on_malloc=0 not %run %t 2>&1 | FileCheck %s
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:malloc_context_size=0:fast_unwind_on_malloc=1 not %run %t 2>&1 | FileCheck %s
 // XFAIL: arm-linux-gnueabi
 // XFAIL: armv7l-unknown-linux-gnueabihf
 
diff --git a/test/asan/TestCases/log-path_test.cc b/test/asan/TestCases/log-path_test.cc
index 7dd1fad..d253a6f 100644
--- a/test/asan/TestCases/log-path_test.cc
+++ b/test/asan/TestCases/log-path_test.cc
@@ -9,21 +9,21 @@
 
 // Good log_path.
 // RUN: rm -f %t.log.*
-// RUN: env ASAN_OPTIONS=log_path=%t.log not %run %t 2> %t.out
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:log_path=%t.log not %run %t 2> %t.out
 // RUN: FileCheck %s --check-prefix=CHECK-ERROR < %t.log.*
 
 // Invalid log_path.
-// RUN: env ASAN_OPTIONS=log_path=/dev/null/INVALID not %run %t 2> %t.out
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:log_path=/dev/null/INVALID not %run %t 2> %t.out
 // RUN: FileCheck %s --check-prefix=CHECK-INVALID < %t.out
 
 // Too long log_path.
-// RUN: env ASAN_OPTIONS=log_path=`for((i=0;i<10000;i++)); do echo -n $i; done` \
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:log_path=`for((i=0;i<10000;i++)); do echo -n $i; done` \
 // RUN:   not %run %t 2> %t.out
 // RUN: FileCheck %s --check-prefix=CHECK-LONG < %t.out
 
 // Run w/o errors should not produce any log.
 // RUN: rm -f %t.log.*
-// RUN: env ASAN_OPTIONS=log_path=%t.log  %run %t ARG ARG ARG
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:log_path=%t.log  %run %t ARG ARG ARG
 // RUN: not cat %t.log.*
 
 // FIXME: log_path is not supported on Windows yet.
diff --git a/test/asan/TestCases/malloc_context_size.cc b/test/asan/TestCases/malloc_context_size.cc
index 0d9f315..91e1bdc 100644
--- a/test/asan/TestCases/malloc_context_size.cc
+++ b/test/asan/TestCases/malloc_context_size.cc
@@ -1,9 +1,9 @@
 // RUN: %clangxx_asan -O0 %s -o %t
-// RUN: env ASAN_OPTIONS=malloc_context_size=0:fast_unwind_on_malloc=0 not %run %t 2>&1 | FileCheck %s
-// RUN: env ASAN_OPTIONS=malloc_context_size=0:fast_unwind_on_malloc=1 not %run %t 2>&1 | FileCheck %s
-// RUN: env ASAN_OPTIONS=malloc_context_size=1:fast_unwind_on_malloc=0 not %run %t 2>&1 | FileCheck %s
-// RUN: env ASAN_OPTIONS=malloc_context_size=1:fast_unwind_on_malloc=1 not %run %t 2>&1 | FileCheck %s
-// RUN: env ASAN_OPTIONS=malloc_context_size=2 not %run %t 2>&1 | FileCheck %s --check-prefix=TWO
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:malloc_context_size=0:fast_unwind_on_malloc=0 not %run %t 2>&1 | FileCheck %s
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:malloc_context_size=0:fast_unwind_on_malloc=1 not %run %t 2>&1 | FileCheck %s
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:malloc_context_size=1:fast_unwind_on_malloc=0 not %run %t 2>&1 | FileCheck %s
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:malloc_context_size=1:fast_unwind_on_malloc=1 not %run %t 2>&1 | FileCheck %s
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:malloc_context_size=2 not %run %t 2>&1 | FileCheck %s --check-prefix=TWO
 
 int main() {
   char *x = new char[20];
diff --git a/test/asan/TestCases/malloc_fill.cc b/test/asan/TestCases/malloc_fill.cc
index 5c92680..13a73a7 100644
--- a/test/asan/TestCases/malloc_fill.cc
+++ b/test/asan/TestCases/malloc_fill.cc
@@ -1,8 +1,8 @@
 // Check that we fill malloc-ed memory correctly.
 // RUN: %clangxx_asan %s -o %t
 // RUN: %run %t | FileCheck %s
-// RUN: env ASAN_OPTIONS=max_malloc_fill_size=10:malloc_fill_byte=8 %run %t | FileCheck %s --check-prefix=CHECK-10-8
-// RUN: env ASAN_OPTIONS=max_malloc_fill_size=20:malloc_fill_byte=171 %run %t | FileCheck %s --check-prefix=CHECK-20-ab
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:max_malloc_fill_size=10:malloc_fill_byte=8 %run %t | FileCheck %s --check-prefix=CHECK-10-8
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:max_malloc_fill_size=20:malloc_fill_byte=171 %run %t | FileCheck %s --check-prefix=CHECK-20-ab
 
 #include <stdio.h>
 int main(int argc, char **argv) {
diff --git a/test/asan/TestCases/max_redzone.cc b/test/asan/TestCases/max_redzone.cc
index 01c25a9..c5539bc 100644
--- a/test/asan/TestCases/max_redzone.cc
+++ b/test/asan/TestCases/max_redzone.cc
@@ -1,8 +1,8 @@
 // Test max_redzone runtime option.
 
-// RUN: %clangxx_asan -O0 %s -o %t && env ASAN_OPTIONS=max_redzone=16 %run %t 0 2>&1
+// RUN: %clangxx_asan -O0 %s -o %t && env ASAN_OPTIONS=$ASAN_OPTIONS:max_redzone=16 %run %t 0 2>&1
 // RUN: %clangxx_asan -O0 %s -o %t && %run %t 1 2>&1
-// RUN: %clangxx_asan -O3 %s -o %t && env ASAN_OPTIONS=max_redzone=16 %run %t 0 2>&1
+// RUN: %clangxx_asan -O3 %s -o %t && env ASAN_OPTIONS=$ASAN_OPTIONS:max_redzone=16 %run %t 0 2>&1
 // RUN: %clangxx_asan -O3 %s -o %t && %run %t 1 2>&1
 
 #include <stdio.h>
diff --git a/test/asan/TestCases/memcmp_strict_test.cc b/test/asan/TestCases/memcmp_strict_test.cc
index 16b7673..a15d0a3 100644
--- a/test/asan/TestCases/memcmp_strict_test.cc
+++ b/test/asan/TestCases/memcmp_strict_test.cc
@@ -1,5 +1,5 @@
-// RUN: %clangxx_asan -O0 %s -o %t && env ASAN_OPTIONS=strict_memcmp=0 %run %t
-// RUN: %clangxx_asan -O0 %s -o %t && env ASAN_OPTIONS=strict_memcmp=1 not %run %t 2>&1 | FileCheck %s
+// RUN: %clangxx_asan -O0 %s -o %t && env ASAN_OPTIONS=$ASAN_OPTIONS:strict_memcmp=0 %run %t
+// RUN: %clangxx_asan -O0 %s -o %t && env ASAN_OPTIONS=$ASAN_OPTIONS:strict_memcmp=1 not %run %t 2>&1 | FileCheck %s
 // Default to strict_memcmp=1.
 // RUN: %clangxx_asan -O0 %s -o %t && not %run %t 2>&1 | FileCheck %s
 
diff --git a/test/asan/TestCases/mmap_limit_mb.cc b/test/asan/TestCases/mmap_limit_mb.cc
index d4ffb2e..0241052 100644
--- a/test/asan/TestCases/mmap_limit_mb.cc
+++ b/test/asan/TestCases/mmap_limit_mb.cc
@@ -3,10 +3,10 @@
 // RUN: %clangxx_asan -O2 %s -o %t
 // RUN: %run %t 20 16
 // RUN: %run %t 30 1000000
-// RUN: env ASAN_OPTIONS=mmap_limit_mb=300 %run %t 20 16
-// RUN: env ASAN_OPTIONS=mmap_limit_mb=300 %run %t 20 1000000
-// RUN: env ASAN_OPTIONS=mmap_limit_mb=300 not %run %t 500 16 2>&1 | FileCheck %s
-// RUN: env ASAN_OPTIONS=mmap_limit_mb=300 not %run %t 500 1000000 2>&1 | FileCheck %s
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:mmap_limit_mb=300 %run %t 20 16
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:mmap_limit_mb=300 %run %t 20 1000000
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:mmap_limit_mb=300 not %run %t 500 16 2>&1 | FileCheck %s
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:mmap_limit_mb=300 not %run %t 500 1000000 2>&1 | FileCheck %s
 // XFAIL: arm-linux-gnueabi
 
 #include <assert.h>
diff --git a/test/asan/TestCases/poison_partial.cc b/test/asan/TestCases/poison_partial.cc
index ce9c98b..8a89215 100644
--- a/test/asan/TestCases/poison_partial.cc
+++ b/test/asan/TestCases/poison_partial.cc
@@ -1,8 +1,8 @@
 // RUN: %clangxx_asan -O0 %s -o %t
 // RUN: not %run %t      2>&1 | FileCheck %s
 // RUN: not %run %t heap 2>&1 | FileCheck %s
-// RUN: env ASAN_OPTIONS=poison_partial=0 %run %t
-// RUN: env ASAN_OPTIONS=poison_partial=0 %run %t heap
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:poison_partial=0 %run %t
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:poison_partial=0 %run %t heap
 #include <string.h>
 char g[21];
 char *x;
diff --git a/test/asan/TestCases/print_summary.cc b/test/asan/TestCases/print_summary.cc
index 12dfa26..6759340 100644
--- a/test/asan/TestCases/print_summary.cc
+++ b/test/asan/TestCases/print_summary.cc
@@ -1,7 +1,7 @@
 // RUN: %clangxx_asan -O0 %s -o %t
 // RUN: not %run %t 2>&1 | FileCheck %s --check-prefix=SOURCE
-// RUN: env ASAN_OPTIONS=symbolize=false not %run %t 2>&1 | FileCheck %s --check-prefix=MODULE
-// RUN: env ASAN_OPTIONS=print_summary=false not %run %t 2>&1 | FileCheck %s --check-prefix=MISSING
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:symbolize=false not %run %t 2>&1 | FileCheck %s --check-prefix=MODULE
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:print_summary=false not %run %t 2>&1 | FileCheck %s --check-prefix=MISSING
 
 int main() {
   char *x = new char[20];
diff --git a/test/asan/TestCases/printf-1.c b/test/asan/TestCases/printf-1.c
index 5657083..2df74b6 100644
--- a/test/asan/TestCases/printf-1.c
+++ b/test/asan/TestCases/printf-1.c
@@ -1,6 +1,6 @@
 // RUN: %clang_asan -O2 %s -o %t
-// RUN: env ASAN_OPTIONS=check_printf=1 %run %t 2>&1 | FileCheck %s
-// RUN: env ASAN_OPTIONS=check_printf=0 %run %t 2>&1 | FileCheck %s
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:check_printf=1 %run %t 2>&1 | FileCheck %s
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:check_printf=0 %run %t 2>&1 | FileCheck %s
 // RUN: %run %t 2>&1 | FileCheck %s
 
 #include <stdio.h>
diff --git a/test/asan/TestCases/printf-2.c b/test/asan/TestCases/printf-2.c
index e9cb47e..b3ab961 100644
--- a/test/asan/TestCases/printf-2.c
+++ b/test/asan/TestCases/printf-2.c
@@ -1,9 +1,9 @@
 // RUN: %clang_asan -O2 %s -o %t
 // We need replace_str=0 and replace_intrin=0 to avoid reporting errors in
 // strlen() and memcpy() called by printf().
-// RUN: env ASAN_OPTIONS=replace_str=0:replace_intrin=0:check_printf=1 not %run %t 2>&1 | FileCheck --check-prefix=CHECK-ON %s
-// RUN: env ASAN_OPTIONS=replace_str=0:replace_intrin=0:check_printf=0 %run %t 2>&1 | FileCheck --check-prefix=CHECK-OFF %s
-// RUN: env ASAN_OPTIONS=replace_str=0:replace_intrin=0 not %run %t 2>&1 | FileCheck --check-prefix=CHECK-ON %s
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:replace_str=0:replace_intrin=0:check_printf=1 not %run %t 2>&1 | FileCheck --check-prefix=CHECK-ON %s
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:replace_str=0:replace_intrin=0:check_printf=0 %run %t 2>&1 | FileCheck --check-prefix=CHECK-OFF %s
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:replace_str=0:replace_intrin=0 not %run %t 2>&1 | FileCheck --check-prefix=CHECK-ON %s
 
 // FIXME: printf is not intercepted on Windows yet.
 // XFAIL: win32
diff --git a/test/asan/TestCases/printf-3.c b/test/asan/TestCases/printf-3.c
index d16833d..bc9fece 100644
--- a/test/asan/TestCases/printf-3.c
+++ b/test/asan/TestCases/printf-3.c
@@ -1,6 +1,6 @@
 // RUN: %clang_asan -O2 %s -o %t
-// RUN: env ASAN_OPTIONS=check_printf=1 not %run %t 2>&1 | FileCheck --check-prefix=CHECK-ON %s
-// RUN: env ASAN_OPTIONS=check_printf=0 %run %t 2>&1 | FileCheck --check-prefix=CHECK-OFF %s
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:check_printf=1 not %run %t 2>&1 | FileCheck --check-prefix=CHECK-ON %s
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:check_printf=0 %run %t 2>&1 | FileCheck --check-prefix=CHECK-OFF %s
 // RUN: not %run %t 2>&1 | FileCheck --check-prefix=CHECK-ON %s
 
 // FIXME: printf is not intercepted on Windows yet.
diff --git a/test/asan/TestCases/printf-4.c b/test/asan/TestCases/printf-4.c
index e269211..b2a14ff 100644
--- a/test/asan/TestCases/printf-4.c
+++ b/test/asan/TestCases/printf-4.c
@@ -1,8 +1,8 @@
 // RUN: %clang_asan -O2 %s -o %t
 // We need replace_str=0 and replace_intrin=0 to avoid reporting errors in
 // strlen() and memcpy() called by puts().
-// RUN: env ASAN_OPTIONS=replace_str=0:replace_intrin=0:check_printf=1 not %run %t 2>&1 | FileCheck --check-prefix=CHECK-ON %s
-// RUN: env ASAN_OPTIONS=replace_str=0:replace_intrin=0 not %run %t 2>&1 | FileCheck --check-prefix=CHECK-ON %s
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:replace_str=0:replace_intrin=0:check_printf=1 not %run %t 2>&1 | FileCheck --check-prefix=CHECK-ON %s
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:replace_str=0:replace_intrin=0 not %run %t 2>&1 | FileCheck --check-prefix=CHECK-ON %s
 
 // FIXME: printf is not intercepted on Windows yet.
 // XFAIL: win32
diff --git a/test/asan/TestCases/printf-5.c b/test/asan/TestCases/printf-5.c
index ac2c1c4..d4e2a0a 100644
--- a/test/asan/TestCases/printf-5.c
+++ b/test/asan/TestCases/printf-5.c
@@ -1,8 +1,8 @@
 // RUN: %clang_asan -O2 %s -o %t
 // We need replace_intrin=0 to avoid reporting errors in memcpy.
-// RUN: env ASAN_OPTIONS=replace_intrin=0:check_printf=1 not %run %t 2>&1 | FileCheck --check-prefix=CHECK-ON %s
-// RUN: env ASAN_OPTIONS=replace_intrin=0:check_printf=0 %run %t 2>&1 | FileCheck --check-prefix=CHECK-OFF %s
-// RUN: env ASAN_OPTIONS=replace_intrin=0 not %run %t 2>&1 | FileCheck --check-prefix=CHECK-ON %s
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:replace_intrin=0:check_printf=1 not %run %t 2>&1 | FileCheck --check-prefix=CHECK-ON %s
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:replace_intrin=0:check_printf=0 %run %t 2>&1 | FileCheck --check-prefix=CHECK-OFF %s
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:replace_intrin=0 not %run %t 2>&1 | FileCheck --check-prefix=CHECK-ON %s
 
 // FIXME: printf is not intercepted on Windows yet.
 // XFAIL: win32
diff --git a/test/asan/TestCases/stack-overflow.cc b/test/asan/TestCases/stack-overflow.cc
index d4bb747..d792c46 100644
--- a/test/asan/TestCases/stack-overflow.cc
+++ b/test/asan/TestCases/stack-overflow.cc
@@ -1,18 +1,18 @@
 // Test ASan detection of stack-overflow condition.
 
-// RUN: %clangxx_asan -O0 %s -DSMALL_FRAME -pthread -o %t && env ASAN_OPTIONS=use_sigaltstack=1 not %run %t 2>&1 | FileCheck %s
-// RUN: %clangxx_asan -O3 %s -DSMALL_FRAME -pthread -o %t && env ASAN_OPTIONS=use_sigaltstack=1 not %run %t 2>&1 | FileCheck %s
-// RUN: %clangxx_asan -O0 %s -DSAVE_ALL_THE_REGISTERS -pthread -o %t && env ASAN_OPTIONS=use_sigaltstack=1 not %run %t 2>&1 | FileCheck %s
-// RUN: %clangxx_asan -O3 %s -DSAVE_ALL_THE_REGISTERS -pthread -o %t && env ASAN_OPTIONS=use_sigaltstack=1 not %run %t 2>&1 | FileCheck %s
-// RUN: %clangxx_asan -O0 %s -pthread -o %t && env ASAN_OPTIONS=use_sigaltstack=1 not %run %t 2>&1 | FileCheck %s
-// RUN: %clangxx_asan -O3 %s -pthread -o %t && env ASAN_OPTIONS=use_sigaltstack=1 not %run %t 2>&1 | FileCheck %s
+// RUN: %clangxx_asan -O0 %s -DSMALL_FRAME -pthread -o %t && env ASAN_OPTIONS=$ASAN_OPTIONS:use_sigaltstack=1 not %run %t 2>&1 | FileCheck %s
+// RUN: %clangxx_asan -O3 %s -DSMALL_FRAME -pthread -o %t && env ASAN_OPTIONS=$ASAN_OPTIONS:use_sigaltstack=1 not %run %t 2>&1 | FileCheck %s
+// RUN: %clangxx_asan -O0 %s -DSAVE_ALL_THE_REGISTERS -pthread -o %t && env ASAN_OPTIONS=$ASAN_OPTIONS:use_sigaltstack=1 not %run %t 2>&1 | FileCheck %s
+// RUN: %clangxx_asan -O3 %s -DSAVE_ALL_THE_REGISTERS -pthread -o %t && env ASAN_OPTIONS=$ASAN_OPTIONS:use_sigaltstack=1 not %run %t 2>&1 | FileCheck %s
+// RUN: %clangxx_asan -O0 %s -pthread -o %t && env ASAN_OPTIONS=$ASAN_OPTIONS:use_sigaltstack=1 not %run %t 2>&1 | FileCheck %s
+// RUN: %clangxx_asan -O3 %s -pthread -o %t && env ASAN_OPTIONS=$ASAN_OPTIONS:use_sigaltstack=1 not %run %t 2>&1 | FileCheck %s
 
-// RUN: %clangxx_asan -O0 %s -DTHREAD -DSMALL_FRAME -pthread -o %t && env ASAN_OPTIONS=use_sigaltstack=1 not %run %t 2>&1 | FileCheck %s
-// RUN: %clangxx_asan -O3 %s -DTHREAD -DSMALL_FRAME -pthread -o %t && env ASAN_OPTIONS=use_sigaltstack=1 not %run %t 2>&1 | FileCheck %s
-// RUN: %clangxx_asan -O0 %s -DTHREAD -DSAVE_ALL_THE_REGISTERS -pthread -o %t && env ASAN_OPTIONS=use_sigaltstack=1 not %run %t 2>&1 | FileCheck %s
-// RUN: %clangxx_asan -O3 %s -DTHREAD -DSAVE_ALL_THE_REGISTERS -pthread -o %t && env ASAN_OPTIONS=use_sigaltstack=1 not %run %t 2>&1 | FileCheck %s
-// RUN: %clangxx_asan -O0 %s -DTHREAD -pthread -o %t && env ASAN_OPTIONS=use_sigaltstack=1 not %run %t 2>&1 | FileCheck %s
-// RUN: %clangxx_asan -O3 %s -DTHREAD -pthread -o %t && env ASAN_OPTIONS=use_sigaltstack=1 not %run %t 2>&1 | FileCheck %s
+// RUN: %clangxx_asan -O0 %s -DTHREAD -DSMALL_FRAME -pthread -o %t && env ASAN_OPTIONS=$ASAN_OPTIONS:use_sigaltstack=1 not %run %t 2>&1 | FileCheck %s
+// RUN: %clangxx_asan -O3 %s -DTHREAD -DSMALL_FRAME -pthread -o %t && env ASAN_OPTIONS=$ASAN_OPTIONS:use_sigaltstack=1 not %run %t 2>&1 | FileCheck %s
+// RUN: %clangxx_asan -O0 %s -DTHREAD -DSAVE_ALL_THE_REGISTERS -pthread -o %t && env ASAN_OPTIONS=$ASAN_OPTIONS:use_sigaltstack=1 not %run %t 2>&1 | FileCheck %s
+// RUN: %clangxx_asan -O3 %s -DTHREAD -DSAVE_ALL_THE_REGISTERS -pthread -o %t && env ASAN_OPTIONS=$ASAN_OPTIONS:use_sigaltstack=1 not %run %t 2>&1 | FileCheck %s
+// RUN: %clangxx_asan -O0 %s -DTHREAD -pthread -o %t && env ASAN_OPTIONS=$ASAN_OPTIONS:use_sigaltstack=1 not %run %t 2>&1 | FileCheck %s
+// RUN: %clangxx_asan -O3 %s -DTHREAD -pthread -o %t && env ASAN_OPTIONS=$ASAN_OPTIONS:use_sigaltstack=1 not %run %t 2>&1 | FileCheck %s
 // RUN: not %run %t 2>&1 | FileCheck %s
 // REQUIRES: stable-runtime
 
diff --git a/test/asan/TestCases/stack-use-after-return.cc b/test/asan/TestCases/stack-use-after-return.cc
index 437c457..669e870 100644
--- a/test/asan/TestCases/stack-use-after-return.cc
+++ b/test/asan/TestCases/stack-use-after-return.cc
@@ -1,9 +1,9 @@
-// RUN: export ASAN_OPTIONS=detect_stack_use_after_return=1
+// RUN: export ASAN_OPTIONS=$ASAN_OPTIONS:detect_stack_use_after_return=1
 // RUN: %clangxx_asan  -O0 %s -pthread -o %t && not %run %t 2>&1 | FileCheck %s
 // RUN: %clangxx_asan  -O1 %s -pthread -o %t && not %run %t 2>&1 | FileCheck %s
 // RUN: %clangxx_asan  -O2 %s -pthread -o %t && not %run %t 2>&1 | FileCheck %s
 // RUN: %clangxx_asan  -O3 %s -pthread -o %t && not %run %t 2>&1 | FileCheck %s
-// RUN: env ASAN_OPTIONS=detect_stack_use_after_return=0 %run %t
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:detect_stack_use_after_return=0 %run %t
 // Regression test for a CHECK failure with small stack size and large frame.
 // RUN: %clangxx_asan  -O3 %s -pthread -o %t -DkSize=10000 -DUseThread -DkStackSize=65536 && not %run %t 2>&1 | FileCheck --check-prefix=THREAD %s
 //
diff --git a/test/asan/TestCases/strcasestr-1.c b/test/asan/TestCases/strcasestr-1.c
new file mode 100644
index 0000000..c6f9d19
--- /dev/null
+++ b/test/asan/TestCases/strcasestr-1.c
@@ -0,0 +1,24 @@
+// Test haystack overflow in strcasestr function
+// RUN: %clang_asan %s -o %t && ASAN_OPTIONS=$ASAN_OPTIONS:strict_string_checks=true not %run %t 2>&1 | FileCheck %s
+
+// Test intercept_strstr asan option
+// Disable other interceptors because strlen may be called inside strcasestr
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:intercept_strstr=false:replace_str=false %run %t 2>&1
+
+// There's no interceptor for strcasestr on Windows
+// XFAIL: win32
+
+#define _GNU_SOURCE
+#include <assert.h>
+#include <string.h>
+
+int main(int argc, char **argv) {
+  char *r = 0;
+  char s2[] = "c";
+  char s1[] = {'a', 'C'};
+  char s3 = 0;
+  r = strcasestr(s1, s2);
+  // CHECK:'s{{[1|3]}}' <== Memory access at offset {{[0-9]+ .*}}flows this variable
+  assert(r == s1 + 1);
+  return 0;
+}
diff --git a/test/asan/TestCases/strcasestr-2.c b/test/asan/TestCases/strcasestr-2.c
new file mode 100644
index 0000000..a4bc636
--- /dev/null
+++ b/test/asan/TestCases/strcasestr-2.c
@@ -0,0 +1,24 @@
+// Test needle overflow in strcasestr function
+// RUN: %clang_asan %s -o %t && ASAN_OPTIONS=$ASAN_OPTIONS:strict_string_checks=true not %run %t 2>&1 | FileCheck %s
+
+// Test intercept_strstr asan option
+// Disable other interceptors because strlen may be called inside strcasestr
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:intercept_strstr=false:replace_str=false %run %t 2>&1
+
+// There's no interceptor for strcasestr on Windows
+// XFAIL: win32
+
+#define _GNU_SOURCE
+#include <assert.h>
+#include <string.h>
+
+int main(int argc, char **argv) {
+  char *r = 0;
+  char s1[] = "ab";
+  char s2[] = {'c'};
+  char s3 = 0;
+  r = strcasestr(s1, s2);
+  assert(r == 0);
+  // CHECK:'s{{[2|3]}}' <== Memory access at offset {{[0-9]+ .*}}flows this variable
+  return 0;
+}
diff --git a/test/asan/TestCases/strcasestr_strict.c b/test/asan/TestCases/strcasestr_strict.c
new file mode 100644
index 0000000..03c066b
--- /dev/null
+++ b/test/asan/TestCases/strcasestr_strict.c
@@ -0,0 +1,28 @@
+// Test strict_string_checks option in strcasestr function
+// RUN: %clang_asan %s -o %t && %run %t 2>&1
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:strict_string_checks=false %run %t 2>&1
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:strict_string_checks=true not %run %t 2>&1 | FileCheck %s
+
+// There's no interceptor for strcasestr on Windows
+// XFAIL: win32
+
+#define _GNU_SOURCE
+#include <assert.h>
+#include <stdlib.h>
+#include <string.h>
+
+int main(int argc, char **argv) {
+  size_t size = 100;
+  char *s1 = (char*)malloc(size);
+  char *s2 = (char*)malloc(size);
+  memset(s1, 'o', size);
+  memset(s2, 'O', size);
+  s2[size - 1]='\0';
+  char* r = strcasestr(s1, s2);
+  // CHECK: {{.*ERROR: AddressSanitizer: heap-buffer-overflow on address}}
+  // CHECK: READ of size 101
+  assert(r == s1);
+  free(s1);
+  free(s2);
+  return 0;
+}
diff --git a/test/asan/TestCases/strcat_strict.c b/test/asan/TestCases/strcat_strict.c
index 806b682..8321f5b 100644
--- a/test/asan/TestCases/strcat_strict.c
+++ b/test/asan/TestCases/strcat_strict.c
@@ -1,11 +1,11 @@
 // Test strict_string_checks option in strcat function
 // RUN: %clang_asan %s -o %t
 // RUN: not %run %t test1 2>&1 | FileCheck %s --check-prefix=CHECK1-NONSTRICT --check-prefix=CHECK1
-// RUN: ASAN_OPTIONS=strict_string_checks=false not  %run %t test1 2>&1 | FileCheck %s --check-prefix=CHECK1-NONSTRICT --check-prefix=CHECK1
-// RUN: ASAN_OPTIONS=strict_string_checks=true not %run %t test1 2>&1 | FileCheck %s --check-prefix=CHECK1-STRICT --check-prefix=CHECK1
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:strict_string_checks=false not  %run %t test1 2>&1 | FileCheck %s --check-prefix=CHECK1-NONSTRICT --check-prefix=CHECK1
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:strict_string_checks=true not %run %t test1 2>&1 | FileCheck %s --check-prefix=CHECK1-STRICT --check-prefix=CHECK1
 // RUN: not %run %t test2 2>&1 | FileCheck %s --check-prefix=CHECK2-NONSTRICT --check-prefix=CHECK2
-// RUN: ASAN_OPTIONS=strict_string_checks=false not  %run %t test2 2>&1 | FileCheck %s --check-prefix=CHECK2-NONSTRICT --check-prefix=CHECK2
-// RUN: ASAN_OPTIONS=strict_string_checks=true not %run %t test2 2>&1 | FileCheck %s --check-prefix=CHECK2-STRICT --check-prefix=CHECK2
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:strict_string_checks=false not  %run %t test2 2>&1 | FileCheck %s --check-prefix=CHECK2-NONSTRICT --check-prefix=CHECK2
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:strict_string_checks=true not %run %t test2 2>&1 | FileCheck %s --check-prefix=CHECK2-STRICT --check-prefix=CHECK2
 
 #include <assert.h>
 #include <stdlib.h>
diff --git a/test/asan/TestCases/strchr_strict.c b/test/asan/TestCases/strchr_strict.c
index d0c32f7..48c1f13 100644
--- a/test/asan/TestCases/strchr_strict.c
+++ b/test/asan/TestCases/strchr_strict.c
@@ -1,7 +1,7 @@
 // Test strict_string_checks option in strchr function
 // RUN: %clang_asan %s -o %t && %run %t 2>&1
-// RUN: ASAN_OPTIONS=strict_string_checks=false %run %t 2>&1
-// RUN: ASAN_OPTIONS=strict_string_checks=true not %run %t 2>&1 | FileCheck %s
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:strict_string_checks=false %run %t 2>&1
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:strict_string_checks=true not %run %t 2>&1 | FileCheck %s
 
 #include <assert.h>
 #include <stdlib.h>
diff --git a/test/asan/TestCases/strcmp_strict.c b/test/asan/TestCases/strcmp_strict.c
index 6514ab9..316765e 100644
--- a/test/asan/TestCases/strcmp_strict.c
+++ b/test/asan/TestCases/strcmp_strict.c
@@ -1,7 +1,7 @@
 // Test strict_string_checks option in strcmp function
 // RUN: %clang_asan %s -o %t && %run %t 2>&1
-// RUN: ASAN_OPTIONS=strict_string_checks=false %run %t 2>&1
-// RUN: ASAN_OPTIONS=strict_string_checks=true not %run %t 2>&1 | FileCheck %s
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:strict_string_checks=false %run %t 2>&1
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:strict_string_checks=true not %run %t 2>&1 | FileCheck %s
 
 #include <assert.h>
 #include <stdlib.h>
diff --git a/test/asan/TestCases/strcspn-1.c b/test/asan/TestCases/strcspn-1.c
new file mode 100644
index 0000000..5a19222
--- /dev/null
+++ b/test/asan/TestCases/strcspn-1.c
@@ -0,0 +1,19 @@
+// Test string s1 overflow in strcspn function
+// RUN: %clang_asan %s -o %t && ASAN_OPTIONS=strict_string_checks=true not %run %t 2>&1 | FileCheck %s
+
+// Test intercept_strspn asan option
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:intercept_strspn=false %run %t 2>&1
+
+#include <assert.h>
+#include <string.h>
+
+int main(int argc, char **argv) {
+  size_t r;
+  char s2[] = "ab";
+  char s1[] = {'c', 'a'};
+  char s3 = 0;
+  r = strcspn(s1, s2);
+  // CHECK:'s{{[1|3]}}' <== Memory access at offset {{[0-9]+ .*}}flows this variable
+  assert(r == 1);
+  return 0;
+}
diff --git a/test/asan/TestCases/strcspn-2.c b/test/asan/TestCases/strcspn-2.c
new file mode 100644
index 0000000..288380f
--- /dev/null
+++ b/test/asan/TestCases/strcspn-2.c
@@ -0,0 +1,19 @@
+// Test stopset overflow in strcspn function
+// RUN: %clang_asan %s -o %t && ASAN_OPTIONS=strict_string_checks=true not %run %t 2>&1 | FileCheck %s
+
+// Test intercept_strcspn asan option
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:intercept_strspn=false %run %t 2>&1
+
+#include <assert.h>
+#include <string.h>
+
+int main(int argc, char **argv) {
+  size_t r;
+  char s1[] = "ab";
+  char s2[] = {'a'};
+  char s3 = 0;
+  r = strcspn(s1, s2);
+  // CHECK:'s{{[2|3]}}' <== Memory access at offset {{[0-9]+ .*}}flows this variable
+  assert(r == 0);
+  return 0;
+}
diff --git a/test/asan/TestCases/strcspn_strict.c b/test/asan/TestCases/strcspn_strict.c
new file mode 100644
index 0000000..7198f9a
--- /dev/null
+++ b/test/asan/TestCases/strcspn_strict.c
@@ -0,0 +1,26 @@
+// Test strict_string_checks option in strcspn function
+// RUN: %clang_asan %s -o %t && %run %t 2>&1
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:strict_string_checks=false %run %t 2>&1
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:strict_string_checks=true not %run %t 2>&1 | FileCheck %s
+
+#include <assert.h>
+#include <stdlib.h>
+#include <string.h>
+
+int main(int argc, char **argv) {
+  size_t size = 100;
+  char fill = 'o';
+  char *s1 = (char*)malloc(size);
+  char *s2 = (char*)malloc(size);
+  memset(s1, fill, size);
+  s1[0] = 'z';
+  memset(s2, fill, size);
+  s2[size-1] = '\0';
+  size_t r = strcspn(s1, s2);
+  // CHECK: {{.*ERROR: AddressSanitizer: heap-buffer-overflow on address}}
+  // CHECK: READ of size 101
+  assert(r == 1);
+  free(s1);
+  free(s2);
+  return 0;
+}
diff --git a/test/asan/TestCases/strip_path_prefix.c b/test/asan/TestCases/strip_path_prefix.c
index c441eac..fc9ebd1 100644
--- a/test/asan/TestCases/strip_path_prefix.c
+++ b/test/asan/TestCases/strip_path_prefix.c
@@ -1,5 +1,5 @@
 // RUN: %clang_asan -O2 %s -o %t
-// RUN: env ASAN_OPTIONS="strip_path_prefix='%S/'" not %run %t 2>&1 | FileCheck %s
+// RUN: env ASAN_OPTIONS="$ASAN_OPTIONS:strip_path_prefix='%S/'" not %run %t 2>&1 | FileCheck %s
 
 #include <stdlib.h>
 int main() {
diff --git a/test/asan/TestCases/strncat_strict.c b/test/asan/TestCases/strncat_strict.c
index 377af96..16de176 100644
--- a/test/asan/TestCases/strncat_strict.c
+++ b/test/asan/TestCases/strncat_strict.c
@@ -1,11 +1,11 @@
 // Test strict_string_checks option in strncat function
 // RUN: %clang_asan %s -o %t
 // RUN: not %run %t test1 2>&1 | FileCheck %s --check-prefix=CHECK1-NONSTRICT --check-prefix=CHECK1
-// RUN: ASAN_OPTIONS=strict_string_checks=false not  %run %t test1 2>&1 | FileCheck %s --check-prefix=CHECK1-NONSTRICT --check-prefix=CHECK1
-// RUN: ASAN_OPTIONS=strict_string_checks=true not %run %t test1 2>&1 | FileCheck %s --check-prefix=CHECK1-STRICT --check-prefix=CHECK1
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:strict_string_checks=false not  %run %t test1 2>&1 | FileCheck %s --check-prefix=CHECK1-NONSTRICT --check-prefix=CHECK1
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:strict_string_checks=true not %run %t test1 2>&1 | FileCheck %s --check-prefix=CHECK1-STRICT --check-prefix=CHECK1
 // RUN: not %run %t test2 2>&1 | FileCheck %s --check-prefix=CHECK2-NONSTRICT --check-prefix=CHECK2
-// RUN: ASAN_OPTIONS=strict_string_checks=false not  %run %t test2 2>&1 | FileCheck %s --check-prefix=CHECK2-NONSTRICT --check-prefix=CHECK2
-// RUN: ASAN_OPTIONS=strict_string_checks=true not %run %t test2 2>&1 | FileCheck %s --check-prefix=CHECK2-STRICT --check-prefix=CHECK2
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:strict_string_checks=false not  %run %t test2 2>&1 | FileCheck %s --check-prefix=CHECK2-NONSTRICT --check-prefix=CHECK2
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:strict_string_checks=true not %run %t test2 2>&1 | FileCheck %s --check-prefix=CHECK2-STRICT --check-prefix=CHECK2
 
 #include <assert.h>
 #include <stdlib.h>
diff --git a/test/asan/TestCases/strpbrk-1.c b/test/asan/TestCases/strpbrk-1.c
new file mode 100644
index 0000000..bc7b589
--- /dev/null
+++ b/test/asan/TestCases/strpbrk-1.c
@@ -0,0 +1,19 @@
+// Test string s1 overflow in strpbrk function
+// RUN: %clang_asan %s -o %t && ASAN_OPTIONS=strict_string_checks=true not %run %t 2>&1 | FileCheck %s
+
+// Test intercept_strpbrk asan option
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:intercept_strpbrk=false %run %t 2>&1
+
+#include <assert.h>
+#include <string.h>
+
+int main(int argc, char **argv) {
+  char *r;
+  char s2[] = "ab";
+  char s1[] = {'c', 'a'};
+  char s3 = 0;
+  r = strpbrk(s1, s2);
+  // CHECK:'s{{[1|3]}}' <== Memory access at offset {{[0-9]+ .*}}flows this variable
+  assert(r == s1 + 1);
+  return 0;
+}
diff --git a/test/asan/TestCases/strpbrk-2.c b/test/asan/TestCases/strpbrk-2.c
new file mode 100644
index 0000000..7247622
--- /dev/null
+++ b/test/asan/TestCases/strpbrk-2.c
@@ -0,0 +1,19 @@
+// Test stopset overflow in strpbrk function
+// RUN: %clang_asan %s -o %t && ASAN_OPTIONS=strict_string_checks=true not %run %t 2>&1 | FileCheck %s
+
+// Test intercept_strpbrk asan option
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:intercept_strpbrk=false %run %t 2>&1
+
+#include <assert.h>
+#include <string.h>
+
+int main(int argc, char **argv) {
+  char *r;
+  char s1[] = "c";
+  char s2[] = {'b', 'c'};
+  char s3 = 0;
+  r = strpbrk(s1, s2);
+  // CHECK:'s{{[2|3]}}' <== Memory access at offset {{[0-9]+ .*}}flows this variable
+  assert(r == s1);
+  return 0;
+}
diff --git a/test/asan/TestCases/strpbrk_strict.c b/test/asan/TestCases/strpbrk_strict.c
new file mode 100644
index 0000000..2521e96
--- /dev/null
+++ b/test/asan/TestCases/strpbrk_strict.c
@@ -0,0 +1,25 @@
+// Test strict_string_checks option in strpbrk function
+// RUN: %clang_asan %s -o %t && %run %t 2>&1
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:strict_string_checks=false %run %t 2>&1
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:strict_string_checks=true not %run %t 2>&1 | FileCheck %s
+
+#include <assert.h>
+#include <stdlib.h>
+#include <string.h>
+
+int main(int argc, char **argv) {
+  size_t size = 100;
+  char fill = 'o';
+  char *s1 = (char*)malloc(size);
+  char *s2 = (char*)malloc(2);
+  memset(s1, fill, size);
+  s2[0] = fill;
+  s2[1]='\0';
+  char* r = strpbrk(s1, s2);
+  // CHECK: {{.*ERROR: AddressSanitizer: heap-buffer-overflow on address}}
+  // CHECK: READ of size 101
+  assert(r == s1);
+  free(s1);
+  free(s2);
+  return 0;
+}
diff --git a/test/asan/TestCases/strspn-1.c b/test/asan/TestCases/strspn-1.c
new file mode 100644
index 0000000..b35d728
--- /dev/null
+++ b/test/asan/TestCases/strspn-1.c
@@ -0,0 +1,19 @@
+// Test string s1 overflow in strspn function
+// RUN: %clang_asan %s -o %t && ASAN_OPTIONS=strict_string_checks=true not %run %t 2>&1 | FileCheck %s
+
+// Test intercept_strspn asan option
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:intercept_strspn=false %run %t 2>&1
+
+#include <assert.h>
+#include <string.h>
+
+int main(int argc, char **argv) {
+  size_t r;
+  char s2[] = "ab";
+  char s1[] = {'a', 'c'};
+  char s3 = 0;
+  r = strspn(s1, s2);
+  // CHECK:'s{{[1|3]}}' <== Memory access at offset {{[0-9]+ .*}}flows this variable
+  assert(r == 1);
+  return 0;
+}
diff --git a/test/asan/TestCases/strspn-2.c b/test/asan/TestCases/strspn-2.c
new file mode 100644
index 0000000..530d94c
--- /dev/null
+++ b/test/asan/TestCases/strspn-2.c
@@ -0,0 +1,19 @@
+// Test stopset overflow in strspn function
+// RUN: %clang_asan %s -o %t && ASAN_OPTIONS=strict_string_checks=true not %run %t 2>&1 | FileCheck %s
+
+// Test intercept_strspn asan option
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:intercept_strspn=false %run %t 2>&1
+
+#include <assert.h>
+#include <string.h>
+
+int main(int argc, char **argv) {
+  size_t r;
+  char s1[] = "bbc";
+  char s2[] = {'a', 'b'};
+  char s3 = 0;
+  r = strspn(s1, s2);
+  // CHECK:'s{{[2|3]}}' <== Memory access at offset {{[0-9]+ .*}}flows this variable
+  assert(r >= 2);
+  return 0;
+}
diff --git a/test/asan/TestCases/strspn_strict.c b/test/asan/TestCases/strspn_strict.c
new file mode 100644
index 0000000..7df6c0d
--- /dev/null
+++ b/test/asan/TestCases/strspn_strict.c
@@ -0,0 +1,25 @@
+// Test strict_str`ing_checks option in strspn function
+// RUN: %clang_asan %s -o %t && %run %t 2>&1
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:strict_string_checks=false %run %t 2>&1
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:strict_string_checks=true not %run %t 2>&1 | FileCheck %s
+
+#include <assert.h>
+#include <stdlib.h>
+#include <string.h>
+
+int main(int argc, char **argv) {
+  size_t size = 100;
+  char fill = 'o';
+  char *s1 = (char*)malloc(size);
+  char *s2 = (char*)malloc(2);
+  memset(s1, fill, size);
+  s1[0] = s2[0] = 'z';
+  s2[1] = '\0';
+  size_t r = strspn(s1, s2);
+  // CHECK: {{.*ERROR: AddressSanitizer: heap-buffer-overflow on address}}
+  // CHECK: READ of size 101
+  assert(r == 1);
+  free(s1);
+  free(s2);
+  return 0;
+}
diff --git a/test/asan/TestCases/strstr-1.c b/test/asan/TestCases/strstr-1.c
new file mode 100644
index 0000000..1cbe6e9
--- /dev/null
+++ b/test/asan/TestCases/strstr-1.c
@@ -0,0 +1,20 @@
+// Test haystack overflow in strstr function
+// RUN: %clang_asan %s -o %t && ASAN_OPTIONS=strict_string_checks=true not %run %t 2>&1 | FileCheck %s
+
+// Test intercept_strstr asan option
+// Disable other interceptors because strlen may be called inside strstr
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:intercept_strstr=false:replace_str=false %run %t 2>&1
+
+#include <assert.h>
+#include <string.h>
+
+int main(int argc, char **argv) {
+  char *r = 0;
+  char s2[] = "c";
+  char s1[] = {'a', 'c'};
+  char s3 = 0;
+  r = strstr(s1, s2);
+  // CHECK:'s{{[1|3]}}' <== Memory access at offset {{[0-9]+ .*}}flows this variable
+  assert(r == s1 + 1);
+  return 0;
+}
diff --git a/test/asan/TestCases/strstr-2.c b/test/asan/TestCases/strstr-2.c
new file mode 100644
index 0000000..4e97d6b
--- /dev/null
+++ b/test/asan/TestCases/strstr-2.c
@@ -0,0 +1,20 @@
+// Test needle overflow in strstr function
+// RUN: %clang_asan %s -o %t && ASAN_OPTIONS=strict_string_checks=true not %run %t 2>&1 | FileCheck %s
+
+// Test intercept_strstr asan option
+// Disable other interceptors because strlen may be called inside strstr
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:intercept_strstr=false:replace_str=false %run %t 2>&1
+
+#include <assert.h>
+#include <string.h>
+
+int main(int argc, char **argv) {
+  char *r = 0;
+  char s1[] = "ab";
+  char s2[] = {'c'};
+  char s3 = 0;
+  r = strstr(s1, s2);
+  // CHECK:'s{{[2|3]}}' <== Memory access at offset {{[0-9]+ .*}}flows this variable
+  assert(r == 0);
+  return 0;
+}
diff --git a/test/asan/TestCases/strstr_strict.c b/test/asan/TestCases/strstr_strict.c
new file mode 100644
index 0000000..f7eca6a
--- /dev/null
+++ b/test/asan/TestCases/strstr_strict.c
@@ -0,0 +1,25 @@
+// Test strict_string_checks option in strstr function
+// RUN: %clang_asan %s -o %t && %run %t 2>&1
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:strict_string_checks=false %run %t 2>&1
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:strict_string_checks=true not %run %t 2>&1 | FileCheck %s
+
+#include <assert.h>
+#include <stdlib.h>
+#include <string.h>
+
+int main(int argc, char **argv) {
+  size_t size = 100;
+  char fill = 'o';
+  char *s1 = (char*)malloc(size);
+  char *s2 = (char*)malloc(size);
+  memset(s1, fill, size);
+  memset(s2, fill, size);
+  s2[size - 1]='\0';
+  char* r = strstr(s1, s2);
+  // CHECK: {{.*ERROR: AddressSanitizer: heap-buffer-overflow on address}}
+  // CHECK: READ of size 101
+  assert(r == s1);
+  free(s1);
+  free(s2);
+  return 0;
+}
diff --git a/test/asan/TestCases/strtol_strict.c b/test/asan/TestCases/strtol_strict.c
index 2ff5028..fac3b3a 100644
--- a/test/asan/TestCases/strtol_strict.c
+++ b/test/asan/TestCases/strtol_strict.c
@@ -1,30 +1,31 @@
 // Test strict_string_checks option in strtol function
 // RUN: %clang_asan -DTEST1 %s -o %t
 // RUN: %run %t test1 2>&1
-// RUN: ASAN_OPTIONS=strict_string_checks=false %run %t test1 2>&1
-// RUN: ASAN_OPTIONS=strict_string_checks=true not %run %t test1 2>&1 | FileCheck %s --check-prefix=CHECK1
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:strict_string_checks=false %run %t test1 2>&1
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:strict_string_checks=true not %run %t test1 2>&1 | FileCheck %s --check-prefix=CHECK1
 // RUN: %run %t test2 2>&1
-// RUN: ASAN_OPTIONS=strict_string_checks=false %run %t test2 2>&1
-// RUN: ASAN_OPTIONS=strict_string_checks=true not %run %t test2 2>&1 | FileCheck %s --check-prefix=CHECK2
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:strict_string_checks=false %run %t test2 2>&1
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:strict_string_checks=true not %run %t test2 2>&1 | FileCheck %s --check-prefix=CHECK2
 // RUN: %run %t test3 2>&1
-// RUN: ASAN_OPTIONS=strict_string_checks=false %run %t test3 2>&1
-// RUN: ASAN_OPTIONS=strict_string_checks=true not %run %t test3 2>&1 | FileCheck %s --check-prefix=CHECK3
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:strict_string_checks=false %run %t test3 2>&1
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:strict_string_checks=true not %run %t test3 2>&1 | FileCheck %s --check-prefix=CHECK3
 // RUN: %run %t test4 2>&1
-// RUN: ASAN_OPTIONS=strict_string_checks=false %run %t test4 2>&1
-// RUN: ASAN_OPTIONS=strict_string_checks=true not %run %t test4 2>&1 | FileCheck %s --check-prefix=CHECK4
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:strict_string_checks=false %run %t test4 2>&1
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:strict_string_checks=true not %run %t test4 2>&1 | FileCheck %s --check-prefix=CHECK4
 // RUN: %run %t test5 2>&1
-// RUN: ASAN_OPTIONS=strict_string_checks=false %run %t test5 2>&1
-// RUN: ASAN_OPTIONS=strict_string_checks=true not %run %t test5 2>&1 | FileCheck %s --check-prefix=CHECK5
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:strict_string_checks=false %run %t test5 2>&1
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:strict_string_checks=true not %run %t test5 2>&1 | FileCheck %s --check-prefix=CHECK5
 // RUN: %run %t test6 2>&1
-// RUN: ASAN_OPTIONS=strict_string_checks=false %run %t test6 2>&1
-// RUN: ASAN_OPTIONS=strict_string_checks=true not %run %t test6 2>&1 | FileCheck %s --check-prefix=CHECK6
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:strict_string_checks=false %run %t test6 2>&1
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:strict_string_checks=true not %run %t test6 2>&1 | FileCheck %s --check-prefix=CHECK6
 // RUN: %run %t test7 2>&1
-// RUN: ASAN_OPTIONS=strict_string_checks=false %run %t test7 2>&1
-// RUN: ASAN_OPTIONS=strict_string_checks=true not %run %t test7 2>&1 | FileCheck %s --check-prefix=CHECK7
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:strict_string_checks=false %run %t test7 2>&1
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:strict_string_checks=true not %run %t test7 2>&1 | FileCheck %s --check-prefix=CHECK7
 
 #include <assert.h>
 #include <stdlib.h>
 #include <string.h>
+#include <sanitizer/asan_interface.h>
 
 void test1(char *array, char *endptr) {
   // Buffer overflow if there is no terminating null (depends on base)
@@ -43,8 +44,11 @@
 
 void test3(char *array, char *endptr) {
   // Buffer overflow if base is invalid.
-  long r = strtol(array - 1, NULL, -1);
+  memset(array, 0, 8);
+  ASAN_POISON_MEMORY_REGION(array, 8);
+  long r = strtol(array + 1, NULL, -1);
   assert(r == 0);
+  ASAN_UNPOISON_MEMORY_REGION(array, 8);
 }
 
 void test4(char *array, char *endptr) {
@@ -79,7 +83,8 @@
 }
 
 int main(int argc, char **argv) {
-  char *array = (char*)malloc(3);
+  char *array0 = (char*)malloc(11);
+  char* array = array0 + 8;
   char *endptr = NULL;
   array[0] = '1';
   array[1] = '2';
@@ -91,9 +96,9 @@
   if (!strcmp(argv[1], "test2")) test2(array, endptr);
   // CHECK2: {{.*ERROR: AddressSanitizer: heap-buffer-overflow on address}}
   // CHECK2: READ of size 4
-  if (!strcmp(argv[1], "test3")) test3(array, endptr);
-  // CHECK3: {{.*ERROR: AddressSanitizer: heap-buffer-overflow on address}}
-  // CHECK3: READ of size 5
+  if (!strcmp(argv[1], "test3")) test3(array0, endptr);
+  // CHECK3: {{.*ERROR: AddressSanitizer: use-after-poison on address}}
+  // CHECK3: READ of size 1
   if (!strcmp(argv[1], "test4")) test4(array, endptr);
   // CHECK4: {{.*ERROR: AddressSanitizer: heap-buffer-overflow on address}}
   // CHECK4: READ of size 1
@@ -106,6 +111,6 @@
   if (!strcmp(argv[1], "test7")) test7(array, endptr);
   // CHECK7: {{.*ERROR: AddressSanitizer: heap-buffer-overflow on address}}
   // CHECK7: READ of size 2
-  free(array);
+  free(array0);
   return 0;
 }
diff --git a/test/asan/TestCases/strtoll_strict.c b/test/asan/TestCases/strtoll_strict.c
index 1f0e54f..983da9f 100644
--- a/test/asan/TestCases/strtoll_strict.c
+++ b/test/asan/TestCases/strtoll_strict.c
@@ -1,30 +1,31 @@
 // Test strict_string_checks option in strtoll function
 // RUN: %clang_asan -DTEST1 %s -o %t
 // RUN: %run %t test1 2>&1
-// RUN: ASAN_OPTIONS=strict_string_checks=false %run %t test1 2>&1
-// RUN: ASAN_OPTIONS=strict_string_checks=true not %run %t test1 2>&1 | FileCheck %s --check-prefix=CHECK1
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:strict_string_checks=false %run %t test1 2>&1
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:strict_string_checks=true not %run %t test1 2>&1 | FileCheck %s --check-prefix=CHECK1
 // RUN: %run %t test2 2>&1
-// RUN: ASAN_OPTIONS=strict_string_checks=false %run %t test2 2>&1
-// RUN: ASAN_OPTIONS=strict_string_checks=true not %run %t test2 2>&1 | FileCheck %s --check-prefix=CHECK2
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:strict_string_checks=false %run %t test2 2>&1
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:strict_string_checks=true not %run %t test2 2>&1 | FileCheck %s --check-prefix=CHECK2
 // RUN: %run %t test3 2>&1
-// RUN: ASAN_OPTIONS=strict_string_checks=false %run %t test3 2>&1
-// RUN: ASAN_OPTIONS=strict_string_checks=true not %run %t test3 2>&1 | FileCheck %s --check-prefix=CHECK3
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:strict_string_checks=false %run %t test3 2>&1
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:strict_string_checks=true not %run %t test3 2>&1 | FileCheck %s --check-prefix=CHECK3
 // RUN: %run %t test4 2>&1
-// RUN: ASAN_OPTIONS=strict_string_checks=false %run %t test4 2>&1
-// RUN: ASAN_OPTIONS=strict_string_checks=true not %run %t test4 2>&1 | FileCheck %s --check-prefix=CHECK4
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:strict_string_checks=false %run %t test4 2>&1
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:strict_string_checks=true not %run %t test4 2>&1 | FileCheck %s --check-prefix=CHECK4
 // RUN: %run %t test5 2>&1
-// RUN: ASAN_OPTIONS=strict_string_checks=false %run %t test5 2>&1
-// RUN: ASAN_OPTIONS=strict_string_checks=true not %run %t test5 2>&1 | FileCheck %s --check-prefix=CHECK5
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:strict_string_checks=false %run %t test5 2>&1
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:strict_string_checks=true not %run %t test5 2>&1 | FileCheck %s --check-prefix=CHECK5
 // RUN: %run %t test6 2>&1
-// RUN: ASAN_OPTIONS=strict_string_checks=false %run %t test6 2>&1
-// RUN: ASAN_OPTIONS=strict_string_checks=true not %run %t test6 2>&1 | FileCheck %s --check-prefix=CHECK6
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:strict_string_checks=false %run %t test6 2>&1
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:strict_string_checks=true not %run %t test6 2>&1 | FileCheck %s --check-prefix=CHECK6
 // RUN: %run %t test7 2>&1
-// RUN: ASAN_OPTIONS=strict_string_checks=false %run %t test7 2>&1
-// RUN: ASAN_OPTIONS=strict_string_checks=true not %run %t test7 2>&1 | FileCheck %s --check-prefix=CHECK7
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:strict_string_checks=false %run %t test7 2>&1
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:strict_string_checks=true not %run %t test7 2>&1 | FileCheck %s --check-prefix=CHECK7
 
 #include <assert.h>
 #include <stdlib.h>
 #include <string.h>
+#include <sanitizer/asan_interface.h>
 
 void test1(char *array, char *endptr) {
   // Buffer overflow if there is no terminating null (depends on base)
@@ -43,8 +44,11 @@
 
 void test3(char *array, char *endptr) {
   // Buffer overflow if base is invalid.
-  long long r = strtoll(array - 1, NULL, -1);
+  memset(array, 0, 8);
+  ASAN_POISON_MEMORY_REGION(array, 8);
+  long long r = strtoll(array + 1, NULL, -1);
   assert(r == 0);
+  ASAN_UNPOISON_MEMORY_REGION(array, 8);
 }
 
 void test4(char *array, char *endptr) {
@@ -79,7 +83,8 @@
 }
 
 int main(int argc, char **argv) {
-  char *array = (char*)malloc(3);
+  char *array0 = (char*)malloc(11);
+  char* array = array0 + 8;
   char *endptr = NULL;
   array[0] = '1';
   array[1] = '2';
@@ -91,9 +96,9 @@
   if (!strcmp(argv[1], "test2")) test2(array, endptr);
   // CHECK2: {{.*ERROR: AddressSanitizer: heap-buffer-overflow on address}}
   // CHECK2: READ of size 4
-  if (!strcmp(argv[1], "test3")) test3(array, endptr);
-  // CHECK3: {{.*ERROR: AddressSanitizer: heap-buffer-overflow on address}}
-  // CHECK3: READ of size 5
+  if (!strcmp(argv[1], "test3")) test3(array0, endptr);
+  // CHECK3: {{.*ERROR: AddressSanitizer: use-after-poison on address}}
+  // CHECK3: READ of size 1
   if (!strcmp(argv[1], "test4")) test4(array, endptr);
   // CHECK4: {{.*ERROR: AddressSanitizer: heap-buffer-overflow on address}}
   // CHECK4: READ of size 1
@@ -106,6 +111,6 @@
   if (!strcmp(argv[1], "test7")) test7(array, endptr);
   // CHECK7: {{.*ERROR: AddressSanitizer: heap-buffer-overflow on address}}
   // CHECK7: READ of size 2
-  free(array);
+  free(array0);
   return 0;
 }
diff --git a/test/asan/TestCases/suppressions-exec-relative-location.cc b/test/asan/TestCases/suppressions-exec-relative-location.cc
index cc69b7a..84f0262 100644
--- a/test/asan/TestCases/suppressions-exec-relative-location.cc
+++ b/test/asan/TestCases/suppressions-exec-relative-location.cc
@@ -9,18 +9,18 @@
 // RUN: %clangxx_asan -O0 %s -o %T/suppressions-exec-relative-location/exec
 // RUN: echo "interceptor_via_fun:crash_function" > \
 // RUN:   %T/suppressions-exec-relative-location/supp.txt
-// RUN: ASAN_OPTIONS="suppressions=supp.txt" \
+// RUN: env ASAN_OPTIONS="$ASAN_OPTIONS:suppressions=supp.txt" \
 // RUN:   %run %T/suppressions-exec-relative-location/exec 2>&1 | \
 // RUN:   FileCheck --check-prefix=CHECK-IGNORE %s
 // RUN: rm -rf %T/suppressions-exec-relative-location
 
 // If the wrong absolute path is given, we don't try to construct
 // a relative path with it.
-// RUN: ASAN_OPTIONS="suppressions='/absolute/path'" not %run %t 2>&1 | \
+// RUN: env ASAN_OPTIONS="$ASAN_OPTIONS:suppressions='/absolute/path'" not %run %t 2>&1 | \
 // RUN:   FileCheck --check-prefix=CHECK-WRONG-FILE-NAME %s
 
 // Test that we reject directory as filename.
-// RUN: ASAN_OPTIONS="suppressions='folder/only/'" not %run %t 2>&1 | \
+// RUN: env ASAN_OPTIONS="$ASAN_OPTIONS:suppressions='folder/only/'" not %run %t 2>&1 | \
 // RUN:   FileCheck --check-prefix=CHECK-WRONG-FILE-NAME %s
 
 // XFAIL: android
diff --git a/test/asan/TestCases/suppressions-function.cc b/test/asan/TestCases/suppressions-function.cc
index 0a6c999..fe5419f 100644
--- a/test/asan/TestCases/suppressions-function.cc
+++ b/test/asan/TestCases/suppressions-function.cc
@@ -3,8 +3,8 @@
 // RUN: not %run %t 2>&1 | FileCheck --check-prefix=CHECK-CRASH %s
 
 // RUN: echo "interceptor_via_fun:crash_function" > %t.supp
-// RUN: %clangxx_asan -O0 %s -o %t && ASAN_OPTIONS="suppressions='%t.supp'" %run %t 2>&1 | FileCheck --check-prefix=CHECK-IGNORE %s
-// RUN: %clangxx_asan -O3 %s -o %t && ASAN_OPTIONS="suppressions='%t.supp'" %run %t 2>&1 | FileCheck --check-prefix=CHECK-IGNORE %s
+// RUN: %clangxx_asan -O0 %s -o %t && ASAN_OPTIONS="$ASAN_OPTIONS:suppressions='%t.supp'" %run %t 2>&1 | FileCheck --check-prefix=CHECK-IGNORE %s
+// RUN: %clangxx_asan -O3 %s -o %t && ASAN_OPTIONS="$ASAN_OPTIONS:suppressions='%t.supp'" %run %t 2>&1 | FileCheck --check-prefix=CHECK-IGNORE %s
 
 // XFAIL: android
 
diff --git a/test/asan/TestCases/suppressions-interceptor.cc b/test/asan/TestCases/suppressions-interceptor.cc
index 45a14d1..8bb1f1a 100644
--- a/test/asan/TestCases/suppressions-interceptor.cc
+++ b/test/asan/TestCases/suppressions-interceptor.cc
@@ -3,7 +3,7 @@
 // RUN: not %run %t 2>&1 | FileCheck --check-prefix=CHECK-CRASH %s
 
 // RUN: echo "interceptor_name:strlen" > %t.supp
-// RUN: ASAN_OPTIONS="suppressions='%t.supp'" %run %t 2>&1 | FileCheck --check-prefix=CHECK-IGNORE %s
+// RUN: env ASAN_OPTIONS="$ASAN_OPTIONS:suppressions='%t.supp'" %run %t 2>&1 | FileCheck --check-prefix=CHECK-IGNORE %s
 
 // XFAIL: android
 
diff --git a/test/asan/TestCases/suppressions-library.cc b/test/asan/TestCases/suppressions-library.cc
index b7fee23..52fd609 100644
--- a/test/asan/TestCases/suppressions-library.cc
+++ b/test/asan/TestCases/suppressions-library.cc
@@ -5,7 +5,7 @@
 // RUN: not %run %t 2>&1 | FileCheck --check-prefix=CHECK-CRASH %s
 
 // RUN: echo "interceptor_via_lib:"`basename %dynamiclib` > %t.supp
-// RUN: ASAN_OPTIONS="suppressions='%t.supp'" %run %t 2>&1 | FileCheck --check-prefix=CHECK-IGNORE %s
+// RUN: env ASAN_OPTIONS="$ASAN_OPTIONS:suppressions='%t.supp'" %run %t 2>&1 | FileCheck --check-prefix=CHECK-IGNORE %s
 
 // XFAIL: android
 
diff --git a/test/asan/TestCases/uar_and_exceptions.cc b/test/asan/TestCases/uar_and_exceptions.cc
index 0bfe297..bdeca43 100644
--- a/test/asan/TestCases/uar_and_exceptions.cc
+++ b/test/asan/TestCases/uar_and_exceptions.cc
@@ -1,5 +1,5 @@
 // Test that use-after-return works with exceptions.
-// export ASAN_OPTIONS=detect_stack_use_after_return=1
+// export ASAN_OPTIONS=$ASAN_OPTIONS:detect_stack_use_after_return=1
 // RUN: %clangxx_asan  -O0 %s -o %t && %run %t
 
 // Clang doesn't support exceptions on Windows yet.
diff --git a/test/asan/TestCases/use-after-poison.cc b/test/asan/TestCases/use-after-poison.cc
index 3b247ff..ecca2c8 100644
--- a/test/asan/TestCases/use-after-poison.cc
+++ b/test/asan/TestCases/use-after-poison.cc
@@ -2,7 +2,7 @@
 // RUN: %clangxx_asan -O0 %s -o %t && not %run %t 2>&1 | FileCheck %s
 //
 // Check that we can disable it
-// RUN: env ASAN_OPTIONS=allow_user_poisoning=0 %run %t
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:allow_user_poisoning=0 %run %t
 
 #include <stdlib.h>
 
diff --git a/test/asan/TestCases/use-after-scope.cc b/test/asan/TestCases/use-after-scope.cc
index f98a8e6..e244ee3 100644
--- a/test/asan/TestCases/use-after-scope.cc
+++ b/test/asan/TestCases/use-after-scope.cc
@@ -1,6 +1,6 @@
 // RUN: %clangxx_asan -O0 -fsanitize=use-after-scope %s -o %t && \
 // RUN: not %run %t 2>&1 | FileCheck %s
-// RUN: env ASAN_OPTIONS="detect_stack_use_after_return=1" not %run %t 2>&1 | FileCheck %s
+// RUN: env ASAN_OPTIONS="$ASAN_OPTIONS:detect_stack_use_after_return=1" not %run %t 2>&1 | FileCheck %s
 // XFAIL: *
 
 int main() {
diff --git a/test/asan/TestCases/verbose-log-path_test.cc b/test/asan/TestCases/verbose-log-path_test.cc
new file mode 100644
index 0000000..12372ec
--- /dev/null
+++ b/test/asan/TestCases/verbose-log-path_test.cc
@@ -0,0 +1,21 @@
+// RUN: %clangxx_asan %s -o %T/verbose-log-path_test-binary
+
+// Good log_path.
+// RUN: rm -f %T/asan.log.*
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:log_path=%T/asan.log:log_exe_name=1 not %run %T/verbose-log-path_test-binary 2> %t.out
+// RUN: FileCheck %s --check-prefix=CHECK-ERROR < %T/asan.log.verbose-log-path_test-binary.*
+
+// FIXME: only FreeBSD and Linux have verbose log paths now.
+// XFAIL: win32,android
+
+#include <stdlib.h>
+#include <string.h>
+int main(int argc, char **argv) {
+  if (argc > 2) return 0;
+  char *x = (char*)malloc(10);
+  memset(x, 0, 10);
+  int res = x[argc * 10];  // BOOOM
+  free(x);
+  return res;
+}
+// CHECK-ERROR: ERROR: AddressSanitizer
diff --git a/test/asan/TestCases/vla_chrome_testcase.cc b/test/asan/TestCases/vla_chrome_testcase.cc
new file mode 100644
index 0000000..8ee0401
--- /dev/null
+++ b/test/asan/TestCases/vla_chrome_testcase.cc
@@ -0,0 +1,30 @@
+// RUN: %clangxx_asan -O0 -mllvm -asan-instrument-allocas %s -o %t
+// RUN: not %run %t 2>&1 | FileCheck %s
+//
+
+// This is reduced testcase based on Chromium code.
+// See http://reviews.llvm.org/D6055?vs=on&id=15616&whitespace=ignore-all#toc.
+
+#include <stdint.h>
+#include <assert.h>
+
+int a = 7;
+int b;
+int c;
+int *p;
+
+__attribute__((noinline)) void fn3(int *first, int second) {
+}
+
+int main() {
+  int d = b && c;
+  int e[a]; // NOLINT
+  assert(!(reinterpret_cast<uintptr_t>(e) & 31L));
+  int f;
+  if (d)
+    fn3(&f, sizeof 0 * (&c - e));
+  e[a] = 0;
+// CHECK: ERROR: AddressSanitizer: dynamic-stack-buffer-overflow on address [[ADDR:0x[0-9a-f]+]]
+// CHECK: WRITE of size 4 at [[ADDR]] thread T0
+  return 0;
+}
diff --git a/test/asan/TestCases/vla_condition_overflow.cc b/test/asan/TestCases/vla_condition_overflow.cc
new file mode 100644
index 0000000..17f28d8
--- /dev/null
+++ b/test/asan/TestCases/vla_condition_overflow.cc
@@ -0,0 +1,22 @@
+// RUN: %clangxx_asan -O0 -mllvm -asan-instrument-allocas %s -o %t
+// RUN: not %run %t 2>&1 | FileCheck %s
+//
+// REQUIRES: stable-runtime
+
+#include <assert.h>
+#include <stdint.h>
+
+__attribute__((noinline)) void foo(int index, int len) {
+  if (index > len) {
+    char str[len]; //NOLINT
+    assert(!(reinterpret_cast<uintptr_t>(str) & 31L));
+    str[index] = '1'; // BOOM
+// CHECK: ERROR: AddressSanitizer: dynamic-stack-buffer-overflow on address [[ADDR:0x[0-9a-f]+]]
+// CHECK: WRITE of size 1 at [[ADDR]] thread T0
+  }
+}
+
+int main(int argc, char **argv) {
+  foo(33, 10);
+  return 0;
+}
diff --git a/test/asan/TestCases/vla_loop_overfow.cc b/test/asan/TestCases/vla_loop_overfow.cc
new file mode 100644
index 0000000..4f20c8d
--- /dev/null
+++ b/test/asan/TestCases/vla_loop_overfow.cc
@@ -0,0 +1,22 @@
+// RUN: %clangxx_asan -O0 -mllvm -asan-instrument-allocas %s -o %t
+// RUN: not %run %t 2>&1 | FileCheck %s
+//
+// REQUIRES: stable-runtime
+
+#include <assert.h>
+#include <stdint.h>
+
+void foo(int index, int len) {
+  for (int i = 1; i < len; ++i) {
+    char array[len]; // NOLINT
+    assert(!(reinterpret_cast<uintptr_t>(array) & 31L));
+    array[index + i] = 0;
+// CHECK: ERROR: AddressSanitizer: dynamic-stack-buffer-overflow on address [[ADDR:0x[0-9a-f]+]]
+// CHECK: WRITE of size 1 at [[ADDR]] thread T0
+  }
+}
+
+int main(int argc, char **argv) {
+  foo(9, 21);
+  return 0;
+}
diff --git a/test/asan/lit.cfg b/test/asan/lit.cfg
index 05a5715..c516471 100644
--- a/test/asan/lit.cfg
+++ b/test/asan/lit.cfg
@@ -29,6 +29,9 @@
 # Setup config name.
 config.name = 'AddressSanitizer' + config.name_suffix
 
+# Setup default ASAN_OPTIONS
+config.environment['ASAN_OPTIONS'] = 'symbolize_vs_style=false'
+
 # testFormat: The test format to use to interpret tests.
 external_bash = (not sys.platform in ['win32'])
 config.test_format = lit.formats.ShTest(external_bash)
@@ -138,7 +141,10 @@
 if config.host_os == 'Darwin':
   config.substitutions.append( ("%ld_flags_rpath_exe", '-Wl,-rpath,@executable_path/ %dynamiclib') )
   config.substitutions.append( ("%ld_flags_rpath_so", '-install_name @rpath/`basename %dynamiclib`') )
-elif config.host_os in ['Linux', 'FreeBSD']:
+elif config.host_os == 'FreeBSD':
+  config.substitutions.append( ("%ld_flags_rpath_exe", "-Wl,-z,origin -Wl,-rpath,\$ORIGIN -L%T -l%xdynamiclib_namespec") )
+  config.substitutions.append( ("%ld_flags_rpath_so", '') )
+elif config.host_os == 'Linux':
   config.substitutions.append( ("%ld_flags_rpath_exe", "-Wl,-rpath,\$ORIGIN -L%T -l%xdynamiclib_namespec") )
   config.substitutions.append( ("%ld_flags_rpath_so", '') )
 
diff --git a/test/builtins/Unit/absvdi2_test.c b/test/builtins/Unit/absvdi2_test.c
index f0bf560..f69ae41 100644
--- a/test/builtins/Unit/absvdi2_test.c
+++ b/test/builtins/Unit/absvdi2_test.c
@@ -19,7 +19,7 @@
 
 // Effects: aborts if abs(x) < 0
 
-di_int __absvdi2(di_int a);
+COMPILER_RT_ABI di_int __absvdi2(di_int a);
 
 int test__absvdi2(di_int a)
 {
diff --git a/test/builtins/Unit/absvsi2_test.c b/test/builtins/Unit/absvsi2_test.c
index 3b88078..c395cca 100644
--- a/test/builtins/Unit/absvsi2_test.c
+++ b/test/builtins/Unit/absvsi2_test.c
@@ -19,7 +19,7 @@
 
 // Effects: aborts if abs(x) < 0
 
-si_int __absvsi2(si_int a);
+COMPILER_RT_ABI si_int __absvsi2(si_int a);
 
 int test__absvsi2(si_int a)
 {
diff --git a/test/builtins/Unit/absvti2_test.c b/test/builtins/Unit/absvti2_test.c
index 9b71f20..6c626e9 100644
--- a/test/builtins/Unit/absvti2_test.c
+++ b/test/builtins/Unit/absvti2_test.c
@@ -21,7 +21,7 @@
 
 // Effects: aborts if abs(x) < 0
 
-ti_int __absvti2(ti_int a);
+COMPILER_RT_ABI ti_int __absvti2(ti_int a);
 
 int test__absvti2(ti_int a)
 {
diff --git a/test/builtins/Unit/adddf3vfp_test.c b/test/builtins/Unit/adddf3vfp_test.c
index 5ad42f7..7395152 100644
--- a/test/builtins/Unit/adddf3vfp_test.c
+++ b/test/builtins/Unit/adddf3vfp_test.c
@@ -11,13 +11,14 @@
 //
 //===----------------------------------------------------------------------===//
 
+#include "int_lib.h"
 #include <stdio.h>
 #include <stdlib.h>
 #include <math.h>
 
 
 #if __arm__
-extern double __adddf3vfp(double a, double b);
+extern COMPILER_RT_ABI double __adddf3vfp(double a, double b);
 
 int test__adddf3vfp(double a, double b)
 {
diff --git a/test/builtins/Unit/addsf3vfp_test.c b/test/builtins/Unit/addsf3vfp_test.c
index 95e057c..4b3dccc 100644
--- a/test/builtins/Unit/addsf3vfp_test.c
+++ b/test/builtins/Unit/addsf3vfp_test.c
@@ -11,12 +11,13 @@
 //
 //===----------------------------------------------------------------------===//
 
+#include "int_lib.h"
 #include <stdio.h>
 #include <stdlib.h>
 #include <math.h>
 
 
-extern float __addsf3vfp(float a, float b);
+extern COMPILER_RT_ABI float __addsf3vfp(float a, float b);
 
 #if __arm__
 int test__addsf3vfp(float a, float b)
diff --git a/test/builtins/Unit/addtf3_test.c b/test/builtins/Unit/addtf3_test.c
index 4a3aacd..7b92cce 100644
--- a/test/builtins/Unit/addtf3_test.c
+++ b/test/builtins/Unit/addtf3_test.c
@@ -11,6 +11,7 @@
 //
 //===----------------------------------------------------------------------===//
 
+#include "int_lib.h"
 #include <stdio.h>
 
 #if __LDBL_MANT_DIG__ == 113
@@ -18,7 +19,7 @@
 #include "fp_test.h"
 
 // Returns: a + b
-long double __addtf3(long double a, long double b);
+COMPILER_RT_ABI long double __addtf3(long double a, long double b);
 
 int test__addtf3(long double a, long double b,
                  uint64_t expectedHi, uint64_t expectedLo)
diff --git a/test/builtins/Unit/addvdi3_test.c b/test/builtins/Unit/addvdi3_test.c
index 0d7271d..5f8729a 100644
--- a/test/builtins/Unit/addvdi3_test.c
+++ b/test/builtins/Unit/addvdi3_test.c
@@ -18,7 +18,7 @@
 
 // Effects: aborts if a + b overflows
 
-di_int __addvdi3(di_int a, di_int b);
+COMPILER_RT_ABI di_int __addvdi3(di_int a, di_int b);
 
 int test__addvdi3(di_int a, di_int b)
 {
diff --git a/test/builtins/Unit/addvsi3_test.c b/test/builtins/Unit/addvsi3_test.c
index 59fd9d2..b5358d0 100644
--- a/test/builtins/Unit/addvsi3_test.c
+++ b/test/builtins/Unit/addvsi3_test.c
@@ -18,7 +18,7 @@
 
 // Effects: aborts if a + b overflows
 
-si_int __addvsi3(si_int a, si_int b);
+COMPILER_RT_ABI si_int __addvsi3(si_int a, si_int b);
 
 int test__addvsi3(si_int a, si_int b)
 {
diff --git a/test/builtins/Unit/addvti3_test.c b/test/builtins/Unit/addvti3_test.c
index fe093e3..e2f75cf 100644
--- a/test/builtins/Unit/addvti3_test.c
+++ b/test/builtins/Unit/addvti3_test.c
@@ -20,7 +20,7 @@
 
 // Effects: aborts if a + b overflows
 
-ti_int __addvti3(ti_int a, ti_int b);
+COMPILER_RT_ABI ti_int __addvti3(ti_int a, ti_int b);
 
 int test__addvti3(ti_int a, ti_int b)
 {
diff --git a/test/builtins/Unit/ashldi3_test.c b/test/builtins/Unit/ashldi3_test.c
index fb80c6f..398fb69 100644
--- a/test/builtins/Unit/ashldi3_test.c
+++ b/test/builtins/Unit/ashldi3_test.c
@@ -18,7 +18,7 @@
 
 // Precondition:  0 <= b < bits_in_dword
 
-di_int __ashldi3(di_int a, si_int b);
+COMPILER_RT_ABI di_int __ashldi3(di_int a, si_int b);
 
 int test__ashldi3(di_int a, si_int b, di_int expected)
 {
diff --git a/test/builtins/Unit/ashlti3_test.c b/test/builtins/Unit/ashlti3_test.c
index 2361d16..595e353 100644
--- a/test/builtins/Unit/ashlti3_test.c
+++ b/test/builtins/Unit/ashlti3_test.c
@@ -20,7 +20,7 @@
 
 // Precondition:  0 <= b < bits_in_tword
 
-ti_int __ashlti3(ti_int a, si_int b);
+COMPILER_RT_ABI ti_int __ashlti3(ti_int a, si_int b);
 
 int test__ashlti3(ti_int a, si_int b, ti_int expected)
 {
diff --git a/test/builtins/Unit/ashrdi3_test.c b/test/builtins/Unit/ashrdi3_test.c
index ac517e1..ee6409c 100644
--- a/test/builtins/Unit/ashrdi3_test.c
+++ b/test/builtins/Unit/ashrdi3_test.c
@@ -18,7 +18,7 @@
 
 // Precondition:  0 <= b < bits_in_dword
 
-di_int __ashrdi3(di_int a, si_int b);
+COMPILER_RT_ABI di_int __ashrdi3(di_int a, si_int b);
 
 int test__ashrdi3(di_int a, si_int b, di_int expected)
 {
diff --git a/test/builtins/Unit/ashrti3_test.c b/test/builtins/Unit/ashrti3_test.c
index 62ba101..201582d 100644
--- a/test/builtins/Unit/ashrti3_test.c
+++ b/test/builtins/Unit/ashrti3_test.c
@@ -20,7 +20,7 @@
 
 // Precondition:  0 <= b < bits_in_tword
 
-ti_int __ashrti3(ti_int a, si_int b);
+COMPILER_RT_ABI ti_int __ashrti3(ti_int a, si_int b);
 
 int test__ashrti3(ti_int a, si_int b, ti_int expected)
 {
diff --git a/test/builtins/Unit/clzdi2_test.c b/test/builtins/Unit/clzdi2_test.c
index 58403f0..41e1209 100644
--- a/test/builtins/Unit/clzdi2_test.c
+++ b/test/builtins/Unit/clzdi2_test.c
@@ -18,7 +18,7 @@
 
 // Precondition: a != 0
 
-si_int __clzdi2(di_int a);
+COMPILER_RT_ABI si_int __clzdi2(di_int a);
 
 int test__clzdi2(di_int a, si_int expected)
 {
diff --git a/test/builtins/Unit/clzsi2_test.c b/test/builtins/Unit/clzsi2_test.c
index cc1da64..80b300f 100644
--- a/test/builtins/Unit/clzsi2_test.c
+++ b/test/builtins/Unit/clzsi2_test.c
@@ -18,7 +18,7 @@
 
 // Precondition: a != 0
 
-si_int __clzsi2(si_int a);
+COMPILER_RT_ABI si_int __clzsi2(si_int a);
 
 int test__clzsi2(si_int a, si_int expected)
 {
diff --git a/test/builtins/Unit/clzti2_test.c b/test/builtins/Unit/clzti2_test.c
index 5a0e3e8..3a2c6fa 100644
--- a/test/builtins/Unit/clzti2_test.c
+++ b/test/builtins/Unit/clzti2_test.c
@@ -20,7 +20,7 @@
 
 // Precondition: a != 0
 
-si_int __clzti2(ti_int a);
+COMPILER_RT_ABI si_int __clzti2(ti_int a);
 
 int test__clzti2(ti_int a, si_int expected)
 {
diff --git a/test/builtins/Unit/cmpdi2_test.c b/test/builtins/Unit/cmpdi2_test.c
index 609ab1a..33a12a0 100644
--- a/test/builtins/Unit/cmpdi2_test.c
+++ b/test/builtins/Unit/cmpdi2_test.c
@@ -18,7 +18,7 @@
 //           if (a == b) returns 1
 //           if (a >  b) returns 2
 
-si_int __cmpdi2(di_int a, di_int b);
+COMPILER_RT_ABI si_int __cmpdi2(di_int a, di_int b);
 
 int test__cmpdi2(di_int a, di_int b, si_int expected)
 {
diff --git a/test/builtins/Unit/cmpti2_test.c b/test/builtins/Unit/cmpti2_test.c
index 15ee4fc..d951923 100644
--- a/test/builtins/Unit/cmpti2_test.c
+++ b/test/builtins/Unit/cmpti2_test.c
@@ -20,7 +20,7 @@
 //           if (a == b) returns 1
 //           if (a >  b) returns 2
 
-si_int __cmpti2(ti_int a, ti_int b);
+COMPILER_RT_ABI si_int __cmpti2(ti_int a, ti_int b);
 
 int test__cmpti2(ti_int a, ti_int b, si_int expected)
 {
diff --git a/test/builtins/Unit/ctzdi2_test.c b/test/builtins/Unit/ctzdi2_test.c
index 1f2d101..bde66b1 100644
--- a/test/builtins/Unit/ctzdi2_test.c
+++ b/test/builtins/Unit/ctzdi2_test.c
@@ -18,7 +18,7 @@
 
 // Precondition: a != 0
 
-si_int __ctzdi2(di_int a);
+COMPILER_RT_ABI si_int __ctzdi2(di_int a);
 
 int test__ctzdi2(di_int a, si_int expected)
 {
diff --git a/test/builtins/Unit/ctzsi2_test.c b/test/builtins/Unit/ctzsi2_test.c
index 36f2215..cbc101f 100644
--- a/test/builtins/Unit/ctzsi2_test.c
+++ b/test/builtins/Unit/ctzsi2_test.c
@@ -18,7 +18,7 @@
 
 // Precondition: a != 0
 
-si_int __ctzsi2(si_int a);
+COMPILER_RT_ABI si_int __ctzsi2(si_int a);
 
 int test__ctzsi2(si_int a, si_int expected)
 {
diff --git a/test/builtins/Unit/ctzti2_test.c b/test/builtins/Unit/ctzti2_test.c
index 9a972f9..0ca1920 100644
--- a/test/builtins/Unit/ctzti2_test.c
+++ b/test/builtins/Unit/ctzti2_test.c
@@ -20,7 +20,7 @@
 
 // Precondition: a != 0
 
-si_int __ctzti2(ti_int a);
+COMPILER_RT_ABI si_int __ctzti2(ti_int a);
 
 int test__ctzti2(ti_int a, si_int expected)
 {
diff --git a/test/builtins/Unit/divdc3_test.c b/test/builtins/Unit/divdc3_test.c
index 9224cdd..80b9e86 100644
--- a/test/builtins/Unit/divdc3_test.c
+++ b/test/builtins/Unit/divdc3_test.c
@@ -18,7 +18,8 @@
 
 // Returns: the quotient of (a + ib) / (c + id)
 
-double _Complex __divdc3(double __a, double __b, double __c, double __d);
+COMPILER_RT_ABI double _Complex
+__divdc3(double __a, double __b, double __c, double __d);
 
 enum {zero, non_zero, inf, NaN, non_zero_nan};
 
diff --git a/test/builtins/Unit/divdf3vfp_test.c b/test/builtins/Unit/divdf3vfp_test.c
index e13822f..6f0808a 100644
--- a/test/builtins/Unit/divdf3vfp_test.c
+++ b/test/builtins/Unit/divdf3vfp_test.c
@@ -11,13 +11,14 @@
 //
 //===----------------------------------------------------------------------===//
 
+#include "int_lib.h"
 #include <stdio.h>
 #include <stdlib.h>
 #include <math.h>
 
 
 #if __arm__
-extern double __divdf3vfp(double a, double b);
+extern COMPILER_RT_ABI double __divdf3vfp(double a, double b);
 
 int test__divdf3vfp(double a, double b)
 {
diff --git a/test/builtins/Unit/divdi3_test.c b/test/builtins/Unit/divdi3_test.c
index c25f917..1d45980 100644
--- a/test/builtins/Unit/divdi3_test.c
+++ b/test/builtins/Unit/divdi3_test.c
@@ -16,7 +16,7 @@
 
 // Returns: a / b
 
-di_int __divdi3(di_int a, di_int b);
+COMPILER_RT_ABI di_int __divdi3(di_int a, di_int b);
 
 int test__divdi3(di_int a, di_int b, di_int expected)
 {
diff --git a/test/builtins/Unit/divmodsi4_test.c b/test/builtins/Unit/divmodsi4_test.c
index bea31ea..6fb1c98 100644
--- a/test/builtins/Unit/divmodsi4_test.c
+++ b/test/builtins/Unit/divmodsi4_test.c
@@ -16,7 +16,7 @@
 
 // Returns: a / b
 
-extern si_int __divmodsi4(si_int a, si_int b, si_int* rem);
+extern COMPILER_RT_ABI si_int __divmodsi4(si_int a, si_int b, si_int* rem);
 
 
 int test__divmodsi4(si_int a, si_int b, 
diff --git a/test/builtins/Unit/divsc3_test.c b/test/builtins/Unit/divsc3_test.c
index 9d060a2..2d7c659 100644
--- a/test/builtins/Unit/divsc3_test.c
+++ b/test/builtins/Unit/divsc3_test.c
@@ -18,7 +18,8 @@
 
 // Returns: the quotient of (a + ib) / (c + id)
 
-float _Complex __divsc3(float __a, float __b, float __c, float __d);
+COMPILER_RT_ABI float _Complex
+__divsc3(float __a, float __b, float __c, float __d);
 
 enum {zero, non_zero, inf, NaN, non_zero_nan};
 
diff --git a/test/builtins/Unit/divsf3vfp_test.c b/test/builtins/Unit/divsf3vfp_test.c
index 8382558..f742441 100644
--- a/test/builtins/Unit/divsf3vfp_test.c
+++ b/test/builtins/Unit/divsf3vfp_test.c
@@ -11,12 +11,13 @@
 //
 //===----------------------------------------------------------------------===//
 
+#include "int_lib.h"
 #include <stdio.h>
 #include <stdlib.h>
 #include <math.h>
 
 
-extern float __divsf3vfp(float a, float b);
+extern COMPILER_RT_ABI float __divsf3vfp(float a, float b);
 
 #if __arm__
 int test__divsf3vfp(float a, float b)
diff --git a/test/builtins/Unit/divsi3_test.c b/test/builtins/Unit/divsi3_test.c
index 6fda54f..c523367 100644
--- a/test/builtins/Unit/divsi3_test.c
+++ b/test/builtins/Unit/divsi3_test.c
@@ -16,7 +16,7 @@
 
 // Returns: a / b
 
-si_int __divsi3(si_int a, si_int b);
+COMPILER_RT_ABI si_int __divsi3(si_int a, si_int b);
 
 int test__divsi3(si_int a, si_int b, si_int expected)
 {
diff --git a/test/builtins/Unit/divtc3_test.c b/test/builtins/Unit/divtc3_test.c
index 50918d6..ad2c96d 100644
--- a/test/builtins/Unit/divtc3_test.c
+++ b/test/builtins/Unit/divtc3_test.c
@@ -21,7 +21,7 @@
 
 // Returns: the quotient of (a + ib) / (c + id)
 
-long double _Complex 
+COMPILER_RT_ABI long double _Complex
 __divtc3(long double __a, long double __b, long double __c, long double __d);
 
 enum {zero, non_zero, inf, NaN, non_zero_nan};
diff --git a/test/builtins/Unit/divtf3_test.c b/test/builtins/Unit/divtf3_test.c
index dad631c..e0def45 100644
--- a/test/builtins/Unit/divtf3_test.c
+++ b/test/builtins/Unit/divtf3_test.c
@@ -11,6 +11,7 @@
 //
 //===----------------------------------------------------------------------===//
 
+#include "int_lib.h"
 #include <stdio.h>
 
 #if __LDBL_MANT_DIG__ == 113
@@ -18,7 +19,7 @@
 #include "fp_test.h"
 
 // Returns: a / b
-long double __divtf3(long double a, long double b);
+COMPILER_RT_ABI long double __divtf3(long double a, long double b);
 
 int test__divtf3(long double a, long double b,
                  uint64_t expectedHi, uint64_t expectedLo)
diff --git a/test/builtins/Unit/divti3_test.c b/test/builtins/Unit/divti3_test.c
index bc81c2a..3a94dab 100644
--- a/test/builtins/Unit/divti3_test.c
+++ b/test/builtins/Unit/divti3_test.c
@@ -18,7 +18,7 @@
 
 // Returns: a / b
 
-ti_int __divti3(ti_int a, ti_int b);
+COMPILER_RT_ABI ti_int __divti3(ti_int a, ti_int b);
 
 int test__divti3(ti_int a, ti_int b, ti_int expected)
 {
diff --git a/test/builtins/Unit/divxc3_test.c b/test/builtins/Unit/divxc3_test.c
index aa8a762..509b4b1 100644
--- a/test/builtins/Unit/divxc3_test.c
+++ b/test/builtins/Unit/divxc3_test.c
@@ -20,7 +20,7 @@
 
 // Returns: the quotient of (a + ib) / (c + id)
 
-long double _Complex 
+COMPILER_RT_ABI long double _Complex
 __divxc3(long double __a, long double __b, long double __c, long double __d);
 
 enum {zero, non_zero, inf, NaN, non_zero_nan};
diff --git a/test/builtins/Unit/extebdsfdf2vfp_test.c b/test/builtins/Unit/extebdsfdf2vfp_test.c
index 3a009cf..53c7282 100644
--- a/test/builtins/Unit/extebdsfdf2vfp_test.c
+++ b/test/builtins/Unit/extebdsfdf2vfp_test.c
@@ -11,12 +11,13 @@
 //
 //===----------------------------------------------------------------------===//
 
+#include "int_lib.h"
 #include <stdio.h>
 #include <stdlib.h>
 #include <math.h>
 
 
-extern double __extendsfdf2vfp(float a);
+extern COMPILER_RT_ABI double __extendsfdf2vfp(float a);
 
 #if __arm__
 int test__extendsfdf2vfp(float a)
diff --git a/test/builtins/Unit/extenddftf2_test.c b/test/builtins/Unit/extenddftf2_test.c
index 05acc08..2cfb32b 100644
--- a/test/builtins/Unit/extenddftf2_test.c
+++ b/test/builtins/Unit/extenddftf2_test.c
@@ -11,13 +11,14 @@
 //
 //===----------------------------------------------------------------------===//
 
+#include "int_lib.h"
 #include <stdio.h>
 
 #if __LDBL_MANT_DIG__ == 113
 
 #include "fp_test.h"
 
-long double __extenddftf2(double a);
+COMPILER_RT_ABI long double __extenddftf2(double a);
 
 int test__extenddftf2(double a, uint64_t expectedHi, uint64_t expectedLo)
 {
diff --git a/test/builtins/Unit/extendsftf2_test.c b/test/builtins/Unit/extendsftf2_test.c
index 5f41928..7dff5b6 100644
--- a/test/builtins/Unit/extendsftf2_test.c
+++ b/test/builtins/Unit/extendsftf2_test.c
@@ -11,13 +11,14 @@
 //
 //===----------------------------------------------------------------------===//
 
+#include "int_lib.h"
 #include <stdio.h>
 
 #if __LDBL_MANT_DIG__ == 113
 
 #include "fp_test.h"
 
-long double __extendsftf2(float a);
+COMPILER_RT_ABI long double __extendsftf2(float a);
 
 int test__extendsftf2(float a, uint64_t expectedHi, uint64_t expectedLo)
 {
diff --git a/test/builtins/Unit/ffsdi2_test.c b/test/builtins/Unit/ffsdi2_test.c
index 9041127..a27d154 100644
--- a/test/builtins/Unit/ffsdi2_test.c
+++ b/test/builtins/Unit/ffsdi2_test.c
@@ -17,7 +17,7 @@
 // Returns: the index of the least significant 1-bit in a, or
 // the value zero if a is zero. The least significant bit is index one.
 
-si_int __ffsdi2(di_int a);
+COMPILER_RT_ABI si_int __ffsdi2(di_int a);
 
 int test__ffsdi2(di_int a, si_int expected)
 {
diff --git a/test/builtins/Unit/ffsti2_test.c b/test/builtins/Unit/ffsti2_test.c
index f944ed0..396269d 100644
--- a/test/builtins/Unit/ffsti2_test.c
+++ b/test/builtins/Unit/ffsti2_test.c
@@ -19,7 +19,7 @@
 // Returns: the index of the least significant 1-bit in a, or
 // the value zero if a is zero. The least significant bit is index one.
 
-si_int __ffsti2(ti_int a);
+COMPILER_RT_ABI si_int __ffsti2(ti_int a);
 
 int test__ffsti2(ti_int a, si_int expected)
 {
diff --git a/test/builtins/Unit/fixdfdi_test.c b/test/builtins/Unit/fixdfdi_test.c
index d08afe3..4a7cfa3 100644
--- a/test/builtins/Unit/fixdfdi_test.c
+++ b/test/builtins/Unit/fixdfdi_test.c
@@ -22,7 +22,7 @@
 
 // seee eeee eeee mmmm mmmm mmmm mmmm mmmm | mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm
 
-di_int __fixdfdi(double a);
+COMPILER_RT_ABI di_int __fixdfdi(double a);
 
 int test__fixdfdi(double a, di_int expected)
 {
diff --git a/test/builtins/Unit/fixdfti_test.c b/test/builtins/Unit/fixdfti_test.c
index bfa88fd..b5da456 100644
--- a/test/builtins/Unit/fixdfti_test.c
+++ b/test/builtins/Unit/fixdfti_test.c
@@ -24,7 +24,7 @@
 
 // seee eeee eeee mmmm mmmm mmmm mmmm mmmm | mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm
 
-ti_int __fixdfti(double a);
+COMPILER_RT_ABI ti_int __fixdfti(double a);
 
 int test__fixdfti(double a, ti_int expected)
 {
diff --git a/test/builtins/Unit/fixsfdi_test.c b/test/builtins/Unit/fixsfdi_test.c
index d3e934a..f37ecef 100644
--- a/test/builtins/Unit/fixsfdi_test.c
+++ b/test/builtins/Unit/fixsfdi_test.c
@@ -22,7 +22,7 @@
 
 // seee eeee emmm mmmm mmmm mmmm mmmm mmmm
 
-di_int __fixsfdi(float a);
+COMPILER_RT_ABI di_int __fixsfdi(float a);
 
 int test__fixsfdi(float a, di_int expected)
 {
diff --git a/test/builtins/Unit/fixsfti_test.c b/test/builtins/Unit/fixsfti_test.c
index 2b0b997..38748aa 100644
--- a/test/builtins/Unit/fixsfti_test.c
+++ b/test/builtins/Unit/fixsfti_test.c
@@ -24,7 +24,7 @@
 
 // seee eeee emmm mmmm mmmm mmmm mmmm mmmm
 
-ti_int __fixsfti(float a);
+COMPILER_RT_ABI ti_int __fixsfti(float a);
 
 int test__fixsfti(float a, ti_int expected)
 {
diff --git a/test/builtins/Unit/fixunsdfdi_test.c b/test/builtins/Unit/fixunsdfdi_test.c
index 0803fd2..3998482 100644
--- a/test/builtins/Unit/fixunsdfdi_test.c
+++ b/test/builtins/Unit/fixunsdfdi_test.c
@@ -24,7 +24,7 @@
 
 // seee eeee eeee mmmm mmmm mmmm mmmm mmmm | mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm
 
-du_int __fixunsdfdi(double a);
+COMPILER_RT_ABI du_int __fixunsdfdi(double a);
 
 int test__fixunsdfdi(double a, du_int expected)
 {
diff --git a/test/builtins/Unit/fixunsdfsi_test.c b/test/builtins/Unit/fixunsdfsi_test.c
index 54fe35b..551fc88 100644
--- a/test/builtins/Unit/fixunsdfsi_test.c
+++ b/test/builtins/Unit/fixunsdfsi_test.c
@@ -24,7 +24,7 @@
 
 // seee eeee eeee mmmm mmmm mmmm mmmm mmmm | mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm
 
-su_int __fixunsdfsi(double a);
+COMPILER_RT_ABI su_int __fixunsdfsi(double a);
 
 int test__fixunsdfsi(double a, su_int expected)
 {
diff --git a/test/builtins/Unit/fixunsdfsivfp_test.c b/test/builtins/Unit/fixunsdfsivfp_test.c
index 3727cf7..ebd0be2 100644
--- a/test/builtins/Unit/fixunsdfsivfp_test.c
+++ b/test/builtins/Unit/fixunsdfsivfp_test.c
@@ -11,12 +11,13 @@
 //
 //===----------------------------------------------------------------------===//
 
+#include "int_lib.h"
 #include <stdio.h>
 #include <stdlib.h>
 #include <math.h>
 
 
-extern unsigned int __fixunsdfsivfp(double a);
+extern COMPILER_RT_ABI unsigned int __fixunsdfsivfp(double a);
 
 #if __arm__
 int test__fixunsdfsivfp(double a)
diff --git a/test/builtins/Unit/fixunsdfti_test.c b/test/builtins/Unit/fixunsdfti_test.c
index 9f89de4..e1aa56d 100644
--- a/test/builtins/Unit/fixunsdfti_test.c
+++ b/test/builtins/Unit/fixunsdfti_test.c
@@ -26,7 +26,7 @@
 
 #ifdef CRT_HAS_128BIT
 
-tu_int __fixunsdfti(double a);
+COMPILER_RT_ABI tu_int __fixunsdfti(double a);
 
 int test__fixunsdfti(double a, tu_int expected)
 {
diff --git a/test/builtins/Unit/fixunssfdi_test.c b/test/builtins/Unit/fixunssfdi_test.c
index ac89be7..812457a 100644
--- a/test/builtins/Unit/fixunssfdi_test.c
+++ b/test/builtins/Unit/fixunssfdi_test.c
@@ -24,7 +24,7 @@
 
 // seee eeee emmm mmmm mmmm mmmm mmmm mmmm
 
-du_int __fixunssfdi(float a);
+COMPILER_RT_ABI du_int __fixunssfdi(float a);
 
 int test__fixunssfdi(float a, du_int expected)
 {
diff --git a/test/builtins/Unit/fixunssfsi_test.c b/test/builtins/Unit/fixunssfsi_test.c
index ce6a928..94a8b08 100644
--- a/test/builtins/Unit/fixunssfsi_test.c
+++ b/test/builtins/Unit/fixunssfsi_test.c
@@ -24,7 +24,7 @@
 
 // seee eeee emmm mmmm mmmm mmmm mmmm mmmm
 
-su_int __fixunssfsi(float a);
+COMPILER_RT_ABI su_int __fixunssfsi(float a);
 
 int test__fixunssfsi(float a, su_int expected)
 {
diff --git a/test/builtins/Unit/fixunssfti_test.c b/test/builtins/Unit/fixunssfti_test.c
index 7965b95..979d661 100644
--- a/test/builtins/Unit/fixunssfti_test.c
+++ b/test/builtins/Unit/fixunssfti_test.c
@@ -26,7 +26,7 @@
 
 // seee eeee emmm mmmm mmmm mmmm mmmm mmmm
 
-tu_int __fixunssfti(float a);
+COMPILER_RT_ABI tu_int __fixunssfti(float a);
 
 int test__fixunssfti(float a, tu_int expected)
 {
diff --git a/test/builtins/Unit/fixunstfdi_test.c b/test/builtins/Unit/fixunstfdi_test.c
index a5a9460..60ea503 100644
--- a/test/builtins/Unit/fixunstfdi_test.c
+++ b/test/builtins/Unit/fixunstfdi_test.c
@@ -25,7 +25,7 @@
 //             value in long double is representable in du_int or is negative 
 //                 (no range checking performed)
 
-du_int __fixunstfdi(long double a);
+COMPILER_RT_ABI du_int __fixunstfdi(long double a);
 
 int test__fixunstfdi(long double a, du_int expected)
 {
diff --git a/test/builtins/Unit/fixunsxfdi_test.c b/test/builtins/Unit/fixunsxfdi_test.c
index 4308f6f..6f42079 100644
--- a/test/builtins/Unit/fixunsxfdi_test.c
+++ b/test/builtins/Unit/fixunsxfdi_test.c
@@ -28,7 +28,7 @@
 // gggg gggg gggg gggg gggg gggg gggg gggg | gggg gggg gggg gggg seee eeee eeee eeee |
 // 1mmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm | mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm
 
-du_int __fixunsxfdi(long double a);
+COMPILER_RT_ABI du_int __fixunsxfdi(long double a);
 
 int test__fixunsxfdi(long double a, du_int expected)
 {
diff --git a/test/builtins/Unit/fixunsxfsi_test.c b/test/builtins/Unit/fixunsxfsi_test.c
index cb2a7f4..0d78dcb 100644
--- a/test/builtins/Unit/fixunsxfsi_test.c
+++ b/test/builtins/Unit/fixunsxfsi_test.c
@@ -26,7 +26,7 @@
 // gggg gggg gggg gggg gggg gggg gggg gggg | gggg gggg gggg gggg seee eeee eeee eeee |
 // 1mmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm | mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm
 
-su_int __fixunsxfsi(long double a);
+COMPILER_RT_ABI su_int __fixunsxfsi(long double a);
 
 int test__fixunsxfsi(long double a, su_int expected)
 {
diff --git a/test/builtins/Unit/fixunsxfti_test.c b/test/builtins/Unit/fixunsxfti_test.c
index 7d18b12..94b5aeb 100644
--- a/test/builtins/Unit/fixunsxfti_test.c
+++ b/test/builtins/Unit/fixunsxfti_test.c
@@ -27,7 +27,7 @@
 // gggg gggg gggg gggg gggg gggg gggg gggg | gggg gggg gggg gggg seee eeee eeee eeee |
 // 1mmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm | mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm
 
-tu_int __fixunsxfti(long double a);
+COMPILER_RT_ABI tu_int __fixunsxfti(long double a);
 
 int test__fixunsxfti(long double a, tu_int expected)
 {
diff --git a/test/builtins/Unit/fixxfdi_test.c b/test/builtins/Unit/fixxfdi_test.c
index 43ac0f8..0a90a56 100644
--- a/test/builtins/Unit/fixxfdi_test.c
+++ b/test/builtins/Unit/fixxfdi_test.c
@@ -25,7 +25,7 @@
 // gggg gggg gggg gggg gggg gggg gggg gggg | gggg gggg gggg gggg seee eeee eeee eeee |
 // 1mmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm | mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm
 
-di_int __fixxfdi(long double a);
+COMPILER_RT_ABI di_int __sfixxfdi(long double a);
 
 int test__fixxfdi(long double a, di_int expected)
 {
diff --git a/test/builtins/Unit/fixxfti_test.c b/test/builtins/Unit/fixxfti_test.c
index 87914c5..b8573cc 100644
--- a/test/builtins/Unit/fixxfti_test.c
+++ b/test/builtins/Unit/fixxfti_test.c
@@ -25,7 +25,7 @@
 // gggg gggg gggg gggg gggg gggg gggg gggg | gggg gggg gggg gggg seee eeee eeee eeee |
 // 1mmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm | mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm
 
-ti_int __fixxfti(long double a);
+COMPILER_RT_ABI ti_int __fixxfti(long double a);
 
 int test__fixxfti(long double a, ti_int expected)
 {
diff --git a/test/builtins/Unit/floatdidf_test.c b/test/builtins/Unit/floatdidf_test.c
index af3dacd..9bf2be9 100644
--- a/test/builtins/Unit/floatdidf_test.c
+++ b/test/builtins/Unit/floatdidf_test.c
@@ -22,7 +22,7 @@
 
 // seee eeee eeee mmmm mmmm mmmm mmmm mmmm | mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm
 
-double __floatdidf(di_int a);
+COMPILER_RT_ABI double __floatdidf(di_int a);
 
 int test__floatdidf(di_int a, double expected)
 {
diff --git a/test/builtins/Unit/floatdisf_test.c b/test/builtins/Unit/floatdisf_test.c
index 3e71df7..a55c6a9 100644
--- a/test/builtins/Unit/floatdisf_test.c
+++ b/test/builtins/Unit/floatdisf_test.c
@@ -22,7 +22,7 @@
 
 // seee eeee emmm mmmm mmmm mmmm mmmm mmmm
 
-float __floatdisf(di_int a);
+COMPILER_RT_ABI float __floatdisf(di_int a);
 
 int test__floatdisf(di_int a, float expected)
 {
diff --git a/test/builtins/Unit/floatdixf_test.c b/test/builtins/Unit/floatdixf_test.c
index 3376664..f6ab5a4 100644
--- a/test/builtins/Unit/floatdixf_test.c
+++ b/test/builtins/Unit/floatdixf_test.c
@@ -23,7 +23,7 @@
 // gggg gggg gggg gggg gggg gggg gggg gggg | gggg gggg gggg gggg seee eeee eeee eeee |
 // 1mmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm | mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm
 
-long double __floatdixf(di_int a);
+long COMPILER_RT_ABI double __floatdixf(di_int a);
 
 int test__floatdixf(di_int a, long double expected)
 {
diff --git a/test/builtins/Unit/floatsidfvfp_test.c b/test/builtins/Unit/floatsidfvfp_test.c
index e21ecda..e5ea3a4 100644
--- a/test/builtins/Unit/floatsidfvfp_test.c
+++ b/test/builtins/Unit/floatsidfvfp_test.c
@@ -11,12 +11,13 @@
 //
 //===----------------------------------------------------------------------===//
 
+#include "int_lib.h"
 #include <stdio.h>
 #include <stdlib.h>
 #include <math.h>
 
 
-extern double __floatsidfvfp(int a);
+extern COMPILER_RT_ABI double __floatsidfvfp(int a);
 
 #if __arm__
 int test__floatsidfvfp(int a)
diff --git a/test/builtins/Unit/floatsisfvfp_test.c b/test/builtins/Unit/floatsisfvfp_test.c
index d20905b..ab21e2e 100644
--- a/test/builtins/Unit/floatsisfvfp_test.c
+++ b/test/builtins/Unit/floatsisfvfp_test.c
@@ -11,12 +11,13 @@
 //
 //===----------------------------------------------------------------------===//
 
+#include "int_lib.h"
 #include <stdio.h>
 #include <stdlib.h>
 #include <math.h>
 
 
-extern float __floatsisfvfp(int a);
+extern COMPILER_RT_ABI float __floatsisfvfp(int a);
 
 #if __arm__
 int test__floatsisfvfp(int a)
diff --git a/test/builtins/Unit/floatsitf_test.c b/test/builtins/Unit/floatsitf_test.c
index db4d020..8373c7d 100644
--- a/test/builtins/Unit/floatsitf_test.c
+++ b/test/builtins/Unit/floatsitf_test.c
@@ -11,13 +11,14 @@
 //
 //===----------------------------------------------------------------------===//
 
+#include "int_lib.h"
 #include <stdio.h>
 
 #if __LDBL_MANT_DIG__ == 113
 
 #include "fp_test.h"
 
-long double __floatsitf(int a);
+long COMPILER_RT_ABI double __floatsitf(int a);
 
 int test__floatsitf(int a, uint64_t expectedHi, uint64_t expectedLo)
 {
diff --git a/test/builtins/Unit/floattidf_test.c b/test/builtins/Unit/floattidf_test.c
index 476304f..3af382a 100644
--- a/test/builtins/Unit/floattidf_test.c
+++ b/test/builtins/Unit/floattidf_test.c
@@ -24,7 +24,7 @@
 
 // seee eeee eeee mmmm mmmm mmmm mmmm mmmm | mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm
 
-double __floattidf(ti_int a);
+COMPILER_RT_ABI double __floattidf(ti_int a);
 
 int test__floattidf(ti_int a, double expected)
 {
diff --git a/test/builtins/Unit/floattisf_test.c b/test/builtins/Unit/floattisf_test.c
index 75b8e91..0f5dc54 100644
--- a/test/builtins/Unit/floattisf_test.c
+++ b/test/builtins/Unit/floattisf_test.c
@@ -24,7 +24,7 @@
 
 // seee eeee emmm mmmm mmmm mmmm mmmm mmmm
 
-float __floattisf(ti_int a);
+COMPILER_RT_ABI float __floattisf(ti_int a);
 
 int test__floattisf(ti_int a, float expected)
 {
diff --git a/test/builtins/Unit/floattixf_test.c b/test/builtins/Unit/floattixf_test.c
index ce35668..d281deb 100644
--- a/test/builtins/Unit/floattixf_test.c
+++ b/test/builtins/Unit/floattixf_test.c
@@ -25,7 +25,7 @@
 // gggg gggg gggg gggg gggg gggg gggg gggg | gggg gggg gggg gggg seee eeee eeee eeee |
 // 1mmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm | mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm
 
-long double __floattixf(ti_int a);
+COMPILER_RT_ABI long double __floattixf(ti_int a);
 
 int test__floattixf(ti_int a, long double expected)
 {
diff --git a/test/builtins/Unit/floatundidf_test.c b/test/builtins/Unit/floatundidf_test.c
index ae91ac3..97fb1e5 100644
--- a/test/builtins/Unit/floatundidf_test.c
+++ b/test/builtins/Unit/floatundidf_test.c
@@ -22,7 +22,7 @@
 
 // seee eeee eeee mmmm mmmm mmmm mmmm mmmm | mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm
 
-double __floatundidf(du_int a);
+COMPILER_RT_ABI double __floatundidf(du_int a);
 
 int test__floatundidf(di_int a, double expected)
 {
diff --git a/test/builtins/Unit/floatundisf_test.c b/test/builtins/Unit/floatundisf_test.c
index 394c945..40b6bcc 100644
--- a/test/builtins/Unit/floatundisf_test.c
+++ b/test/builtins/Unit/floatundisf_test.c
@@ -22,7 +22,7 @@
 
 // seee eeee emmm mmmm mmmm mmmm mmmm mmmm
 
-float __floatundisf(du_int a);
+COMPILER_RT_ABI float __floatundisf(du_int a);
 
 int test__floatundisf(du_int a, float expected)
 {
diff --git a/test/builtins/Unit/floatundixf_test.c b/test/builtins/Unit/floatundixf_test.c
index 1974fa0..690dce1 100644
--- a/test/builtins/Unit/floatundixf_test.c
+++ b/test/builtins/Unit/floatundixf_test.c
@@ -24,7 +24,7 @@
 // gggg gggg gggg gggg gggg gggg gggg gggg | gggg gggg gggg gggg seee eeee eeee eeee |
 // 1mmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm | mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm
 
-long double __floatundixf(du_int a);
+COMPILER_RT_ABI long double __floatundixf(du_int a);
 
 int test__floatundixf(du_int a, long double expected)
 {
diff --git a/test/builtins/Unit/floatunsitf_test.c b/test/builtins/Unit/floatunsitf_test.c
index 1af72d2..c3d3fe9 100644
--- a/test/builtins/Unit/floatunsitf_test.c
+++ b/test/builtins/Unit/floatunsitf_test.c
@@ -11,13 +11,14 @@
 //
 //===----------------------------------------------------------------------===//
 
+#include "int_lib.h"
 #include <stdio.h>
 
 #if __LDBL_MANT_DIG__ == 113
 
 #include "fp_test.h"
 
-long double __floatunsitf(unsigned int a);
+COMPILER_RT_ABI long double __floatunsitf(unsigned int a);
 
 int test__floatunsitf(unsigned int a, uint64_t expectedHi, uint64_t expectedLo)
 {
diff --git a/test/builtins/Unit/floatunssidfvfp_test.c b/test/builtins/Unit/floatunssidfvfp_test.c
index 4883af1..75e4bbd 100644
--- a/test/builtins/Unit/floatunssidfvfp_test.c
+++ b/test/builtins/Unit/floatunssidfvfp_test.c
@@ -11,12 +11,13 @@
 //
 //===----------------------------------------------------------------------===//
 
+#include "int_lib.h"
 #include <stdio.h>
 #include <stdlib.h>
 #include <math.h>
 
 
-extern double __floatunssidfvfp(unsigned int a);
+extern COMPILER_RT_ABI double __floatunssidfvfp(unsigned int a);
 
 #if __arm__
 int test__floatunssidfvfp(unsigned int a)
diff --git a/test/builtins/Unit/floatunssisfvfp_test.c b/test/builtins/Unit/floatunssisfvfp_test.c
index 917061a..47f837c 100644
--- a/test/builtins/Unit/floatunssisfvfp_test.c
+++ b/test/builtins/Unit/floatunssisfvfp_test.c
@@ -14,9 +14,9 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <math.h>
+#include "int_lib.h"
 
-
-extern float __floatunssisfvfp(unsigned int a);
+extern COMPILER_RT_ABI float __floatunssisfvfp(unsigned int a);
 
 #if __arm__
 int test__floatunssisfvfp(unsigned int a)
diff --git a/test/builtins/Unit/floatuntidf_test.c b/test/builtins/Unit/floatuntidf_test.c
index 3cab027..9855ff7 100644
--- a/test/builtins/Unit/floatuntidf_test.c
+++ b/test/builtins/Unit/floatuntidf_test.c
@@ -24,7 +24,7 @@
 
 // seee eeee eeee mmmm mmmm mmmm mmmm mmmm | mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm
 
-double __floatuntidf(tu_int a);
+COMPILER_RT_ABI double __floatuntidf(tu_int a);
 
 int test__floatuntidf(tu_int a, double expected)
 {
diff --git a/test/builtins/Unit/floatuntisf_test.c b/test/builtins/Unit/floatuntisf_test.c
index aeac3ee..9b5ff79 100644
--- a/test/builtins/Unit/floatuntisf_test.c
+++ b/test/builtins/Unit/floatuntisf_test.c
@@ -24,7 +24,7 @@
 
 // seee eeee emmm mmmm mmmm mmmm mmmm mmmm
 
-float __floatuntisf(tu_int a);
+COMPILER_RT_ABI float __floatuntisf(tu_int a);
 
 int test__floatuntisf(tu_int a, float expected)
 {
diff --git a/test/builtins/Unit/floatuntixf_test.c b/test/builtins/Unit/floatuntixf_test.c
index 9c3434f..c58b55d 100644
--- a/test/builtins/Unit/floatuntixf_test.c
+++ b/test/builtins/Unit/floatuntixf_test.c
@@ -25,7 +25,7 @@
 // gggg gggg gggg gggg gggg gggg gggg gggg | gggg gggg gggg gggg seee eeee eeee eeee |
 // 1mmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm | mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm
 
-long double __floatuntixf(tu_int a);
+COMPILER_RT_ABI long double __floatuntixf(tu_int a);
 
 int test__floatuntixf(tu_int a, long double expected)
 {
diff --git a/test/builtins/Unit/fp_test.h b/test/builtins/Unit/fp_test.h
index 3bf9cb5..ea101cc 100644
--- a/test/builtins/Unit/fp_test.h
+++ b/test/builtins/Unit/fp_test.h
@@ -39,6 +39,7 @@
     return ret;
 }
 
+#if __LDBL_MANT_DIG__ == 113
 static inline long double fromRep128(uint64_t hi, uint64_t lo)
 {
     __uint128_t x = ((__uint128_t)hi << 64) + lo;
@@ -46,6 +47,12 @@
     memcpy(&ret, &x, 16);
     return ret;
 }
+#endif
+
+static inline uint16_t toRep16(uint16_t x)
+{
+    return x;
+}
 
 static inline uint16_t toRep16(uint16_t x)
 {
@@ -66,12 +73,32 @@
     return ret;
 }
 
+#if __LDBL_MANT_DIG__ == 113
 static inline __uint128_t toRep128(long double x)
 {
     __uint128_t ret;
     memcpy(&ret, &x, 16);
     return ret;
 }
+#endif
+
+static inline int compareResultH(uint16_t result,
+                                 uint16_t expected)
+{
+    uint16_t rep = toRep16(result);
+
+    if (rep == expected){
+        return 0;
+    }
+    // test other posible NaN representation(signal NaN)
+    else if (expected == 0x7e00U){
+        if ((rep & 0x7c00U) == 0x7c00U &&
+            (rep & 0x3ffU) > 0){
+            return 0;
+        }
+    }
+    return 1;
+}
 
 static inline int compareResultH(uint16_t result,
                                  uint16_t expected)
@@ -127,6 +154,7 @@
     return 1;
 }
 
+#if __LDBL_MANT_DIG__ == 113
 // return 0 if equal
 // use two 64-bit integers intead of one 128-bit integer
 // because 128-bit integer constant can't be assigned directly
@@ -150,6 +178,7 @@
     }
     return 1;
 }
+#endif
 
 static inline int compareResultCMP(int result,
                                    enum EXPECTED_RESULT expected)
@@ -221,10 +250,17 @@
     return fromRep64(0x7ff8000000000000UL);
 }
 
+#if __LDBL_MANT_DIG__ == 113
 static inline long double makeQNaN128()
 {
     return fromRep128(0x7fff800000000000UL, 0x0UL);
 }
+#endif
+
+static inline uint16_t makeNaN16(uint16_t rand)
+{
+    return fromRep16(0x7c00U | (rand & 0x7fffU));
+}
 
 static inline uint16_t makeNaN16(uint16_t rand)
 {
@@ -241,10 +277,17 @@
     return fromRep64(0x7ff0000000000000UL | (rand & 0xfffffffffffffUL));
 }
 
+#if __LDBL_MANT_DIG__ == 113
 static inline long double makeNaN128(uint64_t rand)
 {
     return fromRep128(0x7fff000000000000UL | (rand & 0xffffffffffffUL), 0x0UL);
 }
+#endif
+
+static inline uint16_t makeInf16()
+{
+    return fromRep16(0x7c00U);
+}
 
 static inline uint16_t makeInf16()
 {
@@ -261,7 +304,9 @@
     return fromRep64(0x7ff0000000000000UL);
 }
 
+#if __LDBL_MANT_DIG__ == 113
 static inline long double makeInf128()
 {
     return fromRep128(0x7fff000000000000UL, 0x0UL);
 }
+#endif
diff --git a/test/builtins/Unit/lshrdi3_test.c b/test/builtins/Unit/lshrdi3_test.c
index ffc6a69..d48ae4d 100644
--- a/test/builtins/Unit/lshrdi3_test.c
+++ b/test/builtins/Unit/lshrdi3_test.c
@@ -18,7 +18,7 @@
 
 // Precondition:  0 <= b < bits_in_dword
 
-di_int __lshrdi3(di_int a, si_int b);
+COMPILER_RT_ABI di_int __lshrdi3(di_int a, si_int b);
 
 int test__lshrdi3(di_int a, si_int b, di_int expected)
 {
diff --git a/test/builtins/Unit/lshrti3_test.c b/test/builtins/Unit/lshrti3_test.c
index 3f33c08..f5a0dd6 100644
--- a/test/builtins/Unit/lshrti3_test.c
+++ b/test/builtins/Unit/lshrti3_test.c
@@ -20,7 +20,7 @@
 
 // Precondition:  0 <= b < bits_in_dword
 
-ti_int __lshrti3(ti_int a, si_int b);
+COMPILER_RT_ABI ti_int __lshrti3(ti_int a, si_int b);
 
 int test__lshrti3(ti_int a, si_int b, ti_int expected)
 {
diff --git a/test/builtins/Unit/moddi3_test.c b/test/builtins/Unit/moddi3_test.c
index 9f6801d..62e8f22 100644
--- a/test/builtins/Unit/moddi3_test.c
+++ b/test/builtins/Unit/moddi3_test.c
@@ -16,7 +16,7 @@
 
 // Returns: a % b
 
-di_int __moddi3(di_int a, di_int b);
+COMPILER_RT_ABI di_int __moddi3(di_int a, di_int b);
 
 int test__moddi3(di_int a, di_int b, di_int expected)
 {
diff --git a/test/builtins/Unit/modsi3_test.c b/test/builtins/Unit/modsi3_test.c
index 52ec9a0..8c9f588 100644
--- a/test/builtins/Unit/modsi3_test.c
+++ b/test/builtins/Unit/modsi3_test.c
@@ -17,7 +17,7 @@
 
 /* Returns: a % b */
 
-si_int __modsi3(si_int a, si_int b);
+COMPILER_RT_ABI si_int __modsi3(si_int a, si_int b);
 
 int test__modsi3(si_int a, si_int b, si_int expected) {
     si_int x = __modsi3(a, b);
diff --git a/test/builtins/Unit/modti3_test.c b/test/builtins/Unit/modti3_test.c
index ba9f980..99413aa 100644
--- a/test/builtins/Unit/modti3_test.c
+++ b/test/builtins/Unit/modti3_test.c
@@ -18,7 +18,7 @@
 
 // Returns: a % b
 
-ti_int __modti3(ti_int a, ti_int b);
+COMPILER_RT_ABI ti_int __modti3(ti_int a, ti_int b);
 
 int test__modti3(ti_int a, ti_int b, ti_int expected)
 {
diff --git a/test/builtins/Unit/muldc3_test.c b/test/builtins/Unit/muldc3_test.c
index 112b612..6902ef3 100644
--- a/test/builtins/Unit/muldc3_test.c
+++ b/test/builtins/Unit/muldc3_test.c
@@ -18,7 +18,8 @@
 
 // Returns: the product of a + ib and c + id
 
-double _Complex __muldc3(double __a, double __b, double __c, double __d);
+COMPILER_RT_ABI double _Complex
+__muldc3(double __a, double __b, double __c, double __d);
 
 enum {zero, non_zero, inf, NaN, non_zero_nan};
 
diff --git a/test/builtins/Unit/muldf3vfp_test.c b/test/builtins/Unit/muldf3vfp_test.c
index 73454bf..766972d 100644
--- a/test/builtins/Unit/muldf3vfp_test.c
+++ b/test/builtins/Unit/muldf3vfp_test.c
@@ -11,13 +11,14 @@
 //
 //===----------------------------------------------------------------------===//
 
+#include "int_lib.h"
 #include <stdio.h>
 #include <stdlib.h>
 #include <math.h>
 
 
 #if __arm__
-extern double __muldf3vfp(double a, double b);
+extern COMPILER_RT_ABI double __muldf3vfp(double a, double b);
 
 int test__muldf3vfp(double a, double b)
 {
diff --git a/test/builtins/Unit/muldi3_test.c b/test/builtins/Unit/muldi3_test.c
index 83b5255..651dd01 100644
--- a/test/builtins/Unit/muldi3_test.c
+++ b/test/builtins/Unit/muldi3_test.c
@@ -14,7 +14,7 @@
 #include "int_lib.h"
 #include <stdio.h>
 
-di_int __muldi3(di_int a, di_int b);
+COMPILER_RT_ABI di_int __muldi3(di_int a, di_int b);
 
 int test__muldi3(di_int a, di_int b, di_int expected)
 {
diff --git a/test/builtins/Unit/mulodi4_test.c b/test/builtins/Unit/mulodi4_test.c
index 10a0eaa..4546609 100644
--- a/test/builtins/Unit/mulodi4_test.c
+++ b/test/builtins/Unit/mulodi4_test.c
@@ -14,7 +14,7 @@
 #include "int_lib.h"
 #include <stdio.h>
 
-extern di_int __mulodi4(di_int a, di_int b, int* overflow);
+extern COMPILER_RT_ABI di_int __mulodi4(di_int a, di_int b, int* overflow);
 
 int test__mulodi4(di_int a, di_int b, di_int expected, int expected_overflow)
 {
diff --git a/test/builtins/Unit/mulosi4_test.c b/test/builtins/Unit/mulosi4_test.c
index fc509db..6a27d69 100644
--- a/test/builtins/Unit/mulosi4_test.c
+++ b/test/builtins/Unit/mulosi4_test.c
@@ -18,7 +18,7 @@
 
 // Effects: aborts if a * b overflows
 
-si_int __mulosi4(si_int a, si_int b, int *overflow);
+COMPILER_RT_ABI si_int __mulosi4(si_int a, si_int b, int *overflow);
 
 int test__mulosi4(si_int a, si_int b, si_int expected, int expected_overflow)
 {
diff --git a/test/builtins/Unit/muloti4_test.c b/test/builtins/Unit/muloti4_test.c
index 95439a4..d00e7bb 100644
--- a/test/builtins/Unit/muloti4_test.c
+++ b/test/builtins/Unit/muloti4_test.c
@@ -20,7 +20,7 @@
 
 // Effects: sets overflow if a * b overflows
 
-ti_int __muloti4(ti_int a, ti_int b, int *overflow);
+COMPILER_RT_ABI ti_int __muloti4(ti_int a, ti_int b, int *overflow);
 
 int test__muloti4(ti_int a, ti_int b, ti_int expected, int expected_overflow)
 {
diff --git a/test/builtins/Unit/mulsc3_test.c b/test/builtins/Unit/mulsc3_test.c
index 7a1b3ae..eeb537a 100644
--- a/test/builtins/Unit/mulsc3_test.c
+++ b/test/builtins/Unit/mulsc3_test.c
@@ -18,7 +18,8 @@
 
 // Returns: the product of a + ib and c + id
 
-float _Complex __mulsc3(float __a, float __b, float __c, float __d);
+COMPILER_RT_ABI float _Complex
+__mulsc3(float __a, float __b, float __c, float __d);
 
 enum {zero, non_zero, inf, NaN, non_zero_nan};
 
diff --git a/test/builtins/Unit/mulsf3vfp_test.c b/test/builtins/Unit/mulsf3vfp_test.c
index 92cf1f1..5b0f6c1 100644
--- a/test/builtins/Unit/mulsf3vfp_test.c
+++ b/test/builtins/Unit/mulsf3vfp_test.c
@@ -11,12 +11,13 @@
 //
 //===----------------------------------------------------------------------===//
 
+#include "int_lib.h"
 #include <stdio.h>
 #include <stdlib.h>
 #include <math.h>
 
 
-extern float __mulsf3vfp(float a, float b);
+extern COMPILER_RT_ABI float __mulsf3vfp(float a, float b);
 
 #if __arm__
 int test__mulsf3vfp(float a, float b)
diff --git a/test/builtins/Unit/multc3_test.c b/test/builtins/Unit/multc3_test.c
index 8d34801..b148263 100644
--- a/test/builtins/Unit/multc3_test.c
+++ b/test/builtins/Unit/multc3_test.c
@@ -21,7 +21,7 @@
 
 // Returns: the product of a + ib and c + id
 
-long double _Complex
+COMPILER_RT_ABI long double _Complex
 __multc3(long double __a, long double __b, long double __c, long double __d);
 
 enum {zero, non_zero, inf, NaN, non_zero_nan};
diff --git a/test/builtins/Unit/multf3_test.c b/test/builtins/Unit/multf3_test.c
index 8961005..98a8f7a 100644
--- a/test/builtins/Unit/multf3_test.c
+++ b/test/builtins/Unit/multf3_test.c
@@ -18,7 +18,7 @@
 #include "fp_test.h"
 
 // Returns: a * b
-long double __multf3(long double a, long double b);
+COMPILER_RT_ABI long double __multf3(long double a, long double b);
 
 int test__multf3(long double a, long double b,
                  uint64_t expectedHi, uint64_t expectedLo)
diff --git a/test/builtins/Unit/multi3_test.c b/test/builtins/Unit/multi3_test.c
index 2ccbd06..04b1b8a 100644
--- a/test/builtins/Unit/multi3_test.c
+++ b/test/builtins/Unit/multi3_test.c
@@ -16,7 +16,7 @@
 
 #ifdef CRT_HAS_128BIT
 
-ti_int __multi3(ti_int a, ti_int b);
+COMPILER_RT_ABI ti_int __multi3(ti_int a, ti_int b);
 
 int test__multi3(ti_int a, ti_int b, ti_int expected)
 {
diff --git a/test/builtins/Unit/mulvdi3_test.c b/test/builtins/Unit/mulvdi3_test.c
index a023bf6..7f16c4c 100644
--- a/test/builtins/Unit/mulvdi3_test.c
+++ b/test/builtins/Unit/mulvdi3_test.c
@@ -18,7 +18,7 @@
 
 // Effects: aborts if a * b overflows
 
-di_int __mulvdi3(di_int a, di_int b);
+COMPILER_RT_ABI di_int __mulvdi3(di_int a, di_int b);
 
 int test__mulvdi3(di_int a, di_int b, di_int expected)
 {
diff --git a/test/builtins/Unit/mulvsi3_test.c b/test/builtins/Unit/mulvsi3_test.c
index 1eb53a5..64df4fe 100644
--- a/test/builtins/Unit/mulvsi3_test.c
+++ b/test/builtins/Unit/mulvsi3_test.c
@@ -18,7 +18,7 @@
 
 // Effects: aborts if a * b overflows
 
-si_int __mulvsi3(si_int a, si_int b);
+COMPILER_RT_ABI si_int __mulvsi3(si_int a, si_int b);
 
 int test__mulvsi3(si_int a, si_int b, si_int expected)
 {
diff --git a/test/builtins/Unit/mulvti3_test.c b/test/builtins/Unit/mulvti3_test.c
index 6336f45..bf2f731 100644
--- a/test/builtins/Unit/mulvti3_test.c
+++ b/test/builtins/Unit/mulvti3_test.c
@@ -20,7 +20,7 @@
 
 // Effects: aborts if a * b overflows
 
-ti_int __mulvti3(ti_int a, ti_int b);
+COMPILER_RT_ABI ti_int __mulvti3(ti_int a, ti_int b);
 
 int test__mulvti3(ti_int a, ti_int b, ti_int expected)
 {
diff --git a/test/builtins/Unit/mulxc3_test.c b/test/builtins/Unit/mulxc3_test.c
index 4297c16..e77e94f 100644
--- a/test/builtins/Unit/mulxc3_test.c
+++ b/test/builtins/Unit/mulxc3_test.c
@@ -20,7 +20,7 @@
 
 // Returns: the product of a + ib and c + id
 
-long double _Complex
+COMPILER_RT_ABI long double _Complex
 __mulxc3(long double __a, long double __b, long double __c, long double __d);
 
 enum {zero, non_zero, inf, NaN, non_zero_nan};
diff --git a/test/builtins/Unit/negdf2vfp_test.c b/test/builtins/Unit/negdf2vfp_test.c
index dc55428..f0e6677 100644
--- a/test/builtins/Unit/negdf2vfp_test.c
+++ b/test/builtins/Unit/negdf2vfp_test.c
@@ -16,7 +16,7 @@
 #include <math.h>
 
 
-extern double __negdf2vfp(double a);
+extern COMPILER_RT_ABI double __negdf2vfp(double a);
 
 #if __arm__
 int test__negdf2vfp(double a)
diff --git a/test/builtins/Unit/negdi2_test.c b/test/builtins/Unit/negdi2_test.c
index 510b3b0..beccd71 100644
--- a/test/builtins/Unit/negdi2_test.c
+++ b/test/builtins/Unit/negdi2_test.c
@@ -16,7 +16,7 @@
 
 // Returns: -a
 
-di_int __negdi2(di_int a);
+COMPILER_RT_ABI di_int __negdi2(di_int a);
 
 int test__negdi2(di_int a, di_int expected)
 {
diff --git a/test/builtins/Unit/negsf2vfp_test.c b/test/builtins/Unit/negsf2vfp_test.c
index ef54cee..9e47d89 100644
--- a/test/builtins/Unit/negsf2vfp_test.c
+++ b/test/builtins/Unit/negsf2vfp_test.c
@@ -11,12 +11,13 @@
 //
 //===----------------------------------------------------------------------===//
 
+#include "int_lib.h"
 #include <stdio.h>
 #include <stdlib.h>
 #include <math.h>
 
 
-extern float __negsf2vfp(float a);
+extern COMPILER_RT_ABI float __negsf2vfp(float a);
 
 #if __arm__
 int test__negsf2vfp(float a)
diff --git a/test/builtins/Unit/negti2_test.c b/test/builtins/Unit/negti2_test.c
index a40c0c3..b075978 100644
--- a/test/builtins/Unit/negti2_test.c
+++ b/test/builtins/Unit/negti2_test.c
@@ -18,7 +18,7 @@
 
 // Returns: -a
 
-ti_int __negti2(ti_int a);
+COMPILER_RT_ABI ti_int __negti2(ti_int a);
 
 int test__negti2(ti_int a, ti_int expected)
 {
diff --git a/test/builtins/Unit/negvdi2_test.c b/test/builtins/Unit/negvdi2_test.c
index 9617b95..5c202e5 100644
--- a/test/builtins/Unit/negvdi2_test.c
+++ b/test/builtins/Unit/negvdi2_test.c
@@ -18,7 +18,7 @@
 
 // Effects: aborts if -a overflows
 
-di_int __negvdi2(di_int a);
+COMPILER_RT_ABI di_int __negvdi2(di_int a);
 
 int test__negvdi2(di_int a)
 {
diff --git a/test/builtins/Unit/negvsi2_test.c b/test/builtins/Unit/negvsi2_test.c
index 5ea0e2e..6330803 100644
--- a/test/builtins/Unit/negvsi2_test.c
+++ b/test/builtins/Unit/negvsi2_test.c
@@ -18,7 +18,7 @@
 
 // Effects: aborts if -a overflows
 
-si_int __negvsi2(si_int a);
+COMPILER_RT_ABI si_int __negvsi2(si_int a);
 
 int test__negvsi2(si_int a)
 {
diff --git a/test/builtins/Unit/negvti2_test.c b/test/builtins/Unit/negvti2_test.c
index 8126cdb..005f8a8 100644
--- a/test/builtins/Unit/negvti2_test.c
+++ b/test/builtins/Unit/negvti2_test.c
@@ -20,8 +20,8 @@
 
 // Effects: aborts if -a overflows
 
-ti_int __negvti2(ti_int a);
-ti_int __negti2(ti_int a);
+COMPILER_RT_ABI ti_int __negvti2(ti_int a);
+COMPILER_RT_ABI ti_int __negti2(ti_int a);
 
 int test__negvti2(ti_int a)
 {
diff --git a/test/builtins/Unit/paritydi2_test.c b/test/builtins/Unit/paritydi2_test.c
index 5360e37..98220bd 100644
--- a/test/builtins/Unit/paritydi2_test.c
+++ b/test/builtins/Unit/paritydi2_test.c
@@ -17,7 +17,7 @@
 
 // Returns: 1 if number of bits is odd else returns 0
 
-si_int __paritydi2(di_int a);
+COMPILER_RT_ABI si_int __paritydi2(di_int a);
 
 int naive_parity(di_int a)
 {
diff --git a/test/builtins/Unit/paritysi2_test.c b/test/builtins/Unit/paritysi2_test.c
index 3ea8473..175aeb2 100644
--- a/test/builtins/Unit/paritysi2_test.c
+++ b/test/builtins/Unit/paritysi2_test.c
@@ -17,7 +17,7 @@
 
 // Returns: 1 if number of bits is odd else returns 0
 
-si_int __paritysi2(si_int a);
+COMPILER_RT_ABI si_int __paritysi2(si_int a);
 
 int naive_parity(si_int a)
 {
diff --git a/test/builtins/Unit/parityti2_test.c b/test/builtins/Unit/parityti2_test.c
index 8f065b9..cc1e999 100644
--- a/test/builtins/Unit/parityti2_test.c
+++ b/test/builtins/Unit/parityti2_test.c
@@ -19,7 +19,7 @@
 
 // Returns: 1 if number of bits is odd else returns 0
 
-si_int __parityti2(ti_int a);
+COMPILER_RT_ABI si_int __parityti2(ti_int a);
 
 int naive_parity(ti_int a)
 {
diff --git a/test/builtins/Unit/popcountdi2_test.c b/test/builtins/Unit/popcountdi2_test.c
index 4c56117..bfd4977 100644
--- a/test/builtins/Unit/popcountdi2_test.c
+++ b/test/builtins/Unit/popcountdi2_test.c
@@ -17,7 +17,7 @@
 
 // Returns: count of 1 bits
 
-si_int __popcountdi2(di_int a);
+COMPILER_RT_ABI si_int __popcountdi2(di_int a);
 
 int naive_popcount(di_int a)
 {
diff --git a/test/builtins/Unit/popcountsi2_test.c b/test/builtins/Unit/popcountsi2_test.c
index d0a05c4..10b757d 100644
--- a/test/builtins/Unit/popcountsi2_test.c
+++ b/test/builtins/Unit/popcountsi2_test.c
@@ -17,7 +17,7 @@
 
 // Returns: count of 1 bits
 
-si_int __popcountsi2(si_int a);
+COMPILER_RT_ABI si_int __popcountsi2(si_int a);
 
 int naive_popcount(si_int a)
 {
diff --git a/test/builtins/Unit/popcountti2_test.c b/test/builtins/Unit/popcountti2_test.c
index d17e03a..3a3c3cb 100644
--- a/test/builtins/Unit/popcountti2_test.c
+++ b/test/builtins/Unit/popcountti2_test.c
@@ -19,7 +19,7 @@
 
 // Returns: count of 1 bits
 
-si_int __popcountti2(ti_int a);
+COMPILER_RT_ABI si_int __popcountti2(ti_int a);
 
 int naive_popcount(ti_int a)
 {
diff --git a/test/builtins/Unit/powidf2_test.c b/test/builtins/Unit/powidf2_test.c
index 2abc84d..c499d9a 100644
--- a/test/builtins/Unit/powidf2_test.c
+++ b/test/builtins/Unit/powidf2_test.c
@@ -17,7 +17,7 @@
 
 // Returns: a ^ b
 
-double __powidf2(double a, si_int b);
+COMPILER_RT_ABI double __powidf2(double a, si_int b);
 
 int test__powidf2(double a, si_int b, double expected)
 {
diff --git a/test/builtins/Unit/powisf2_test.c b/test/builtins/Unit/powisf2_test.c
index 98409f4..1186ef4 100644
--- a/test/builtins/Unit/powisf2_test.c
+++ b/test/builtins/Unit/powisf2_test.c
@@ -17,7 +17,7 @@
 
 // Returns: a ^ b
 
-float __powisf2(float a, si_int b);
+COMPILER_RT_ABI float __powisf2(float a, si_int b);
 
 int test__powisf2(float a, si_int b, float expected)
 {
diff --git a/test/builtins/Unit/powitf2_test.c b/test/builtins/Unit/powitf2_test.c
index dfe7588..13c890a 100644
--- a/test/builtins/Unit/powitf2_test.c
+++ b/test/builtins/Unit/powitf2_test.c
@@ -20,7 +20,7 @@
 
 // Returns: a ^ b
 
-long double __powitf2(long double a, si_int b);
+COMPILER_RT_ABI long double __powitf2(long double a, si_int b);
 
 int test__powitf2(long double a, si_int b, long double expected)
 {
diff --git a/test/builtins/Unit/powixf2_test.c b/test/builtins/Unit/powixf2_test.c
index 201870b..a28f1f9 100644
--- a/test/builtins/Unit/powixf2_test.c
+++ b/test/builtins/Unit/powixf2_test.c
@@ -19,7 +19,7 @@
 
 // Returns: a ^ b
 
-long double __powixf2(long double a, si_int b);
+COMPILER_RT_ABI long double __powixf2(long double a, si_int b);
 
 int test__powixf2(long double a, si_int b, long double expected)
 {
diff --git a/test/builtins/Unit/ppc/floatditf_test.c b/test/builtins/Unit/ppc/floatditf_test.c
index 578260a..71ecf7c 100644
--- a/test/builtins/Unit/ppc/floatditf_test.c
+++ b/test/builtins/Unit/ppc/floatditf_test.c
@@ -1,7 +1,7 @@
 #include <stdint.h>
 #include <stdio.h>
 
-long double __floatditf(int64_t);
+COMPILER_RT_ABI long double __floatditf(int64_t);
 
 #include "floatunditf_test.h"
 #include "DD.h"
diff --git a/test/builtins/Unit/ppc/floatunditf_test.c b/test/builtins/Unit/ppc/floatunditf_test.c
index 68390d1..4d1ce08 100644
--- a/test/builtins/Unit/ppc/floatunditf_test.c
+++ b/test/builtins/Unit/ppc/floatunditf_test.c
@@ -1,7 +1,7 @@
 #include <stdint.h>
 #include <stdio.h>
 
-long double __floatunditf(uint64_t);
+COMPILER_RT_ABI long double __floatunditf(uint64_t);
 
 #include "floatunditf_test.h"
 #include "DD.h"
diff --git a/test/builtins/Unit/subdf3vfp_test.c b/test/builtins/Unit/subdf3vfp_test.c
index 86d6f2f..5d5d711 100644
--- a/test/builtins/Unit/subdf3vfp_test.c
+++ b/test/builtins/Unit/subdf3vfp_test.c
@@ -17,7 +17,7 @@
 
 
 #if __arm__
-extern double __subdf3vfp(double a, double b);
+extern COMPILER_RT_ABI double __subdf3vfp(double a, double b);
 
 int test__subdf3vfp(double a, double b)
 {
diff --git a/test/builtins/Unit/subsf3vfp_test.c b/test/builtins/Unit/subsf3vfp_test.c
index 223e7f8..fe60058 100644
--- a/test/builtins/Unit/subsf3vfp_test.c
+++ b/test/builtins/Unit/subsf3vfp_test.c
@@ -11,12 +11,13 @@
 //
 //===----------------------------------------------------------------------===//
 
+#include "int_lib.h"
 #include <stdio.h>
 #include <stdlib.h>
 #include <math.h>
 
 
-extern float __subsf3vfp(float a, float b);
+extern COMPILER_RT_ABI float __subsf3vfp(float a, float b);
 
 #if __arm__
 int test__subsf3vfp(float a, float b)
diff --git a/test/builtins/Unit/subtf3_test.c b/test/builtins/Unit/subtf3_test.c
index 2ab249a..ad115a4 100644
--- a/test/builtins/Unit/subtf3_test.c
+++ b/test/builtins/Unit/subtf3_test.c
@@ -18,7 +18,7 @@
 #include "fp_test.h"
 
 // Returns: a - b
-long double __subtf3(long double a, long double b);
+COMPILER_RT_ABI long double __subtf3(long double a, long double b);
 
 int test__subtf3(long double a, long double b,
                  uint64_t expectedHi, uint64_t expectedLo)
diff --git a/test/builtins/Unit/subvdi3_test.c b/test/builtins/Unit/subvdi3_test.c
index 0fb8f51..96e825c 100644
--- a/test/builtins/Unit/subvdi3_test.c
+++ b/test/builtins/Unit/subvdi3_test.c
@@ -19,7 +19,7 @@
 
 // Effects: aborts if a - b overflows
 
-di_int __subvdi3(di_int a, di_int b);
+COMPILER_RT_ABI di_int __subvdi3(di_int a, di_int b);
 
 int test__subvdi3(di_int a, di_int b)
 {
diff --git a/test/builtins/Unit/subvsi3_test.c b/test/builtins/Unit/subvsi3_test.c
index 14e6ce1..03ef504 100644
--- a/test/builtins/Unit/subvsi3_test.c
+++ b/test/builtins/Unit/subvsi3_test.c
@@ -19,7 +19,7 @@
 
 // Effects: aborts if a - b overflows
 
-si_int __subvsi3(si_int a, si_int b);
+COMPILER_RT_ABI si_int __subvsi3(si_int a, si_int b);
 
 int test__subvsi3(si_int a, si_int b)
 {
diff --git a/test/builtins/Unit/subvti3_test.c b/test/builtins/Unit/subvti3_test.c
index b2c225c..40eb518 100644
--- a/test/builtins/Unit/subvti3_test.c
+++ b/test/builtins/Unit/subvti3_test.c
@@ -21,7 +21,7 @@
 
 // Effects: aborts if a - b overflows
 
-ti_int __subvti3(ti_int a, ti_int b);
+COMPILER_RT_ABI ti_int __subvti3(ti_int a, ti_int b);
 
 int test__subvti3(ti_int a, ti_int b)
 {
diff --git a/test/builtins/Unit/truncdfsf2vfp_test.c b/test/builtins/Unit/truncdfsf2vfp_test.c
index afc7868..eaeda65 100644
--- a/test/builtins/Unit/truncdfsf2vfp_test.c
+++ b/test/builtins/Unit/truncdfsf2vfp_test.c
@@ -11,12 +11,13 @@
 //
 //===----------------------------------------------------------------------===//
 
+#include "int_lib.h"
 #include <stdio.h>
 #include <stdlib.h>
 #include <math.h>
 
 
-extern float __truncdfsf2vfp(double a);
+extern COMPILER_RT_ABI float __truncdfsf2vfp(double a);
 
 #if __arm__
 int test__truncdfsf2vfp(double a)
diff --git a/test/builtins/Unit/trunctfdf2_test.c b/test/builtins/Unit/trunctfdf2_test.c
index 46855e3..0366a8c 100644
--- a/test/builtins/Unit/trunctfdf2_test.c
+++ b/test/builtins/Unit/trunctfdf2_test.c
@@ -11,13 +11,14 @@
 //
 //===----------------------------------------------------------------------===//
 
+#include "int_lib.h"
 #include <stdio.h>
 
 #if __LDBL_MANT_DIG__ == 113
 
 #include "fp_test.h"
 
-double __trunctfdf2(long double a);
+COMPILER_RT_ABI double __trunctfdf2(long double a);
 
 int test__trunctfdf2(long double a, uint64_t expected)
 {
diff --git a/test/builtins/Unit/trunctfsf2_test.c b/test/builtins/Unit/trunctfsf2_test.c
index 44e7fd1..a6b922c 100644
--- a/test/builtins/Unit/trunctfsf2_test.c
+++ b/test/builtins/Unit/trunctfsf2_test.c
@@ -11,13 +11,14 @@
 //
 //===----------------------------------------------------------------------===//
 
+#include "int_lib.h"
 #include <stdio.h>
 
 #if __LDBL_MANT_DIG__ == 113
 
 #include "fp_test.h"
 
-float __trunctfsf2(long double a);
+COMPILER_RT_ABI float __trunctfsf2(long double a);
 
 int test__trunctfsf2(long double a, uint32_t expected)
 {
diff --git a/test/builtins/Unit/ucmpdi2_test.c b/test/builtins/Unit/ucmpdi2_test.c
index 2205907..65ae4fc 100644
--- a/test/builtins/Unit/ucmpdi2_test.c
+++ b/test/builtins/Unit/ucmpdi2_test.c
@@ -18,7 +18,7 @@
 //           if (a == b) returns 1
 //           if (a >  b) returns 2
 
-si_int __ucmpdi2(du_int a, du_int b);
+COMPILER_RT_ABI si_int __ucmpdi2(du_int a, du_int b);
 
 int test__ucmpdi2(du_int a, du_int b, si_int expected)
 {
diff --git a/test/builtins/Unit/ucmpti2_test.c b/test/builtins/Unit/ucmpti2_test.c
index 0713da8..826cd64 100644
--- a/test/builtins/Unit/ucmpti2_test.c
+++ b/test/builtins/Unit/ucmpti2_test.c
@@ -20,7 +20,7 @@
 //           if (a == b) returns 1
 //           if (a >  b) returns 2
 
-si_int __ucmpti2(tu_int a, tu_int b);
+COMPILER_RT_ABI si_int __ucmpti2(tu_int a, tu_int b);
 
 int test__ucmpti2(tu_int a, tu_int b, si_int expected)
 {
diff --git a/test/builtins/Unit/udivdi3_test.c b/test/builtins/Unit/udivdi3_test.c
index 24843f8..48c99e3 100644
--- a/test/builtins/Unit/udivdi3_test.c
+++ b/test/builtins/Unit/udivdi3_test.c
@@ -16,7 +16,7 @@
 
 // Returns: a / b
 
-du_int __udivdi3(du_int a, du_int b);
+COMPILER_RT_ABI du_int __udivdi3(du_int a, du_int b);
 
 int test__udivdi3(du_int a, du_int b, du_int expected_q)
 {
diff --git a/test/builtins/Unit/udivmoddi4_test.c b/test/builtins/Unit/udivmoddi4_test.c
index 43bf1a1..79af1ee 100644
--- a/test/builtins/Unit/udivmoddi4_test.c
+++ b/test/builtins/Unit/udivmoddi4_test.c
@@ -17,7 +17,7 @@
 // Effects: if rem != 0, *rem = a % b
 // Returns: a / b
 
-du_int __udivmoddi4(du_int a, du_int b, du_int* rem);
+COMPILER_RT_ABI du_int __udivmoddi4(du_int a, du_int b, du_int* rem);
 
 int test__udivmoddi4(du_int a, du_int b, du_int expected_q, du_int expected_r)
 {
diff --git a/test/builtins/Unit/udivmodsi4_test.c b/test/builtins/Unit/udivmodsi4_test.c
index d734cd1..4c14e29 100644
--- a/test/builtins/Unit/udivmodsi4_test.c
+++ b/test/builtins/Unit/udivmodsi4_test.c
@@ -16,7 +16,7 @@
 
 // Returns: a / b
 
-extern su_int __udivmodsi4(su_int a, su_int b, su_int* rem);
+extern COMPILER_RT_ABI su_int __udivmodsi4(su_int a, su_int b, su_int* rem);
 
 int test__udivmodsi4(su_int a, su_int b, 
 						su_int expected_result, su_int expected_rem)
diff --git a/test/builtins/Unit/udivmodti4_test.c b/test/builtins/Unit/udivmodti4_test.c
index 751aa86..c424661 100644
--- a/test/builtins/Unit/udivmodti4_test.c
+++ b/test/builtins/Unit/udivmodti4_test.c
@@ -19,7 +19,7 @@
 // Effects: if rem != 0, *rem = a % b
 // Returns: a / b
 
-tu_int __udivmodti4(tu_int a, tu_int b, tu_int* rem);
+COMPILER_RT_ABI tu_int __udivmodti4(tu_int a, tu_int b, tu_int* rem);
 
 int test__udivmodti4(tu_int a, tu_int b, tu_int expected_q, tu_int expected_r)
 {
diff --git a/test/builtins/Unit/udivsi3_test.c b/test/builtins/Unit/udivsi3_test.c
index 325e4e6..4905386 100644
--- a/test/builtins/Unit/udivsi3_test.c
+++ b/test/builtins/Unit/udivsi3_test.c
@@ -16,7 +16,7 @@
 
 // Returns: a / b
 
-su_int __udivsi3(su_int a, su_int b);
+COMPILER_RT_ABI su_int __udivsi3(su_int a, su_int b);
 
 int test__udivsi3(su_int a, su_int b, su_int expected_q)
 {
diff --git a/test/builtins/Unit/udivti3_test.c b/test/builtins/Unit/udivti3_test.c
index af5aad9..f24ff03 100644
--- a/test/builtins/Unit/udivti3_test.c
+++ b/test/builtins/Unit/udivti3_test.c
@@ -18,7 +18,7 @@
 
 // Returns: a / b
 
-tu_int __udivti3(tu_int a, tu_int b);
+COMPILER_RT_ABI tu_int __udivti3(tu_int a, tu_int b);
 
 int test__udivti3(tu_int a, tu_int b, tu_int expected_q)
 {
diff --git a/test/builtins/Unit/umoddi3_test.c b/test/builtins/Unit/umoddi3_test.c
index a8f39b4..b46fb40 100644
--- a/test/builtins/Unit/umoddi3_test.c
+++ b/test/builtins/Unit/umoddi3_test.c
@@ -16,7 +16,7 @@
 
 // Returns: a % b
 
-du_int __umoddi3(du_int a, du_int b);
+COMPILER_RT_ABI du_int __umoddi3(du_int a, du_int b);
 
 int test__umoddi3(du_int a, du_int b, du_int expected_r)
 {
diff --git a/test/builtins/Unit/umodsi3_test.c b/test/builtins/Unit/umodsi3_test.c
index 66da695..3655da1 100644
--- a/test/builtins/Unit/umodsi3_test.c
+++ b/test/builtins/Unit/umodsi3_test.c
@@ -16,7 +16,7 @@
 
 // Returns: a % b
 
-su_int __umodsi3(su_int a, su_int b);
+COMPILER_RT_ABI su_int __umodsi3(su_int a, su_int b);
 
 int test__umodsi3(su_int a, su_int b, su_int expected_r)
 {
diff --git a/test/builtins/Unit/umodti3_test.c b/test/builtins/Unit/umodti3_test.c
index 93b556c..21e82a4 100644
--- a/test/builtins/Unit/umodti3_test.c
+++ b/test/builtins/Unit/umodti3_test.c
@@ -18,7 +18,7 @@
 
 // Returns: a % b
 
-tu_int __umodti3(tu_int a, tu_int b);
+COMPILER_RT_ABI tu_int __umodti3(tu_int a, tu_int b);
 
 int test__umodti3(tu_int a, tu_int b, tu_int expected_r)
 {
diff --git a/test/cfi/bad-cast.cpp b/test/cfi/bad-cast.cpp
index 39d8a35..712262d 100644
--- a/test/cfi/bad-cast.cpp
+++ b/test/cfi/bad-cast.cpp
@@ -61,7 +61,6 @@
 // Tests that the CFI enforcement detects bad casts.
 
 #include <stdio.h>
-#include <utility>
 #include "utils.h"
 
 struct A {
diff --git a/test/cfi/lit.cfg b/test/cfi/lit.cfg
index 204d332..2343ff1 100644
--- a/test/cfi/lit.cfg
+++ b/test/cfi/lit.cfg
@@ -1,36 +1,15 @@
 import lit.formats
 import os
-import subprocess
-import sys
 
 config.name = 'cfi'
 config.suffixes = ['.cpp']
 config.test_source_root = os.path.dirname(__file__)
 
-def is_darwin_lto_supported():
-  return os.path.exists(os.path.join(config.llvm_shlib_dir, 'libLTO.dylib'))
-
-def is_linux_lto_supported():
-  if not os.path.exists(os.path.join(config.llvm_shlib_dir, 'LLVMgold.so')):
-    return False
-
-  ld_cmd = subprocess.Popen([config.gold_executable, '--help'], stdout = subprocess.PIPE)
-  ld_out = ld_cmd.stdout.read().decode()
-  ld_cmd.wait()
-
-  if not '-plugin' in ld_out:
-    return False
-
-  return True
-
 clangxx = ' '.join([config.clang] + config.cxx_mode_flags)
 
 config.substitutions.append((r"%clangxx ", clangxx + ' '))
-
-if sys.platform == 'darwin' and is_darwin_lto_supported():
-  config.substitutions.append((r"%clangxx_cfi ", 'env DYLD_LIBRARY_PATH=' + config.llvm_shlib_dir + ' ' + clangxx + ' -fsanitize=cfi '))
-elif sys.platform.startswith('linux') and is_linux_lto_supported():
-  config.substitutions.append((r"%clangxx_cfi ", clangxx + ' -fuse-ld=gold -fsanitize=cfi '))
+if config.lto_supported:
+  config.substitutions.append((r"%clangxx_cfi ", ' '.join(config.lto_launch + [clangxx] + config.lto_flags + ['-fsanitize=cfi '])))
 else:
   config.unsupported = True
 
diff --git a/test/lit.common.cfg b/test/lit.common.cfg
index 0a55186..2a5d01c 100644
--- a/test/lit.common.cfg
+++ b/test/lit.common.cfg
@@ -5,6 +5,7 @@
 # It is mostly copied from lit.cfg used by Clang.
 import os
 import platform
+import subprocess
 
 import lit.formats
 import lit.util
@@ -37,7 +38,9 @@
 config.available_features.add(compiler_id)
 
 # Clear some environment variables that might affect Clang.
-possibly_dangerous_env_vars = ['COMPILER_PATH', 'RC_DEBUG_OPTIONS',
+possibly_dangerous_env_vars = ['ASAN_OPTIONS', 'DFSAN_OPTIONS', 'LSAN_OPTIONS',
+                               'MSAN_OPTIONS', 'UBSAN_OPTIONS',
+                               'COMPILER_PATH', 'RC_DEBUG_OPTIONS',
                                'CINDEXTEST_PREAMBLE_FILE', 'LIBRARY_PATH',
                                'CPATH', 'C_INCLUDE_PATH', 'CPLUS_INCLUDE_PATH',
                                'OBJC_INCLUDE_PATH', 'OBJCPLUS_INCLUDE_PATH',
@@ -88,3 +91,30 @@
   config.available_features.add('compiler-rt-optimized')
 
 lit.util.usePlatformSdkOnDarwin(config, lit_config)
+
+def is_darwin_lto_supported():
+  return os.path.exists(os.path.join(config.llvm_shlib_dir, 'libLTO.dylib'))
+
+def is_linux_lto_supported():
+  if not os.path.exists(os.path.join(config.llvm_shlib_dir, 'LLVMgold.so')):
+    return False
+
+  ld_cmd = subprocess.Popen([config.gold_executable, '--help'], stdout = subprocess.PIPE)
+  ld_out = ld_cmd.stdout.read().decode()
+  ld_cmd.wait()
+
+  if not '-plugin' in ld_out:
+    return False
+
+  return True
+
+if sys.platform == 'darwin' and is_darwin_lto_supported():
+  config.lto_supported = True
+  config.lto_launch = ["env", "DYLD_LIBRARY_PATH=" + config.llvm_shlib_dir]
+  config.lto_flags = []
+elif sys.platform.startswith('linux') and is_linux_lto_supported():
+  config.lto_supported = True
+  config.lto_launch = []
+  config.lto_flags = ["-fuse-ld=gold"]
+else:
+  config.lto_supported = False
diff --git a/test/lsan/TestCases/recoverable_leak_check.cc b/test/lsan/TestCases/recoverable_leak_check.cc
new file mode 100644
index 0000000..0fe377f
--- /dev/null
+++ b/test/lsan/TestCases/recoverable_leak_check.cc
@@ -0,0 +1,32 @@
+// Test for on-demand leak checking.
+// RUN: LSAN_BASE="use_stacks=0:use_registers=0"
+// RUN: %clangxx_lsan %s -o %t
+// RUN: LSAN_OPTIONS=$LSAN_BASE %run %t foo 2>&1 | FileCheck %s
+// RUN: LSAN_OPTIONS=$LSAN_BASE %run %t 2>&1 | FileCheck %s
+
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sanitizer/lsan_interface.h>
+
+void *p;
+
+int main(int argc, char *argv[]) {
+  p = malloc(23);
+
+  assert(__lsan_do_recoverable_leak_check() == 0);
+
+  fprintf(stderr, "Test alloc: %p.\n", malloc(1337));
+// CHECK: Test alloc:
+
+  assert(__lsan_do_recoverable_leak_check() == 1);
+// CHECK: SUMMARY: {{(Leak|Address)}}Sanitizer: 1337 byte
+
+  // Test that we correctly reset chunk tags.
+  p = 0;
+  assert(__lsan_do_recoverable_leak_check() == 1);
+// CHECK: SUMMARY: {{(Leak|Address)}}Sanitizer: 1360 byte
+
+  _exit(0);
+}
diff --git a/test/msan/ioctl_sound.cc b/test/msan/Linux/ioctl_sound.cc
similarity index 100%
rename from test/msan/ioctl_sound.cc
rename to test/msan/Linux/ioctl_sound.cc
diff --git a/test/msan/mallinfo.cc b/test/msan/Linux/mallinfo.cc
similarity index 100%
rename from test/msan/mallinfo.cc
rename to test/msan/Linux/mallinfo.cc
diff --git a/test/msan/obstack.cc b/test/msan/Linux/obstack.cc
similarity index 100%
rename from test/msan/obstack.cc
rename to test/msan/Linux/obstack.cc
diff --git a/test/msan/backtrace.cc b/test/msan/backtrace.cc
index b6cfcbe..9cb883c 100644
--- a/test/msan/backtrace.cc
+++ b/test/msan/backtrace.cc
@@ -17,7 +17,7 @@
   char **s = backtrace_symbols(buf, sz);
   assert(s > 0);
   for (int i = 0; i < sz; ++i)
-    printf("%d\n", strlen(s[i]));
+    printf("%d\n", (int)strlen(s[i]));
 }
 
 int main(void) {
diff --git a/test/msan/coverage-levels.cc b/test/msan/coverage-levels.cc
index 7c2e143..d71bfec 100644
--- a/test/msan/coverage-levels.cc
+++ b/test/msan/coverage-levels.cc
@@ -1,13 +1,13 @@
 // Test various levels of coverage
 //
-// RUN: %clangxx_msan -DINIT_VAR=1 -O1 -fsanitize-coverage=1  %s -o %t
+// RUN: %clangxx_msan -DINIT_VAR=1 -O1 -fsanitize-coverage=func  %s -o %t
 // RUN: mkdir -p %T/coverage-levels
 // RUN: MSAN_OPTIONS=coverage=1:verbosity=1:coverage_dir=%T/coverage-levels %run %t 2>&1 | FileCheck %s --check-prefix=CHECK1 --check-prefix=CHECK_NOWARN
-// RUN: %clangxx_msan -O1 -fsanitize-coverage=1  %s -o %t
+// RUN: %clangxx_msan -O1 -fsanitize-coverage=func  %s -o %t
 // RUN: MSAN_OPTIONS=coverage=1:verbosity=1:coverage_dir=%T/coverage-levels not %run %t 2>&1 | FileCheck %s --check-prefix=CHECK1 --check-prefix=CHECK_WARN
-// RUN: %clangxx_msan -O1 -fsanitize-coverage=2  %s -o %t
+// RUN: %clangxx_msan -O1 -fsanitize-coverage=bb  %s -o %t
 // RUN: MSAN_OPTIONS=coverage=1:verbosity=1:coverage_dir=%T/coverage-levels not %run %t 2>&1 | FileCheck %s --check-prefix=CHECK2 --check-prefix=CHECK_WARN
-// RUN: %clangxx_msan -O1 -fsanitize-coverage=3  %s -o %t
+// RUN: %clangxx_msan -O1 -fsanitize-coverage=edge  %s -o %t
 // RUN: MSAN_OPTIONS=coverage=1:verbosity=1:coverage_dir=%T/coverage-levels not %run %t 2>&1 | FileCheck %s --check-prefix=CHECK3 --check-prefix=CHECK_WARN
 //
 volatile int sink;
diff --git a/test/msan/ftime.cc b/test/msan/ftime.cc
index 5ed9358..7a5a2fb 100644
--- a/test/msan/ftime.cc
+++ b/test/msan/ftime.cc
@@ -1,5 +1,8 @@
 // RUN: %clangxx_msan -O0 -g %s -o %t && %run %t
 
+// ftime() is deprecated on FreeBSD.
+// XFAIL: freebsd
+
 #include <assert.h>
 #include <sys/timeb.h>
 
diff --git a/test/msan/getline.cc b/test/msan/getline.cc
index 51e105e..ee12d4d 100644
--- a/test/msan/getline.cc
+++ b/test/msan/getline.cc
@@ -7,6 +7,10 @@
 // RUN: %clang_msan -O0 -xc -D_GNU_SOURCE=1 %s -o %t && %run %t %t-testdata
 // RUN: %clang_msan -O2 -xc -D_GNU_SOURCE=1 %s -o %t && %run %t %t-testdata
 
+#if defined(__FreeBSD__)
+#define _WITH_GETLINE  // To declare getline().
+#endif
+
 #include <assert.h>
 #include <stdio.h>
 #include <stdlib.h>
diff --git a/test/msan/iconv.cc b/test/msan/iconv.cc
index c4f2534..c2da938 100644
--- a/test/msan/iconv.cc
+++ b/test/msan/iconv.cc
@@ -15,7 +15,12 @@
   char inbuf_[100];
   strcpy(inbuf_, "sample text");
   char outbuf_[100];
+#if defined(__FreeBSD__)
+  // FreeBSD's iconv() expects the 2nd argument be of type 'const char**'.
+  const char *inbuf = inbuf_;
+#else
   char *inbuf = inbuf_;
+#endif
   char *outbuf = outbuf_;
   size_t inbytesleft = strlen(inbuf_);
   size_t outbytesleft = sizeof(outbuf_);
diff --git a/test/msan/if_indextoname.cc b/test/msan/if_indextoname.cc
index 7f7dea7..7b1b989 100644
--- a/test/msan/if_indextoname.cc
+++ b/test/msan/if_indextoname.cc
@@ -18,6 +18,6 @@
     printf("No network interfaces found.\n");
     return 0;
   }
-  assert(strlen(ifname) + 1 == __msan_test_shadow(ifname, sizeof(ifname)));
+  assert(strlen(ifname) + 1 <= __msan_test_shadow(ifname, sizeof(ifname)));
   return 0;
 }
diff --git a/test/msan/ifaddrs.cc b/test/msan/ifaddrs.cc
index 568e661..6f5eb93 100644
--- a/test/msan/ifaddrs.cc
+++ b/test/msan/ifaddrs.cc
@@ -10,6 +10,10 @@
 
 #include <vector>
 
+#if defined(__FreeBSD__)
+#include <sys/socket.h>  // To define 'struct sockaddr'.
+#endif
+
 #include <sanitizer/msan_interface.h>
 
 #define CHECK_AND_PUSH(addr, size)                                \
diff --git a/test/msan/initgroups.cc b/test/msan/initgroups.cc
index d11fd58..974b1cb 100644
--- a/test/msan/initgroups.cc
+++ b/test/msan/initgroups.cc
@@ -2,6 +2,7 @@
 
 #include <sys/types.h>
 #include <grp.h>
+#include <unistd.h>  // FreeBSD declares initgroups() here.
 
 int main(void) {
   initgroups("root", 0);
diff --git a/test/msan/lit.cfg b/test/msan/lit.cfg
index f425e25..011ccd2 100644
--- a/test/msan/lit.cfg
+++ b/test/msan/lit.cfg
@@ -14,6 +14,9 @@
                      "-fno-omit-frame-pointer",
                      "-fno-optimize-sibling-calls",
                      "-m64"] + config.debug_info_flags
+# Some Msan tests leverage backtrace() which requires libexecinfo on FreeBSD.
+if config.host_os == 'FreeBSD':
+  clang_msan_cflags += ["-lexecinfo"]
 clang_msan_cxxflags = config.cxx_mode_flags + clang_msan_cflags
 
 def build_invocation(compile_flags):
diff --git a/test/msan/mmap.cc b/test/msan/mmap.cc
new file mode 100644
index 0000000..cd7b93d
--- /dev/null
+++ b/test/msan/mmap.cc
@@ -0,0 +1,43 @@
+// Test that mmap (without MAP_FIXED) always returns valid application addresses.
+// RUN: %clangxx_msan -O0 %s -o %t && %run %t
+// RUN: %clangxx_msan -O0 -fsanitize-memory-track-origins %s -o %t && %run %t
+
+#include <assert.h>
+#include <errno.h>
+#include <stdint.h>
+#include <sys/mman.h>
+#include <stdio.h>
+
+bool AddrIsApp(void *p) {
+  uintptr_t addr = (uintptr_t)p;
+#if defined(__FreeBSD__) && defined(__x86_64__)
+  return addr < 0x010000000000ULL || addr >= 0x600000000000ULL;
+#elif defined(__x86_64__)
+  return addr >= 0x600000000000ULL;
+#elif defined(__mips64)
+  return addr >= 0x00e000000000ULL;
+#endif
+}
+
+int main() {
+  // Large enough to quickly exhaust the entire address space.
+#if defined(__mips64)
+  const size_t kMapSize = 0x100000000ULL;
+#else
+  const size_t kMapSize = 0x1000000000ULL;
+#endif
+  int success_count = 0;
+  while (true) {
+    void *p = mmap(0, kMapSize, PROT_WRITE,
+                   MAP_PRIVATE | MAP_ANONYMOUS | MAP_NORESERVE, -1, 0);
+    printf("%p\n", p);
+    if (p == MAP_FAILED) {
+      assert(errno == ENOMEM);
+      break;
+    }
+    assert(AddrIsApp(p));
+    success_count++;
+  }
+  printf("successful mappings: %d\n", success_count);
+  assert(success_count > 5);
+}
diff --git a/test/msan/mmap_below_shadow.cc b/test/msan/mmap_below_shadow.cc
index 2b507d0..5f25a9b 100644
--- a/test/msan/mmap_below_shadow.cc
+++ b/test/msan/mmap_below_shadow.cc
@@ -15,7 +15,10 @@
 
 int main(void) {
   // Hint address just below shadow.
-#if defined(__x86_64__)
+#if defined(__FreeBSD__) && defined(__x86_64__)
+  uintptr_t hint = 0x0f0000000000ULL;
+  const uintptr_t app_start = 0x000000000000ULL;
+#elif defined(__x86_64__)
   uintptr_t hint = 0x4f0000000000ULL;
   const uintptr_t app_start = 0x600000000000ULL;
 #elif defined (__mips64)
diff --git a/test/msan/report-demangling.cc b/test/msan/report-demangling.cc
index e75ba87..fbb6554 100644
--- a/test/msan/report-demangling.cc
+++ b/test/msan/report-demangling.cc
@@ -15,5 +15,5 @@
   return f();
   // CHECK: WARNING: MemorySanitizer: use-of-uninitialized-value
   // CHECK: Uninitialized value was created by an allocation of 'x' in the stack frame of function '_Z1fv'
-  // CHECK: #0 {{.*}} in f() {{.*}}report-demangling.cc:[[@LINE-10]]
+  // CHECK: #0 {{.*}} in f{{.*}} {{.*}}report-demangling.cc:[[@LINE-10]]
 }
diff --git a/test/profile/Inputs/instrprof-dynamic-a.cpp b/test/profile/Inputs/instrprof-dynamic-a.cpp
index 67de263..2ec484a 100644
--- a/test/profile/Inputs/instrprof-dynamic-a.cpp
+++ b/test/profile/Inputs/instrprof-dynamic-a.cpp
@@ -1,7 +1,7 @@
 #include "instrprof-dynamic-header.h"
 void a() {
   if (true) {
-    bar<void>();
-    bar<char>();
+    bar<void>(1);
+    bar<char>(1);
   }
 }
diff --git a/test/profile/Inputs/instrprof-dynamic-b.cpp b/test/profile/Inputs/instrprof-dynamic-b.cpp
index c8fb75e..5c2d9ba 100644
--- a/test/profile/Inputs/instrprof-dynamic-b.cpp
+++ b/test/profile/Inputs/instrprof-dynamic-b.cpp
@@ -1,7 +1,7 @@
 #include "instrprof-dynamic-header.h"
 void b() {
   if (true) {
-    bar<void>();
-    bar<int>();
+    bar<void>(1);
+    bar<int>(1);
   }
 }
diff --git a/test/profile/Inputs/instrprof-dynamic-header.h b/test/profile/Inputs/instrprof-dynamic-header.h
index 1dc2e37..7a57b13 100644
--- a/test/profile/Inputs/instrprof-dynamic-header.h
+++ b/test/profile/Inputs/instrprof-dynamic-header.h
@@ -1,5 +1,7 @@
-template <class T> void bar() {
-  if (true) {}
+template <class T> void bar(int X) {
+  if (X) {
+    X *= 4;
+  }
 }
 void a();
 void b();
diff --git a/test/profile/Inputs/instrprof-dynamic-main.cpp b/test/profile/Inputs/instrprof-dynamic-main.cpp
index 0dd6021..2cf37c8 100644
--- a/test/profile/Inputs/instrprof-dynamic-main.cpp
+++ b/test/profile/Inputs/instrprof-dynamic-main.cpp
@@ -2,7 +2,7 @@
 void foo(int K) { if (K) {} }
 int main(int argc, char *argv[]) {
   foo(5);
-  bar<void>();
+  bar<void>(1);
   a();
   b();
   return 0;
diff --git a/test/profile/instrprof-override-filename-then-reset-default.c b/test/profile/instrprof-override-filename-then-reset-default.c
new file mode 100644
index 0000000..137a3b2
--- /dev/null
+++ b/test/profile/instrprof-override-filename-then-reset-default.c
@@ -0,0 +1,19 @@
+// RUN: rm -rf %t.d
+// RUN: mkdir -p %t.d
+// RUN: cd %t.d
+// RUN: %clang_profgen -O3 %s -o %t.out
+// RUN: %run %t.out %t.d/bad.profraw
+// RUN: llvm-profdata merge -o %t.d/default.profdata %t.d/default.profraw
+// RUN: %clang_profuse=%t.d/default.profdata -o - -S -emit-llvm %s | FileCheck %s
+
+
+void __llvm_profile_override_default_filename(const char *);
+int main(int argc, const char *argv[]) {
+  // CHECK: br i1 %{{.*}}, label %{{.*}}, label %{{.*}}, !prof ![[PD1:[0-9]+]]
+  if (argc < 2)
+    return 1;
+  __llvm_profile_override_default_filename(argv[1]);
+  __llvm_profile_override_default_filename(0);
+  return 0;
+}
+// CHECK: ![[PD1]] = !{!"branch_weights", i32 1, i32 2}
diff --git a/test/profile/instrprof-override-filename-with-env.c b/test/profile/instrprof-override-filename-with-env.c
new file mode 100644
index 0000000..cce8389
--- /dev/null
+++ b/test/profile/instrprof-override-filename-with-env.c
@@ -0,0 +1,14 @@
+// RUN: %clang_profgen -o %t -O3 %s
+// RUN: env LLVM_PROFILE_FILE=%t.good.profraw %run %t %t.bad.profraw
+// RUN: llvm-profdata merge -o %t.profdata %t.good.profraw
+// RUN: %clang_profuse=%t.profdata -o - -S -emit-llvm %s | FileCheck %s
+
+void __llvm_profile_override_default_filename(const char *);
+int main(int argc, const char *argv[]) {
+  // CHECK: br i1 %{{.*}}, label %{{.*}}, label %{{.*}}, !prof ![[PD1:[0-9]+]]
+  if (argc < 2)
+    return 1;
+  __llvm_profile_override_default_filename(argv[1]);
+  return 0;
+}
+// CHECK: ![[PD1]] = !{!"branch_weights", i32 1, i32 2}
diff --git a/test/profile/instrprof-override-filename.c b/test/profile/instrprof-override-filename.c
new file mode 100644
index 0000000..59dea29
--- /dev/null
+++ b/test/profile/instrprof-override-filename.c
@@ -0,0 +1,14 @@
+// RUN: %clang_profgen -o %t -O3 %s
+// RUN: %run %t %t.profraw
+// RUN: llvm-profdata merge -o %t.profdata %t.profraw
+// RUN: %clang_profuse=%t.profdata -o - -S -emit-llvm %s | FileCheck %s
+
+void __llvm_profile_override_default_filename(const char *);
+int main(int argc, const char *argv[]) {
+  // CHECK: br i1 %{{.*}}, label %{{.*}}, label %{{.*}}, !prof ![[PD1:[0-9]+]]
+  if (argc < 2)
+    return 1;
+  __llvm_profile_override_default_filename(argv[1]);
+  return 0;
+}
+// CHECK: ![[PD1]] = !{!"branch_weights", i32 1, i32 2}
diff --git a/test/profile/instrprof-set-filename-then-reset-default.c b/test/profile/instrprof-set-filename-then-reset-default.c
new file mode 100644
index 0000000..6c07994
--- /dev/null
+++ b/test/profile/instrprof-set-filename-then-reset-default.c
@@ -0,0 +1,18 @@
+// RUN: rm -rf %t.d
+// RUN: mkdir -p %t.d
+// RUN: cd %t.d
+// RUN: %clang_profgen -O3 %s -o %t.out
+// RUN: %run %t.out %t.d/bad.profraw
+// RUN: llvm-profdata merge -o %t.d/default.profdata %t.d/default.profraw
+// RUN: %clang_profuse=%t.d/default.profdata -o - -S -emit-llvm %s | FileCheck %s
+
+void __llvm_profile_set_filename(const char *);
+int main(int argc, const char *argv[]) {
+  // CHECK: br i1 %{{.*}}, label %{{.*}}, label %{{.*}}, !prof ![[PD1:[0-9]+]]
+  if (argc < 2)
+    return 1;
+  __llvm_profile_set_filename(argv[1]);
+  __llvm_profile_set_filename(0);
+  return 0;
+}
+// CHECK: ![[PD1]] = !{!"branch_weights", i32 1, i32 2}
diff --git a/test/safestack/CMakeLists.txt b/test/safestack/CMakeLists.txt
new file mode 100644
index 0000000..6f5c2f9
--- /dev/null
+++ b/test/safestack/CMakeLists.txt
@@ -0,0 +1,29 @@
+set(SAFESTACK_LIT_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR})
+set(SAFESTACK_LIT_BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR})
+
+set(SAFESTACK_TEST_DEPS ${SANITIZER_COMMON_LIT_TEST_DEPS})
+if(NOT COMPILER_RT_STANDALONE_BUILD)
+  list(APPEND SAFESTACK_TEST_DEPS safestack)
+
+  # Some tests require LTO, so add a dependency on the relevant LTO plugin.
+  if(LLVM_ENABLE_PIC AND LLVM_BINUTILS_INCDIR)
+    list(APPEND SAFESTACK_TEST_DEPS
+      LLVMgold
+    )
+  endif()
+  if(APPLE)
+    list(APPEND SAFESTACK_TEST_DEPS
+      LTO
+    )
+  endif()
+endif()
+
+configure_lit_site_cfg(
+  ${CMAKE_CURRENT_SOURCE_DIR}/lit.site.cfg.in
+  ${CMAKE_CURRENT_BINARY_DIR}/lit.site.cfg
+  )
+
+add_lit_testsuite(check-safestack "Running the SafeStack tests"
+  ${CMAKE_CURRENT_BINARY_DIR}
+  DEPENDS ${SAFESTACK_TEST_DEPS})
+set_target_properties(check-safestack PROPERTIES FOLDER "SafeStack tests")
diff --git a/test/safestack/buffer-copy-vla.c b/test/safestack/buffer-copy-vla.c
new file mode 100644
index 0000000..356a1ac
--- /dev/null
+++ b/test/safestack/buffer-copy-vla.c
@@ -0,0 +1,26 @@
+// RUN: %clang_safestack %s -o %t
+// RUN: %run %t
+
+#include "utils.h"
+
+// Test that loads/stores work correctly for VLAs on the unsafe stack.
+
+int main(int argc, char **argv)
+{
+  int i = 128;
+  break_optimization(&i);
+  char buffer[i];
+
+  // check that we can write to a buffer
+  for (i = 0; argv[0][i] && i < sizeof (buffer) - 1; ++i)
+    buffer[i] = argv[0][i];
+  buffer[i] = '\0';
+
+  break_optimization(buffer);
+
+  // check that we can read from a buffer
+  for (i = 0; argv[0][i] && i < sizeof (buffer) - 1; ++i)
+    if (buffer[i] != argv[0][i])
+      return 1;
+  return 0;
+}
diff --git a/test/safestack/buffer-copy.c b/test/safestack/buffer-copy.c
new file mode 100644
index 0000000..96b2302
--- /dev/null
+++ b/test/safestack/buffer-copy.c
@@ -0,0 +1,25 @@
+// RUN: %clang_safestack %s -o %t
+// RUN: %run %t
+
+#include "utils.h"
+
+// Test that loads/stores work correctly for variables on the unsafe stack.
+
+int main(int argc, char **argv)
+{
+  int i;
+  char buffer[128];
+
+  // check that we can write to a buffer
+  for (i = 0; argv[0][i] && i < sizeof (buffer) - 1; ++i)
+    buffer[i] = argv[0][i];
+  buffer[i] = '\0';
+
+  break_optimization(buffer);
+
+  // check that we can read from a buffer
+  for (i = 0; argv[0][i] && i < sizeof (buffer) - 1; ++i)
+    if (buffer[i] != argv[0][i])
+      return 1;
+  return 0;
+}
diff --git a/test/safestack/init.c b/test/safestack/init.c
new file mode 100644
index 0000000..cff75f5
--- /dev/null
+++ b/test/safestack/init.c
@@ -0,0 +1,9 @@
+// RUN: %clang_safestack %s -o %t
+// RUN: %run %t
+
+// Basic smoke test for the runtime library.
+
+int main(int argc, char **argv)
+{
+  return 0;
+}
diff --git a/test/safestack/lit.cfg b/test/safestack/lit.cfg
new file mode 100644
index 0000000..13fc92f
--- /dev/null
+++ b/test/safestack/lit.cfg
@@ -0,0 +1,24 @@
+# -*- Python -*-
+
+import os
+
+# Setup config name.
+config.name = 'SafeStack'
+
+# Setup source root.
+config.test_source_root = os.path.dirname(__file__)
+
+# Test suffixes.
+config.suffixes = ['.c', '.cc', '.cpp', '.m', '.mm', '.ll', '.test']
+
+# Add clang substitutions.
+config.substitutions.append( ("%clang_nosafestack ", config.clang + " -O0 -fno-sanitize=safe-stack ") )
+config.substitutions.append( ("%clang_safestack ", config.clang + " -O0 -fsanitize=safe-stack ") )
+
+if config.lto_supported:
+  config.available_features.add('lto')
+  config.substitutions.append((r"%clang_lto_safestack ", ' '.join(config.lto_launch + [config.clang] + config.lto_flags + ['-flto -fsanitize=safe-stack '])))
+
+# SafeStack tests are currently supported on Linux, FreeBSD and Darwin only.
+if config.host_os not in ['Linux', 'FreeBSD', 'Darwin']:
+   config.unsupported = True
diff --git a/test/safestack/lit.site.cfg.in b/test/safestack/lit.site.cfg.in
new file mode 100644
index 0000000..cb1e729
--- /dev/null
+++ b/test/safestack/lit.site.cfg.in
@@ -0,0 +1,8 @@
+## Autogenerated by LLVM/Clang configuration.
+# Do not edit!
+
+# Load common config for all compiler-rt lit tests.
+lit_config.load_config(config, "@COMPILER_RT_BINARY_DIR@/test/lit.common.configured")
+
+# Load tool-specific config that would do the real work.
+lit_config.load_config(config, "@SAFESTACK_LIT_SOURCE_DIR@/lit.cfg")
diff --git a/test/safestack/lto.c b/test/safestack/lto.c
new file mode 100644
index 0000000..6ee23a1
--- /dev/null
+++ b/test/safestack/lto.c
@@ -0,0 +1,12 @@
+// REQUIRES: lto
+
+// RUN: %clang_lto_safestack %s -o %t
+// RUN: %run %t
+
+// Test that safe stack works with LTO.
+
+int main() {
+  char c[] = "hello world";
+  puts(c);
+  return 0;
+}
diff --git a/test/safestack/overflow.c b/test/safestack/overflow.c
new file mode 100644
index 0000000..14e2982
--- /dev/null
+++ b/test/safestack/overflow.c
@@ -0,0 +1,23 @@
+// RUN: %clang_safestack %s -o %t
+// RUN: %run %t
+
+// RUN: %clang_nosafestack -fno-stack-protector %s -o %t
+// RUN: not %run %t
+
+// Test that buffer overflows on the unsafe stack do not affect variables on the
+// safe stack.
+
+__attribute__((noinline))
+void fct(volatile int *buffer)
+{
+  memset(buffer - 1, 0, 7 * sizeof(int));
+}
+
+int main(int argc, char **argv)
+{
+  int value1 = 42;
+  int buffer[5];
+  int value2 = 42;
+  fct(buffer);
+  return value1 != 42 || value2 != 42;
+}
diff --git a/test/safestack/pthread-cleanup.c b/test/safestack/pthread-cleanup.c
new file mode 100644
index 0000000..805366c
--- /dev/null
+++ b/test/safestack/pthread-cleanup.c
@@ -0,0 +1,31 @@
+// RUN: %clang_safestack %s -pthread -o %t
+// RUN: not --crash %run %t
+
+// Test that unsafe stacks are deallocated correctly on thread exit.
+
+#include <stdlib.h>
+#include <string.h>
+#include <pthread.h>
+
+enum { kBufferSize = (1 << 15) };
+
+void *t1_start(void *ptr)
+{
+  char buffer[kBufferSize];
+  return buffer;
+}
+
+int main(int argc, char **argv)
+{
+  pthread_t t1;
+  char *buffer = NULL;
+
+  if (pthread_create(&t1, NULL, t1_start, NULL))
+    abort();
+  if (pthread_join(t1, &buffer))
+    abort();
+
+  // should segfault here
+  memset(buffer, 0, kBufferSize);
+  return 0;
+}
diff --git a/test/safestack/pthread.c b/test/safestack/pthread.c
new file mode 100644
index 0000000..1687c10
--- /dev/null
+++ b/test/safestack/pthread.c
@@ -0,0 +1,40 @@
+// RUN: %clang_safestack %s -pthread -o %t
+// RUN: %run %t
+
+// Test that pthreads receive their own unsafe stack.
+
+#include <stdlib.h>
+#include <string.h>
+#include <pthread.h>
+#include "utils.h"
+
+static int ptr_test = 42;
+
+void *t1_start(void *ptr)
+{
+  if (ptr != &ptr_test)
+    abort();
+
+  // safe stack
+  int val = ptr_test * 5;
+
+  // unsafe stack
+  char buffer[8096]; // two pages
+  memset(buffer, val, sizeof (buffer));
+  break_optimization(buffer);
+
+  return ptr;
+}
+
+int main(int argc, char **argv)
+{
+  pthread_t t1;
+  void *ptr = NULL;
+  if (pthread_create(&t1, NULL, t1_start, &ptr_test))
+    abort();
+  if (pthread_join(t1, &ptr))
+    abort();
+  if (ptr != &ptr_test)
+    abort();
+  return 0;
+}
diff --git a/test/safestack/utils.h b/test/safestack/utils.h
new file mode 100644
index 0000000..b04e3bd
--- /dev/null
+++ b/test/safestack/utils.h
@@ -0,0 +1,8 @@
+#ifndef UTILS_H
+#define UTILS_H
+
+static inline void break_optimization(void *arg) {
+  __asm__ __volatile__("" : : "r" (arg) : "memory");
+}
+
+#endif
diff --git a/test/sanitizer_common/CMakeLists.txt b/test/sanitizer_common/CMakeLists.txt
index 42f2690..a0d08a8 100644
--- a/test/sanitizer_common/CMakeLists.txt
+++ b/test/sanitizer_common/CMakeLists.txt
@@ -28,6 +28,7 @@
           ${COMPILER_RT_TEST_COMPILER_CFLAGS})
     else()
       get_target_flags_for_arch(${arch} SANITIZER_COMMON_TEST_TARGET_CFLAGS)
+      string(REPLACE ";" " " SANITIZER_COMMON_TEST_TARGET_CFLAGS "${SANITIZER_COMMON_TEST_TARGET_CFLAGS}")
     endif()
     set(CONFIG_NAME ${tool}-${arch}-${OS_NAME})
     configure_lit_site_cfg(
diff --git a/test/sanitizer_common/TestCases/Linux/assert.cc b/test/sanitizer_common/TestCases/Linux/assert.cc
new file mode 100644
index 0000000..7f9b0a0
--- /dev/null
+++ b/test/sanitizer_common/TestCases/Linux/assert.cc
@@ -0,0 +1,24 @@
+// Test the handle_abort option.
+// RUN: %clang %s -o %t
+// RUN:                              not --crash %run %t 2>&1 | FileCheck --check-prefix=CHECK0 %s
+// RUN: %tool_options=handle_abort=0 not --crash %run %t 2>&1 | FileCheck --check-prefix=CHECK0 %s
+// RUN: %tool_options=handle_abort=1 not         %run %t 2>&1 | FileCheck --check-prefix=CHECK1 %s
+// FIXME: implement in other sanitizers, not just asan.
+// XFAIL: msan
+// XFAIL: lsan
+// XFAIL: tsan
+#include <assert.h>
+#include <stdio.h>
+#include <sanitizer/asan_interface.h>
+
+void death() {
+  fprintf(stderr, "DEATH CALLBACK\n");
+}
+
+int main(int argc, char **argv) {
+  __sanitizer_set_death_callback(death);
+  assert(argc == 100);
+}
+// CHECK1: ERROR: {{.*}}Sanitizer:
+// CHECK1: DEATH CALLBACK
+// CHECK0-NOT: Sanitizer
diff --git a/test/sanitizer_common/TestCases/Linux/getpwnam_r_invalid_user.cc b/test/sanitizer_common/TestCases/Linux/getpwnam_r_invalid_user.cc
index a8b51d7..c0d6cfe 100644
--- a/test/sanitizer_common/TestCases/Linux/getpwnam_r_invalid_user.cc
+++ b/test/sanitizer_common/TestCases/Linux/getpwnam_r_invalid_user.cc
@@ -2,6 +2,7 @@
 // RUN: %clangxx -O0 -g %s -o %t && %run %t
 
 #include <assert.h>
+#include <errno.h>
 #include <pwd.h>
 #include <signal.h>
 #include <stdio.h>
@@ -13,7 +14,7 @@
   struct passwd *pwdres;
   char buf[10000];
   int res = getpwnam_r("no-such-user", &pwd, buf, sizeof(buf), &pwdres);
-  assert(res == 0);
+  assert(res == 0 || res == ENOENT);
   assert(pwdres == 0);
   return 0;
 }
diff --git a/test/sanitizer_common/TestCases/Posix/decorate_proc_maps.cc b/test/sanitizer_common/TestCases/Posix/decorate_proc_maps.cc
new file mode 100644
index 0000000..6224717
--- /dev/null
+++ b/test/sanitizer_common/TestCases/Posix/decorate_proc_maps.cc
@@ -0,0 +1,60 @@
+// RUN: %clangxx -g %s -o %t
+// RUN: %tool_options=decorate_proc_maps=1 %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-%tool_name
+#include <errno.h>
+#include <fcntl.h>
+#include <pthread.h>
+#include <stdio.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+bool CopyFdToFd(int in_fd, int out_fd) {
+  const size_t kBufSize = 0x10000;
+  static char buf[kBufSize];
+  while (true) {
+    ssize_t got = read(in_fd, buf, kBufSize);
+    if (got > 0) {
+      write(out_fd, buf, got);
+    } else if (got == 0) {
+      break;
+    } else if (errno != EAGAIN || errno != EWOULDBLOCK || errno != EINTR) {
+      fprintf(stderr, "error reading file, errno %d\n", errno);
+      return false;
+    }
+  }
+  return true;
+}
+
+void *ThreadFn(void *arg) {
+  (void)arg;
+  int fd = open("/proc/self/maps", O_RDONLY);
+  bool res = CopyFdToFd(fd, 2);
+  close(fd);
+  return (void *)!res;
+}
+
+int main(void) {
+  pthread_t t;
+  void *res;
+  pthread_create(&t, 0, ThreadFn, 0);
+  pthread_join(t, &res);
+  return (int)(size_t)res;
+}
+
+// CHECK-asan: rw-p {{.*}} [low shadow]
+// CHECK-asan: ---p {{.*}} [shadow gap]
+// CHECK-asan: rw-p {{.*}} [high shadow]
+
+// CHECK-msan: ---p {{.*}} [invalid]
+// CHECK-msan: rw-p {{.*}} [shadow]
+// CHECK-msan: ---p {{.*}} [origin]
+
+// CHECK-tsan: rw-p {{.*}} [shadow]
+// CHECK-tsan: rw-p {{.*}} [meta shadow]
+// CHECK-tsan: rw-p {{.*}} [trace 0]
+// CHECK-tsan: rw-p {{.*}} [trace header 0]
+// CHECK-tsan: rw-p {{.*}} [trace 1]
+// CHECK-tsan: rw-p {{.*}} [trace header 1]
+
+// Nothing interesting with standalone LSan.
+// CHECK-lsan: decorate_proc_maps
diff --git a/test/sanitizer_common/TestCases/Posix/lit.local.cfg b/test/sanitizer_common/TestCases/Posix/lit.local.cfg
new file mode 100644
index 0000000..a6d96d3
--- /dev/null
+++ b/test/sanitizer_common/TestCases/Posix/lit.local.cfg
@@ -0,0 +1,9 @@
+def getRoot(config):
+  if not config.parent:
+    return config
+  return getRoot(config.parent)
+
+root = getRoot(config)
+
+if root.host_os in ['Windows', 'Darwin']:
+  config.unsupported = True
diff --git a/test/sanitizer_common/TestCases/strcasestr.c b/test/sanitizer_common/TestCases/strcasestr.c
new file mode 100644
index 0000000..4de3cac
--- /dev/null
+++ b/test/sanitizer_common/TestCases/strcasestr.c
@@ -0,0 +1,16 @@
+// RUN: %clang %s -o %t && %run %t 2>&1
+
+// There's no interceptor for strcasestr on Windows
+// XFAIL: win32
+
+#define _GNU_SOURCE
+#include <assert.h>
+#include <string.h>
+int main(int argc, char **argv) {
+  char *r = 0;
+  char s1[] = "aB";
+  char s2[] = "b";
+  r = strcasestr(s1, s2);
+  assert(r == s1 + 1);
+  return 0;
+}
diff --git a/test/sanitizer_common/TestCases/strcspn.c b/test/sanitizer_common/TestCases/strcspn.c
new file mode 100644
index 0000000..066a27b
--- /dev/null
+++ b/test/sanitizer_common/TestCases/strcspn.c
@@ -0,0 +1,13 @@
+// RUN: %clang %s -o %t && %run %t 2>&1
+
+#include <assert.h>
+#include <string.h>
+
+int main(int argc, char **argv) {
+  size_t r;
+  char s1[] = "ad";
+  char s2[] = "cd";
+  r = strcspn(s1, s2);
+  assert(r == 1);
+  return 0;
+}
diff --git a/test/sanitizer_common/TestCases/strpbrk.c b/test/sanitizer_common/TestCases/strpbrk.c
new file mode 100644
index 0000000..318e3a4
--- /dev/null
+++ b/test/sanitizer_common/TestCases/strpbrk.c
@@ -0,0 +1,14 @@
+// RUN: %clang %s -o %t && %run %t 2>&1
+
+#include <assert.h>
+#include <string.h>
+
+
+int main(int argc, char **argv) {
+  char *r = 0;
+  char s1[] = "ad";
+  char s2[] = "cd";
+  r = strpbrk(s1, s2);
+  assert(r == s1 + 1);
+  return 0;
+}
diff --git a/test/sanitizer_common/TestCases/strspn.c b/test/sanitizer_common/TestCases/strspn.c
new file mode 100644
index 0000000..a9a2430
--- /dev/null
+++ b/test/sanitizer_common/TestCases/strspn.c
@@ -0,0 +1,13 @@
+// RUN: %clang %s -o %t && %run %t 2>&1
+
+#include <assert.h>
+#include <string.h>
+
+int main(int argc, char **argv) {
+  size_t r;
+  char s1[] = "ab";
+  char s2[] = "ac";
+  r = strspn(s1, s2);
+  assert(r == 1);
+  return 0;
+}
diff --git a/test/sanitizer_common/TestCases/strstr.c b/test/sanitizer_common/TestCases/strstr.c
new file mode 100644
index 0000000..2089ac7
--- /dev/null
+++ b/test/sanitizer_common/TestCases/strstr.c
@@ -0,0 +1,12 @@
+// RUN: %clang %s -o %t && %run %t 2>&1
+
+#include <assert.h>
+#include <string.h>
+int main(int argc, char **argv) {
+  char *r = 0;
+  char s1[] = "ab";
+  char s2[] = "b";
+  r = strstr(s1, s2);
+  assert(r == s1 + 1);
+  return 0;
+}
diff --git a/test/sanitizer_common/lit.common.cfg b/test/sanitizer_common/lit.common.cfg
index fb37815..f2d3fec 100644
--- a/test/sanitizer_common/lit.common.cfg
+++ b/test/sanitizer_common/lit.common.cfg
@@ -30,6 +30,7 @@
 
 config.substitutions.append( ("%clang ", build_invocation(clang_cflags)) )
 config.substitutions.append( ("%clangxx ", build_invocation(clang_cxxflags)) )
+config.substitutions.append( ("%tool_name", config.tool_name) )
 config.substitutions.append( ("%tool_options", tool_options) )
 
 config.suffixes = ['.c', '.cc', '.cpp']
diff --git a/test/tsan/cond_race.cc b/test/tsan/cond_race.cc
index 52654f1..4daf37f 100644
--- a/test/tsan/cond_race.cc
+++ b/test/tsan/cond_race.cc
@@ -1,4 +1,4 @@
-// RUN: %clang_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s
+// RUN: %clangxx_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s
 // CHECK-NOT: unlock of unlocked mutex
 // CHECK: ThreadSanitizer: data race
 // CHECK: pthread_cond_signal
diff --git a/test/tsan/heap_race.cc b/test/tsan/heap_race.cc
index c3da68f..0201ea9 100644
--- a/test/tsan/heap_race.cc
+++ b/test/tsan/heap_race.cc
@@ -1,17 +1,21 @@
 // RUN: %clangxx_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s
+#include "test.h"
 #include <pthread.h>
 #include <stdio.h>
 #include <stddef.h>
 
 void *Thread(void *a) {
   ((int*)a)[0]++;
+  barrier_wait(&barrier);
   return NULL;
 }
 
 int main() {
+  barrier_init(&barrier, 2);
   int *p = new int(42);
   pthread_t t;
   pthread_create(&t, NULL, Thread, p);
+  barrier_wait(&barrier);
   p[0]++;
   pthread_join(t, NULL);
   delete p;
diff --git a/test/tsan/ignore_free.cc b/test/tsan/ignore_free.cc
index bb6c6ee..4e67895 100644
--- a/test/tsan/ignore_free.cc
+++ b/test/tsan/ignore_free.cc
@@ -1,4 +1,4 @@
-// RUN: %clang_tsan -O1 %s -o %t && %run %t 2>&1 | FileCheck %s
+// RUN: %clangxx_tsan -O1 %s -o %t && %run %t 2>&1 | FileCheck %s
 #include "test.h"
 
 extern "C" {
diff --git a/test/tsan/ignore_malloc.cc b/test/tsan/ignore_malloc.cc
index 1f633f0..100b4e5 100644
--- a/test/tsan/ignore_malloc.cc
+++ b/test/tsan/ignore_malloc.cc
@@ -1,4 +1,4 @@
-// RUN: %clang_tsan -O1 %s -o %t && %run %t 2>&1 | FileCheck %s
+// RUN: %clangxx_tsan -O1 %s -o %t && %run %t 2>&1 | FileCheck %s
 #include "test.h"
 
 extern "C" {
diff --git a/test/tsan/java.h b/test/tsan/java.h
index 35fdbc1..6923e86 100644
--- a/test/tsan/java.h
+++ b/test/tsan/java.h
@@ -18,4 +18,7 @@
 int  __tsan_java_acquire(jptr addr);
 int  __tsan_java_release(jptr addr);
 int  __tsan_java_release_store(jptr addr);
+
+void __tsan_read1_pc(jptr addr, jptr pc);
+void __tsan_write1_pc(jptr addr, jptr pc);
 }
diff --git a/test/tsan/java_race.cc b/test/tsan/java_race.cc
index ede058e..140a2a3 100644
--- a/test/tsan/java_race.cc
+++ b/test/tsan/java_race.cc
@@ -2,11 +2,13 @@
 #include "java.h"
 
 void *Thread(void *p) {
+  barrier_wait(&barrier);
   *(int*)p = 42;
   return 0;
 }
 
 int main() {
+  barrier_init(&barrier, 2);
   int const kHeapSize = 1024 * 1024;
   jptr jheap = (jptr)malloc(kHeapSize + 8) + 8;
   __tsan_java_init(jheap, kHeapSize);
@@ -15,6 +17,7 @@
   pthread_t th;
   pthread_create(&th, 0, Thread, (void*)jheap);
   *(int*)jheap = 43;
+  barrier_wait(&barrier);
   pthread_join(th, 0);
   __tsan_java_free(jheap, kBlockSize);
   fprintf(stderr, "DONE\n");
diff --git a/test/tsan/java_race_pc.cc b/test/tsan/java_race_pc.cc
new file mode 100644
index 0000000..015a0b1
--- /dev/null
+++ b/test/tsan/java_race_pc.cc
@@ -0,0 +1,36 @@
+// RUN: %clangxx_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s
+#include "java.h"
+
+void foobar() {
+}
+
+void barbaz() {
+}
+
+void *Thread(void *p) {
+  barrier_wait(&barrier);
+  __tsan_read1_pc((jptr)p, (jptr)foobar + 1);
+  return 0;
+}
+
+int main() {
+  barrier_init(&barrier, 2);
+  int const kHeapSize = 1024 * 1024;
+  jptr jheap = (jptr)malloc(kHeapSize + 8) + 8;
+  __tsan_java_init(jheap, kHeapSize);
+  const int kBlockSize = 16;
+  __tsan_java_alloc(jheap, kBlockSize);
+  pthread_t th;
+  pthread_create(&th, 0, Thread, (void*)jheap);
+  __tsan_write1_pc((jptr)jheap, (jptr)barbaz + 1);
+  barrier_wait(&barrier);
+  pthread_join(th, 0);
+  __tsan_java_free(jheap, kBlockSize);
+  fprintf(stderr, "DONE\n");
+  return __tsan_java_fini();
+}
+
+// CHECK: WARNING: ThreadSanitizer: data race
+// CHECK:     #0 foobar
+// CHECK:     #0 barbaz
+// CHECK: DONE
diff --git a/test/tsan/longjmp.cc b/test/tsan/longjmp.cc
index d7371c5..d642067 100644
--- a/test/tsan/longjmp.cc
+++ b/test/tsan/longjmp.cc
@@ -1,4 +1,8 @@
 // RUN: %clang_tsan -O1 %s -o %t && %run %t 2>&1 | FileCheck %s
+
+// Longjmp assembly has not been implemented for mips64 yet
+// XFAIL: mips64
+
 #include <stdio.h>
 #include <stdlib.h>
 #include <setjmp.h>
diff --git a/test/tsan/longjmp2.cc b/test/tsan/longjmp2.cc
index 546019b..eee423d 100644
--- a/test/tsan/longjmp2.cc
+++ b/test/tsan/longjmp2.cc
@@ -1,4 +1,8 @@
 // RUN: %clang_tsan -O1 %s -o %t && %run %t 2>&1 | FileCheck %s
+
+// Longjmp assembly has not been implemented for mips64 yet
+// XFAIL: mips64
+
 #include <stdio.h>
 #include <stdlib.h>
 #include <setjmp.h>
diff --git a/test/tsan/longjmp3.cc b/test/tsan/longjmp3.cc
index 71d964d..79965c4 100644
--- a/test/tsan/longjmp3.cc
+++ b/test/tsan/longjmp3.cc
@@ -1,4 +1,8 @@
 // RUN: %clang_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s
+
+// Longjmp assembly has not been implemented for mips64 yet
+// XFAIL: mips64
+
 #include <pthread.h>
 #include <stdio.h>
 #include <stdlib.h>
diff --git a/test/tsan/longjmp4.cc b/test/tsan/longjmp4.cc
index 15330f5..c858399 100644
--- a/test/tsan/longjmp4.cc
+++ b/test/tsan/longjmp4.cc
@@ -1,4 +1,8 @@
 // RUN: %clang_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s
+
+// Longjmp assembly has not been implemented for mips64 yet
+// XFAIL: mips64
+
 #include <pthread.h>
 #include <stdio.h>
 #include <stdlib.h>
diff --git a/test/tsan/malloc_stack.cc b/test/tsan/malloc_stack.cc
index ba1d62b..f0c6f93 100644
--- a/test/tsan/malloc_stack.cc
+++ b/test/tsan/malloc_stack.cc
@@ -1,4 +1,4 @@
-// RUN: %clang_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s
+// RUN: %clangxx_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s
 #include "test.h"
 
 _Atomic(int*) p;
diff --git a/test/tsan/mop1.c b/test/tsan/mop1.c
new file mode 100644
index 0000000..e61c5b8
--- /dev/null
+++ b/test/tsan/mop1.c
@@ -0,0 +1,40 @@
+// RUN: %clang_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s
+#include "test.h"
+
+// We want to establish the following sequence of accesses to X:
+// - main thread writes X
+// - thread2 reads X, this read happens-before the write in main thread
+// - thread1 reads X, this read is concurrent with the write in main thread
+// Write in main thread and read in thread1 should be detected as a race.
+// Previously tsan replaced write by main thread with read by thread1,
+// as the result the race was not detected.
+
+volatile long X, Y, Z;
+
+void *Thread1(void *x) {
+  barrier_wait(&barrier);
+  barrier_wait(&barrier);
+  Y = X;
+  return NULL;
+}
+
+void *Thread2(void *x) {
+  Z = X;
+  barrier_wait(&barrier);
+  return NULL;
+}
+
+int main() {
+  barrier_init(&barrier, 2);
+  pthread_t t[2];
+  pthread_create(&t[0], 0, Thread1, 0);
+  X = 42;
+  barrier_wait(&barrier);
+  pthread_create(&t[1], 0, Thread2, 0);
+  pthread_join(t[0], 0);
+  pthread_join(t[1], 0);
+  return 0;
+}
+
+// CHECK: WARNING: ThreadSanitizer: data race
+
diff --git a/test/tsan/setuid.c b/test/tsan/setuid.c
new file mode 100644
index 0000000..bc9c8ca
--- /dev/null
+++ b/test/tsan/setuid.c
@@ -0,0 +1,26 @@
+// RUN: %clang_tsan -O1 %s -o %t && %run %t 2>&1 | FileCheck %s
+#include "test.h"
+#include <sys/types.h>
+#include <unistd.h>
+
+// Setuid call used to hang because the background tsan thread did not handle
+// SIGSETXID signal. Note that we don't care whether setuid call succeeds
+// or not.
+
+static void *thread(void *arg) {
+  (void)arg;
+  sleep(1);
+  return 0;
+}
+
+int main() {
+  // Create another thread just for completeness of the picture.
+  pthread_t th;
+  pthread_create(&th, 0, thread, 0);
+  setuid(0);
+  pthread_join(th, 0);
+  fprintf(stderr, "DONE\n");
+  return 0;
+}
+
+// CHECK: DONE
diff --git a/test/tsan/setuid2.c b/test/tsan/setuid2.c
new file mode 100644
index 0000000..67a6fd1
--- /dev/null
+++ b/test/tsan/setuid2.c
@@ -0,0 +1,21 @@
+// RUN: %clang_tsan -O1 %s -o %t && TSAN_OPTIONS="flush_memory_ms=1 memory_limit_mb=1" %run %t 2>&1 | FileCheck %s
+#include "test.h"
+#include <sys/types.h>
+#include <unistd.h>
+#include <time.h>
+
+// Test that setuid call works in presence of stoptheworld.
+
+int main() {
+  struct timespec tp0, tp1;
+  clock_gettime(CLOCK_MONOTONIC, &tp0);
+  clock_gettime(CLOCK_MONOTONIC, &tp1);
+  while (tp1.tv_sec - tp0.tv_sec < 3) {
+    clock_gettime(CLOCK_MONOTONIC, &tp1);
+    setuid(0);
+  }
+  fprintf(stderr, "DONE\n");
+  return 0;
+}
+
+// CHECK: DONE
diff --git a/test/tsan/signal_longjmp.cc b/test/tsan/signal_longjmp.cc
index 84b0682..2525c89 100644
--- a/test/tsan/signal_longjmp.cc
+++ b/test/tsan/signal_longjmp.cc
@@ -3,6 +3,9 @@
 // Test case for longjumping out of signal handler:
 // https://code.google.com/p/thread-sanitizer/issues/detail?id=75
 
+// Longjmp assembly has not been implemented for mips64 yet
+// XFAIL: mips64
+
 #include <setjmp.h>
 #include <signal.h>
 #include <stdlib.h>
diff --git a/test/tsan/signal_recursive.cc b/test/tsan/signal_recursive.cc
index 825338d..67fc9c0 100644
--- a/test/tsan/signal_recursive.cc
+++ b/test/tsan/signal_recursive.cc
@@ -3,6 +3,8 @@
 // Test case for recursive signal handlers, adopted from:
 // https://code.google.com/p/thread-sanitizer/issues/detail?id=71
 
+// REQUIRES: disabled
+
 #include "test.h"
 #include <semaphore.h>
 #include <signal.h>
diff --git a/test/tsan/thread_detach2.c b/test/tsan/thread_detach2.c
new file mode 100644
index 0000000..8133980
--- /dev/null
+++ b/test/tsan/thread_detach2.c
@@ -0,0 +1,28 @@
+// RUN: %clang_tsan -O1 %s -o %t && %run %t 2>&1 | FileCheck %s
+#include "test.h"
+
+// Test for https://llvm.org/bugs/show_bug.cgi?id=23235
+// The bug was that synchronization between thread creation and thread start
+// is not established if pthread_create is followed by pthread_detach.
+
+int x;
+
+void *Thread(void *a) {
+  x = 42;
+  barrier_wait(&barrier);
+  return 0;
+}
+
+int main() {
+  barrier_init(&barrier, 2);
+  pthread_t t;
+  x = 43;
+  pthread_create(&t, 0, Thread, 0);
+  pthread_detach(t);
+  barrier_wait(&barrier);
+  printf("PASS\n");
+  return 0;
+}
+
+// CHECK-NOT: WARNING: ThreadSanitizer: data race
+// CHECK: PASS
diff --git a/test/ubsan/CMakeLists.txt b/test/ubsan/CMakeLists.txt
index 760ce60..cd197c7 100644
--- a/test/ubsan/CMakeLists.txt
+++ b/test/ubsan/CMakeLists.txt
@@ -1,6 +1,20 @@
 set(UBSAN_LIT_TESTS_DIR ${CMAKE_CURRENT_SOURCE_DIR})
 
 set(UBSAN_TESTSUITES)
+set(UBSAN_TEST_DEPS ${SANITIZER_COMMON_LIT_TEST_DEPS})
+
+macro(add_ubsan_testsuite test_mode sanitizer arch)
+  set(UBSAN_LIT_TEST_MODE "${test_mode}")
+  set(CONFIG_NAME ${UBSAN_LIT_TEST_MODE}-${arch})
+  configure_lit_site_cfg(
+    ${CMAKE_CURRENT_SOURCE_DIR}/lit.site.cfg.in
+    ${CMAKE_CURRENT_BINARY_DIR}/${CONFIG_NAME}/lit.site.cfg)
+  list(APPEND UBSAN_TESTSUITES ${CMAKE_CURRENT_BINARY_DIR}/${CONFIG_NAME})
+  if(NOT COMPILER_RT_STANDALONE_BUILD)
+    list(APPEND UBSAN_TEST_DEPS ${sanitizer})
+  endif()
+endmacro()
+
 foreach(arch ${UBSAN_SUPPORTED_ARCH})
   set(UBSAN_TEST_TARGET_ARCH ${arch})
   if(${arch} MATCHES "arm|aarch64")
@@ -8,29 +22,21 @@
     set(UBSAN_TEST_TARGET_CFLAGS ${COMPILER_RT_TEST_COMPILER_CFLAGS})
   else()
     get_target_flags_for_arch(${arch} UBSAN_TEST_TARGET_CFLAGS)
+    string(REPLACE ";" " " UBSAN_TEST_TARGET_CFLAGS "${UBSAN_TEST_TARGET_CFLAGS}")
   endif()
-  set(UBSAN_LIT_TEST_MODE "Standalone")
-  set(CONFIG_NAME ${UBSAN_LIT_TEST_MODE}-${arch})
-  configure_lit_site_cfg(
-    ${CMAKE_CURRENT_SOURCE_DIR}/lit.site.cfg.in
-    ${CMAKE_CURRENT_BINARY_DIR}/${CONFIG_NAME}/lit.site.cfg)
-  list(APPEND UBSAN_TESTSUITES ${CMAKE_CURRENT_BINARY_DIR}/${CONFIG_NAME})
+  add_ubsan_testsuite("Standalone" ubsan ${arch})
 
-  if(COMPILER_RT_HAS_ASAN)
-    set(UBSAN_LIT_TEST_MODE "AddressSanitizer")
-    set(CONFIG_NAME ${UBSAN_LIT_TEST_MODE}-${arch})
-    configure_lit_site_cfg(
-       ${CMAKE_CURRENT_SOURCE_DIR}/lit.site.cfg.in
-       ${CMAKE_CURRENT_BINARY_DIR}/${CONFIG_NAME}/lit.site.cfg)
-    list(APPEND UBSAN_TESTSUITES ${CMAKE_CURRENT_BINARY_DIR}/${CONFIG_NAME})
+  if(COMPILER_RT_HAS_ASAN AND ";${ASAN_SUPPORTED_ARCH};" MATCHES ";${arch};")
+    add_ubsan_testsuite("AddressSanitizer" asan ${arch})
+  endif()
+  if(COMPILER_RT_HAS_MSAN AND ";${MSAN_SUPPORTED_ARCH};" MATCHES ";${arch};")
+    add_ubsan_testsuite("MemorySanitizer" msan ${arch})
+  endif()
+  if(COMPILER_RT_HAS_TSAN AND ";${TSAN_SUPPORTED_ARCH};" MATCHES ";${arch};")
+    add_ubsan_testsuite("ThreadSanitizer" tsan ${arch})
   endif()
 endforeach()
 
-set(UBSAN_TEST_DEPS ${SANITIZER_COMMON_LIT_TEST_DEPS})
-if(NOT COMPILER_RT_STANDALONE_BUILD)
-  list(APPEND UBSAN_TEST_DEPS ubsan asan)
-endif()
-
 add_lit_testsuite(check-ubsan "Running UndefinedBehaviorSanitizer tests"
   ${UBSAN_TESTSUITES}
   DEPENDS ${UBSAN_TEST_DEPS})
diff --git a/test/ubsan/TestCases/Float/cast-overflow.cpp b/test/ubsan/TestCases/Float/cast-overflow.cpp
index 82c6e0d..61bf431 100644
--- a/test/ubsan/TestCases/Float/cast-overflow.cpp
+++ b/test/ubsan/TestCases/Float/cast-overflow.cpp
@@ -1,7 +1,6 @@
-// FIXME: run this (and other) UBSan tests in both 32- and 64-bit modes (?).
-// RUN: %clangxx -fsanitize=float-cast-overflow %s -o %t
+// RUN: %clangxx -fsanitize=float-cast-overflow -g %s -o %t
 // RUN: %run %t _
-// RUN: %run %t 0 2>&1 | FileCheck %s --check-prefix=CHECK-0
+// RUN: env UBSAN_OPTIONS=print_summary=1 %run %t 0 2>&1 | FileCheck %s --check-prefix=CHECK-0
 // RUN: %run %t 1 2>&1 | FileCheck %s --check-prefix=CHECK-1
 // RUN: %run %t 2 2>&1 | FileCheck %s --check-prefix=CHECK-2
 // RUN: %run %t 3 2>&1 | FileCheck %s --check-prefix=CHECK-3
@@ -85,11 +84,14 @@
     // successfully round-trip, depending on the rounding mode.
     // CHECK-0: runtime error: value 2.14748{{.*}} is outside the range of representable values of type 'int'
     static int test_int = MaxFloatRepresentableAsInt + 0x80;
+    // CHECK-0: SUMMARY: {{.*}}Sanitizer: undefined-behavior {{.*}}cast-overflow.cpp:[[@LINE-1]]
     return 0;
     }
-  case '1':
+  case '1': {
     // CHECK-1: runtime error: value -2.14748{{.*}} is outside the range of representable values of type 'int'
-    return MinFloatRepresentableAsInt - 0x100;
+    static int test_int = MinFloatRepresentableAsInt - 0x100;
+    return 0;
+  }
   case '2': {
     // CHECK-2: runtime error: value -1 is outside the range of representable values of type 'unsigned int'
     volatile float f = -1.0;
@@ -107,9 +109,11 @@
     static int test_int = Inf;
     return 0;
   }
-  case '5':
+  case '5': {
     // CHECK-5: runtime error: value {{.*}} is outside the range of representable values of type 'int'
-    return NaN;
+    static int test_int = NaN;
+    return 0;
+  }
 
     // Integer -> floating point overflow.
   case '6': {
diff --git a/test/ubsan/TestCases/Integer/incdec-overflow.cpp b/test/ubsan/TestCases/Integer/incdec-overflow.cpp
index fc7141c..a8a6615 100644
--- a/test/ubsan/TestCases/Integer/incdec-overflow.cpp
+++ b/test/ubsan/TestCases/Integer/incdec-overflow.cpp
@@ -1,7 +1,7 @@
-// RUN: %clangxx -DOP=n++ -fsanitize=signed-integer-overflow %s -o %t && %run %t 2>&1 | FileCheck %s
-// RUN: %clangxx -DOP=++n -fsanitize=signed-integer-overflow %s -o %t && %run %t 2>&1 | FileCheck %s
-// RUN: %clangxx -DOP=m-- -fsanitize=signed-integer-overflow %s -o %t && %run %t 2>&1 | FileCheck %s
-// RUN: %clangxx -DOP=--m -fsanitize=signed-integer-overflow %s -o %t && %run %t 2>&1 | FileCheck %s
+// RUN: %clangxx -DOP=n++ -fsanitize=signed-integer-overflow %s -o %t && %run %t 2>&1 | FileCheck %s --check-prefix=PLUS
+// RUN: %clangxx -DOP=++n -fsanitize=signed-integer-overflow %s -o %t && %run %t 2>&1 | FileCheck %s --check-prefix=PLUS
+// RUN: %clangxx -DOP=m-- -fsanitize=signed-integer-overflow %s -o %t && %run %t 2>&1 | FileCheck %s --check-prefix=MINUS
+// RUN: %clangxx -DOP=--m -fsanitize=signed-integer-overflow %s -o %t && %run %t 2>&1 | FileCheck %s --check-prefix=MINUS
 
 #include <stdint.h>
 
@@ -10,7 +10,7 @@
   n++;
   n++;
   int m = -n - 1;
-  // CHECK: incdec-overflow.cpp:15:3: runtime error: signed integer overflow: [[MINUS:-?]]214748364
-  // CHECK: + [[MINUS]]1 cannot be represented in type 'int'
   OP;
+  // PLUS: incdec-overflow.cpp:[[@LINE-1]]:3: runtime error: signed integer overflow: 2147483647 + 1 cannot be represented in type 'int'
+  // MINUS: incdec-overflow.cpp:[[@LINE-2]]:3: runtime error: signed integer overflow: -2147483648 - 1 cannot be represented in type 'int'
 }
diff --git a/test/ubsan/TestCases/Misc/Linux/coverage-levels.cc b/test/ubsan/TestCases/Misc/Linux/coverage-levels.cc
index d00b3e0..df6e835 100644
--- a/test/ubsan/TestCases/Misc/Linux/coverage-levels.cc
+++ b/test/ubsan/TestCases/Misc/Linux/coverage-levels.cc
@@ -2,18 +2,21 @@
 //
 // RUN: mkdir -p %T/coverage-levels
 // RUN: OPT=coverage=1:verbosity=1:coverage_dir=%T/coverage-levels
-// RUN: %clangxx -fsanitize=shift                        -DGOOD_SHIFT=1 -O1 -fsanitize-coverage=1  %s -o %t
+// RUN: %clangxx -fsanitize=shift                        -DGOOD_SHIFT=1 -O1 -fsanitize-coverage=func  %s -o %t
 // RUN: UBSAN_OPTIONS=$OPT %run %t 2>&1 | FileCheck %s --check-prefix=CHECK1 --check-prefix=CHECK_NOWARN
-// RUN: %clangxx -fsanitize=undefined                    -DGOOD_SHIFT=1 -O1 -fsanitize-coverage=1  %s -o %t
+// RUN: %clangxx -fsanitize=undefined                    -DGOOD_SHIFT=1 -O1 -fsanitize-coverage=func  %s -o %t
 // RUN: UBSAN_OPTIONS=$OPT %run %t 2>&1 | FileCheck %s --check-prefix=CHECK1 --check-prefix=CHECK_NOWARN
 
-// RUN: %clangxx -fsanitize=shift -O1 -fsanitize-coverage=1  %s -o %t
+// RUN: %clangxx -fsanitize=shift -O1 -fsanitize-coverage=func  %s -o %t
 // RUN: UBSAN_OPTIONS=$OPT %run %t 2>&1 | FileCheck %s --check-prefix=CHECK1 --check-prefix=CHECK_WARN
-// RUN: %clangxx -fsanitize=shift -O1 -fsanitize-coverage=2  %s -o %t
+// RUN: %clangxx -fsanitize=shift -O1 -fsanitize-coverage=bb  %s -o %t
 // RUN: UBSAN_OPTIONS=$OPT %run %t 2>&1 | FileCheck %s --check-prefix=CHECK2 --check-prefix=CHECK_WARN
-// RUN: %clangxx -fsanitize=shift -O1 -fsanitize-coverage=3  %s -o %t
+// RUN: %clangxx -fsanitize=shift -O1 -fsanitize-coverage=edge  %s -o %t
 // RUN: UBSAN_OPTIONS=$OPT %run %t 2>&1 | FileCheck %s --check-prefix=CHECK3 --check-prefix=CHECK_WARN
 
+// Coverage is not yet implemented in TSan.
+// XFAIL: ubsan-tsan
+
 volatile int sink;
 int main(int argc, char **argv) {
   int shift = argc * 32;
diff --git a/test/ubsan/TestCases/Misc/Linux/ubsan_options.cc b/test/ubsan/TestCases/Misc/Linux/ubsan_options.cc
new file mode 100644
index 0000000..2be8792
--- /dev/null
+++ b/test/ubsan/TestCases/Misc/Linux/ubsan_options.cc
@@ -0,0 +1,18 @@
+// RUN: %clangxx -fsanitize=integer -fsanitize-recover=integer %s -o %t
+// RUN: not %t 2>&1 | FileCheck %s
+
+// __ubsan_default_options() doesn't work on Darwin.
+// XFAIL: darwin
+
+#include <stdint.h>
+
+extern "C" const char *__ubsan_default_options() {
+  return "halt_on_error=1";
+}
+
+int main() {
+  (void)(uint64_t(10000000000000000000ull) + uint64_t(9000000000000000000ull));
+  // CHECK: ubsan_options.cc:[[@LINE-1]]:44: runtime error: unsigned integer overflow
+  return 0;
+}
+
diff --git a/test/ubsan/TestCases/Misc/log-path_test.cc b/test/ubsan/TestCases/Misc/log-path_test.cc
new file mode 100644
index 0000000..b39e1b0
--- /dev/null
+++ b/test/ubsan/TestCases/Misc/log-path_test.cc
@@ -0,0 +1,33 @@
+// FIXME: https://code.google.com/p/address-sanitizer/issues/detail?id=316
+// XFAIL: android
+
+// RUN: %clangxx -fsanitize=undefined %s -O1 -o %t
+
+// Regular run.
+// RUN: %run %t -4 2> %t.out
+// RUN: FileCheck %s --check-prefix=CHECK-ERROR < %t.out
+
+// Good log_path.
+// RUN: rm -f %t.log.*
+// RUN: env UBSAN_OPTIONS=log_path=%t.log %run %t -4 2> %t.out
+// RUN: FileCheck %s --check-prefix=CHECK-ERROR < %t.log.*
+
+// Run w/o errors should not produce any log.
+// RUN: rm -f %t.log.*
+// RUN: env UBSAN_OPTIONS=log_path=%t.log  %run %t 4
+// RUN: not cat %t.log.*
+
+// FIXME: log_path is not supported on Windows yet.
+// XFAIL: win32
+
+#include <stdio.h>
+#include <stdlib.h>
+int main(int argc, char *argv[]) {
+  double a = atof(argv[1]);
+  unsigned int ai = (unsigned int) a;
+  printf("%f %u\n", a, ai);
+  return 0;
+}
+
+// CHECK-ERROR: runtime error: value -4 is outside the range of representable values of type 'unsigned int'
+
diff --git a/test/ubsan/TestCases/Misc/missing_return.cpp b/test/ubsan/TestCases/Misc/missing_return.cpp
index 5d3d54d..a9b0799 100644
--- a/test/ubsan/TestCases/Misc/missing_return.cpp
+++ b/test/ubsan/TestCases/Misc/missing_return.cpp
@@ -1,15 +1,13 @@
 // RUN: %clangxx -fsanitize=return -g %s -O3 -o %t
 // RUN: not %run %t 2>&1 | FileCheck %s
-// RUN: UBSAN_OPTIONS=print_stacktrace=1 not %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-%os-STACKTRACE
+// RUN: UBSAN_OPTIONS=print_stacktrace=1 not %run %t 2>&1 | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-%os-STACKTRACE
 
 // CHECK: missing_return.cpp:[[@LINE+1]]:5: runtime error: execution reached the end of a value-returning function without returning a value
 int f() {
-// Slow stack unwinding is disabled on Darwin for now, see
+// Slow stack unwinding is not available on Darwin for now, see
 // https://code.google.com/p/address-sanitizer/issues/detail?id=137
-// CHECK-Linux-STACKTRACE: #0 {{.*}} in f(){{.*}}missing_return.cpp:[[@LINE-3]]
-// CHECK-FreeBSD-STACKTRACE: #0 {{.*}} in f(void){{.*}}missing_return.cpp:[[@LINE-4]]
-// Check for already checked line to avoid lit error reports.
-// CHECK-Darwin-STACKTRACE: missing_return.cpp
+// CHECK-Linux-STACKTRACE: #0 {{.*}}f(){{.*}}missing_return.cpp:[[@LINE-3]]
+// CHECK-FreeBSD-STACKTRACE: #0 {{.*}}f(void){{.*}}missing_return.cpp:[[@LINE-4]]
 }
 
 int main(int, char **argv) {
diff --git a/test/ubsan/TestCases/TypeCheck/misaligned.cpp b/test/ubsan/TestCases/TypeCheck/misaligned.cpp
index 9c8455d..0c9275d 100644
--- a/test/ubsan/TestCases/TypeCheck/misaligned.cpp
+++ b/test/ubsan/TestCases/TypeCheck/misaligned.cpp
@@ -45,7 +45,7 @@
     return *p && 0;
     // Slow stack unwinding is disabled on Darwin for now, see
     // https://code.google.com/p/address-sanitizer/issues/detail?id=137
-    // CHECK-Linux-STACK-LOAD: #0 {{.*}} in main{{.*}}misaligned.cpp
+    // CHECK-Linux-STACK-LOAD: #0 {{.*}}main{{.*}}misaligned.cpp
     // Check for the already checked line to avoid lit error reports.
     // CHECK-Darwin-STACK-LOAD: {{ }}
 
diff --git a/test/ubsan/TestCases/TypeCheck/vptr.cpp b/test/ubsan/TestCases/TypeCheck/vptr.cpp
index a0681fc..6c7955b 100644
--- a/test/ubsan/TestCases/TypeCheck/vptr.cpp
+++ b/test/ubsan/TestCases/TypeCheck/vptr.cpp
@@ -1,38 +1,33 @@
-// RUN: %clangxx -frtti -fsanitize=vptr -g %s -O3 -o %t
+// RUN: %clangxx -frtti -fsanitize=vptr -fno-sanitize-recover=vptr -g %s -O3 -o %t
+// RUN: export UBSAN_OPTIONS=print_stacktrace=1
 // RUN: %run %t rT && %run %t mT && %run %t fT && %run %t cT
 // RUN: %run %t rU && %run %t mU && %run %t fU && %run %t cU
 // RUN: %run %t rS && %run %t rV && %run %t oV
-// RUN: %run %t mS 2>&1 | FileCheck %s --check-prefix=CHECK-MEMBER --strict-whitespace
-// RUN: %run %t fS 2>&1 | FileCheck %s --check-prefix=CHECK-MEMFUN --strict-whitespace
-// RUN: %run %t cS 2>&1 | FileCheck %s --check-prefix=CHECK-DOWNCAST --strict-whitespace
-// RUN: %run %t mV 2>&1 | FileCheck %s --check-prefix=CHECK-MEMBER --strict-whitespace
-// RUN: %run %t fV 2>&1 | FileCheck %s --check-prefix=CHECK-MEMFUN --strict-whitespace
-// RUN: %run %t cV 2>&1 | FileCheck %s --check-prefix=CHECK-DOWNCAST --strict-whitespace
-// RUN: %run %t oU 2>&1 | FileCheck %s --check-prefix=CHECK-OFFSET --strict-whitespace
-// RUN: %run %t m0 2>&1 | FileCheck %s --check-prefix=CHECK-NULL-MEMBER --strict-whitespace
+// RUN: not %run %t mS 2>&1 | FileCheck %s --check-prefix=CHECK-MEMBER --check-prefix=CHECK-%os-MEMBER --strict-whitespace
+// RUN: not %run %t fS 2>&1 | FileCheck %s --check-prefix=CHECK-MEMFUN --strict-whitespace
+// RUN: not %run %t cS 2>&1 | FileCheck %s --check-prefix=CHECK-DOWNCAST --check-prefix=CHECK-%os-DOWNCAST --strict-whitespace
+// RUN: not %run %t mV 2>&1 | FileCheck %s --check-prefix=CHECK-MEMBER --check-prefix=CHECK-%os-MEMBER --strict-whitespace
+// RUN: not %run %t fV 2>&1 | FileCheck %s --check-prefix=CHECK-MEMFUN --strict-whitespace
+// RUN: not %run %t cV 2>&1 | FileCheck %s --check-prefix=CHECK-DOWNCAST --check-prefix=CHECK-%os-DOWNCAST --strict-whitespace
+// RUN: not %run %t oU 2>&1 | FileCheck %s --check-prefix=CHECK-OFFSET --check-prefix=CHECK-%os-OFFSET --strict-whitespace
+// RUN: not %run %t m0 2>&1 | FileCheck %s --check-prefix=CHECK-NULL-MEMBER --check-prefix=CHECK-%os-NULL-MEMBER --strict-whitespace
 
 // RUN: (echo "vptr_check:S"; echo "vptr_check:T"; echo "vptr_check:U") > %t.supp
-// RUN: UBSAN_OPTIONS="suppressions='%t.supp':halt_on_error=1" %run %t mS 2>&1
-// RUN: UBSAN_OPTIONS="suppressions='%t.supp':halt_on_error=1" %run %t fS 2>&1
-// RUN: UBSAN_OPTIONS="suppressions='%t.supp':halt_on_error=1" %run %t cS 2>&1
-// RUN: UBSAN_OPTIONS="suppressions='%t.supp':halt_on_error=1" %run %t mV 2>&1
-// RUN: UBSAN_OPTIONS="suppressions='%t.supp':halt_on_error=1" %run %t fV 2>&1
-// RUN: UBSAN_OPTIONS="suppressions='%t.supp':halt_on_error=1" %run %t cV 2>&1
-// RUN: UBSAN_OPTIONS="suppressions='%t.supp':halt_on_error=1" %run %t oU 2>&1
+// RUN: UBSAN_OPTIONS="suppressions='%t.supp'" %run %t mS
+// RUN: UBSAN_OPTIONS="suppressions='%t.supp'" %run %t fS
+// RUN: UBSAN_OPTIONS="suppressions='%t.supp'" %run %t cS
+// RUN: UBSAN_OPTIONS="suppressions='%t.supp'" %run %t mV
+// RUN: UBSAN_OPTIONS="suppressions='%t.supp'" %run %t fV
+// RUN: UBSAN_OPTIONS="suppressions='%t.supp'" %run %t cV
+// RUN: UBSAN_OPTIONS="suppressions='%t.supp'" %run %t oU
 
 // RUN: echo "vptr_check:S" > %t.loc-supp
-// RUN: UBSAN_OPTIONS="suppressions='%t.loc-supp':halt_on_error=1" not %run %t x- 2>&1 | FileCheck %s --check-prefix=CHECK-LOC-SUPPRESS
+// RUN: UBSAN_OPTIONS="suppressions='%t.loc-supp'" not %run %t x- 2>&1 | FileCheck %s --check-prefix=CHECK-LOC-SUPPRESS
 
-// FIXME: This test produces linker errors on Darwin.
-// XFAIL: darwin
 // REQUIRES: stable-runtime
 #include <new>
-
-extern "C" {
-const char *__ubsan_default_options() {
-  return "print_stacktrace=1";
-}
-}
+#include <assert.h>
+#include <stdio.h>
 
 struct S {
   S() : a(0) {}
@@ -58,7 +53,9 @@
 
 int access_p(T *p, char type);
 
-int main(int, char **argv) {
+int main(int argc, char **argv) {
+  assert(argc > 1);
+  fprintf(stderr, "Test case: %s\n", argv[1]);
   T t;
   (void)t.a;
   (void)t.b;
@@ -107,7 +104,7 @@
   case 'r':
     // Binding a reference to storage of appropriate size and alignment is OK.
     {T &r = *p;}
-    break;
+    return 0;
 
   case 'x':
     for (int i = 0; i < 2; i++) {
@@ -128,7 +125,7 @@
     // CHECK-MEMBER-NEXT: {{^ .. .. .. ..  .. .. .. .. .. .. .. ..  }}
     // CHECK-MEMBER-NEXT: {{^              \^~~~~~~~~~~(~~~~~~~~~~~~)? *$}}
     // CHECK-MEMBER-NEXT: {{^              vptr for}} [[DYN_TYPE]]
-    // CHECK-MEMBER-NEXT: #0 {{.*}} in access_p{{.*}}vptr.cpp:[[@LINE+1]]
+    // CHECK-Linux-MEMBER: #0 {{.*}}access_p{{.*}}vptr.cpp:[[@LINE+1]]
     return p->b;
 
     // CHECK-NULL-MEMBER: vptr.cpp:[[@LINE-2]]:15: runtime error: member access within address [[PTR:0x[0-9a-f]*]] which does not point to an object of type 'T'
@@ -136,7 +133,7 @@
     // CHECK-NULL-MEMBER-NEXT: {{^  ?.. .. .. ..  ?00 00 00 00  ?00 00 00 00  ?}}
     // CHECK-NULL-MEMBER-NEXT: {{^              \^~~~~~~~~~~(~~~~~~~~~~~~)? *$}}
     // CHECK-NULL-MEMBER-NEXT: {{^              invalid vptr}}
-    // CHECK-NULL-MEMBER-NEXT: #0 {{.*}} in access_p{{.*}}vptr.cpp:[[@LINE-7]]
+    // CHECK-Linux-NULL-MEMBER: #0 {{.*}}access_p{{.*}}vptr.cpp:[[@LINE-7]]
 
   case 'f':
     // CHECK-MEMFUN: vptr.cpp:[[@LINE+6]]:12: runtime error: member call on address [[PTR:0x[0-9a-f]*]] which does not point to an object of type 'T'
@@ -153,17 +150,18 @@
     // CHECK-OFFSET-NEXT: {{^ .. .. .. ..  .. .. .. .. .. .. .. ..  .. .. .. .. .. .. .. ..  .. .. .. .. .. .. .. ..  }}
     // CHECK-OFFSET-NEXT: {{^              \^                        (                         ~~~~~~~~~~~~)?~~~~~~~~~~~ *$}}
     // CHECK-OFFSET-NEXT: {{^                                       (                         )?vptr for}} 'T' base class of [[DYN_TYPE]]
-    // CHECK-OFFSET-NEXT: #0 {{.*}} in access_p{{.*}}vptr.cpp:[[@LINE+1]]
+    // CHECK-Linux-OFFSET: #0 {{.*}}access_p{{.*}}vptr.cpp:[[@LINE+1]]
     return reinterpret_cast<U*>(p)->v() - 2;
 
   case 'c':
-    // CHECK-DOWNCAST: vptr.cpp:[[@LINE+6]]:5: runtime error: downcast of address [[PTR:0x[0-9a-f]*]] which does not point to an object of type 'T'
+    // CHECK-DOWNCAST: vptr.cpp:[[@LINE+6]]:11: runtime error: downcast of address [[PTR:0x[0-9a-f]*]] which does not point to an object of type 'T'
     // CHECK-DOWNCAST-NEXT: [[PTR]]: note: object is of type [[DYN_TYPE:'S'|'U']]
     // CHECK-DOWNCAST-NEXT: {{^ .. .. .. ..  .. .. .. .. .. .. .. ..  }}
     // CHECK-DOWNCAST-NEXT: {{^              \^~~~~~~~~~~(~~~~~~~~~~~~)? *$}}
     // CHECK-DOWNCAST-NEXT: {{^              vptr for}} [[DYN_TYPE]]
-    // CHECK-DOWNCAST-NEXT: #0 {{.*}} in access_p{{.*}}vptr.cpp:[[@LINE+1]]
-    static_cast<T*>(reinterpret_cast<S*>(p));
+    // CHECK-Linux-DOWNCAST: #0 {{.*}}access_p{{.*}}vptr.cpp:[[@LINE+1]]
+    (void)static_cast<T*>(reinterpret_cast<S*>(p));
     return 0;
   }
+  return 0;
 }
diff --git a/test/ubsan/lit.common.cfg b/test/ubsan/lit.common.cfg
index 5a406ee..5d3e78e 100644
--- a/test/ubsan/lit.common.cfg
+++ b/test/ubsan/lit.common.cfg
@@ -21,14 +21,18 @@
   config.available_features.add("ubsan-standalone")
   clang_ubsan_cflags = []
 elif ubsan_lit_test_mode == "AddressSanitizer":
-  if config.host_os == 'Darwin':
-    # ubsan-asan doesn't yet work on Darwin,
-    # see http://llvm.org/bugs/show_bug.cgi?id=21112.
-    config.unsupported = True
   config.name = 'UBSan-ASan-' + config.target_arch
   config.available_features.add("ubsan-asan")
   clang_ubsan_cflags = ["-fsanitize=address"]
   config.environment['ASAN_OPTIONS'] = 'detect_leaks=0'
+elif ubsan_lit_test_mode == "MemorySanitizer":
+  config.name = 'UBSan-MSan-' + config.target_arch
+  config.available_features.add("ubsan-msan")
+  clang_ubsan_cflags = ["-fsanitize=memory"]
+elif ubsan_lit_test_mode == "ThreadSanitizer":
+  config.name = 'UBSan-TSan-' + config.target_arch
+  config.available_features.add("ubsan-tsan")
+  clang_ubsan_cflags = ["-fsanitize=thread"]
 else:
   lit_config.fatal("Unknown UBSan test mode: %r" % ubsan_lit_test_mode)