[compiler-rt] 10436ae - Revert "[asan][windows] Eliminate the static asan runtime on windows (#81677)"
Charlie Barto via llvm-commits
llvm-commits at lists.llvm.org
Wed May 29 17:53:21 PDT 2024
Author: Charlie Barto
Date: 2024-05-29T17:52:54-07:00
New Revision: 10436aede261db5260e0e11a4aa66565ba975848
URL: https://github.com/llvm/llvm-project/commit/10436aede261db5260e0e11a4aa66565ba975848
DIFF: https://github.com/llvm/llvm-project/commit/10436aede261db5260e0e11a4aa66565ba975848.diff
LOG: Revert "[asan][windows] Eliminate the static asan runtime on windows (#81677)"
This reverts commit 246234ac70faa1e3281a2bb83dfc4dd206a7d59c.
Added:
compiler-rt/lib/asan/asan_win_dll_thunk.cpp
compiler-rt/lib/sanitizer_common/sanitizer_coverage_win_dll_thunk.cpp
compiler-rt/lib/sanitizer_common/sanitizer_coverage_win_dynamic_runtime_thunk.cpp
compiler-rt/lib/sanitizer_common/sanitizer_coverage_win_weak_interception.cpp
compiler-rt/lib/sanitizer_common/sanitizer_win_dll_thunk.cpp
compiler-rt/lib/sanitizer_common/sanitizer_win_dll_thunk.h
compiler-rt/lib/sanitizer_common/sanitizer_win_dynamic_runtime_thunk.cpp
compiler-rt/lib/sanitizer_common/sanitizer_win_weak_interception.cpp
compiler-rt/lib/sanitizer_common/sanitizer_win_weak_interception.h
compiler-rt/lib/ubsan/ubsan_win_dll_thunk.cpp
compiler-rt/lib/ubsan/ubsan_win_dynamic_runtime_thunk.cpp
compiler-rt/lib/ubsan/ubsan_win_weak_interception.cpp
Modified:
clang/lib/Driver/SanitizerArgs.cpp
clang/lib/Driver/ToolChains/MSVC.cpp
clang/test/Driver/cl-link.c
compiler-rt/CMakeLists.txt
compiler-rt/lib/asan/CMakeLists.txt
compiler-rt/lib/asan/asan_flags.cpp
compiler-rt/lib/asan/asan_globals_win.cpp
compiler-rt/lib/asan/asan_malloc_win.cpp
compiler-rt/lib/asan/asan_win_dynamic_runtime_thunk.cpp
compiler-rt/lib/asan/tests/CMakeLists.txt
compiler-rt/lib/profile/CMakeLists.txt
compiler-rt/lib/sanitizer_common/CMakeLists.txt
compiler-rt/lib/sanitizer_common/sanitizer_common_interface.inc
compiler-rt/lib/ubsan/CMakeLists.txt
compiler-rt/test/asan/TestCases/Darwin/interface_symbols_darwin.cpp
compiler-rt/test/asan/TestCases/Linux/interface_symbols_linux.cpp
compiler-rt/test/asan/TestCases/Windows/double_free.cpp
compiler-rt/test/asan/TestCases/Windows/free_hook_realloc.cpp
compiler-rt/test/asan/TestCases/Windows/malloc_left_oob.cpp
compiler-rt/test/asan/TestCases/Windows/malloc_right_oob.cpp
compiler-rt/test/asan/TestCases/Windows/malloc_uaf.cpp
compiler-rt/test/asan/TestCases/Windows/msvc/dll_and_lib.cpp
compiler-rt/test/asan/TestCases/Windows/msvc/dll_large_function.cpp
compiler-rt/test/asan/TestCases/Windows/realloc_left_oob.cpp
compiler-rt/test/asan/TestCases/Windows/realloc_right_oob.cpp
compiler-rt/test/asan/TestCases/Windows/realloc_uaf.cpp
compiler-rt/test/asan/TestCases/Windows/symbols_path.cpp
compiler-rt/test/asan/TestCases/Windows/unsymbolized.cpp
compiler-rt/test/asan/TestCases/Windows/use_after_realloc.cpp
compiler-rt/test/asan/TestCases/debug_double_free.cpp
compiler-rt/test/asan/TestCases/debug_report.cpp
compiler-rt/test/asan/TestCases/default_options.cpp
compiler-rt/test/asan/TestCases/on_error_callback.cpp
compiler-rt/test/asan/TestCases/report_error_summary.cpp
compiler-rt/test/asan/lit.cfg.py
Removed:
compiler-rt/lib/asan/asan_malloc_win_thunk.cpp
compiler-rt/lib/asan/asan_win_common_runtime_thunk.cpp
compiler-rt/lib/asan/asan_win_common_runtime_thunk.h
compiler-rt/lib/asan/asan_win_static_runtime_thunk.cpp
compiler-rt/lib/sanitizer_common/sanitizer_coverage_win_runtime_thunk.cpp
compiler-rt/lib/sanitizer_common/sanitizer_win_immortalize.h
compiler-rt/lib/sanitizer_common/sanitizer_win_interception.cpp
compiler-rt/lib/sanitizer_common/sanitizer_win_interception.h
compiler-rt/lib/sanitizer_common/sanitizer_win_thunk_interception.cpp
compiler-rt/lib/sanitizer_common/sanitizer_win_thunk_interception.h
compiler-rt/lib/ubsan/ubsan_win_runtime_thunk.cpp
################################################################################
diff --git a/clang/lib/Driver/SanitizerArgs.cpp b/clang/lib/Driver/SanitizerArgs.cpp
index 7b7fd2d9d4742..273f215ca94a8 100644
--- a/clang/lib/Driver/SanitizerArgs.cpp
+++ b/clang/lib/Driver/SanitizerArgs.cpp
@@ -909,16 +909,10 @@ SanitizerArgs::SanitizerArgs(const ToolChain &TC,
DiagnoseErrors);
}
- SharedRuntime = Args.hasFlag(
- options::OPT_shared_libsan, options::OPT_static_libsan,
- TC.getTriple().isAndroid() || TC.getTriple().isOSFuchsia() ||
- TC.getTriple().isOSDarwin() || TC.getTriple().isOSWindows());
- if (!SharedRuntime && TC.getTriple().isOSWindows()) {
- Arg *A =
- Args.getLastArg(options::OPT_shared_libsan, options::OPT_static_libsan);
- D.Diag(clang::diag::err_drv_unsupported_opt_for_target)
- << A->getSpelling() << TC.getTriple().str();
- }
+ SharedRuntime =
+ Args.hasFlag(options::OPT_shared_libsan, options::OPT_static_libsan,
+ TC.getTriple().isAndroid() || TC.getTriple().isOSFuchsia() ||
+ TC.getTriple().isOSDarwin());
ImplicitCfiRuntime = TC.getTriple().isAndroid();
diff --git a/clang/lib/Driver/ToolChains/MSVC.cpp b/clang/lib/Driver/ToolChains/MSVC.cpp
index bf54f04363851..b7021d4b996dd 100644
--- a/clang/lib/Driver/ToolChains/MSVC.cpp
+++ b/clang/lib/Driver/ToolChains/MSVC.cpp
@@ -201,10 +201,10 @@ void visualstudio::Linker::ConstructJob(Compilation &C, const JobAction &JA,
if (TC.getSanitizerArgs(Args).needsAsanRt()) {
CmdArgs.push_back(Args.MakeArgString("-debug"));
CmdArgs.push_back(Args.MakeArgString("-incremental:no"));
- CmdArgs.push_back(TC.getCompilerRTArgString(Args, "asan_dynamic"));
- auto defines = Args.getAllArgValues(options::OPT_D);
- if (Args.hasArg(options::OPT__SLASH_MD, options::OPT__SLASH_MDd) ||
- find(begin(defines), end(defines), "_DLL") != end(defines)) {
+ if (TC.getSanitizerArgs(Args).needsSharedRt() ||
+ Args.hasArg(options::OPT__SLASH_MD, options::OPT__SLASH_MDd)) {
+ for (const auto &Lib : {"asan_dynamic", "asan_dynamic_runtime_thunk"})
+ CmdArgs.push_back(TC.getCompilerRTArgString(Args, Lib));
// Make sure the dynamic runtime thunk is not optimized out at link time
// to ensure proper SEH handling.
CmdArgs.push_back(Args.MakeArgString(
@@ -213,15 +213,19 @@ void visualstudio::Linker::ConstructJob(Compilation &C, const JobAction &JA,
: "-include:__asan_seh_interceptor"));
// Make sure the linker consider all object files from the dynamic runtime
// thunk.
- CmdArgs.push_back(Args.MakeArgString(
- std::string("-wholearchive:") +
+ CmdArgs.push_back(Args.MakeArgString(std::string("-wholearchive:") +
TC.getCompilerRT(Args, "asan_dynamic_runtime_thunk")));
+ } else if (DLL) {
+ CmdArgs.push_back(TC.getCompilerRTArgString(Args, "asan_dll_thunk"));
} else {
- // Make sure the linker consider all object files from the static runtime
- // thunk.
- CmdArgs.push_back(Args.MakeArgString(
- std::string("-wholearchive:") +
- TC.getCompilerRT(Args, "asan_static_runtime_thunk")));
+ for (const auto &Lib : {"asan", "asan_cxx"}) {
+ CmdArgs.push_back(TC.getCompilerRTArgString(Args, Lib));
+ // Make sure the linker consider all object files from the static lib.
+ // This is necessary because instrumented dlls need access to all the
+ // interface exported by the static lib in the main executable.
+ CmdArgs.push_back(Args.MakeArgString(std::string("-wholearchive:") +
+ TC.getCompilerRT(Args, Lib)));
+ }
}
}
diff --git a/clang/test/Driver/cl-link.c b/clang/test/Driver/cl-link.c
index f526044276045..ffd0b5ac4bade 100644
--- a/clang/test/Driver/cl-link.c
+++ b/clang/test/Driver/cl-link.c
@@ -13,8 +13,10 @@
// ASAN: link.exe
// ASAN: "-debug"
// ASAN: "-incremental:no"
-// ASAN: "{{[^"]*}}clang_rt.asan_dynamic.lib"
-// ASAN: "-wholearchive:{{.*}}clang_rt.asan_static_runtime_thunk.lib"
+// ASAN: "{{[^"]*}}clang_rt.asan.lib"
+// ASAN: "-wholearchive:{{.*}}clang_rt.asan.lib"
+// ASAN: "{{[^"]*}}clang_rt.asan_cxx.lib"
+// ASAN: "-wholearchive:{{.*}}clang_rt.asan_cxx.lib"
// ASAN: "{{.*}}cl-link{{.*}}.obj"
// RUN: %clang_cl -m32 -arch:IA32 --target=i386-pc-win32 /MD /Tc%s -fuse-ld=link -### -fsanitize=address 2>&1 | FileCheck --check-prefix=ASAN-MD %s
@@ -22,6 +24,7 @@
// ASAN-MD: "-debug"
// ASAN-MD: "-incremental:no"
// ASAN-MD: "{{.*}}clang_rt.asan_dynamic.lib"
+// ASAN-MD: "{{[^"]*}}clang_rt.asan_dynamic_runtime_thunk.lib"
// ASAN-MD: "-include:___asan_seh_interceptor"
// ASAN-MD: "-wholearchive:{{.*}}clang_rt.asan_dynamic_runtime_thunk.lib"
// ASAN-MD: "{{.*}}cl-link{{.*}}.obj"
@@ -37,8 +40,7 @@
// ASAN-DLL: "-dll"
// ASAN-DLL: "-debug"
// ASAN-DLL: "-incremental:no"
-// ASAN-DLL: "{{.*}}clang_rt.asan_dynamic.lib"
-// ASAN-DLL: "-wholearchive:{{.*}}clang_rt.asan_static_runtime_thunk.lib"
+// ASAN-DLL: "{{.*}}clang_rt.asan_dll_thunk.lib"
// ASAN-DLL: "{{.*}}cl-link{{.*}}.obj"
// RUN: %clang_cl /Zi /Tc%s -fuse-ld=link -### 2>&1 | FileCheck --check-prefix=DEBUG %s
diff --git a/compiler-rt/CMakeLists.txt b/compiler-rt/CMakeLists.txt
index 158fa270c3f15..6ce451e3cac2e 100644
--- a/compiler-rt/CMakeLists.txt
+++ b/compiler-rt/CMakeLists.txt
@@ -378,12 +378,8 @@ if("${COMPILER_RT_DEFAULT_TARGET_ARCH}" MATCHES "s390x")
endif()
if(MSVC)
-
- # asan on windows only supports the release dll version of the runtimes, in the interest of
- # only having one asan dll to support/test. Having asan statically linked
- # with the runtime might be possible, but it multiplies the number of scenerios to test.
- # the program USING sanitizers can use whatever version of the runtime it wants to.
- set(CMAKE_MSVC_RUNTIME_LIBRARY MultiThreadedDLL)
+ # FIXME: In fact, sanitizers should support both /MT and /MD, see PR20214.
+ set(CMAKE_MSVC_RUNTIME_LIBRARY MultiThreaded)
# Remove any /M[DT][d] flags, and strip any definitions of _DEBUG.
# Since we're using CMAKE_MSVC_RUNTIME_LIBRARY (CMP0091 set to NEW),
diff --git a/compiler-rt/lib/asan/CMakeLists.txt b/compiler-rt/lib/asan/CMakeLists.txt
index f992419c6d982..463ea233b37aa 100644
--- a/compiler-rt/lib/asan/CMakeLists.txt
+++ b/compiler-rt/lib/asan/CMakeLists.txt
@@ -32,20 +32,6 @@ set(ASAN_SOURCES
asan_win.cpp
)
-if(WIN32)
- set(ASAN_DYNAMIC_RUNTIME_THUNK_SOURCES
- asan_globals_win.cpp
- asan_win_common_runtime_thunk.cpp
- asan_win_dynamic_runtime_thunk.cpp
- )
- set(ASAN_STATIC_RUNTIME_THUNK_SOURCES
- asan_globals_win.cpp
- asan_malloc_win_thunk.cpp
- asan_win_common_runtime_thunk.cpp
- asan_win_static_runtime_thunk.cpp
- )
-endif()
-
if (NOT WIN32 AND NOT APPLE)
list(APPEND ASAN_SOURCES
asan_interceptors_vfork.S
@@ -150,7 +136,7 @@ append_list_if(MINGW "${MINGW_LIBRARIES}" ASAN_DYNAMIC_LIBS)
add_compiler_rt_object_libraries(RTAsan_dynamic
OS ${SANITIZER_COMMON_SUPPORTED_OS}
ARCHS ${ASAN_SUPPORTED_ARCH}
- SOURCES ${ASAN_SOURCES}
+ SOURCES ${ASAN_SOURCES} ${ASAN_CXX_SOURCES}
ADDITIONAL_HEADERS ${ASAN_HEADERS}
CFLAGS ${ASAN_DYNAMIC_CFLAGS}
DEFS ${ASAN_DYNAMIC_DEFINITIONS})
@@ -235,52 +221,46 @@ else()
RTSanitizerCommonSymbolizerInternal
RTLSanCommon
RTUbsan)
- if (NOT WIN32)
- add_compiler_rt_runtime(clang_rt.asan
- STATIC
- ARCHS ${ASAN_SUPPORTED_ARCH}
- OBJECT_LIBS RTAsan_preinit
- RTAsan
- ${ASAN_COMMON_RUNTIME_OBJECT_LIBS}
- CFLAGS ${ASAN_CFLAGS}
- DEFS ${ASAN_COMMON_DEFINITIONS}
- PARENT_TARGET asan)
- add_compiler_rt_runtime(clang_rt.asan_cxx
- STATIC
- ARCHS ${ASAN_SUPPORTED_ARCH}
- OBJECT_LIBS RTAsan_cxx
- RTUbsan_cxx
- CFLAGS ${ASAN_CFLAGS}
- DEFS ${ASAN_COMMON_DEFINITIONS}
- PARENT_TARGET asan)
+ add_compiler_rt_runtime(clang_rt.asan
+ STATIC
+ ARCHS ${ASAN_SUPPORTED_ARCH}
+ OBJECT_LIBS RTAsan_preinit
+ RTAsan
+ ${ASAN_COMMON_RUNTIME_OBJECT_LIBS}
+ CFLAGS ${ASAN_CFLAGS}
+ DEFS ${ASAN_COMMON_DEFINITIONS}
+ PARENT_TARGET asan)
- add_compiler_rt_runtime(clang_rt.asan_static
- STATIC
- ARCHS ${ASAN_SUPPORTED_ARCH}
- OBJECT_LIBS RTAsan_static
- CFLAGS ${ASAN_CFLAGS}
- DEFS ${ASAN_COMMON_DEFINITIONS}
- PARENT_TARGET asan)
+ add_compiler_rt_runtime(clang_rt.asan_cxx
+ STATIC
+ ARCHS ${ASAN_SUPPORTED_ARCH}
+ OBJECT_LIBS RTAsan_cxx
+ RTUbsan_cxx
+ CFLAGS ${ASAN_CFLAGS}
+ DEFS ${ASAN_COMMON_DEFINITIONS}
+ PARENT_TARGET asan)
- add_compiler_rt_runtime(clang_rt.asan-preinit
- STATIC
- ARCHS ${ASAN_SUPPORTED_ARCH}
- OBJECT_LIBS RTAsan_preinit
- CFLAGS ${ASAN_CFLAGS}
- DEFS ${ASAN_COMMON_DEFINITIONS}
- PARENT_TARGET asan)
- endif()
+ add_compiler_rt_runtime(clang_rt.asan_static
+ STATIC
+ ARCHS ${ASAN_SUPPORTED_ARCH}
+ OBJECT_LIBS RTAsan_static
+ CFLAGS ${ASAN_CFLAGS}
+ DEFS ${ASAN_COMMON_DEFINITIONS}
+ PARENT_TARGET asan)
+
+ add_compiler_rt_runtime(clang_rt.asan-preinit
+ STATIC
+ ARCHS ${ASAN_SUPPORTED_ARCH}
+ OBJECT_LIBS RTAsan_preinit
+ CFLAGS ${ASAN_CFLAGS}
+ DEFS ${ASAN_COMMON_DEFINITIONS}
+ PARENT_TARGET asan)
foreach(arch ${ASAN_SUPPORTED_ARCH})
if (COMPILER_RT_HAS_VERSION_SCRIPT)
- if(WIN32)
- set(SANITIZER_RT_VERSION_LIST_LIBS clang_rt.asan-${arch})
- else()
- set(SANITIZER_RT_VERSION_LIST_LIBS clang_rt.asan-${arch} clang_rt.asan_cxx-${arch})
- endif()
add_sanitizer_rt_version_list(clang_rt.asan-dynamic-${arch}
- LIBS ${SANITIZER_RT_VERSION_LIST_LIBS}
+ LIBS 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)
@@ -298,11 +278,25 @@ else()
endif()
set(ASAN_DYNAMIC_WEAK_INTERCEPTION)
+ if (WIN32)
+ add_compiler_rt_object_libraries(AsanWeakInterception
+ ${SANITIZER_COMMON_SUPPORTED_OS}
+ ARCHS ${arch}
+ SOURCES
+ asan_win_weak_interception.cpp
+ CFLAGS ${ASAN_CFLAGS} -DSANITIZER_DYNAMIC
+ DEFS ${ASAN_COMMON_DEFINITIONS})
+ set(ASAN_DYNAMIC_WEAK_INTERCEPTION
+ AsanWeakInterception
+ UbsanWeakInterception
+ SancovWeakInterception
+ SanitizerCommonWeakInterception)
+ endif()
+
add_compiler_rt_runtime(clang_rt.asan
SHARED
ARCHS ${arch}
OBJECT_LIBS ${ASAN_COMMON_RUNTIME_OBJECT_LIBS}
- RTAsan_cxx
RTAsan_dynamic
# The only purpose of RTAsan_dynamic_version_script_dummy is to
# carry a dependency of the shared runtime on the version script.
@@ -330,12 +324,36 @@ else()
endif()
if (WIN32)
+ add_compiler_rt_object_libraries(AsanDllThunk
+ ${SANITIZER_COMMON_SUPPORTED_OS}
+ ARCHS ${arch}
+ SOURCES asan_globals_win.cpp
+ asan_win_dll_thunk.cpp
+ CFLAGS ${ASAN_CFLAGS} -DSANITIZER_DLL_THUNK
+ DEFS ${ASAN_COMMON_DEFINITIONS})
+
+ add_compiler_rt_runtime(clang_rt.asan_dll_thunk
+ STATIC
+ ARCHS ${arch}
+ OBJECT_LIBS AsanDllThunk
+ UbsanDllThunk
+ SancovDllThunk
+ SanitizerCommonDllThunk
+ SOURCES $<TARGET_OBJECTS:RTInterception.${arch}>
+ PARENT_TARGET asan)
+
set(DYNAMIC_RUNTIME_THUNK_CFLAGS "-DSANITIZER_DYNAMIC_RUNTIME_THUNK")
+ if(MSVC)
+ list(APPEND DYNAMIC_RUNTIME_THUNK_CFLAGS "-Zl")
+ elseif(CMAKE_C_COMPILER_ID MATCHES Clang)
+ list(APPEND DYNAMIC_RUNTIME_THUNK_CFLAGS "-nodefaultlibs")
+ endif()
add_compiler_rt_object_libraries(AsanDynamicRuntimeThunk
${SANITIZER_COMMON_SUPPORTED_OS}
ARCHS ${arch}
- SOURCES ${ASAN_DYNAMIC_RUNTIME_THUNK_SOURCES}
+ SOURCES asan_globals_win.cpp
+ asan_win_dynamic_runtime_thunk.cpp
CFLAGS ${ASAN_CFLAGS} ${DYNAMIC_RUNTIME_THUNK_CFLAGS}
DEFS ${ASAN_COMMON_DEFINITIONS})
@@ -343,35 +361,12 @@ else()
STATIC
ARCHS ${arch}
OBJECT_LIBS AsanDynamicRuntimeThunk
- UbsanRuntimeThunk
- SancovRuntimeThunk
- SanitizerRuntimeThunk
+ UbsanDynamicRuntimeThunk
+ SancovDynamicRuntimeThunk
+ SanitizerCommonDynamicRuntimeThunk
CFLAGS ${ASAN_CFLAGS} ${DYNAMIC_RUNTIME_THUNK_CFLAGS}
DEFS ${ASAN_COMMON_DEFINITIONS}
PARENT_TARGET asan)
-
- # mingw does not support static linkage of the CRT
- if(NOT MINGW)
- set(STATIC_RUNTIME_THUNK_CFLAGS "-DSANITIZER_STATIC_RUNTIME_THUNK")
-
- add_compiler_rt_object_libraries(AsanStaticRuntimeThunk
- ${SANITIZER_COMMON_SUPPORTED_OS}
- ARCHS ${arch}
- SOURCES ${ASAN_STATIC_RUNTIME_THUNK_SOURCES}
- CFLAGS ${ASAN_DYNAMIC_CFLAGS} ${STATIC_RUNTIME_THUNK_CFLAGS}
- DEFS ${ASAN_DYNAMIC_DEFINITIONS})
-
- add_compiler_rt_runtime(clang_rt.asan_static_runtime_thunk
- STATIC
- ARCHS ${arch}
- OBJECT_LIBS AsanStaticRuntimeThunk
- UbsanRuntimeThunk
- SancovRuntimeThunk
- SanitizerRuntimeThunk
- CFLAGS ${ASAN_DYNAMIC_CFLAGS} ${STATIC_RUNTIME_THUNK_CFLAGS}
- DEFS ${ASAN_DYNAMIC_DEFINITIONS}
- PARENT_TARGET asan)
- endif()
endif()
endforeach()
endif()
diff --git a/compiler-rt/lib/asan/asan_flags.cpp b/compiler-rt/lib/asan/asan_flags.cpp
index 56deb1b0d082b..2398984332321 100644
--- a/compiler-rt/lib/asan/asan_flags.cpp
+++ b/compiler-rt/lib/asan/asan_flags.cpp
@@ -11,16 +11,14 @@
// ASan flag parsing logic.
//===----------------------------------------------------------------------===//
-#include "asan_flags.h"
-
#include "asan_activation.h"
+#include "asan_flags.h"
#include "asan_interface_internal.h"
#include "asan_stack.h"
#include "lsan/lsan_common.h"
#include "sanitizer_common/sanitizer_common.h"
-#include "sanitizer_common/sanitizer_flag_parser.h"
#include "sanitizer_common/sanitizer_flags.h"
-#include "sanitizer_common/sanitizer_win_interception.h"
+#include "sanitizer_common/sanitizer_flag_parser.h"
#include "ubsan/ubsan_flags.h"
#include "ubsan/ubsan_platform.h"
@@ -49,21 +47,7 @@ static void RegisterAsanFlags(FlagParser *parser, Flags *f) {
#undef ASAN_FLAG
}
-static void DisplayHelpMessages(FlagParser *parser) {
- // TODO(eugenis): dump all flags at verbosity>=2?
- if (Verbosity()) {
- ReportUnrecognizedFlags();
- }
-
- if (common_flags()->help) {
- parser->PrintFlagDescriptions();
- }
-}
-
-static void InitializeDefaultFlags() {
- Flags *f = flags();
- FlagParser asan_parser;
-
+void InitializeFlags() {
// Set the default values and prepare for parsing ASan and common flags.
SetCommonFlagsDefaults();
{
@@ -76,8 +60,10 @@ static void InitializeDefaultFlags() {
cf.exitcode = 1;
OverrideCommonFlags(cf);
}
+ Flags *f = flags();
f->SetDefaults();
+ FlagParser asan_parser;
RegisterAsanFlags(&asan_parser, f);
RegisterCommonFlags(&asan_parser);
@@ -140,12 +126,13 @@ static void InitializeDefaultFlags() {
InitializeCommonFlags();
- // TODO(samsonov): print all of the flags (ASan, LSan, common).
- DisplayHelpMessages(&asan_parser);
-}
+ // TODO(eugenis): dump all flags at verbosity>=2?
+ if (Verbosity()) ReportUnrecognizedFlags();
-static void ProcessFlags() {
- Flags *f = flags();
+ if (common_flags()->help) {
+ // TODO(samsonov): print all of the flags (ASan, LSan, common).
+ asan_parser.PrintFlagDescriptions();
+ }
// Flag validation:
if (!CAN_SANITIZE_LEAKS && common_flags()->detect_leaks) {
@@ -212,67 +199,6 @@ static void ProcessFlags() {
}
}
-void InitializeFlags() {
- InitializeDefaultFlags();
- ProcessFlags();
-
-#if SANITIZER_WINDOWS
- // On Windows, weak symbols are emulated by having the user program
- // register which weak functions are defined.
- // The ASAN DLL will initialize flags prior to user module initialization,
- // so __asan_default_options will not point to the user definition yet.
- // We still want to ensure we capture when options are passed via
- // __asan_default_options, so we add a callback to be run
- // when it is registered with the runtime.
-
- // There is theoretically time between the initial ProcessFlags and
- // registering the weak callback where a weak function could be added and we
- // would miss it, but in practice, InitializeFlags will always happen under
- // the loader lock (if built as a DLL) and so will any calls to
- // __sanitizer_register_weak_function.
- AddRegisterWeakFunctionCallback(
- reinterpret_cast<uptr>(__asan_default_options), []() {
- FlagParser asan_parser;
-
- RegisterAsanFlags(&asan_parser, flags());
- RegisterCommonFlags(&asan_parser);
- asan_parser.ParseString(__asan_default_options());
-
- DisplayHelpMessages(&asan_parser);
- ProcessFlags();
- });
-
-# if CAN_SANITIZE_UB
- AddRegisterWeakFunctionCallback(
- reinterpret_cast<uptr>(__ubsan_default_options), []() {
- FlagParser ubsan_parser;
-
- __ubsan::RegisterUbsanFlags(&ubsan_parser, __ubsan::flags());
- RegisterCommonFlags(&ubsan_parser);
- ubsan_parser.ParseString(__ubsan_default_options());
-
- // To match normal behavior, do not print UBSan help.
- ProcessFlags();
- });
-# endif
-
-# if CAN_SANITIZE_LEAKS
- AddRegisterWeakFunctionCallback(
- reinterpret_cast<uptr>(__lsan_default_options), []() {
- FlagParser lsan_parser;
-
- __lsan::RegisterLsanFlags(&lsan_parser, __lsan::flags());
- RegisterCommonFlags(&lsan_parser);
- lsan_parser.ParseString(__lsan_default_options());
-
- // To match normal behavior, do not print LSan help.
- ProcessFlags();
- });
-# endif
-
-#endif
-}
-
} // namespace __asan
SANITIZER_INTERFACE_WEAK_DEF(const char*, __asan_default_options, void) {
diff --git a/compiler-rt/lib/asan/asan_globals_win.cpp b/compiler-rt/lib/asan/asan_globals_win.cpp
index 8267f07b9cce4..19af88ab12b40 100644
--- a/compiler-rt/lib/asan/asan_globals_win.cpp
+++ b/compiler-rt/lib/asan/asan_globals_win.cpp
@@ -28,9 +28,7 @@ static void call_on_globals(void (*hook)(__asan_global *, uptr)) {
__asan_global *end = &__asan_globals_end;
uptr byte
diff = (uptr)end - (uptr)start;
if (byte
diff % sizeof(__asan_global) != 0) {
-# if defined(SANITIZER_DLL_THUNK) || \
- defined(SANITIZER_DYNAMIC_RUNTIME_THUNK) || \
- defined(SANITIZER_STATIC_RUNTIME_THUNK)
+#if defined(SANITIZER_DLL_THUNK) || defined(SANITIZER_DYNAMIC_RUNTIME_THUNK)
__debugbreak();
#else
CHECK("corrupt asan global array");
diff --git a/compiler-rt/lib/asan/asan_malloc_win.cpp b/compiler-rt/lib/asan/asan_malloc_win.cpp
index 3278f07219876..7e1d04c36dd58 100644
--- a/compiler-rt/lib/asan/asan_malloc_win.cpp
+++ b/compiler-rt/lib/asan/asan_malloc_win.cpp
@@ -58,69 +58,97 @@ using namespace __asan;
// MD: Memory allocation functions are defined in the CRT .dll,
// so we have to intercept them before they are called for the first time.
+#if ASAN_DYNAMIC
+# define ALLOCATION_FUNCTION_ATTRIBUTE
+#else
+# define ALLOCATION_FUNCTION_ATTRIBUTE SANITIZER_INTERFACE_ATTRIBUTE
+#endif
+
extern "C" {
-__declspec(noinline) size_t _msize(void *ptr) {
+ALLOCATION_FUNCTION_ATTRIBUTE
+size_t _msize(void *ptr) {
GET_CURRENT_PC_BP_SP;
(void)sp;
return asan_malloc_usable_size(ptr, pc, bp);
}
-__declspec(noinline) size_t _msize_base(void *ptr) { return _msize(ptr); }
+ALLOCATION_FUNCTION_ATTRIBUTE
+size_t _msize_base(void *ptr) {
+ return _msize(ptr);
+}
-__declspec(noinline) void free(void *ptr) {
+ALLOCATION_FUNCTION_ATTRIBUTE
+void free(void *ptr) {
GET_STACK_TRACE_FREE;
return asan_free(ptr, &stack, FROM_MALLOC);
}
-__declspec(noinline) void _free_dbg(void *ptr, int) { free(ptr); }
+ALLOCATION_FUNCTION_ATTRIBUTE
+void _free_dbg(void *ptr, int) {
+ free(ptr);
+}
-__declspec(noinline) void _free_base(void *ptr) { free(ptr); }
+ALLOCATION_FUNCTION_ATTRIBUTE
+void _free_base(void *ptr) {
+ free(ptr);
+}
-__declspec(noinline) void *malloc(size_t size) {
+ALLOCATION_FUNCTION_ATTRIBUTE
+void *malloc(size_t size) {
GET_STACK_TRACE_MALLOC;
return asan_malloc(size, &stack);
}
-__declspec(noinline) void *_malloc_base(size_t size) { return malloc(size); }
+ALLOCATION_FUNCTION_ATTRIBUTE
+void *_malloc_base(size_t size) {
+ return malloc(size);
+}
-__declspec(noinline) void *_malloc_dbg(size_t size, int, const char *, int) {
+ALLOCATION_FUNCTION_ATTRIBUTE
+void *_malloc_dbg(size_t size, int, const char *, int) {
return malloc(size);
}
-__declspec(noinline) void *calloc(size_t nmemb, size_t size) {
+ALLOCATION_FUNCTION_ATTRIBUTE
+void *calloc(size_t nmemb, size_t size) {
GET_STACK_TRACE_MALLOC;
return asan_calloc(nmemb, size, &stack);
}
-__declspec(noinline) void *_calloc_base(size_t nmemb, size_t size) {
+ALLOCATION_FUNCTION_ATTRIBUTE
+void *_calloc_base(size_t nmemb, size_t size) {
return calloc(nmemb, size);
}
-__declspec(noinline) void *_calloc_dbg(size_t nmemb, size_t size, int,
- const char *, int) {
+ALLOCATION_FUNCTION_ATTRIBUTE
+void *_calloc_dbg(size_t nmemb, size_t size, int, const char *, int) {
return calloc(nmemb, size);
}
-__declspec(noinline) void *_calloc_impl(size_t nmemb, size_t size,
- int *errno_tmp) {
+ALLOCATION_FUNCTION_ATTRIBUTE
+void *_calloc_impl(size_t nmemb, size_t size, int *errno_tmp) {
return calloc(nmemb, size);
}
-__declspec(noinline) void *realloc(void *ptr, size_t size) {
+ALLOCATION_FUNCTION_ATTRIBUTE
+void *realloc(void *ptr, size_t size) {
GET_STACK_TRACE_MALLOC;
return asan_realloc(ptr, size, &stack);
}
-__declspec(noinline) void *_realloc_dbg(void *ptr, size_t size, int) {
+ALLOCATION_FUNCTION_ATTRIBUTE
+void *_realloc_dbg(void *ptr, size_t size, int) {
UNREACHABLE("_realloc_dbg should not exist!");
return 0;
}
-__declspec(noinline) void *_realloc_base(void *ptr, size_t size) {
+ALLOCATION_FUNCTION_ATTRIBUTE
+void *_realloc_base(void *ptr, size_t size) {
return realloc(ptr, size);
}
-__declspec(noinline) void *_recalloc(void *p, size_t n, size_t elem_size) {
+ALLOCATION_FUNCTION_ATTRIBUTE
+void *_recalloc(void *p, size_t n, size_t elem_size) {
if (!p)
return calloc(n, elem_size);
const size_t size = n * elem_size;
@@ -138,41 +166,23 @@ __declspec(noinline) void *_recalloc(void *p, size_t n, size_t elem_size) {
return new_alloc;
}
-__declspec(noinline) void *_recalloc_base(void *p, size_t n, size_t elem_size) {
+ALLOCATION_FUNCTION_ATTRIBUTE
+void *_recalloc_base(void *p, size_t n, size_t elem_size) {
return _recalloc(p, n, elem_size);
}
-__declspec(noinline) void *_expand(void *memblock, size_t size) {
+ALLOCATION_FUNCTION_ATTRIBUTE
+void *_expand(void *memblock, size_t size) {
// _expand is used in realloc-like functions to resize the buffer if possible.
// We don't want memory to stand still while resizing buffers, so return 0.
return 0;
}
-__declspec(noinline) void *_expand_dbg(void *memblock, size_t size) {
+ALLOCATION_FUNCTION_ATTRIBUTE
+void *_expand_dbg(void *memblock, size_t size) {
return _expand(memblock, size);
}
-__declspec(dllexport) size_t __cdecl __asan_msize(void *ptr) {
- return _msize(ptr);
-}
-__declspec(dllexport) void __cdecl __asan_free(void *const ptr) { free(ptr); }
-__declspec(dllexport) void *__cdecl __asan_malloc(const size_t size) {
- return malloc(size);
-}
-__declspec(dllexport) void *__cdecl __asan_calloc(const size_t nmemb,
- const size_t size) {
- return calloc(nmemb, size);
-}
-__declspec(dllexport) void *__cdecl __asan_realloc(void *const ptr,
- const size_t size) {
- return realloc(ptr, size);
-}
-__declspec(dllexport) void *__cdecl __asan_recalloc(void *const ptr,
- const size_t nmemb,
- const size_t size) {
- return _recalloc(ptr, nmemb, size);
-}
-
// TODO(timurrrr): Might want to add support for _aligned_* allocation
// functions to detect a bit more bugs. Those functions seem to wrap malloc().
@@ -477,6 +487,7 @@ static void TryToOverrideFunction(const char *fname, uptr new_func) {
}
void ReplaceSystemMalloc() {
+#if defined(ASAN_DYNAMIC)
TryToOverrideFunction("free", (uptr)free);
TryToOverrideFunction("_free_base", (uptr)free);
TryToOverrideFunction("malloc", (uptr)malloc);
@@ -532,6 +543,8 @@ void ReplaceSystemMalloc() {
// allocation API will be directed to ASan's heap. We don't currently
// intercept all calls to HeapAlloc. If we did, we would have to check on
// HeapFree whether the pointer came from ASan of from the system.
+
+#endif // defined(ASAN_DYNAMIC)
}
} // namespace __asan
diff --git a/compiler-rt/lib/asan/asan_malloc_win_thunk.cpp b/compiler-rt/lib/asan/asan_malloc_win_thunk.cpp
deleted file mode 100644
index abf515b77c4a9..0000000000000
--- a/compiler-rt/lib/asan/asan_malloc_win_thunk.cpp
+++ /dev/null
@@ -1,229 +0,0 @@
-//===-- asan_malloc_win_thunk.cpp
-//-----------------------------------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-//
-// This file is a part of AddressSanitizer, an address sanity checker.
-//
-// Windows-specific malloc interception.
-// This is included statically for projects statically linking
-// with the C Runtime (/MT, /MTd) in order to provide ASAN-aware
-// versions of the C allocation functions.
-//===----------------------------------------------------------------------===//
-
-#ifdef SANITIZER_STATIC_RUNTIME_THUNK
-# include "..\sanitizer_common\sanitizer_allocator_interface.h"
-// #include "asan_win_thunk_common.h"
-
-// Preserve stack traces with noinline.
-# define STATIC_MALLOC_INTERFACE __declspec(noinline)
-
-extern "C" {
-__declspec(dllimport) size_t __cdecl __asan_msize(void *ptr);
-__declspec(dllimport) void __cdecl __asan_free(void *const ptr);
-__declspec(dllimport) void *__cdecl __asan_malloc(const size_t size);
-__declspec(dllimport) void *__cdecl __asan_calloc(const size_t nmemb,
- const size_t size);
-__declspec(dllimport) void *__cdecl __asan_realloc(void *const ptr,
- const size_t size);
-__declspec(dllimport) void *__cdecl __asan_recalloc(void *const ptr,
- const size_t nmemb,
- const size_t size);
-
-// Avoid tailcall optimization to preserve stack frames.
-# pragma optimize("", off)
-
-// _msize
-STATIC_MALLOC_INTERFACE size_t _msize(void *ptr) { return __asan_msize(ptr); }
-
-STATIC_MALLOC_INTERFACE size_t _msize_base(void *ptr) {
- return __asan_msize(ptr);
-}
-
-STATIC_MALLOC_INTERFACE size_t _msize_dbg(void *ptr) {
- return __asan_msize(ptr);
-}
-
-// free
-STATIC_MALLOC_INTERFACE void free(void *const ptr) { return __asan_free(ptr); }
-
-STATIC_MALLOC_INTERFACE void _free_base(void *const ptr) {
- return __asan_free(ptr);
-}
-
-STATIC_MALLOC_INTERFACE void _free_dbg(void *const ptr) {
- return __asan_free(ptr);
-}
-
-// malloc
-STATIC_MALLOC_INTERFACE void *malloc(const size_t size) {
- return __asan_malloc(size);
-}
-
-STATIC_MALLOC_INTERFACE void *_malloc_base(const size_t size) {
- return __asan_malloc(size);
-}
-
-STATIC_MALLOC_INTERFACE void *_malloc_dbg(const size_t size) {
- return __asan_malloc(size);
-}
-
-// calloc
-STATIC_MALLOC_INTERFACE void *calloc(const size_t nmemb, const size_t size) {
- return __asan_calloc(nmemb, size);
-}
-
-STATIC_MALLOC_INTERFACE void *_calloc_base(const size_t nmemb,
- const size_t size) {
- return __asan_calloc(nmemb, size);
-}
-
-STATIC_MALLOC_INTERFACE void *_calloc_impl(const size_t nmemb,
- const size_t size,
- int *const errno_tmp) {
- // Provided by legacy msvcrt.
- (void)errno_tmp;
-
- return __asan_calloc(nmemb, size);
-}
-
-STATIC_MALLOC_INTERFACE void *_calloc_dbg(const size_t nmemb, const size_t size,
- int, const char *, int) {
- return __asan_calloc(nmemb, size);
-}
-
-// realloc
-STATIC_MALLOC_INTERFACE void *realloc(void *const ptr, const size_t size) {
- return __asan_realloc(ptr, size);
-}
-
-STATIC_MALLOC_INTERFACE void *_realloc_base(void *const ptr,
- const size_t size) {
- return __asan_realloc(ptr, size);
-}
-
-STATIC_MALLOC_INTERFACE void *_realloc_dbg(void *const ptr, const size_t size,
- int, const char *, int) {
- return __asan_realloc(ptr, size);
-}
-
-// recalloc
-STATIC_MALLOC_INTERFACE void *_recalloc(void *const ptr, const size_t nmemb,
- const size_t size) {
- return __asan_recalloc(ptr, nmemb, size);
-}
-
-STATIC_MALLOC_INTERFACE void *_recalloc_base(void *const ptr,
- const size_t nmemb,
- const size_t size) {
- return __asan_recalloc(ptr, nmemb, size);
-}
-
-STATIC_MALLOC_INTERFACE void *_recalloc_dbg(void *const ptr, const size_t nmemb,
- const size_t size, int,
- const char *, int) {
- return __asan_recalloc(ptr, nmemb, size);
-}
-
-// expand
-STATIC_MALLOC_INTERFACE void *_expand(void *, size_t) {
- // _expand is used in realloc-like functions to resize the buffer if possible.
- // We don't want memory to stand still while resizing buffers, so return 0.
- return nullptr;
-}
-
-STATIC_MALLOC_INTERFACE void *_expand_dbg(void *, size_t, int, const char *,
- int) {
- return nullptr;
-}
-
-// We need to provide symbols for all the debug CRT functions if we decide to
-// provide any. Most of these functions make no sense under ASan and so we
-// make them no-ops.
-long _CrtSetBreakAlloc(long const) { return ~0; }
-
-void _CrtSetDbgBlockType(void *const, int const) { return; }
-
-typedef int(__cdecl *CRT_ALLOC_HOOK)(int, void *, size_t, int, long,
- const unsigned char *, int);
-
-CRT_ALLOC_HOOK _CrtGetAllocHook() { return nullptr; }
-
-CRT_ALLOC_HOOK _CrtSetAllocHook(CRT_ALLOC_HOOK const hook) { return hook; }
-
-int _CrtCheckMemory() { return 1; }
-
-int _CrtSetDbgFlag(int const new_bits) { return new_bits; }
-
-typedef void (*CrtDoForAllClientObjectsCallback)(void *, void *);
-
-void _CrtDoForAllClientObjects(CrtDoForAllClientObjectsCallback const,
- void *const) {
- return;
-}
-
-int _CrtIsValidPointer(void const *const p, unsigned int const, int const) {
- return p != nullptr;
-}
-
-int _CrtIsValidHeapPointer(void const *const block) {
- if (!block) {
- return 0;
- }
-
- return __sanitizer_get_ownership(block);
-}
-
-int _CrtIsMemoryBlock(void const *const, unsigned const, long *const,
- char **const, int *const) {
- return 0;
-}
-
-int _CrtReportBlockType(void const *const) { return -1; }
-
-typedef void(__cdecl *CRT_DUMP_CLIENT)(void *, size_t);
-
-CRT_DUMP_CLIENT _CrtGetDumpClient() { return nullptr; }
-
-CRT_DUMP_CLIENT _CrtSetDumpClient(CRT_DUMP_CLIENT new_client) {
- return new_client;
-}
-
-void _CrtMemCheckpoint(void *const) { return; }
-
-int _CrtMemDifference(void *const, void const *const, void const *const) {
- return 0;
-}
-
-void _CrtMemDumpAllObjectsSince(void const *const) { return; }
-
-int _CrtDumpMemoryLeaks() { return 0; }
-
-void _CrtMemDumpStatistics(void const *const) { return; }
-
-int _crtDbgFlag{0};
-long _crtBreakAlloc{-1};
-CRT_DUMP_CLIENT _pfnDumpClient{nullptr};
-
-int *__p__crtDbgFlag() { return &_crtDbgFlag; }
-
-long *__p__crtBreakAlloc() { return &_crtBreakAlloc; }
-
-// TODO: These were added upstream but conflict with definitions in ucrtbased.
-// int _CrtDbgReport(int, const char *, int, const char *, const char *, ...) {
-// ShowStatsAndAbort();
-// }
-//
-// int _CrtDbgReportW(int reportType, const wchar_t *, int, const wchar_t *,
-// const wchar_t *, ...) {
-// ShowStatsAndAbort();
-// }
-//
-// int _CrtSetReportMode(int, int) { return 0; }
-
-} // extern "C"
-#endif // SANITIZER_STATIC_RUNTIME_THUNK
diff --git a/compiler-rt/lib/asan/asan_win_common_runtime_thunk.cpp b/compiler-rt/lib/asan/asan_win_common_runtime_thunk.cpp
deleted file mode 100644
index d2c9e66c31337..0000000000000
--- a/compiler-rt/lib/asan/asan_win_common_runtime_thunk.cpp
+++ /dev/null
@@ -1,112 +0,0 @@
-//===-- asan_win_common_runtime_thunk.cpp --------------------------- -----===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-//
-// This file is a part of AddressSanitizer, an address sanity checker.
-//
-// This file defines things that need to be present in the application modules
-// to interact with the ASan DLL runtime correctly and can't be implemented
-// using the default "import library" generated when linking the DLL.
-//
-// This includes:
-// - Cloning shadow memory dynamic address from ASAN DLL
-// - Creating weak aliases to default implementation imported from asan dll
-// - Forwarding the detect_stack_use_after_return runtime option
-// - installing a custom SEH handler
-//
-//===----------------------------------------------------------------------===//
-
-#if defined(SANITIZER_DYNAMIC_RUNTIME_THUNK) || \
- defined(SANITIZER_STATIC_RUNTIME_THUNK)
-# define SANITIZER_IMPORT_INTERFACE 1
-# define WIN32_LEAN_AND_MEAN
-# include "asan_win_common_runtime_thunk.h"
-
-# include <windows.h>
-
-# include "sanitizer_common/sanitizer_win_defs.h"
-# include "sanitizer_common/sanitizer_win_thunk_interception.h"
-
-// Define weak alias for all weak functions imported from asan dll.
-# define INTERFACE_FUNCTION(Name)
-# define INTERFACE_WEAK_FUNCTION(Name) REGISTER_WEAK_FUNCTION(Name)
-# include "asan_interface.inc"
-
-////////////////////////////////////////////////////////////////////////////////
-// Define a copy of __asan_option_detect_stack_use_after_return that should be
-// used when linking an MD runtime with a set of object files on Windows.
-//
-// The ASan MD runtime dllexports '__asan_option_detect_stack_use_after_return',
-// so normally we would just dllimport it. Unfortunately, the dllimport
-// attribute adds __imp_ prefix to the symbol name of a variable.
-// Since in general we don't know if a given TU is going to be used
-// with a MT or MD runtime and we don't want to use ugly __imp_ names on Windows
-// just to work around this issue, let's clone the variable that is constant
-// after initialization anyways.
-
-extern "C" {
-__declspec(dllimport) int __asan_should_detect_stack_use_after_return();
-int __asan_option_detect_stack_use_after_return;
-
-__declspec(dllimport) void *__asan_get_shadow_memory_dynamic_address();
-void *__asan_shadow_memory_dynamic_address;
-
-static void __asan_initialize_cloned_variables() {
- __asan_option_detect_stack_use_after_return =
- __asan_should_detect_stack_use_after_return();
- __asan_shadow_memory_dynamic_address =
- __asan_get_shadow_memory_dynamic_address();
-}
-}
-
-static int asan_thunk_init() {
- __asan_initialize_cloned_variables();
-
-# ifdef SANITIZER_STATIC_RUNTIME_THUNK
- __asan_initialize_static_thunk();
-# endif
-
- return 0;
-}
-
-static void WINAPI asan_thread_init(void *mod, unsigned long reason,
- void *reserved) {
- if (reason == DLL_PROCESS_ATTACH) {
- asan_thunk_init();
- }
-}
-
-// Our cloned variables must be initialized before C/C++ constructors. If TLS
-// is used, our .CRT$XLAB initializer will run first. If not, our .CRT$XIB
-// initializer is needed as a backup.
-extern "C" __declspec(allocate(".CRT$XIB")) int (*__asan_thunk_init)() =
- asan_thunk_init;
-WIN_FORCE_LINK(__asan_thunk_init);
-
-extern "C" __declspec(allocate(".CRT$XLAB")) void(WINAPI *__asan_tls_init)(
- void *, unsigned long, void *) = asan_thread_init;
-WIN_FORCE_LINK(__asan_tls_init);
-
-////////////////////////////////////////////////////////////////////////////////
-// ASan SEH handling.
-// We need to set the ASan-specific SEH handler at the end of CRT initialization
-// of each module (see also asan_win.cpp).
-extern "C" {
-__declspec(dllimport) int __asan_set_seh_filter();
-static int SetSEHFilter() { return __asan_set_seh_filter(); }
-
-// Unfortunately, putting a pointer to __asan_set_seh_filter into
-// __asan_intercept_seh gets optimized out, so we have to use an extra function.
-extern "C" __declspec(allocate(".CRT$XCAB")) int (*__asan_seh_interceptor)() =
- SetSEHFilter;
-WIN_FORCE_LINK(__asan_seh_interceptor);
-}
-
-WIN_FORCE_LINK(__asan_dso_reg_hook)
-
-#endif // defined(SANITIZER_DYNAMIC_RUNTIME_THUNK) ||
- // defined(SANITIZER_STATIC_RUNTIME_THUNK)
diff --git a/compiler-rt/lib/asan/asan_win_common_runtime_thunk.h b/compiler-rt/lib/asan/asan_win_common_runtime_thunk.h
deleted file mode 100644
index 66285eb31ae99..0000000000000
--- a/compiler-rt/lib/asan/asan_win_common_runtime_thunk.h
+++ /dev/null
@@ -1,38 +0,0 @@
-//===-- asan_win_common_runtime_thunk.h -------------------------*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-//
-// This file is a part of AddressSanitizer, an address sanity checker.
-//
-// This file defines things that need to be present in the application modules
-// to interact with the ASan DLL runtime correctly and can't be implemented
-// using the default "import library" generated when linking the DLL.
-//
-//===----------------------------------------------------------------------===//
-
-#if defined(SANITIZER_STATIC_RUNTIME_THUNK) || \
- defined(SANITIZER_DYNAMIC_RUNTIME_THUNK)
-# include "sanitizer_common/sanitizer_win_defs.h"
-
-# pragma section(".CRT$XIB", long, \
- read) // C initializer (during C init before dyninit)
-# pragma section(".CRT$XID", long, \
- read) // First C initializer after CRT initializers
-# pragma section(".CRT$XCAB", long, \
- read) // First C++ initializer after startup initializers
-
-# pragma section(".CRT$XTW", long, read) // First ASAN globals terminator
-# pragma section(".CRT$XTY", long, read) // Last ASAN globals terminator
-
-# pragma section(".CRT$XLAB", long, read) // First TLS initializer
-
-# ifdef SANITIZER_STATIC_RUNTIME_THUNK
-extern "C" void __asan_initialize_static_thunk();
-# endif
-
-#endif // defined(SANITIZER_STATIC_RUNTIME_THUNK) ||
- // defined(SANITIZER_DYNAMIC_RUNTIME_THUNK)
\ No newline at end of file
diff --git a/compiler-rt/lib/asan/asan_win_dll_thunk.cpp b/compiler-rt/lib/asan/asan_win_dll_thunk.cpp
new file mode 100644
index 0000000000000..35871a942a7a1
--- /dev/null
+++ b/compiler-rt/lib/asan/asan_win_dll_thunk.cpp
@@ -0,0 +1,165 @@
+//===-- asan_win_dll_thunk.cpp --------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file is a part of AddressSanitizer, an address sanity checker.
+//
+// This file defines a family of thunks that should be statically linked into
+// the DLLs that have ASan instrumentation in order to delegate the calls to the
+// shared runtime that lives in the main binary.
+// See https://github.com/google/sanitizers/issues/209 for the details.
+//===----------------------------------------------------------------------===//
+
+#ifdef SANITIZER_DLL_THUNK
+#include "asan_init_version.h"
+#include "interception/interception.h"
+#include "sanitizer_common/sanitizer_win_defs.h"
+#include "sanitizer_common/sanitizer_win_dll_thunk.h"
+#include "sanitizer_common/sanitizer_platform_interceptors.h"
+
+// ASan own interface functions.
+#define INTERFACE_FUNCTION(Name) INTERCEPT_SANITIZER_FUNCTION(Name)
+#define INTERFACE_WEAK_FUNCTION(Name) INTERCEPT_SANITIZER_WEAK_FUNCTION(Name)
+#include "asan_interface.inc"
+
+// Memory allocation functions.
+INTERCEPT_WRAP_V_W(free)
+INTERCEPT_WRAP_V_W(_free_base)
+INTERCEPT_WRAP_V_WW(_free_dbg)
+
+INTERCEPT_WRAP_W_W(malloc)
+INTERCEPT_WRAP_W_W(_malloc_base)
+INTERCEPT_WRAP_W_WWWW(_malloc_dbg)
+
+INTERCEPT_WRAP_W_WW(calloc)
+INTERCEPT_WRAP_W_WW(_calloc_base)
+INTERCEPT_WRAP_W_WWWWW(_calloc_dbg)
+INTERCEPT_WRAP_W_WWW(_calloc_impl)
+
+INTERCEPT_WRAP_W_WW(realloc)
+INTERCEPT_WRAP_W_WW(_realloc_base)
+INTERCEPT_WRAP_W_WWW(_realloc_dbg)
+INTERCEPT_WRAP_W_WWW(_recalloc)
+INTERCEPT_WRAP_W_WWW(_recalloc_base)
+
+INTERCEPT_WRAP_W_W(_msize)
+INTERCEPT_WRAP_W_W(_msize_base)
+INTERCEPT_WRAP_W_W(_expand)
+INTERCEPT_WRAP_W_W(_expand_dbg)
+
+// TODO(timurrrr): Might want to add support for _aligned_* allocation
+// functions to detect a bit more bugs. Those functions seem to wrap malloc().
+
+// TODO(timurrrr): Do we need to add _Crt* stuff here? (see asan_malloc_win.cpp)
+
+# if defined(_MSC_VER) && !defined(__clang__)
+// Disable warnings such as: 'void memchr(void)': incorrect number of arguments
+// for intrinsic function, expected '3' arguments.
+# pragma warning(push)
+# pragma warning(disable : 4392)
+# endif
+
+INTERCEPT_LIBRARY_FUNCTION(atoi);
+INTERCEPT_LIBRARY_FUNCTION(atol);
+INTERCEPT_LIBRARY_FUNCTION(atoll);
+INTERCEPT_LIBRARY_FUNCTION(frexp);
+INTERCEPT_LIBRARY_FUNCTION(longjmp);
+#if SANITIZER_INTERCEPT_MEMCHR
+INTERCEPT_LIBRARY_FUNCTION(memchr);
+#endif
+INTERCEPT_LIBRARY_FUNCTION(memcmp);
+INTERCEPT_LIBRARY_FUNCTION(memcpy);
+INTERCEPT_LIBRARY_FUNCTION(memmove);
+INTERCEPT_LIBRARY_FUNCTION(memset);
+INTERCEPT_LIBRARY_FUNCTION(strcat);
+INTERCEPT_LIBRARY_FUNCTION(strchr);
+INTERCEPT_LIBRARY_FUNCTION(strcmp);
+INTERCEPT_LIBRARY_FUNCTION(strcpy);
+INTERCEPT_LIBRARY_FUNCTION(strcspn);
+INTERCEPT_LIBRARY_FUNCTION(_strdup);
+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(strrchr);
+INTERCEPT_LIBRARY_FUNCTION(strspn);
+INTERCEPT_LIBRARY_FUNCTION(strstr);
+INTERCEPT_LIBRARY_FUNCTION(strtok);
+INTERCEPT_LIBRARY_FUNCTION(strtol);
+INTERCEPT_LIBRARY_FUNCTION(strtoll);
+INTERCEPT_LIBRARY_FUNCTION(wcslen);
+INTERCEPT_LIBRARY_FUNCTION(wcsnlen);
+
+# if defined(_MSC_VER) && !defined(__clang__)
+# pragma warning(pop)
+# endif
+
+#ifdef _WIN64
+INTERCEPT_LIBRARY_FUNCTION(__C_specific_handler);
+#else
+INTERCEPT_LIBRARY_FUNCTION(_except_handler3);
+// _except_handler4 checks -GS cookie which is
diff erent for each module, so we
+// can't use INTERCEPT_LIBRARY_FUNCTION(_except_handler4).
+INTERCEPTOR(int, _except_handler4, void *a, void *b, void *c, void *d) {
+ __asan_handle_no_return();
+ return REAL(_except_handler4)(a, b, c, d);
+}
+#endif
+
+// Windows specific functions not included in asan_interface.inc.
+INTERCEPT_WRAP_W_V(__asan_should_detect_stack_use_after_return)
+INTERCEPT_WRAP_W_V(__asan_get_shadow_memory_dynamic_address)
+INTERCEPT_WRAP_W_W(__asan_unhandled_exception_filter)
+
+using namespace __sanitizer;
+
+extern "C" {
+int __asan_option_detect_stack_use_after_return;
+uptr __asan_shadow_memory_dynamic_address;
+} // extern "C"
+
+static int asan_dll_thunk_init() {
+ typedef void (*fntype)();
+ static fntype fn = 0;
+ // asan_dll_thunk_init is expected to be called by only one thread.
+ if (fn) return 0;
+
+ // Ensure all interception was executed.
+ __dll_thunk_init();
+
+ fn = (fntype) dllThunkGetRealAddrOrDie("__asan_init");
+ fn();
+ __asan_option_detect_stack_use_after_return =
+ (__asan_should_detect_stack_use_after_return() != 0);
+ __asan_shadow_memory_dynamic_address =
+ (uptr)__asan_get_shadow_memory_dynamic_address();
+
+#ifndef _WIN64
+ INTERCEPT_FUNCTION(_except_handler4);
+#endif
+ // In DLLs, the callbacks are expected to return 0,
+ // otherwise CRT initialization fails.
+ return 0;
+}
+
+#pragma section(".CRT$XIB", long, read)
+__declspec(allocate(".CRT$XIB")) int (*__asan_preinit)() = asan_dll_thunk_init;
+
+static void WINAPI asan_thread_init(void *mod, unsigned long reason,
+ void *reserved) {
+ if (reason == /*DLL_PROCESS_ATTACH=*/1) asan_dll_thunk_init();
+}
+
+#pragma section(".CRT$XLAB", long, read)
+__declspec(allocate(".CRT$XLAB")) void (WINAPI *__asan_tls_init)(void *,
+ unsigned long, void *) = asan_thread_init;
+
+WIN_FORCE_LINK(__asan_dso_reg_hook)
+
+#endif // SANITIZER_DLL_THUNK
diff --git a/compiler-rt/lib/asan/asan_win_dynamic_runtime_thunk.cpp b/compiler-rt/lib/asan/asan_win_dynamic_runtime_thunk.cpp
index 421fe651b7d91..f0b5ec9eef7f9 100644
--- a/compiler-rt/lib/asan/asan_win_dynamic_runtime_thunk.cpp
+++ b/compiler-rt/lib/asan/asan_win_dynamic_runtime_thunk.cpp
@@ -8,17 +8,76 @@
//
// This file is a part of AddressSanitizer, an address sanity checker.
//
-// This file defines things that need to be present for application modules
-// that are dynamic linked with the C Runtime.
+// This file defines things that need to be present in the application modules
+// to interact with the ASan DLL runtime correctly and can't be implemented
+// using the default "import library" generated when linking the DLL RTL.
+//
+// This includes:
+// - creating weak aliases to default implementation imported from asan dll.
+// - forwarding the detect_stack_use_after_return runtime option
+// - working around deficiencies of the MD runtime
+// - installing a custom SEH handler
//
//===----------------------------------------------------------------------===//
#ifdef SANITIZER_DYNAMIC_RUNTIME_THUNK
-# define WIN32_LEAN_AND_MEAN
-# include <windows.h>
+#define SANITIZER_IMPORT_INTERFACE 1
+#include "sanitizer_common/sanitizer_win_defs.h"
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+
+// Define weak alias for all weak functions imported from asan dll.
+#define INTERFACE_FUNCTION(Name)
+#define INTERFACE_WEAK_FUNCTION(Name) WIN_WEAK_IMPORT_DEF(Name)
+#include "asan_interface.inc"
+
+// First, declare CRT sections we'll be using in this file
+#pragma section(".CRT$XIB", long, read)
+#pragma section(".CRT$XID", long, read)
+#pragma section(".CRT$XCAB", long, read)
+#pragma section(".CRT$XTW", long, read)
+#pragma section(".CRT$XTY", long, read)
+#pragma section(".CRT$XLAB", long, read)
+
+////////////////////////////////////////////////////////////////////////////////
+// Define a copy of __asan_option_detect_stack_use_after_return that should be
+// used when linking an MD runtime with a set of object files on Windows.
+//
+// The ASan MD runtime dllexports '__asan_option_detect_stack_use_after_return',
+// so normally we would just dllimport it. Unfortunately, the dllimport
+// attribute adds __imp_ prefix to the symbol name of a variable.
+// Since in general we don't know if a given TU is going to be used
+// with a MT or MD runtime and we don't want to use ugly __imp_ names on Windows
+// just to work around this issue, let's clone the variable that is constant
+// after initialization anyways.
+extern "C" {
+__declspec(dllimport) int __asan_should_detect_stack_use_after_return();
+int __asan_option_detect_stack_use_after_return;
+
+__declspec(dllimport) void* __asan_get_shadow_memory_dynamic_address();
+void* __asan_shadow_memory_dynamic_address;
+}
+
+static int InitializeClonedVariables() {
+ __asan_option_detect_stack_use_after_return =
+ __asan_should_detect_stack_use_after_return();
+ __asan_shadow_memory_dynamic_address =
+ __asan_get_shadow_memory_dynamic_address();
+ return 0;
+}
+
+static void NTAPI asan_thread_init(void *mod, unsigned long reason,
+ void *reserved) {
+ if (reason == DLL_PROCESS_ATTACH) InitializeClonedVariables();
+}
-# include "asan_win_common_runtime_thunk.h"
-# include "sanitizer_common/sanitizer_win_defs.h"
+// Our cloned variables must be initialized before C/C++ constructors. If TLS
+// is used, our .CRT$XLAB initializer will run first. If not, our .CRT$XIB
+// initializer is needed as a backup.
+__declspec(allocate(".CRT$XIB")) int (*__asan_initialize_cloned_variables)() =
+ InitializeClonedVariables;
+__declspec(allocate(".CRT$XLAB")) void (NTAPI *__asan_tls_init)(void *,
+ unsigned long, void *) = asan_thread_init;
////////////////////////////////////////////////////////////////////////////////
// For some reason, the MD CRT doesn't call the C/C++ terminators during on DLL
@@ -29,26 +88,43 @@
// using atexit() that calls a small subset of C terminators
// where LLVM global_dtors is placed. Fingers crossed, no other C terminators
// are there.
-extern "C" int __cdecl atexit(void(__cdecl *f)(void));
+extern "C" int __cdecl atexit(void (__cdecl *f)(void));
extern "C" void __cdecl _initterm(void *a, void *b);
namespace {
-__declspec(allocate(".CRT$XTW")) void *before_global_dtors = 0;
-__declspec(allocate(".CRT$XTY")) void *after_global_dtors = 0;
+__declspec(allocate(".CRT$XTW")) void* before_global_dtors = 0;
+__declspec(allocate(".CRT$XTY")) void* after_global_dtors = 0;
void UnregisterGlobals() {
_initterm(&before_global_dtors, &after_global_dtors);
}
-int ScheduleUnregisterGlobals() { return atexit(UnregisterGlobals); }
+int ScheduleUnregisterGlobals() {
+ return atexit(UnregisterGlobals);
+}
} // namespace
// We need to call 'atexit(UnregisterGlobals);' as early as possible, but after
// atexit() is initialized (.CRT$XIC). As this is executed before C++
// initializers (think ctors for globals), UnregisterGlobals gets executed after
// dtors for C++ globals.
-extern "C" __declspec(allocate(".CRT$XID")) int (
- *__asan_schedule_unregister_globals)() = ScheduleUnregisterGlobals;
-WIN_FORCE_LINK(__asan_schedule_unregister_globals)
+__declspec(allocate(".CRT$XID"))
+int (*__asan_schedule_unregister_globals)() = ScheduleUnregisterGlobals;
+
+////////////////////////////////////////////////////////////////////////////////
+// ASan SEH handling.
+// We need to set the ASan-specific SEH handler at the end of CRT initialization
+// of each module (see also asan_win.cpp).
+extern "C" {
+__declspec(dllimport) int __asan_set_seh_filter();
+static int SetSEHFilter() { return __asan_set_seh_filter(); }
+
+// Unfortunately, putting a pointer to __asan_set_seh_filter into
+// __asan_intercept_seh gets optimized out, so we have to use an extra function.
+__declspec(allocate(".CRT$XCAB")) int (*__asan_seh_interceptor)() =
+ SetSEHFilter;
+}
+
+WIN_FORCE_LINK(__asan_dso_reg_hook)
-#endif // SANITIZER_DYNAMIC_RUNTIME_THUNK
+#endif // SANITIZER_DYNAMIC_RUNTIME_THUNK
diff --git a/compiler-rt/lib/asan/asan_win_static_runtime_thunk.cpp b/compiler-rt/lib/asan/asan_win_static_runtime_thunk.cpp
deleted file mode 100644
index dec50a5e1d4d9..0000000000000
--- a/compiler-rt/lib/asan/asan_win_static_runtime_thunk.cpp
+++ /dev/null
@@ -1,110 +0,0 @@
-//===-- asan_win_static_runtime_thunk.cpp ---------------------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-//
-// This file is a part of AddressSanitizer, an address sanity checker.
-//
-// This file defines a family of thunks that should be statically linked into
-// modules that are statically linked with the C Runtime in order to delegate
-// the calls to the ASAN runtime DLL.
-// See https://github.com/google/sanitizers/issues/209 for the details.
-//===----------------------------------------------------------------------===//
-
-#ifdef SANITIZER_STATIC_RUNTIME_THUNK
-# include "asan_init_version.h"
-# include "asan_interface_internal.h"
-# include "asan_win_common_runtime_thunk.h"
-# include "sanitizer_common/sanitizer_platform_interceptors.h"
-# include "sanitizer_common/sanitizer_win_defs.h"
-# include "sanitizer_common/sanitizer_win_thunk_interception.h"
-
-# if defined(_MSC_VER) && !defined(__clang__)
-// Disable warnings such as: 'void memchr(void)': incorrect number of arguments
-// for intrinsic function, expected '3' arguments.
-# pragma warning(push)
-# pragma warning(disable : 4392)
-# endif
-
-# define INTERCEPT_LIBRARY_FUNCTION_ASAN(X) \
- INTERCEPT_LIBRARY_FUNCTION(X, "__asan_wrap_" #X)
-
-INTERCEPT_LIBRARY_FUNCTION_ASAN(atoi);
-INTERCEPT_LIBRARY_FUNCTION_ASAN(atol);
-INTERCEPT_LIBRARY_FUNCTION_ASAN(atoll);
-INTERCEPT_LIBRARY_FUNCTION_ASAN(frexp);
-INTERCEPT_LIBRARY_FUNCTION_ASAN(longjmp);
-# if SANITIZER_INTERCEPT_MEMCHR
-INTERCEPT_LIBRARY_FUNCTION_ASAN(memchr);
-# endif
-INTERCEPT_LIBRARY_FUNCTION_ASAN(memcmp);
-INTERCEPT_LIBRARY_FUNCTION_ASAN(memcpy);
-# ifndef _WIN64
-// memmove and memcpy share an implementation on amd64
-INTERCEPT_LIBRARY_FUNCTION_ASAN(memmove);
-# endif
-INTERCEPT_LIBRARY_FUNCTION_ASAN(memset);
-INTERCEPT_LIBRARY_FUNCTION_ASAN(strcat);
-INTERCEPT_LIBRARY_FUNCTION_ASAN(strchr);
-INTERCEPT_LIBRARY_FUNCTION_ASAN(strcmp);
-INTERCEPT_LIBRARY_FUNCTION_ASAN(strcpy);
-INTERCEPT_LIBRARY_FUNCTION_ASAN(strcspn);
-INTERCEPT_LIBRARY_FUNCTION_ASAN(_strdup);
-INTERCEPT_LIBRARY_FUNCTION_ASAN(strlen);
-INTERCEPT_LIBRARY_FUNCTION_ASAN(strncat);
-INTERCEPT_LIBRARY_FUNCTION_ASAN(strncmp);
-INTERCEPT_LIBRARY_FUNCTION_ASAN(strncpy);
-INTERCEPT_LIBRARY_FUNCTION_ASAN(strnlen);
-INTERCEPT_LIBRARY_FUNCTION_ASAN(strpbrk);
-// INTERCEPT_LIBRARY_FUNCTION_ASAN(strrchr);
-INTERCEPT_LIBRARY_FUNCTION_ASAN(strspn);
-INTERCEPT_LIBRARY_FUNCTION_ASAN(strstr);
-INTERCEPT_LIBRARY_FUNCTION_ASAN(strtok);
-INTERCEPT_LIBRARY_FUNCTION_ASAN(strtol);
-INTERCEPT_LIBRARY_FUNCTION_ASAN(wcslen);
-INTERCEPT_LIBRARY_FUNCTION_ASAN(wcsnlen);
-
-# if defined(_MSC_VER) && !defined(__clang__)
-# pragma warning(pop)
-# endif
-
-# ifdef _WIN64
-INTERCEPT_LIBRARY_FUNCTION_ASAN(__C_specific_handler);
-# else
-extern "C" void abort();
-INTERCEPT_LIBRARY_FUNCTION_ASAN(_except_handler3);
-// _except_handler4 checks -GS cookie which is
diff erent for each module, so we
-// can't use INTERCEPT_LIBRARY_FUNCTION_ASAN(_except_handler4), need to apply
-// manually
-extern "C" int _except_handler4(void *, void *, void *, void *);
-static int (*real_except_handler4)(void *, void *, void *,
- void *) = &_except_handler4;
-static int intercept_except_handler4(void *a, void *b, void *c, void *d) {
- __asan_handle_no_return();
- return real_except_handler4(a, b, c, d);
-}
-# endif
-
-// Windows specific functions not included in asan_interface.inc.
-// INTERCEPT_WRAP_W_V(__asan_should_detect_stack_use_after_return)
-// INTERCEPT_WRAP_W_V(__asan_get_shadow_memory_dynamic_address)
-// INTERCEPT_WRAP_W_W(__asan_unhandled_exception_filter)
-
-extern "C" void __asan_initialize_static_thunk() {
-# ifndef _WIN64
- if (real_except_handler4 == &_except_handler4) {
- // Single threaded, no need for synchronization.
- if (!__sanitizer_override_function_by_addr(
- reinterpret_cast<__sanitizer::uptr>(&intercept_except_handler4),
- reinterpret_cast<__sanitizer::uptr>(&_except_handler4),
- reinterpret_cast<__sanitizer::uptr*>(&real_except_handler4))) {
- abort();
- }
- }
-# endif
-}
-
-#endif // SANITIZER_DLL_THUNK
diff --git a/compiler-rt/lib/asan/tests/CMakeLists.txt b/compiler-rt/lib/asan/tests/CMakeLists.txt
index 9c1db7caeb7b7..bda47bd7fd6a2 100644
--- a/compiler-rt/lib/asan/tests/CMakeLists.txt
+++ b/compiler-rt/lib/asan/tests/CMakeLists.txt
@@ -203,7 +203,7 @@ function(add_asan_tests arch test_runtime)
CFLAGS ${ASAN_UNITTEST_INSTRUMENTED_CFLAGS} -D_MT -D_DLL
SOURCES ${ASAN_INST_TEST_SOURCES}
LINK_FLAGS ${ASAN_DYNAMIC_UNITTEST_INSTRUMENTED_LINK_FLAGS}
- -D_MT -D_DLL -Wl,-nodefaultlib:libcmt,-defaultlib:msvcrt,-defaultlib:oldnames
+ -Wl,-nodefaultlib:libcmt,-defaultlib:msvcrt,-defaultlib:oldnames
)
else()
diff --git a/compiler-rt/lib/profile/CMakeLists.txt b/compiler-rt/lib/profile/CMakeLists.txt
index ef23492514898..45e5164891751 100644
--- a/compiler-rt/lib/profile/CMakeLists.txt
+++ b/compiler-rt/lib/profile/CMakeLists.txt
@@ -111,12 +111,6 @@ if(COMPILER_RT_TARGET_HAS_UNAME)
-DCOMPILER_RT_HAS_UNAME=1)
endif()
-if(MSVC)
- # profile historically has only been supported with the static runtime
- # on windows
- set(CMAKE_MSVC_RUNTIME_LIBRARY MultiThreaded)
-endif()
-
# We don't use the C++ Standard Library here, so avoid including it by mistake.
append_list_if(COMPILER_RT_HAS_NOSTDINCXX_FLAG -nostdinc++ EXTRA_FLAGS)
# XRay uses C++ standard library headers.
diff --git a/compiler-rt/lib/sanitizer_common/CMakeLists.txt b/compiler-rt/lib/sanitizer_common/CMakeLists.txt
index 41c3888275a0f..66f2d259aa5fd 100644
--- a/compiler-rt/lib/sanitizer_common/CMakeLists.txt
+++ b/compiler-rt/lib/sanitizer_common/CMakeLists.txt
@@ -42,7 +42,6 @@ set(SANITIZER_SOURCES_NOTERMINATION
sanitizer_thread_registry.cpp
sanitizer_type_traits.cpp
sanitizer_win.cpp
- sanitizer_win_interception.cpp
)
set(SANITIZER_SOURCES
@@ -207,8 +206,8 @@ set(SANITIZER_IMPL_HEADERS
sanitizer_vector.h
sanitizer_win.h
sanitizer_win_defs.h
- sanitizer_win_interception.h
- sanitizer_win_thunk_interception.h
+ sanitizer_win_dll_thunk.h
+ sanitizer_win_weak_interception.h
)
include_directories(..)
@@ -302,23 +301,57 @@ add_compiler_rt_object_libraries(RTSanitizerCommonSymbolizerNoHooks
DEFS ${SANITIZER_COMMON_DEFINITIONS})
if(WIN32)
- set(RUNTIME_THUNK_CFLAGS -DSANITIZER_DYNAMIC_RUNTIME_THUNK -DSANITIZER_STATIC_RUNTIME_THUNK)
- append_list_if(MSVC /Zl RUNTIME_THUNK_CFLAGS)
- add_compiler_rt_object_libraries(SanitizerRuntimeThunk
+ add_compiler_rt_object_libraries(SanitizerCommonWeakInterception
${SANITIZER_COMMON_SUPPORTED_OS}
ARCHS ${SANITIZER_COMMON_SUPPORTED_ARCH}
SOURCES
- sanitizer_win_thunk_interception.cpp
- CFLAGS ${SANITIZER_CFLAGS} ${RUNTIME_THUNK_CFLAGS}
+ sanitizer_win_weak_interception.cpp
+ CFLAGS ${SANITIZER_CFLAGS} -DSANITIZER_DYNAMIC
+ DEFS ${SANITIZER_COMMON_DEFINITIONS})
+ add_compiler_rt_object_libraries(SancovWeakInterception
+ ${SANITIZER_COMMON_SUPPORTED_OS}
+ ARCHS ${SANITIZER_COMMON_SUPPORTED_ARCH}
+ SOURCES
+ sanitizer_coverage_win_weak_interception.cpp
+ CFLAGS ${SANITIZER_CFLAGS} -DSANITIZER_DYNAMIC
+ DEFS ${SANITIZER_COMMON_DEFINITIONS})
+
+ add_compiler_rt_object_libraries(SanitizerCommonDllThunk
+ ${SANITIZER_COMMON_SUPPORTED_OS}
+ ARCHS ${SANITIZER_COMMON_SUPPORTED_ARCH}
+ SOURCES
+ sanitizer_win_dll_thunk.cpp
+ CFLAGS ${SANITIZER_CFLAGS} -DSANITIZER_DLL_THUNK
+ DEFS ${SANITIZER_COMMON_DEFINITIONS})
+ add_compiler_rt_object_libraries(SancovDllThunk
+ ${SANITIZER_COMMON_SUPPORTED_OS}
+ ARCHS ${SANITIZER_COMMON_SUPPORTED_ARCH}
+ SOURCES
+ sanitizer_coverage_win_dll_thunk.cpp
+ sanitizer_coverage_win_sections.cpp
+ CFLAGS ${SANITIZER_CFLAGS} -DSANITIZER_DLL_THUNK
DEFS ${SANITIZER_COMMON_DEFINITIONS})
- add_compiler_rt_object_libraries(SancovRuntimeThunk
+ set(DYNAMIC_RUNTIME_THUNK_CFLAGS "-DSANITIZER_DYNAMIC_RUNTIME_THUNK")
+ if(MSVC)
+ list(APPEND DYNAMIC_RUNTIME_THUNK_CFLAGS "-Zl")
+ elseif(CMAKE_C_COMPILER_ID MATCHES Clang)
+ list(APPEND DYNAMIC_RUNTIME_THUNK_CFLAGS "-nodefaultlibs")
+ endif()
+ add_compiler_rt_object_libraries(SanitizerCommonDynamicRuntimeThunk
+ ${SANITIZER_COMMON_SUPPORTED_OS}
+ ARCHS ${SANITIZER_COMMON_SUPPORTED_ARCH}
+ SOURCES
+ sanitizer_win_dynamic_runtime_thunk.cpp
+ CFLAGS ${SANITIZER_CFLAGS} ${DYNAMIC_RUNTIME_THUNK_CFLAGS}
+ DEFS ${SANITIZER_COMMON_DEFINITIONS})
+ add_compiler_rt_object_libraries(SancovDynamicRuntimeThunk
${SANITIZER_COMMON_SUPPORTED_OS}
ARCHS ${SANITIZER_COMMON_SUPPORTED_ARCH}
SOURCES
- sanitizer_coverage_win_runtime_thunk.cpp
+ sanitizer_coverage_win_dynamic_runtime_thunk.cpp
sanitizer_coverage_win_sections.cpp
- CFLAGS ${SANITIZER_CFLAGS} ${RUNTIME_THUNK_CFLAGS}
+ CFLAGS ${SANITIZER_CFLAGS} ${DYNAMIC_RUNTIME_THUNK_CFLAGS}
DEFS ${SANITIZER_COMMON_DEFINITIONS})
endif()
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_common_interface.inc b/compiler-rt/lib/sanitizer_common/sanitizer_common_interface.inc
index 11f1d963bd6f4..557207fe62ac6 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_common_interface.inc
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_common_interface.inc
@@ -50,9 +50,3 @@ INTERFACE_WEAK_FUNCTION(__sanitizer_malloc_hook)
INTERFACE_FUNCTION(__sanitizer_internal_memcpy)
INTERFACE_FUNCTION(__sanitizer_internal_memmove)
INTERFACE_FUNCTION(__sanitizer_internal_memset)
-
-#if SANITIZER_WINDOWS
-INTERFACE_FUNCTION(__sanitizer_override_function)
-INTERFACE_FUNCTION(__sanitizer_override_function_by_addr)
-INTERFACE_FUNCTION(__sanitizer_register_weak_function)
-#endif
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_coverage_win_dll_thunk.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_coverage_win_dll_thunk.cpp
new file mode 100644
index 0000000000000..d0bf8a4556436
--- /dev/null
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_coverage_win_dll_thunk.cpp
@@ -0,0 +1,20 @@
+//===-- sanitizer_coverage_win_dll_thunk.cpp ------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines a family of thunks that should be statically linked into
+// the DLLs that have instrumentation in order to delegate the calls to the
+// shared runtime that lives in the main binary.
+// See https://github.com/google/sanitizers/issues/209 for the details.
+//===----------------------------------------------------------------------===//
+#ifdef SANITIZER_DLL_THUNK
+#include "sanitizer_win_dll_thunk.h"
+// Sanitizer Coverage interface functions.
+#define INTERFACE_FUNCTION(Name) INTERCEPT_SANITIZER_FUNCTION(Name)
+#define INTERFACE_WEAK_FUNCTION(Name) INTERCEPT_SANITIZER_WEAK_FUNCTION(Name)
+#include "sanitizer_coverage_interface.inc"
+#endif // SANITIZER_DLL_THUNK
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_coverage_win_runtime_thunk.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_coverage_win_dynamic_runtime_thunk.cpp
similarity index 59%
rename from compiler-rt/lib/sanitizer_common/sanitizer_coverage_win_runtime_thunk.cpp
rename to compiler-rt/lib/sanitizer_common/sanitizer_coverage_win_dynamic_runtime_thunk.cpp
index 281944643f216..0bdf0c5aed418 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_coverage_win_runtime_thunk.cpp
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_coverage_win_dynamic_runtime_thunk.cpp
@@ -1,4 +1,4 @@
-//===-- sanitizer_coverage_win_runtime_thunk.cpp --------------------------===//
+//===-- sanitizer_coverage_win_dynamic_runtime_thunk.cpp ------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -10,20 +10,17 @@
// to interact with Sanitizer Coverage, when it is included in a dll.
//
//===----------------------------------------------------------------------===//
-#if defined(SANITIZER_DYNAMIC_RUNTIME_THUNK) || \
- defined(SANITIZER_STATIC_RUNTIME_THUNK)
-# define SANITIZER_IMPORT_INTERFACE 1
-# include "sanitizer_win_defs.h"
-# include "sanitizer_win_thunk_interception.h"
+#ifdef SANITIZER_DYNAMIC_RUNTIME_THUNK
+#define SANITIZER_IMPORT_INTERFACE 1
+#include "sanitizer_win_defs.h"
// Define weak alias for all weak functions imported from sanitizer coverage.
-# define INTERFACE_FUNCTION(Name)
-# define INTERFACE_WEAK_FUNCTION(Name) REGISTER_WEAK_FUNCTION(Name)
-# include "sanitizer_coverage_interface.inc"
-#endif // defined(SANITIZER_DYNAMIC_RUNTIME_THUNK) ||
- // defined(SANITIZER_STATIC_RUNTIME_THUNK)
+#define INTERFACE_FUNCTION(Name)
+#define INTERFACE_WEAK_FUNCTION(Name) WIN_WEAK_IMPORT_DEF(Name)
+#include "sanitizer_coverage_interface.inc"
+#endif // SANITIZER_DYNAMIC_RUNTIME_THUNK
namespace __sanitizer {
// Add one, otherwise unused, external symbol to this object file so that the
// Visual C++ linker includes it and reads the .drective section.
void ForceWholeArchiveIncludeForSanCov() {}
-} // namespace __sanitizer
+}
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_coverage_win_weak_interception.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_coverage_win_weak_interception.cpp
new file mode 100644
index 0000000000000..55263981705fa
--- /dev/null
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_coverage_win_weak_interception.cpp
@@ -0,0 +1,23 @@
+//===-- sanitizer_coverage_win_weak_interception.cpp ----------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+// This module should be included in Sanitizer Coverage when it implemented as a
+// shared library on Windows (dll), in order to delegate the calls of weak
+// functions to the implementation in the main executable when a strong
+// definition is provided.
+//===----------------------------------------------------------------------===//
+#ifdef SANITIZER_DYNAMIC
+#include "sanitizer_win_weak_interception.h"
+#include "sanitizer_interface_internal.h"
+#include "sancov_flags.h"
+// Check if strong definitions for weak functions are present in the main
+// executable. If that is the case, override dll functions to point to strong
+// implementations.
+#define INTERFACE_FUNCTION(Name)
+#define INTERFACE_WEAK_FUNCTION(Name) INTERCEPT_SANITIZER_WEAK_FUNCTION(Name)
+#include "sanitizer_coverage_interface.inc"
+#endif // SANITIZER_DYNAMIC
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_win_dll_thunk.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_win_dll_thunk.cpp
new file mode 100644
index 0000000000000..1562c161a7626
--- /dev/null
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_win_dll_thunk.cpp
@@ -0,0 +1,101 @@
+//===-- sanitizer_win_dll_thunk.cpp ---------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+// This file defines a family of thunks that should be statically linked into
+// the DLLs that have instrumentation in order to delegate the calls to the
+// shared runtime that lives in the main binary.
+// See https://github.com/google/sanitizers/issues/209 for the details.
+//===----------------------------------------------------------------------===//
+
+#ifdef SANITIZER_DLL_THUNK
+#include "sanitizer_win_defs.h"
+#include "sanitizer_win_dll_thunk.h"
+#include "interception/interception.h"
+
+extern "C" {
+void *WINAPI GetModuleHandleA(const char *module_name);
+void abort();
+}
+
+namespace __sanitizer {
+uptr dllThunkGetRealAddrOrDie(const char *name) {
+ uptr ret =
+ __interception::InternalGetProcAddress((void *)GetModuleHandleA(0), name);
+ if (!ret)
+ abort();
+ return ret;
+}
+
+int dllThunkIntercept(const char* main_function, uptr dll_function) {
+ uptr wrapper = dllThunkGetRealAddrOrDie(main_function);
+ if (!__interception::OverrideFunction(dll_function, wrapper, 0))
+ abort();
+ return 0;
+}
+
+int dllThunkInterceptWhenPossible(const char* main_function,
+ const char* default_function, uptr dll_function) {
+ uptr wrapper = __interception::InternalGetProcAddress(
+ (void *)GetModuleHandleA(0), main_function);
+ if (!wrapper)
+ wrapper = dllThunkGetRealAddrOrDie(default_function);
+ if (!__interception::OverrideFunction(dll_function, wrapper, 0))
+ abort();
+ return 0;
+}
+} // namespace __sanitizer
+
+// Include Sanitizer Common interface.
+#define INTERFACE_FUNCTION(Name) INTERCEPT_SANITIZER_FUNCTION(Name)
+#define INTERFACE_WEAK_FUNCTION(Name) INTERCEPT_SANITIZER_WEAK_FUNCTION(Name)
+#include "sanitizer_common_interface.inc"
+
+#pragma section(".DLLTH$A", read)
+#pragma section(".DLLTH$Z", read)
+
+typedef void (*DllThunkCB)();
+extern "C" {
+__declspec(allocate(".DLLTH$A")) DllThunkCB __start_dll_thunk;
+__declspec(allocate(".DLLTH$Z")) DllThunkCB __stop_dll_thunk;
+}
+
+// Disable compiler warnings that show up if we declare our own version
+// of a compiler intrinsic (e.g. strlen).
+#pragma warning(disable: 4391)
+#pragma warning(disable: 4392)
+
+extern "C" int __dll_thunk_init() {
+ static bool flag = false;
+ // __dll_thunk_init is expected to be called by only one thread.
+ if (flag) return 0;
+ flag = true;
+
+ for (DllThunkCB *it = &__start_dll_thunk; it < &__stop_dll_thunk; ++it)
+ if (*it)
+ (*it)();
+
+ // In DLLs, the callbacks are expected to return 0,
+ // otherwise CRT initialization fails.
+ return 0;
+}
+
+// We want to call dll_thunk_init before C/C++ initializers / constructors are
+// executed, otherwise functions like memset might be invoked.
+#pragma section(".CRT$XIB", long, read)
+__declspec(allocate(".CRT$XIB")) int (*__dll_thunk_preinit)() =
+ __dll_thunk_init;
+
+static void WINAPI dll_thunk_thread_init(void *mod, unsigned long reason,
+ void *reserved) {
+ if (reason == /*DLL_PROCESS_ATTACH=*/1) __dll_thunk_init();
+}
+
+#pragma section(".CRT$XLAB", long, read)
+__declspec(allocate(".CRT$XLAB")) void (WINAPI *__dll_thunk_tls_init)(void *,
+ unsigned long, void *) = dll_thunk_thread_init;
+
+#endif // SANITIZER_DLL_THUNK
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_win_dll_thunk.h b/compiler-rt/lib/sanitizer_common/sanitizer_win_dll_thunk.h
new file mode 100644
index 0000000000000..639d91a2edaec
--- /dev/null
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_win_dll_thunk.h
@@ -0,0 +1,181 @@
+//===-- sanitizer_win_dll_thunk.h -----------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+// This header provide helper macros to delegate calls to the shared runtime
+// that lives in the main executable. It should be included to dll_thunks that
+// will be linked to the dlls, when the sanitizer is a static library included
+// in the main executable.
+//===----------------------------------------------------------------------===//
+#ifndef SANITIZER_WIN_DLL_THUNK_H
+#define SANITIZER_WIN_DLL_THUNK_H
+#include "sanitizer_internal_defs.h"
+
+namespace __sanitizer {
+uptr dllThunkGetRealAddrOrDie(const char *name);
+
+int dllThunkIntercept(const char* main_function, uptr dll_function);
+
+int dllThunkInterceptWhenPossible(const char* main_function,
+ const char* default_function, uptr dll_function);
+}
+
+extern "C" int __dll_thunk_init();
+
+// ----------------- Function interception helper macros -------------------- //
+// Override dll_function with main_function from main executable.
+#define INTERCEPT_OR_DIE(main_function, dll_function) \
+ static int intercept_##dll_function() { \
+ return __sanitizer::dllThunkIntercept(main_function, (__sanitizer::uptr) \
+ dll_function); \
+ } \
+ __pragma(section(".DLLTH$M", long, read)) \
+ __declspec(allocate(".DLLTH$M")) int (*__dll_thunk_##dll_function)() = \
+ intercept_##dll_function;
+
+// Try to override dll_function with main_function from main executable.
+// If main_function is not present, override dll_function with default_function.
+#define INTERCEPT_WHEN_POSSIBLE(main_function, default_function, dll_function) \
+ static int intercept_##dll_function() { \
+ return __sanitizer::dllThunkInterceptWhenPossible(main_function, \
+ default_function, (__sanitizer::uptr)dll_function); \
+ } \
+ __pragma(section(".DLLTH$M", long, read)) \
+ __declspec(allocate(".DLLTH$M")) int (*__dll_thunk_##dll_function)() = \
+ intercept_##dll_function;
+
+// -------------------- Function interception macros ------------------------ //
+// Special case of hooks -- ASan own interface functions. Those are only called
+// after __asan_init, thus an empty implementation is sufficient.
+#define INTERCEPT_SANITIZER_FUNCTION(name) \
+ extern "C" __declspec(noinline) void name() { \
+ volatile int prevent_icf = (__LINE__ << 8) ^ __COUNTER__; \
+ static const char function_name[] = #name; \
+ for (const char* ptr = &function_name[0]; *ptr; ++ptr) \
+ prevent_icf ^= *ptr; \
+ (void)prevent_icf; \
+ __debugbreak(); \
+ } \
+ INTERCEPT_OR_DIE(#name, name)
+
+// Special case of hooks -- Weak functions, could be redefined in the main
+// executable, but that is not necessary, so we shouldn't die if we can not find
+// a reference. Instead, when the function is not present in the main executable
+// we consider the default impl provided by asan library.
+#define INTERCEPT_SANITIZER_WEAK_FUNCTION(name) \
+ extern "C" __declspec(noinline) void name() { \
+ volatile int prevent_icf = (__LINE__ << 8) ^ __COUNTER__; \
+ static const char function_name[] = #name; \
+ for (const char* ptr = &function_name[0]; *ptr; ++ptr) \
+ prevent_icf ^= *ptr; \
+ (void)prevent_icf; \
+ __debugbreak(); \
+ } \
+ INTERCEPT_WHEN_POSSIBLE(#name, STRINGIFY(WEAK_EXPORT_NAME(name)), name)
+
+// We can't define our own version of strlen etc. because that would lead to
+// link-time or even type mismatch errors. Instead, we can declare a function
+// just to be able to get its address. Me may miss the first few calls to the
+// functions since it can be called before __dll_thunk_init, but that would lead
+// to false negatives in the startup code before user's global initializers,
+// which isn't a big deal.
+#define INTERCEPT_LIBRARY_FUNCTION(name) \
+ extern "C" void name(); \
+ INTERCEPT_OR_DIE(STRINGIFY(WRAP(name)), name)
+
+// Use these macros for functions that could be called before __dll_thunk_init()
+// is executed and don't lead to errors if defined (free, malloc, etc).
+#define INTERCEPT_WRAP_V_V(name) \
+ extern "C" void name() { \
+ typedef decltype(name) *fntype; \
+ static fntype fn = (fntype)__sanitizer::dllThunkGetRealAddrOrDie(#name); \
+ fn(); \
+ } \
+ INTERCEPT_OR_DIE(#name, name);
+
+#define INTERCEPT_WRAP_V_W(name) \
+ extern "C" void name(void *arg) { \
+ typedef decltype(name) *fntype; \
+ static fntype fn = (fntype)__sanitizer::dllThunkGetRealAddrOrDie(#name); \
+ fn(arg); \
+ } \
+ INTERCEPT_OR_DIE(#name, name);
+
+#define INTERCEPT_WRAP_V_WW(name) \
+ extern "C" void name(void *arg1, void *arg2) { \
+ typedef decltype(name) *fntype; \
+ static fntype fn = (fntype)__sanitizer::dllThunkGetRealAddrOrDie(#name); \
+ fn(arg1, arg2); \
+ } \
+ INTERCEPT_OR_DIE(#name, name);
+
+#define INTERCEPT_WRAP_V_WWW(name) \
+ extern "C" void name(void *arg1, void *arg2, void *arg3) { \
+ typedef decltype(name) *fntype; \
+ static fntype fn = (fntype)__sanitizer::dllThunkGetRealAddrOrDie(#name); \
+ fn(arg1, arg2, arg3); \
+ } \
+ INTERCEPT_OR_DIE(#name, name);
+
+#define INTERCEPT_WRAP_W_V(name) \
+ extern "C" void *name() { \
+ typedef decltype(name) *fntype; \
+ static fntype fn = (fntype)__sanitizer::dllThunkGetRealAddrOrDie(#name); \
+ return fn(); \
+ } \
+ INTERCEPT_OR_DIE(#name, name);
+
+#define INTERCEPT_WRAP_W_W(name) \
+ extern "C" void *name(void *arg) { \
+ typedef decltype(name) *fntype; \
+ static fntype fn = (fntype)__sanitizer::dllThunkGetRealAddrOrDie(#name); \
+ return fn(arg); \
+ } \
+ INTERCEPT_OR_DIE(#name, name);
+
+#define INTERCEPT_WRAP_W_WW(name) \
+ extern "C" void *name(void *arg1, void *arg2) { \
+ typedef decltype(name) *fntype; \
+ static fntype fn = (fntype)__sanitizer::dllThunkGetRealAddrOrDie(#name); \
+ return fn(arg1, arg2); \
+ } \
+ INTERCEPT_OR_DIE(#name, name);
+
+#define INTERCEPT_WRAP_W_WWW(name) \
+ extern "C" void *name(void *arg1, void *arg2, void *arg3) { \
+ typedef decltype(name) *fntype; \
+ static fntype fn = (fntype)__sanitizer::dllThunkGetRealAddrOrDie(#name); \
+ return fn(arg1, arg2, arg3); \
+ } \
+ INTERCEPT_OR_DIE(#name, name);
+
+#define INTERCEPT_WRAP_W_WWWW(name) \
+ extern "C" void *name(void *arg1, void *arg2, void *arg3, void *arg4) { \
+ typedef decltype(name) *fntype; \
+ static fntype fn = (fntype)__sanitizer::dllThunkGetRealAddrOrDie(#name); \
+ return fn(arg1, arg2, arg3, arg4); \
+ } \
+ INTERCEPT_OR_DIE(#name, name);
+
+#define INTERCEPT_WRAP_W_WWWWW(name) \
+ extern "C" void *name(void *arg1, void *arg2, void *arg3, void *arg4, \
+ void *arg5) { \
+ typedef decltype(name) *fntype; \
+ static fntype fn = (fntype)__sanitizer::dllThunkGetRealAddrOrDie(#name); \
+ return fn(arg1, arg2, arg3, arg4, arg5); \
+ } \
+ INTERCEPT_OR_DIE(#name, name);
+
+#define INTERCEPT_WRAP_W_WWWWWW(name) \
+ extern "C" void *name(void *arg1, void *arg2, void *arg3, void *arg4, \
+ void *arg5, void *arg6) { \
+ typedef decltype(name) *fntype; \
+ static fntype fn = (fntype)__sanitizer::dllThunkGetRealAddrOrDie(#name); \
+ return fn(arg1, arg2, arg3, arg4, arg5, arg6); \
+ } \
+ INTERCEPT_OR_DIE(#name, name);
+
+#endif // SANITIZER_WIN_DLL_THUNK_H
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_win_dynamic_runtime_thunk.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_win_dynamic_runtime_thunk.cpp
new file mode 100644
index 0000000000000..87c032c6e61bc
--- /dev/null
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_win_dynamic_runtime_thunk.cpp
@@ -0,0 +1,26 @@
+//===-- santizer_win_dynamic_runtime_thunk.cpp ----------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines things that need to be present in the application modules
+// to interact with Sanitizer Common, when it is included in a dll.
+//
+//===----------------------------------------------------------------------===//
+#ifdef SANITIZER_DYNAMIC_RUNTIME_THUNK
+#define SANITIZER_IMPORT_INTERFACE 1
+#include "sanitizer_win_defs.h"
+// Define weak alias for all weak functions imported from sanitizer common.
+#define INTERFACE_FUNCTION(Name)
+#define INTERFACE_WEAK_FUNCTION(Name) WIN_WEAK_IMPORT_DEF(Name)
+#include "sanitizer_common_interface.inc"
+#endif // SANITIZER_DYNAMIC_RUNTIME_THUNK
+
+namespace __sanitizer {
+// Add one, otherwise unused, external symbol to this object file so that the
+// Visual C++ linker includes it and reads the .drective section.
+void ForceWholeArchiveIncludeForSanitizerCommon() {}
+}
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_win_immortalize.h b/compiler-rt/lib/sanitizer_common/sanitizer_win_immortalize.h
deleted file mode 100644
index 808cd2f771fe1..0000000000000
--- a/compiler-rt/lib/sanitizer_common/sanitizer_win_immortalize.h
+++ /dev/null
@@ -1,71 +0,0 @@
-//===-- sanitizer_win_immortalize.h ---------------------------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-//
-// This file is shared between AddressSanitizer, and interception.
-//
-// Windows-specific thread-safe and pre-CRT global initialization safe
-// infrastructure to create an object whose destructor is never called.
-//===----------------------------------------------------------------------===//
-#if SANITIZER_WINDOWS
-# pragma once
-// Requires including sanitizer_placement_new.h (which is not allowed to be
-// included in headers).
-
-# include "sanitizer_win_defs.h"
-// These types are required to satisfy XFG which requires that the names of the
-// types for indirect calls to be correct as well as the name of the original
-// type for any typedefs.
-
-// TODO: There must be a better way to do this
-# ifndef _WINDOWS_
-typedef void* PVOID;
-typedef int BOOL;
-typedef union _RTL_RUN_ONCE {
- PVOID ptr;
-} INIT_ONCE, *PINIT_ONCE;
-
-extern "C" {
-__declspec(dllimport) int WINAPI InitOnceExecuteOnce(
- PINIT_ONCE, BOOL(WINAPI*)(PINIT_ONCE, PVOID, PVOID*), void*, void*);
-}
-# endif
-
-namespace __sanitizer {
-template <class Ty>
-BOOL WINAPI immortalize_impl(PINIT_ONCE, PVOID storage_ptr, PVOID*) noexcept {
- // Ty must provide a placement new operator
- new (storage_ptr) Ty();
- return 1;
-}
-
-template <class Ty, typename Arg>
-BOOL WINAPI immortalize_impl(PINIT_ONCE, PVOID storage_ptr,
- PVOID* param) noexcept {
- // Ty must provide a placement new operator
- new (storage_ptr) Ty(*((Arg*)param));
- return 1;
-}
-
-template <class Ty>
-Ty& immortalize() { // return a reference to an object that will live forever
- static INIT_ONCE flag;
- alignas(Ty) static unsigned char storage[sizeof(Ty)];
- InitOnceExecuteOnce(&flag, immortalize_impl<Ty>, &storage, nullptr);
- return reinterpret_cast<Ty&>(storage);
-}
-
-template <class Ty, typename Arg>
-Ty& immortalize(
- Arg arg) { // return a reference to an object that will live forever
- static INIT_ONCE flag;
- alignas(Ty) static unsigned char storage[sizeof(Ty)];
- InitOnceExecuteOnce(&flag, immortalize_impl<Ty, Arg>, &storage, &arg);
- return reinterpret_cast<Ty&>(storage);
-}
-} // namespace __sanitizer
-#endif // SANITIZER_WINDOWS
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_win_interception.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_win_interception.cpp
deleted file mode 100644
index 75a1545d00d8b..0000000000000
--- a/compiler-rt/lib/sanitizer_common/sanitizer_win_interception.cpp
+++ /dev/null
@@ -1,156 +0,0 @@
-//===-- sanitizer_win_interception.cpp -------------------- --*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-//
-// Windows-specific export surface to provide interception for parts of the
-// runtime that are always statically linked, both for overriding user-defined
-// functions as well as registering weak functions that the ASAN runtime should
-// use over defaults.
-//
-//===----------------------------------------------------------------------===//
-
-#include "sanitizer_platform.h"
-#if SANITIZER_WINDOWS
-# include <stddef.h>
-
-# include "interception/interception.h"
-# include "sanitizer_addrhashmap.h"
-# include "sanitizer_common.h"
-# include "sanitizer_internal_defs.h"
-# include "sanitizer_placement_new.h"
-# include "sanitizer_win_immortalize.h"
-# include "sanitizer_win_interception.h"
-
-using namespace __sanitizer;
-
-extern "C" void *__ImageBase;
-
-namespace __sanitizer {
-
-static uptr GetSanitizerDllExport(const char *export_name) {
- const uptr function_address =
- __interception::InternalGetProcAddress(&__ImageBase, export_name);
- if (function_address == 0) {
- Report("ERROR: Failed to find sanitizer DLL export '%s'\n", export_name);
- CHECK("Failed to find sanitizer DLL export" && 0);
- }
- return function_address;
-}
-
-struct WeakCallbackList {
- explicit constexpr WeakCallbackList(RegisterWeakFunctionCallback cb)
- : callback(cb), next(nullptr) {}
-
- static void *operator new(size_t size) { return InternalAlloc(size); }
-
- static void operator delete(void *p) { InternalFree(p); }
-
- RegisterWeakFunctionCallback callback;
- WeakCallbackList *next;
-};
-using WeakCallbackMap = AddrHashMap<WeakCallbackList *, 11>;
-
-static WeakCallbackMap *GetWeakCallbackMap() {
- return &immortalize<WeakCallbackMap>();
-}
-
-void AddRegisterWeakFunctionCallback(uptr export_address,
- RegisterWeakFunctionCallback cb) {
- WeakCallbackMap::Handle h_find_or_create(GetWeakCallbackMap(), export_address,
- false, true);
- CHECK(h_find_or_create.exists());
- if (h_find_or_create.created()) {
- *h_find_or_create = new WeakCallbackList(cb);
- } else {
- (*h_find_or_create)->next = new WeakCallbackList(cb);
- }
-}
-
-static void RunWeakFunctionCallbacks(uptr export_address) {
- WeakCallbackMap::Handle h_find(GetWeakCallbackMap(), export_address, false,
- false);
- if (!h_find.exists()) {
- return;
- }
-
- WeakCallbackList *list = *h_find;
- do {
- list->callback();
- } while ((list = list->next));
-}
-
-} // namespace __sanitizer
-
-extern "C" __declspec(dllexport) bool __cdecl __sanitizer_override_function(
- const char *export_name, const uptr user_function,
- uptr *const old_user_function) {
- CHECK(export_name);
- CHECK(user_function);
-
- const uptr sanitizer_function = GetSanitizerDllExport(export_name);
-
- const bool function_overridden = __interception::OverrideFunction(
- user_function, sanitizer_function, old_user_function);
- if (!function_overridden) {
- Report(
- "ERROR: Failed to override local function at '%p' with sanitizer "
- "function '%s'\n",
- user_function, export_name);
- CHECK("Failed to replace local function with sanitizer version." && 0);
- }
-
- return function_overridden;
-}
-
-extern "C"
- __declspec(dllexport) bool __cdecl __sanitizer_override_function_by_addr(
- const uptr source_function, const uptr target_function,
- uptr *const old_target_function) {
- CHECK(source_function);
- CHECK(target_function);
-
- const bool function_overridden = __interception::OverrideFunction(
- target_function, source_function, old_target_function);
- if (!function_overridden) {
- Report(
- "ERROR: Failed to override function at '%p' with function at "
- "'%p'\n",
- target_function, source_function);
- CHECK("Failed to apply function override." && 0);
- }
-
- return function_overridden;
-}
-
-extern "C"
- __declspec(dllexport) bool __cdecl __sanitizer_register_weak_function(
- const char *export_name, const uptr user_function,
- uptr *const old_user_function) {
- CHECK(export_name);
- CHECK(user_function);
-
- const uptr sanitizer_function = GetSanitizerDllExport(export_name);
-
- const bool function_overridden = __interception::OverrideFunction(
- sanitizer_function, user_function, old_user_function);
- if (!function_overridden) {
- Report(
- "ERROR: Failed to register local function at '%p' to be used in "
- "place of sanitizer function '%s'\n.",
- user_function, export_name);
- CHECK("Failed to register weak function." && 0);
- }
-
- // Note that thread-safety of RunWeakFunctionCallbacks in InitializeFlags
- // depends on __sanitizer_register_weak_functions being called during the
- // loader lock.
- RunWeakFunctionCallbacks(sanitizer_function);
-
- return function_overridden;
-}
-
-#endif // SANITIZER_WINDOWS
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_win_interception.h b/compiler-rt/lib/sanitizer_common/sanitizer_win_interception.h
deleted file mode 100644
index 70ae3d6bf31f2..0000000000000
--- a/compiler-rt/lib/sanitizer_common/sanitizer_win_interception.h
+++ /dev/null
@@ -1,32 +0,0 @@
-//===-- sanitizer_win_interception.h ---------------------- --*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-//
-// Windows-specific export surface to provide interception for parts of the
-// runtime that are always statically linked, both for overriding user-defined
-// functions as well as registering weak functions that the ASAN runtime should
-// use over defaults.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef SANITIZER_WIN_INTERCEPTION_H
-#define SANITIZER_WIN_INTERCEPTION_H
-
-#include "sanitizer_platform.h"
-#if SANITIZER_WINDOWS
-
-# include "sanitizer_common.h"
-# include "sanitizer_internal_defs.h"
-
-namespace __sanitizer {
-using RegisterWeakFunctionCallback = void (*)();
-void AddRegisterWeakFunctionCallback(uptr export_address,
- RegisterWeakFunctionCallback cb);
-} // namespace __sanitizer
-
-#endif // SANITIZER_WINDOWS
-#endif // SANITIZER_WIN_INTERCEPTION_H
\ No newline at end of file
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_win_thunk_interception.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_win_thunk_interception.cpp
deleted file mode 100644
index 13db8869abadd..0000000000000
--- a/compiler-rt/lib/sanitizer_common/sanitizer_win_thunk_interception.cpp
+++ /dev/null
@@ -1,110 +0,0 @@
-//===-- sanitizer_win_thunk_interception.cpp ----------------------- -----===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-//
-// This file defines things that need to be present in the application modules
-// to interact with sanitizer DLL correctly and cannot be implemented using the
-// default "import library" generated when linking the DLL.
-//
-// This includes the common infrastructure required to intercept local functions
-// that must be replaced with sanitizer-aware versions, as well as the
-// registration of weak functions with the sanitizer DLL. With this in-place,
-// other sanitizer components can simply write to the .INTR and .WEAK sections.
-//
-//===----------------------------------------------------------------------===//
-
-#if defined(SANITIZER_STATIC_RUNTIME_THUNK) || \
- defined(SANITIZER_DYNAMIC_RUNTIME_THUNK)
-# include "sanitizer_win_thunk_interception.h"
-
-extern "C" void abort();
-
-namespace __sanitizer {
-
-int override_function(const char *export_name, const uptr user_function) {
- if (!__sanitizer_override_function(export_name, user_function)) {
- abort();
- }
-
- return 0;
-}
-
-int register_weak(const char *export_name, const uptr user_function) {
- if (!__sanitizer_register_weak_function(export_name, user_function)) {
- abort();
- }
-
- return 0;
-}
-
-void initialize_thunks(const sanitizer_thunk *first,
- const sanitizer_thunk *last) {
- for (const sanitizer_thunk *it = first; it < last; ++it) {
- if (*it) {
- (*it)();
- }
- }
-}
-} // namespace __sanitizer
-
-# define INTERFACE_FUNCTION(Name)
-# define INTERFACE_WEAK_FUNCTION(Name) REGISTER_WEAK_FUNCTION(Name)
-# include "sanitizer_common_interface.inc"
-
-# pragma section(".INTR$A", read) // intercept begin
-# pragma section(".INTR$Z", read) // intercept end
-# pragma section(".WEAK$A", read) // weak begin
-# pragma section(".WEAK$Z", read) // weak end
-
-extern "C" {
-__declspec(allocate(
- ".INTR$A")) sanitizer_thunk __sanitizer_intercept_thunk_begin;
-__declspec(allocate(".INTR$Z")) sanitizer_thunk __sanitizer_intercept_thunk_end;
-
-__declspec(allocate(
- ".WEAK$A")) sanitizer_thunk __sanitizer_register_weak_thunk_begin;
-__declspec(allocate(
- ".WEAK$Z")) sanitizer_thunk __sanitizer_register_weak_thunk_end;
-}
-
-extern "C" int __sanitizer_thunk_init() {
- // __sanitizer_static_thunk_init is expected to be called by only one thread.
- static bool flag = false;
- if (flag) {
- return 0;
- }
- flag = true;
-
- __sanitizer::initialize_thunks(&__sanitizer_intercept_thunk_begin,
- &__sanitizer_intercept_thunk_end);
- __sanitizer::initialize_thunks(&__sanitizer_register_weak_thunk_begin,
- &__sanitizer_register_weak_thunk_end);
-
- // In DLLs, the callbacks are expected to return 0,
- // otherwise CRT initialization fails.
- return 0;
-}
-
-// We want to call dll_thunk_init before C/C++ initializers / constructors are
-// executed, otherwise functions like memset might be invoked.
-# pragma section(".CRT$XIB", long, read)
-__declspec(allocate(".CRT$XIB")) int (*__sanitizer_thunk_init_ptr)() =
- __sanitizer_thunk_init;
-
-static void WINAPI sanitizer_thunk_thread_init(void *mod, unsigned long reason,
- void *reserved) {
- if (reason == /*DLL_PROCESS_ATTACH=*/1)
- __sanitizer_thunk_init();
-}
-
-# pragma section(".CRT$XLAB", long, read)
-__declspec(allocate(".CRT$XLAB")) void(
- WINAPI *__sanitizer_thunk_thread_init_ptr)(void *, unsigned long, void *) =
- sanitizer_thunk_thread_init;
-
-#endif // defined(SANITIZER_STATIC_RUNTIME_THUNK) ||
- // defined(SANITIZER_DYNAMIC_RUNTIME_THUNK)
\ No newline at end of file
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_win_thunk_interception.h b/compiler-rt/lib/sanitizer_common/sanitizer_win_thunk_interception.h
deleted file mode 100644
index 70177d68aa8e6..0000000000000
--- a/compiler-rt/lib/sanitizer_common/sanitizer_win_thunk_interception.h
+++ /dev/null
@@ -1,81 +0,0 @@
-//===-- sanitizer_win_thunk_interception.h ------------------------- -----===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-// This header provide helper macros and functions to delegate calls to the
-// shared runtime that lives in the sanitizer DLL.
-//===----------------------------------------------------------------------===//
-
-#ifndef SANITIZER_WIN_THUNK_INTERCEPTION_H
-#define SANITIZER_WIN_THUNK_INTERCEPTION_H
-#include <stdint.h>
-
-#include "sanitizer_internal_defs.h"
-
-extern "C" {
-__declspec(dllimport) bool __cdecl __sanitizer_override_function(
- const char *export_name, __sanitizer::uptr user_function,
- __sanitizer::uptr *old_function = nullptr);
-__declspec(dllimport) bool __cdecl __sanitizer_override_function_by_addr(
- __sanitizer::uptr source_function, __sanitizer::uptr target_function,
- __sanitizer::uptr *old_target_function = nullptr);
-__declspec(dllimport) bool __cdecl __sanitizer_register_weak_function(
- const char *export_name, __sanitizer::uptr user_function,
- __sanitizer::uptr *old_function = nullptr);
-}
-
-using sanitizer_thunk = int (*)();
-
-namespace __sanitizer {
-int override_function(const char *export_name, uptr user_function);
-int register_weak(const char *export_name, uptr user_function);
-void initialize_thunks(const sanitizer_thunk *begin,
- const sanitizer_thunk *end);
-} // namespace __sanitizer
-
-// -------------------- Function interception macros ------------------------ //
-// We can't define our own version of strlen etc. because that would lead to
-// link-time or even type mismatch errors. Instead, we can declare a function
-// just to be able to get its address. Me may miss the first few calls to the
-// functions since it can be called before __dll_thunk_init, but that would lead
-// to false negatives in the startup code before user's global initializers,
-// which isn't a big deal.
-// Use .INTR segment to register function pointers that are iterated over during
-// startup that will replace local_function with sanitizer_export.
-
-#define INTERCEPT_LIBRARY_FUNCTION(local_function, sanitizer_export) \
- extern "C" void local_function(); \
- static int intercept_##local_function() { \
- return __sanitizer::override_function( \
- sanitizer_export, \
- reinterpret_cast<__sanitizer::uptr>(local_function)); \
- } \
- __pragma(section(".INTR$M", long, read)) __declspec(allocate( \
- ".INTR$M")) int (*__sanitizer_static_thunk_##local_function)() = \
- intercept_##local_function;
-
-// ------------------ Weak symbol registration macros ---------------------- //
-// Use .WEAK segment to register function pointers that are iterated over during
-// startup that will replace sanitizer_export with local_function
-
-#define REGISTER_WEAK_FUNCTION(local_function) \
- extern "C" void local_function(); \
- extern "C" void WEAK_EXPORT_NAME(local_function)(); \
- WIN_WEAK_IMPORT_DEF(local_function) \
- __attribute__((optnone)) static int register_weak_##local_function() { \
- if ((uintptr_t) & local_function != (uintptr_t) & \
- WEAK_EXPORT_NAME(local_function)) { \
- return __sanitizer::register_weak( \
- SANITIZER_STRINGIFY(WEAK_EXPORT_NAME(local_function)), \
- reinterpret_cast<__sanitizer::uptr>(local_function)); \
- } \
- return 0; \
- } \
- __pragma(section(".WEAK$M", long, read)) __declspec(allocate( \
- ".WEAK$M")) int (*__sanitizer_register_weak_##local_function)() = \
- register_weak_##local_function;
-
-#endif // SANITIZER_WIN_STATIC_RUNTIME_THUNK_H
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_win_weak_interception.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_win_weak_interception.cpp
new file mode 100644
index 0000000000000..b14bbf76d9a76
--- /dev/null
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_win_weak_interception.cpp
@@ -0,0 +1,94 @@
+//===-- sanitizer_win_weak_interception.cpp -------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+// This module should be included in the sanitizer when it is implemented as a
+// shared library on Windows (dll), in order to delegate the calls of weak
+// functions to the implementation in the main executable when a strong
+// definition is provided.
+//===----------------------------------------------------------------------===//
+
+#include "sanitizer_platform.h"
+#if SANITIZER_WINDOWS && SANITIZER_DYNAMIC
+#include "sanitizer_win_weak_interception.h"
+#include "sanitizer_allocator_interface.h"
+#include "sanitizer_interface_internal.h"
+#include "sanitizer_win_defs.h"
+#include "interception/interception.h"
+
+extern "C" {
+void *WINAPI GetModuleHandleA(const char *module_name);
+void abort();
+}
+
+namespace __sanitizer {
+// Try to get a pointer to real_function in the main module and override
+// dll_function with that pointer. If the function isn't found, nothing changes.
+int interceptWhenPossible(uptr dll_function, const char *real_function) {
+ uptr real = __interception::InternalGetProcAddress(
+ (void *)GetModuleHandleA(0), real_function);
+ if (real && !__interception::OverrideFunction((uptr)dll_function, real, 0))
+ abort();
+ return 0;
+}
+} // namespace __sanitizer
+
+// Declare weak hooks.
+extern "C" {
+void __sanitizer_on_print(const char *str);
+void __sanitizer_weak_hook_memcmp(uptr called_pc, const void *s1,
+ const void *s2, uptr n, int result);
+void __sanitizer_weak_hook_strcmp(uptr called_pc, const char *s1,
+ const char *s2, int result);
+void __sanitizer_weak_hook_strncmp(uptr called_pc, const char *s1,
+ const char *s2, uptr n, int result);
+void __sanitizer_weak_hook_strstr(uptr called_pc, const char *s1,
+ const char *s2, char *result);
+}
+
+// Include Sanitizer Common interface.
+#define INTERFACE_FUNCTION(Name)
+#define INTERFACE_WEAK_FUNCTION(Name) INTERCEPT_SANITIZER_WEAK_FUNCTION(Name)
+#include "sanitizer_common_interface.inc"
+
+#pragma section(".WEAK$A", read)
+#pragma section(".WEAK$Z", read)
+
+typedef void (*InterceptCB)();
+extern "C" {
+__declspec(allocate(".WEAK$A")) InterceptCB __start_weak_list;
+__declspec(allocate(".WEAK$Z")) InterceptCB __stop_weak_list;
+}
+
+static int weak_intercept_init() {
+ static bool flag = false;
+ // weak_interception_init is expected to be called by only one thread.
+ if (flag) return 0;
+ flag = true;
+
+ for (InterceptCB *it = &__start_weak_list; it < &__stop_weak_list; ++it)
+ if (*it)
+ (*it)();
+
+ // In DLLs, the callbacks are expected to return 0,
+ // otherwise CRT initialization fails.
+ return 0;
+}
+
+#pragma section(".CRT$XIB", long, read)
+__declspec(allocate(".CRT$XIB")) int (*__weak_intercept_preinit)() =
+ weak_intercept_init;
+
+static void WINAPI weak_intercept_thread_init(void *mod, unsigned long reason,
+ void *reserved) {
+ if (reason == /*DLL_PROCESS_ATTACH=*/1) weak_intercept_init();
+}
+
+#pragma section(".CRT$XLAB", long, read)
+__declspec(allocate(".CRT$XLAB")) void(WINAPI *__weak_intercept_tls_init)(
+ void *, unsigned long, void *) = weak_intercept_thread_init;
+
+#endif // SANITIZER_WINDOWS && SANITIZER_DYNAMIC
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_win_weak_interception.h b/compiler-rt/lib/sanitizer_common/sanitizer_win_weak_interception.h
new file mode 100644
index 0000000000000..5e4d8b8def3e7
--- /dev/null
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_win_weak_interception.h
@@ -0,0 +1,32 @@
+//===-- sanitizer_win_weak_interception.h ---------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+// This header provide helper macros to delegate calls of weak functions to the
+// implementation in the main executable when a strong definition is present.
+//===----------------------------------------------------------------------===//
+#ifndef SANITIZER_WIN_WEAK_INTERCEPTION_H
+#define SANITIZER_WIN_WEAK_INTERCEPTION_H
+#include "sanitizer_internal_defs.h"
+
+namespace __sanitizer {
+int interceptWhenPossible(uptr dll_function, const char *real_function);
+}
+
+// ----------------- Function interception helper macros -------------------- //
+// Weak functions, could be redefined in the main executable, but that is not
+// necessary, so we shouldn't die if we can not find a reference.
+#define INTERCEPT_WEAK(Name) interceptWhenPossible((uptr) Name, #Name);
+
+#define INTERCEPT_SANITIZER_WEAK_FUNCTION(Name) \
+ static int intercept_##Name() { \
+ return __sanitizer::interceptWhenPossible((__sanitizer::uptr) Name, #Name);\
+ } \
+ __pragma(section(".WEAK$M", long, read)) \
+ __declspec(allocate(".WEAK$M")) int (*__weak_intercept_##Name)() = \
+ intercept_##Name;
+
+#endif // SANITIZER_WIN_WEAK_INTERCEPTION_H
diff --git a/compiler-rt/lib/ubsan/CMakeLists.txt b/compiler-rt/lib/ubsan/CMakeLists.txt
index 5d45a53d02dbd..db0b33f1276ef 100644
--- a/compiler-rt/lib/ubsan/CMakeLists.txt
+++ b/compiler-rt/lib/ubsan/CMakeLists.txt
@@ -159,12 +159,33 @@ else()
CFLAGS ${UBSAN_CXXFLAGS})
if (WIN32)
- set(RUNTIME_THUNK_CFLAGS -DSANITIZER_DYNAMIC_RUNTIME_THUNK -DSANITIZER_STATIC_RUNTIME_THUNK)
- add_compiler_rt_object_libraries(UbsanRuntimeThunk
+ add_compiler_rt_object_libraries(UbsanWeakInterception
${SANITIZER_COMMON_SUPPORTED_OS}
ARCHS ${UBSAN_SUPPORTED_ARCH}
SOURCES
- ubsan_win_runtime_thunk.cpp
+ ubsan_win_weak_interception.cpp
+ CFLAGS ${UBSAN_CFLAGS} -DSANITIZER_DYNAMIC
+ DEFS ${UBSAN_COMMON_DEFINITIONS})
+
+ add_compiler_rt_object_libraries(UbsanDllThunk
+ ${SANITIZER_COMMON_SUPPORTED_OS}
+ ARCHS ${UBSAN_SUPPORTED_ARCH}
+ SOURCES
+ ubsan_win_dll_thunk.cpp
+ CFLAGS ${UBSAN_CFLAGS} -DSANITIZER_DLL_THUNK
+ DEFS ${UBSAN_COMMON_DEFINITIONS})
+
+ set(DYNAMIC_RUNTIME_THUNK_CFLAGS "-DSANITIZER_DYNAMIC_RUNTIME_THUNK")
+ if(MSVC)
+ list(APPEND DYNAMIC_RUNTIME_THUNK_CFLAGS "-Zl")
+ elseif(CMAKE_C_COMPILER_ID MATCHES Clang)
+ list(APPEND DYNAMIC_RUNTIME_THUNK_CFLAGS "-nodefaultlibs")
+ endif()
+ add_compiler_rt_object_libraries(UbsanDynamicRuntimeThunk
+ ${SANITIZER_COMMON_SUPPORTED_OS}
+ ARCHS ${UBSAN_SUPPORTED_ARCH}
+ SOURCES
+ ubsan_win_dynamic_runtime_thunk.cpp
CFLAGS ${UBSAN_CFLAGS} ${DYNAMIC_RUNTIME_THUNK_CFLAGS}
DEFS ${UBSAN_COMMON_DEFINITIONS})
endif()
diff --git a/compiler-rt/lib/ubsan/ubsan_win_dll_thunk.cpp b/compiler-rt/lib/ubsan/ubsan_win_dll_thunk.cpp
new file mode 100644
index 0000000000000..5ac7fc3e08e4c
--- /dev/null
+++ b/compiler-rt/lib/ubsan/ubsan_win_dll_thunk.cpp
@@ -0,0 +1,20 @@
+//===-- ubsan_win_dll_thunk.cpp -------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines a family of thunks that should be statically linked into
+// the DLLs that have instrumentation in order to delegate the calls to the
+// shared runtime that lives in the main binary.
+// See https://github.com/google/sanitizers/issues/209 for the details.
+//===----------------------------------------------------------------------===//
+#ifdef SANITIZER_DLL_THUNK
+#include "sanitizer_common/sanitizer_win_dll_thunk.h"
+// Ubsan interface functions.
+#define INTERFACE_FUNCTION(Name) INTERCEPT_SANITIZER_FUNCTION(Name)
+#define INTERFACE_WEAK_FUNCTION(Name) INTERCEPT_SANITIZER_WEAK_FUNCTION(Name)
+#include "ubsan_interface.inc"
+#endif // SANITIZER_DLL_THUNK
diff --git a/compiler-rt/lib/ubsan/ubsan_win_runtime_thunk.cpp b/compiler-rt/lib/ubsan/ubsan_win_dynamic_runtime_thunk.cpp
similarity index 62%
rename from compiler-rt/lib/ubsan/ubsan_win_runtime_thunk.cpp
rename to compiler-rt/lib/ubsan/ubsan_win_dynamic_runtime_thunk.cpp
index 5ca7d6f385cf2..00722b4033a53 100644
--- a/compiler-rt/lib/ubsan/ubsan_win_runtime_thunk.cpp
+++ b/compiler-rt/lib/ubsan/ubsan_win_dynamic_runtime_thunk.cpp
@@ -1,4 +1,4 @@
-//===-- ubsan_win_runtime_thunk.cpp ----------------------------- --===//
+//===-- ubsan_win_dynamic_runtime_thunk.cpp -------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -10,14 +10,11 @@
// to interact with Ubsan, when it is included in a dll.
//
//===----------------------------------------------------------------------===//
-#if defined(SANITIZER_DYNAMIC_RUNTIME_THUNK) || \
- defined(SANITIZER_STATIC_RUNTIME_THUNK)
+#ifdef SANITIZER_DYNAMIC_RUNTIME_THUNK
#define SANITIZER_IMPORT_INTERFACE 1
#include "sanitizer_common/sanitizer_win_defs.h"
-#include "sanitizer_common/sanitizer_win_thunk_interception.h"
// Define weak alias for all weak functions imported from ubsan.
#define INTERFACE_FUNCTION(Name)
-#define INTERFACE_WEAK_FUNCTION(Name) REGISTER_WEAK_FUNCTION(Name)
+#define INTERFACE_WEAK_FUNCTION(Name) WIN_WEAK_IMPORT_DEF(Name)
#include "ubsan_interface.inc"
-#endif // defined(SANITIZER_DYNAMIC_RUNTIME_THUNK) ||
- // defined(SANITIZER_STATIC_RUNTIME_THUNK)
+#endif // SANITIZER_DYNAMIC_RUNTIME_THUNK
diff --git a/compiler-rt/lib/ubsan/ubsan_win_weak_interception.cpp b/compiler-rt/lib/ubsan/ubsan_win_weak_interception.cpp
new file mode 100644
index 0000000000000..01db0c0ce78ab
--- /dev/null
+++ b/compiler-rt/lib/ubsan/ubsan_win_weak_interception.cpp
@@ -0,0 +1,23 @@
+//===-- ubsan_win_weak_interception.cpp -----------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+// This module should be included in Ubsan when it is implemented as a shared
+// library on Windows (dll), in order to delegate the calls of weak functions to
+// the implementation in the main executable when a strong definition is
+// provided.
+//===----------------------------------------------------------------------===//
+#ifdef SANITIZER_DYNAMIC
+#include "sanitizer_common/sanitizer_win_weak_interception.h"
+#include "ubsan_flags.h"
+#include "ubsan_monitor.h"
+// Check if strong definitions for weak functions are present in the main
+// executable. If that is the case, override dll functions to point to strong
+// implementations.
+#define INTERFACE_FUNCTION(Name)
+#define INTERFACE_WEAK_FUNCTION(Name) INTERCEPT_SANITIZER_WEAK_FUNCTION(Name)
+#include "ubsan_interface.inc"
+#endif // SANITIZER_DYNAMIC
diff --git a/compiler-rt/test/asan/TestCases/Darwin/interface_symbols_darwin.cpp b/compiler-rt/test/asan/TestCases/Darwin/interface_symbols_darwin.cpp
index 59dca32672901..2cedbc722c463 100644
--- a/compiler-rt/test/asan/TestCases/Darwin/interface_symbols_darwin.cpp
+++ b/compiler-rt/test/asan/TestCases/Darwin/interface_symbols_darwin.cpp
@@ -35,9 +35,6 @@
// RUN: %p/../../../../lib/sanitizer_common/sanitizer_coverage_interface.inc \
// RUN: | grep -e "INTERFACE_\(WEAK_\)\?FUNCTION" \
// RUN: | grep -v "__sanitizer_weak_hook" \
-// RUN: | grep -v "__sanitizer_override_function" \
-// RUN: | grep -v "__sanitizer_override_function_by_addr" \
-// RUN: | grep -v "__sanitizer_register_weak_function" \
// RUN: | sed -e "s/.*(//" -e "s/).*//" > %t.imports
//
// RUN: cat %t.imports | sort | uniq > %t.imports-sorted
diff --git a/compiler-rt/test/asan/TestCases/Linux/interface_symbols_linux.cpp b/compiler-rt/test/asan/TestCases/Linux/interface_symbols_linux.cpp
index 2d729497548d9..ce1255c957831 100644
--- a/compiler-rt/test/asan/TestCases/Linux/interface_symbols_linux.cpp
+++ b/compiler-rt/test/asan/TestCases/Linux/interface_symbols_linux.cpp
@@ -21,9 +21,6 @@
// RUN: %p/../../../../lib/sanitizer_common/sanitizer_coverage_interface.inc \
// RUN: | grep -e "INTERFACE_\(WEAK_\)\?FUNCTION" \
// RUN: | grep -v "__sanitizer_weak_hook" \
-// RUN: | grep -v "__sanitizer_override_function" \
-// RUN: | grep -v "__sanitizer_override_function_by_addr" \
-// RUN: | grep -v "__sanitizer_register_weak_function" \
// RUN: | sed -e "s/.*(//" -e "s/).*//" > %t.imports
//
// RUN: cat %t.imports | sort | uniq > %t.imports-sorted
diff --git a/compiler-rt/test/asan/TestCases/Windows/double_free.cpp b/compiler-rt/test/asan/TestCases/Windows/double_free.cpp
index 71c45e7e889a2..e288b40fac47a 100644
--- a/compiler-rt/test/asan/TestCases/Windows/double_free.cpp
+++ b/compiler-rt/test/asan/TestCases/Windows/double_free.cpp
@@ -9,13 +9,13 @@ int main() {
free(x);
// CHECK: AddressSanitizer: attempting double-free on [[ADDR:0x[0-9a-f]+]]
// CHECK-NEXT: {{#0 .* free }}
- // CHECK: {{ #[1-3] .* main .*double_free.cpp}}:[[@LINE-3]]
+ // CHECK: {{ #[1-2] .* main .*double_free.cpp}}:[[@LINE-3]]
// CHECK: [[ADDR]] is located 0 bytes inside of 168-byte region
// CHECK-LABEL: freed by thread T0 here:
// CHECK-NEXT: {{#0 .* free }}
- // CHECK: {{ #[1-3] .* main .*double_free.cpp}}:[[@LINE-8]]
+ // CHECK: {{ #[1-2] .* main .*double_free.cpp}}:[[@LINE-8]]
// CHECK-LABEL: previously allocated by thread T0 here:
// CHECK-NEXT: {{#0 .* malloc }}
- // CHECK: {{ #[1-3] .* main .*double_free.cpp}}:[[@LINE-12]]
+ // CHECK: {{ #[1-2] .* main .*double_free.cpp}}:[[@LINE-12]]
return 0;
}
diff --git a/compiler-rt/test/asan/TestCases/Windows/free_hook_realloc.cpp b/compiler-rt/test/asan/TestCases/Windows/free_hook_realloc.cpp
index 297218bf8e99f..11e8c9975cf3b 100644
--- a/compiler-rt/test/asan/TestCases/Windows/free_hook_realloc.cpp
+++ b/compiler-rt/test/asan/TestCases/Windows/free_hook_realloc.cpp
@@ -5,6 +5,9 @@
// FIXME: merge this with the common free_hook_realloc test when we can run
// common tests on Windows.
+// FIXME: Doesn't work with DLLs
+// XFAIL: win32-dynamic-asan
+
#include <stdlib.h>
#include <io.h>
#include <sanitizer/allocator_interface.h>
diff --git a/compiler-rt/test/asan/TestCases/Windows/malloc_left_oob.cpp b/compiler-rt/test/asan/TestCases/Windows/malloc_left_oob.cpp
index e5de2269ffee0..7ea95d2b2184a 100644
--- a/compiler-rt/test/asan/TestCases/Windows/malloc_left_oob.cpp
+++ b/compiler-rt/test/asan/TestCases/Windows/malloc_left_oob.cpp
@@ -12,6 +12,6 @@ int main() {
// CHECK: [[ADDR]] is located 1 bytes before 42-byte region
// CHECK: allocated by thread T0 here:
// CHECK-NEXT: {{#0 .* malloc }}
- // CHECK: {{ #[1-3] .* main .*malloc_left_oob.cpp}}:[[@LINE-8]]
+ // CHECK: {{ #[1-2] .* main .*malloc_left_oob.cpp}}:[[@LINE-8]]
free(buffer);
}
diff --git a/compiler-rt/test/asan/TestCases/Windows/malloc_right_oob.cpp b/compiler-rt/test/asan/TestCases/Windows/malloc_right_oob.cpp
index 6007345755d88..1495632456e08 100644
--- a/compiler-rt/test/asan/TestCases/Windows/malloc_right_oob.cpp
+++ b/compiler-rt/test/asan/TestCases/Windows/malloc_right_oob.cpp
@@ -12,6 +12,6 @@ int main() {
// CHECK: [[ADDR]] is located 0 bytes after 42-byte region
// CHECK: allocated by thread T0 here:
// CHECK-NEXT: {{#0 .* malloc }}
- // CHECK: {{ #[1-3] .* main .*malloc_right_oob.cpp}}:[[@LINE-8]]
+ // CHECK: {{ #[1-2] .* main .*malloc_right_oob.cpp}}:[[@LINE-8]]
free(buffer);
}
diff --git a/compiler-rt/test/asan/TestCases/Windows/malloc_uaf.cpp b/compiler-rt/test/asan/TestCases/Windows/malloc_uaf.cpp
index 59a944c75b60d..d1eac7e55f601 100644
--- a/compiler-rt/test/asan/TestCases/Windows/malloc_uaf.cpp
+++ b/compiler-rt/test/asan/TestCases/Windows/malloc_uaf.cpp
@@ -13,8 +13,8 @@ int main() {
// CHECK: [[ADDR]] is located 0 bytes inside of 42-byte region
// CHECK: freed by thread T0 here:
// CHECK-NEXT: {{#0 .* free }}
- // CHECK: {{ #[1-3] .* main .*malloc_uaf.cpp}}:[[@LINE-8]]
+ // CHECK: {{ #[1-2] .* main .*malloc_uaf.cpp}}:[[@LINE-8]]
// CHECK: previously allocated by thread T0 here:
// CHECK-NEXT: {{#0 .* malloc }}
- // CHECK: {{ #[1-3] .* main .*malloc_uaf.cpp}}:[[@LINE-12]]
+ // CHECK: {{ #[1-2] .* main .*malloc_uaf.cpp}}:[[@LINE-12]]
}
diff --git a/compiler-rt/test/asan/TestCases/Windows/msvc/dll_and_lib.cpp b/compiler-rt/test/asan/TestCases/Windows/msvc/dll_and_lib.cpp
index 175bdefa7c995..96fae6b1d6039 100644
--- a/compiler-rt/test/asan/TestCases/Windows/msvc/dll_and_lib.cpp
+++ b/compiler-rt/test/asan/TestCases/Windows/msvc/dll_and_lib.cpp
@@ -1,9 +1,10 @@
// Just make sure we can link an implib into another DLL
// This used to fail between r212699 and r212814.
// RUN: %clang_cl_asan -DCONFIG=1 %s -c -Fo%t.1.obj
-// RUN: lld-link /nologo /DLL /OUT:%t.1.dll %t.1.obj %asan_lib %asan_thunk
+// RUN: lld-link /nologo /DLL /OUT:%t.1.dll %t.1.obj %asan_dll_thunk
// RUN: %clang_cl_asan -DCONFIG=2 %s -c -Fo%t.2.obj
-// RUN: lld-link /nologo /DLL /OUT:%t.2.dll %t.2.obj %t.1.lib %asan_lib %asan_thunk
+// RUN: lld-link /nologo /DLL /OUT:%t.2.dll %t.2.obj %t.1.lib %asan_dll_thunk
+// REQUIRES: asan-static-runtime
// REQUIRES: lld-available
#if CONFIG==1
diff --git a/compiler-rt/test/asan/TestCases/Windows/msvc/dll_large_function.cpp b/compiler-rt/test/asan/TestCases/Windows/msvc/dll_large_function.cpp
index f0c3deabbcf97..788488dbb8ed8 100644
--- a/compiler-rt/test/asan/TestCases/Windows/msvc/dll_large_function.cpp
+++ b/compiler-rt/test/asan/TestCases/Windows/msvc/dll_large_function.cpp
@@ -3,7 +3,8 @@
// from the DLL. We simulate the large function with
// -mllvm -asan-instrumentation-with-call-threshold=0.
// RUN: %clang_cl_asan %s -c -Fo%t.obj -mllvm -asan-instrumentation-with-call-threshold=0
-// RUN: lld-link /nologo /DLL /OUT:%t.dll %t.obj %asan_lib %asan_thunk
+// RUN: lld-link /nologo /DLL /OUT:%t.dll %t.obj %asan_dll_thunk
+// REQUIRES: asan-static-runtime
// REQUIRES: lld-available
void f(long* foo, long* bar) {
diff --git a/compiler-rt/test/asan/TestCases/Windows/realloc_left_oob.cpp b/compiler-rt/test/asan/TestCases/Windows/realloc_left_oob.cpp
index f1fd139c58251..ebde5f159ae38 100644
--- a/compiler-rt/test/asan/TestCases/Windows/realloc_left_oob.cpp
+++ b/compiler-rt/test/asan/TestCases/Windows/realloc_left_oob.cpp
@@ -12,6 +12,6 @@ int main() {
// CHECK: [[ADDR]] is located 1 bytes before 42-byte region
// CHECK: allocated by thread T0 here:
// CHECK-NEXT: {{#0 .* realloc }}
- // CHECK: {{ #[1-3] .* main .*realloc_left_oob.cpp}}:[[@LINE-8]]
+ // CHECK: {{ #[1-2] .* main .*realloc_left_oob.cpp}}:[[@LINE-8]]
free(buffer);
}
diff --git a/compiler-rt/test/asan/TestCases/Windows/realloc_right_oob.cpp b/compiler-rt/test/asan/TestCases/Windows/realloc_right_oob.cpp
index ea674f53def79..281efed5d3074 100644
--- a/compiler-rt/test/asan/TestCases/Windows/realloc_right_oob.cpp
+++ b/compiler-rt/test/asan/TestCases/Windows/realloc_right_oob.cpp
@@ -12,6 +12,6 @@ int main() {
// CHECK: [[ADDR]] is located 0 bytes after 42-byte region
// CHECK: allocated by thread T0 here:
// CHECK-NEXT: {{#0 .* realloc }}
- // CHECK: {{ #[1-3] .* main .*realloc_right_oob.cpp}}:[[@LINE-8]]
+ // CHECK: {{ #[1-2] .* main .*realloc_right_oob.cpp}}:[[@LINE-8]]
free(buffer);
}
diff --git a/compiler-rt/test/asan/TestCases/Windows/realloc_uaf.cpp b/compiler-rt/test/asan/TestCases/Windows/realloc_uaf.cpp
index 7d9c41ef0f462..6ff2217b11a25 100644
--- a/compiler-rt/test/asan/TestCases/Windows/realloc_uaf.cpp
+++ b/compiler-rt/test/asan/TestCases/Windows/realloc_uaf.cpp
@@ -13,8 +13,8 @@ int main() {
// CHECK: [[ADDR]] is located 0 bytes inside of 42-byte region
// CHECK: freed by thread T0 here:
// CHECK-NEXT: {{#0 .* free }}
- // CHECK: {{ #[1-3] .* main .*realloc_uaf.cpp}}:[[@LINE-8]]
+ // CHECK: {{ #[1-2] .* main .*realloc_uaf.cpp}}:[[@LINE-8]]
// CHECK: previously allocated by thread T0 here:
// CHECK-NEXT: {{#0 .* realloc }}
- // CHECK: {{ #[1-3] .* main .*realloc_uaf.cpp}}:[[@LINE-12]]
+ // CHECK: {{ #[1-2] .* main .*realloc_uaf.cpp}}:[[@LINE-12]]
}
diff --git a/compiler-rt/test/asan/TestCases/Windows/symbols_path.cpp b/compiler-rt/test/asan/TestCases/Windows/symbols_path.cpp
index 05437abc07c82..be99c89e7083e 100644
--- a/compiler-rt/test/asan/TestCases/Windows/symbols_path.cpp
+++ b/compiler-rt/test/asan/TestCases/Windows/symbols_path.cpp
@@ -17,6 +17,6 @@ int main() {
// CHECK: [[ADDR]] is located 1 bytes before 42-byte region
// CHECK: allocated by thread T0 here:
// CHECK-NEXT: {{#0 .* malloc}}
- // CHECK: {{ #[1-3] .* main .*symbols_path.cpp}}:[[@LINE-8]]
+ // CHECK: {{ #[1-2] .* main .*symbols_path.cpp}}:[[@LINE-8]]
free(buffer);
}
diff --git a/compiler-rt/test/asan/TestCases/Windows/unsymbolized.cpp b/compiler-rt/test/asan/TestCases/Windows/unsymbolized.cpp
index 00428b809fccd..0eb1e9ee91b0a 100644
--- a/compiler-rt/test/asan/TestCases/Windows/unsymbolized.cpp
+++ b/compiler-rt/test/asan/TestCases/Windows/unsymbolized.cpp
@@ -4,7 +4,7 @@
// RUN: rm -f %t.pdb
// RUN: %clangxx_asan -c -O2 %s -o %t.obj
-// RUN: lld-link /nologo /OUT:%t.exe %t.obj -defaultlib:libcmt -nodefaultlib:msvcrt -defaultlib:oldnames %asan_static_runtime_thunk %asan_lib
+// RUN: lld-link /nologo /OUT:%t.exe %t.obj %asan_lib %asan_cxx_lib
// RUN: not %run %t.exe 2>&1 | FileCheck %s
// REQUIRES: lld-available
diff --git a/compiler-rt/test/asan/TestCases/Windows/use_after_realloc.cpp b/compiler-rt/test/asan/TestCases/Windows/use_after_realloc.cpp
index 35947b3253857..4c32c63c38fa1 100644
--- a/compiler-rt/test/asan/TestCases/Windows/use_after_realloc.cpp
+++ b/compiler-rt/test/asan/TestCases/Windows/use_after_realloc.cpp
@@ -15,9 +15,9 @@ int main() {
// CHECK: [[ADDR]] is located 0 bytes inside of 32-byte region
// CHECK: freed by thread T0 here:
// CHECK-NEXT: {{#0 .* realloc }}
- // CHECK: {{ #[1-3] .* main .*use_after_realloc.cpp}}:[[@LINE-9]]
+ // CHECK: {{ #[1-2] .* main .*use_after_realloc.cpp}}:[[@LINE-9]]
// CHECK: previously allocated by thread T0 here:
// CHECK-NEXT: {{#0 .* realloc }}
- // CHECK: {{ #[1-3] .* main .*use_after_realloc.cpp}}:[[@LINE-14]]
+ // CHECK: {{ #[1-2] .* main .*use_after_realloc.cpp}}:[[@LINE-14]]
free(buffer);
}
diff --git a/compiler-rt/test/asan/TestCases/debug_double_free.cpp b/compiler-rt/test/asan/TestCases/debug_double_free.cpp
index 8a2ce40bc561f..de5ac7b0c8d5c 100644
--- a/compiler-rt/test/asan/TestCases/debug_double_free.cpp
+++ b/compiler-rt/test/asan/TestCases/debug_double_free.cpp
@@ -4,6 +4,9 @@
#include <stdio.h>
#include <stdlib.h>
+// FIXME: Doesn't work with DLLs
+// XFAIL: win32-dynamic-asan
+
// If we use %p with MSVC, it comes out all upper case. Use %08x to get
// lowercase hex.
#ifdef _MSC_VER
diff --git a/compiler-rt/test/asan/TestCases/debug_report.cpp b/compiler-rt/test/asan/TestCases/debug_report.cpp
index 855642bdc0d3b..617b7ee91e18d 100644
--- a/compiler-rt/test/asan/TestCases/debug_report.cpp
+++ b/compiler-rt/test/asan/TestCases/debug_report.cpp
@@ -6,6 +6,9 @@
#include <stdio.h>
#include <stdlib.h>
+// FIXME: Doesn't work with DLLs
+// XFAIL: win32-dynamic-asan
+
int main() {
// Disable stderr buffering. Needed on Windows.
setvbuf(stderr, NULL, _IONBF, 0);
diff --git a/compiler-rt/test/asan/TestCases/default_options.cpp b/compiler-rt/test/asan/TestCases/default_options.cpp
index 845e8a5f1793e..526dab6450e9b 100644
--- a/compiler-rt/test/asan/TestCases/default_options.cpp
+++ b/compiler-rt/test/asan/TestCases/default_options.cpp
@@ -1,7 +1,11 @@
// RUN: %clangxx_asan -O2 %s -o %t
// RUN: %run %t 2>&1 | FileCheck %s
+// FIXME: Doesn't work with DLLs
+// XFAIL: win32-dynamic-asan
+
const char *kAsanDefaultOptions = "verbosity=1 help=1";
+
// Required for dyld macOS 12.0+
#if (__APPLE__)
__attribute__((weak))
diff --git a/compiler-rt/test/asan/TestCases/on_error_callback.cpp b/compiler-rt/test/asan/TestCases/on_error_callback.cpp
index c38a36f0e33bd..f65a8f1abe831 100644
--- a/compiler-rt/test/asan/TestCases/on_error_callback.cpp
+++ b/compiler-rt/test/asan/TestCases/on_error_callback.cpp
@@ -1,5 +1,8 @@
// RUN: %clangxx_asan -O2 %s -o %t && not %run %t 2>&1 | FileCheck %s
+// FIXME: Doesn't work with DLLs
+// XFAIL: win32-dynamic-asan
+
#include <stdio.h>
#include <stdlib.h>
diff --git a/compiler-rt/test/asan/TestCases/report_error_summary.cpp b/compiler-rt/test/asan/TestCases/report_error_summary.cpp
index 9e024e35bed86..d565d2add7793 100644
--- a/compiler-rt/test/asan/TestCases/report_error_summary.cpp
+++ b/compiler-rt/test/asan/TestCases/report_error_summary.cpp
@@ -1,5 +1,8 @@
// RUN: %clangxx_asan -O0 %s -o %t && not %run %t 2>&1 | FileCheck %s
+// FIXME: Doesn't work with DLLs
+// XFAIL: win32-dynamic-asan
+
#include <stdio.h>
// Required for ld64 macOS 12.0+
diff --git a/compiler-rt/test/asan/lit.cfg.py b/compiler-rt/test/asan/lit.cfg.py
index 05ed7e8dd294e..83b3cbe789cac 100644
--- a/compiler-rt/test/asan/lit.cfg.py
+++ b/compiler-rt/test/asan/lit.cfg.py
@@ -130,11 +130,6 @@ def build_invocation(compile_flags, with_lto=False):
config.compiler_rt_libdir,
"libclang_rt.asan_{}_dynamic.dylib".format(config.apple_platform),
)
- elif config.host_os == "Windows":
- shared_libasan_path = os.path.join(
- config.compiler_rt_libdir,
- "clang_rt.asan_dynamic-{}.lib".format(config.target_suffix),
- )
else:
lit_config.warning(
"%shared_libasan substitution not set but dynamic ASan is available."
@@ -183,22 +178,8 @@ def build_invocation(compile_flags, with_lto=False):
base_lib = os.path.join(
config.compiler_rt_libdir, "clang_rt.asan%%s%s.lib" % config.target_suffix
)
- config.substitutions.append(("%asan_lib", base_lib % "_dynamic"))
- if config.asan_dynamic:
- config.substitutions.append(
- ("%asan_thunk", base_lib % "_dynamic_runtime_thunk")
- )
- else:
- config.substitutions.append(
- ("%asan_thunk", base_lib % "_static_runtime_thunk")
- )
+ config.substitutions.append(("%asan_lib", base_lib % ""))
config.substitutions.append(("%asan_cxx_lib", base_lib % "_cxx"))
- config.substitutions.append(
- ("%asan_dynamic_runtime_thunk", base_lib % "_dynamic_runtime_thunk")
- )
- config.substitutions.append(
- ("%asan_static_runtime_thunk", base_lib % "_static_runtime_thunk")
- )
config.substitutions.append(("%asan_dll_thunk", base_lib % "_dll_thunk"))
else:
# To make some of these tests work on MinGW target without changing their
@@ -281,7 +262,7 @@ def build_invocation(compile_flags, with_lto=False):
# Add the RT libdir to PATH directly so that we can successfully run the gtest
# binary to list its tests.
-if config.host_os == "Windows":
+if config.host_os == "Windows" and config.asan_dynamic:
os.environ["PATH"] = os.path.pathsep.join(
[config.compiler_rt_libdir, os.environ.get("PATH", "")]
)
More information about the llvm-commits
mailing list