Index: cmake/config-ix.cmake =================================================================== --- cmake/config-ix.cmake +++ cmake/config-ix.cmake @@ -429,15 +429,13 @@ set(COMPILER_RT_HAS_SANITIZER_COMMON FALSE) endif() -if (COMPILER_RT_HAS_SANITIZER_COMMON AND - (NOT OS_NAME MATCHES "Windows" OR CMAKE_SIZEOF_VOID_P EQUAL 4)) +if (COMPILER_RT_HAS_SANITIZER_COMMON) set(COMPILER_RT_HAS_INTERCEPTION TRUE) else() set(COMPILER_RT_HAS_INTERCEPTION FALSE) endif() -if (COMPILER_RT_HAS_SANITIZER_COMMON AND ASAN_SUPPORTED_ARCH AND - (NOT OS_NAME MATCHES "Windows" OR CMAKE_SIZEOF_VOID_P EQUAL 4)) +if (COMPILER_RT_HAS_SANITIZER_COMMON AND ASAN_SUPPORTED_ARCH) set(COMPILER_RT_HAS_ASAN TRUE) else() set(COMPILER_RT_HAS_ASAN FALSE) Index: lib/asan/asan_win.cc =================================================================== --- lib/asan/asan_win.cc +++ lib/asan/asan_win.cc @@ -46,11 +46,20 @@ const char* __asan_default_default_options() { return ""; } const char* __asan_default_default_suppressions() { return ""; } void __asan_default_on_error() {} +// 64-bit msvc will not prepend an underscore for symbols +#ifdef _WIN64 +#pragma comment(linker, "/alternatename:__sanitizer_malloc_hook=__sanitizer_default_malloc_hook") // NOLINT +#pragma comment(linker, "/alternatename:__sanitizer_free_hook=__sanitizer_default_free_hook") // NOLINT +#pragma comment(linker, "/alternatename:__asan_default_options=__asan_default_default_options") // NOLINT +#pragma comment(linker, "/alternatename:__asan_default_suppressions=__asan_default_default_suppressions") // NOLINT +#pragma comment(linker, "/alternatename:__asan_on_error=__asan_default_on_error") // NOLINT +#else #pragma comment(linker, "/alternatename:___sanitizer_malloc_hook=___sanitizer_default_malloc_hook") // NOLINT #pragma comment(linker, "/alternatename:___sanitizer_free_hook=___sanitizer_default_free_hook") // NOLINT #pragma comment(linker, "/alternatename:___asan_default_options=___asan_default_default_options") // NOLINT #pragma comment(linker, "/alternatename:___asan_default_suppressions=___asan_default_default_suppressions") // NOLINT #pragma comment(linker, "/alternatename:___asan_on_error=___asan_default_on_error") // NOLINT +#endif // }}} } // extern "C" @@ -61,6 +70,8 @@ REAL(RaiseException)(a, b, c, d); } +// TODO: Win64 has no _except_handler3/4, will implement _C_specific_handler instead +#ifndef _WIN64 INTERCEPTOR(int, _except_handler3, void *a, void *b, void *c, void *d) { CHECK(REAL(_except_handler3)); __asan_handle_no_return(); @@ -76,6 +87,7 @@ __asan_handle_no_return(); return REAL(_except_handler4)(a, b, c, d); } +#endif static thread_return_t THREAD_CALLING_CONV asan_thread_start(void *arg) { AsanThread *t = (AsanThread*)arg; @@ -139,8 +151,12 @@ void InitializePlatformInterceptors() { ASAN_INTERCEPT_FUNC(CreateThread); ASAN_INTERCEPT_FUNC(RaiseException); + +// TODO: Win64 uses _C_specific_handler instead +#ifndef _WIN64 ASAN_INTERCEPT_FUNC(_except_handler3); ASAN_INTERCEPT_FUNC(_except_handler4); +#endif // NtWaitForWorkViaWorkerFactory is always linked dynamically. CHECK(::__interception::OverrideFunction( Index: lib/interception/interception_win.cc =================================================================== --- lib/interception/interception_win.cc +++ lib/interception/interception_win.cc @@ -36,7 +36,7 @@ } static void WriteJumpInstruction(char *jmp_from, char *to) { - // jmp XXYYZZWW = E9 WW ZZ YY XX, where XXYYZZWW is an offset fromt jmp_from + // jmp XXYYZZWW = E9 WW ZZ YY XX, where XXYYZZWW is an offset from jmp_from // to the next instruction to the destination. ptrdiff_t offset = to - jmp_from - 5; *jmp_from = '\xE9'; @@ -68,6 +68,12 @@ // Returns 0 on error. static size_t RoundUpToInstrBoundary(size_t size, char *code) { +#ifdef _WIN64 + // TODO: implement similar logic for x64 instructions + // Win64 RoundUpToInstrBoundary is not supported yet + __debugbreak(); + return 0; +#else size_t cursor = 0; while (cursor < size) { switch (code[cursor]) { @@ -140,12 +146,16 @@ } return cursor; +#endif } bool OverrideFunction(uptr old_func, uptr new_func, uptr *orig_old_func) { #ifdef _WIN64 -#error OverrideFunction is not yet supported on x64 -#endif + // TODO: implement using x64 jmp + // OverrideFunction is not yet supported on x64 + __debugbreak(); + return false; +#else // Function overriding works basically like this: // We write "jmp " (5 bytes) at the beginning of the 'old_func' // to override it. @@ -190,6 +200,7 @@ return false; // not clear if this failure bothers us. return true; +#endif } static void **InterestingDLLsAvailable() { Index: lib/sanitizer_common/sanitizer_atomic_msvc.h =================================================================== --- lib/sanitizer_common/sanitizer_atomic_msvc.h +++ lib/sanitizer_common/sanitizer_atomic_msvc.h @@ -171,12 +171,16 @@ return (u32)_InterlockedExchange((volatile long*)&a->val_dont_use, v); } -#ifndef _WIN64 - INLINE bool atomic_compare_exchange_strong(volatile atomic_uint8_t *a, u8 *cmp, u8 xchgv, memory_order mo) { +#ifdef _WIN64 + // TODO: implement same functionality without inline asm + // Inline asm not supported in Win64 + __debugbreak(); + return false; +#else (void)mo; DCHECK(!((uptr)a % sizeof(*a))); u8 cmpv = *cmp; @@ -192,9 +196,8 @@ return true; *cmp = prev; return false; -} - #endif +} INLINE bool atomic_compare_exchange_strong(volatile atomic_uintptr_t *a, uptr *cmp, Index: test/asan/CMakeLists.txt =================================================================== --- test/asan/CMakeLists.txt +++ test/asan/CMakeLists.txt @@ -102,7 +102,10 @@ if(COMPILER_RT_ASAN_HAS_STATIC_RUNTIME) # Add check-dynamic-asan target. It is a part of check-all only on Windows, # where we want to always test both dynamic and static runtime. - if(NOT OS_NAME MATCHES "Windows") + + # TODO: re-enable the tests for asan Win64 when ready + # disable tests for asan Win64 temporarily + if(NOT OS_NAME MATCHES "Windows" OR CMAKE_SIZEOF_VOID_P EQUAL 8) set(EXCLUDE_FROM_ALL TRUE) endif() add_lit_testsuite(check-asan-dynamic @@ -111,7 +114,7 @@ DEPENDS ${ASAN_DYNAMIC_TEST_DEPS}) set_target_properties(check-asan-dynamic PROPERTIES FOLDER "ASan dynamic tests") - if(NOT OS_NAME MATCHES "Windows") + if(NOT OS_NAME MATCHES "Windows" OR CMAKE_SIZEOF_VOID_P EQUAL 8) set(EXCLUDE_FROM_ALL FALSE) endif() endif()