This patch is activating the build of Asan on Windows 64-bits.
It's fixing compilation errors. The runtime is not yet working. Missing features: OverrideFunction for x64 an equiv function for inline asm (atomic_compare_exchange_strong) shadow memory offset needs to be adjusted RoundUpToInstrBoundary for x64 They will be implemented by subsequent patches. Patch by Wei Wang. Differential revision: http://reviews.llvm.org/D20455 llvm-svn: 271049
This commit is contained in:
parent
0364f67f61
commit
00f3f6e296
|
@ -429,15 +429,13 @@ else()
|
||||||
set(COMPILER_RT_HAS_SANITIZER_COMMON FALSE)
|
set(COMPILER_RT_HAS_SANITIZER_COMMON FALSE)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if (COMPILER_RT_HAS_SANITIZER_COMMON AND
|
if (COMPILER_RT_HAS_SANITIZER_COMMON)
|
||||||
(NOT OS_NAME MATCHES "Windows" OR CMAKE_SIZEOF_VOID_P EQUAL 4))
|
|
||||||
set(COMPILER_RT_HAS_INTERCEPTION TRUE)
|
set(COMPILER_RT_HAS_INTERCEPTION TRUE)
|
||||||
else()
|
else()
|
||||||
set(COMPILER_RT_HAS_INTERCEPTION FALSE)
|
set(COMPILER_RT_HAS_INTERCEPTION FALSE)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if (COMPILER_RT_HAS_SANITIZER_COMMON AND ASAN_SUPPORTED_ARCH AND
|
if (COMPILER_RT_HAS_SANITIZER_COMMON AND ASAN_SUPPORTED_ARCH)
|
||||||
(NOT OS_NAME MATCHES "Windows" OR CMAKE_SIZEOF_VOID_P EQUAL 4))
|
|
||||||
set(COMPILER_RT_HAS_ASAN TRUE)
|
set(COMPILER_RT_HAS_ASAN TRUE)
|
||||||
else()
|
else()
|
||||||
set(COMPILER_RT_HAS_ASAN FALSE)
|
set(COMPILER_RT_HAS_ASAN FALSE)
|
||||||
|
|
|
@ -46,11 +46,20 @@ void __sanitizer_default_free_hook(void *ptr) { }
|
||||||
const char* __asan_default_default_options() { return ""; }
|
const char* __asan_default_default_options() { return ""; }
|
||||||
const char* __asan_default_default_suppressions() { return ""; }
|
const char* __asan_default_default_suppressions() { return ""; }
|
||||||
void __asan_default_on_error() {}
|
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_malloc_hook=___sanitizer_default_malloc_hook") // NOLINT
|
||||||
#pragma comment(linker, "/alternatename:___sanitizer_free_hook=___sanitizer_default_free_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_options=___asan_default_default_options") // NOLINT
|
||||||
#pragma comment(linker, "/alternatename:___asan_default_suppressions=___asan_default_default_suppressions") // 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
|
#pragma comment(linker, "/alternatename:___asan_on_error=___asan_default_on_error") // NOLINT
|
||||||
|
#endif
|
||||||
// }}}
|
// }}}
|
||||||
} // extern "C"
|
} // extern "C"
|
||||||
|
|
||||||
|
@ -61,6 +70,9 @@ INTERCEPTOR_WINAPI(void, RaiseException, void *a, void *b, void *c, void *d) {
|
||||||
REAL(RaiseException)(a, b, c, d);
|
REAL(RaiseException)(a, b, c, d);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO(wwchrome): Win64 has no _except_handler3/4.
|
||||||
|
// Need to implement _C_specific_handler instead.
|
||||||
|
#ifndef _WIN64
|
||||||
INTERCEPTOR(int, _except_handler3, void *a, void *b, void *c, void *d) {
|
INTERCEPTOR(int, _except_handler3, void *a, void *b, void *c, void *d) {
|
||||||
CHECK(REAL(_except_handler3));
|
CHECK(REAL(_except_handler3));
|
||||||
__asan_handle_no_return();
|
__asan_handle_no_return();
|
||||||
|
@ -76,6 +88,7 @@ INTERCEPTOR(int, _except_handler4, void *a, void *b, void *c, void *d) {
|
||||||
__asan_handle_no_return();
|
__asan_handle_no_return();
|
||||||
return REAL(_except_handler4)(a, b, c, d);
|
return REAL(_except_handler4)(a, b, c, d);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static thread_return_t THREAD_CALLING_CONV asan_thread_start(void *arg) {
|
static thread_return_t THREAD_CALLING_CONV asan_thread_start(void *arg) {
|
||||||
AsanThread *t = (AsanThread*)arg;
|
AsanThread *t = (AsanThread*)arg;
|
||||||
|
@ -139,8 +152,12 @@ namespace __asan {
|
||||||
void InitializePlatformInterceptors() {
|
void InitializePlatformInterceptors() {
|
||||||
ASAN_INTERCEPT_FUNC(CreateThread);
|
ASAN_INTERCEPT_FUNC(CreateThread);
|
||||||
ASAN_INTERCEPT_FUNC(RaiseException);
|
ASAN_INTERCEPT_FUNC(RaiseException);
|
||||||
|
|
||||||
|
// TODO(wwchrome): Win64 uses _C_specific_handler instead.
|
||||||
|
#ifndef _WIN64
|
||||||
ASAN_INTERCEPT_FUNC(_except_handler3);
|
ASAN_INTERCEPT_FUNC(_except_handler3);
|
||||||
ASAN_INTERCEPT_FUNC(_except_handler4);
|
ASAN_INTERCEPT_FUNC(_except_handler4);
|
||||||
|
#endif
|
||||||
|
|
||||||
// NtWaitForWorkViaWorkerFactory is always linked dynamically.
|
// NtWaitForWorkViaWorkerFactory is always linked dynamically.
|
||||||
CHECK(::__interception::OverrideFunction(
|
CHECK(::__interception::OverrideFunction(
|
||||||
|
|
|
@ -36,7 +36,7 @@ static void _memcpy(void *dst, void *src, size_t sz) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static void WriteJumpInstruction(char *jmp_from, char *to) {
|
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.
|
// to the next instruction to the destination.
|
||||||
ptrdiff_t offset = to - jmp_from - 5;
|
ptrdiff_t offset = to - jmp_from - 5;
|
||||||
*jmp_from = '\xE9';
|
*jmp_from = '\xE9';
|
||||||
|
@ -68,6 +68,12 @@ static char *GetMemoryForTrampoline(size_t size) {
|
||||||
|
|
||||||
// Returns 0 on error.
|
// Returns 0 on error.
|
||||||
static size_t RoundUpToInstrBoundary(size_t size, char *code) {
|
static size_t RoundUpToInstrBoundary(size_t size, char *code) {
|
||||||
|
#ifdef _WIN64
|
||||||
|
// TODO(wwchrome): Implement similar logic for x64 instructions.
|
||||||
|
// Win64 RoundUpToInstrBoundary is not supported yet.
|
||||||
|
__debugbreak();
|
||||||
|
return 0;
|
||||||
|
#else
|
||||||
size_t cursor = 0;
|
size_t cursor = 0;
|
||||||
while (cursor < size) {
|
while (cursor < size) {
|
||||||
switch (code[cursor]) {
|
switch (code[cursor]) {
|
||||||
|
@ -140,12 +146,16 @@ static size_t RoundUpToInstrBoundary(size_t size, char *code) {
|
||||||
}
|
}
|
||||||
|
|
||||||
return cursor;
|
return cursor;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
bool OverrideFunction(uptr old_func, uptr new_func, uptr *orig_old_func) {
|
bool OverrideFunction(uptr old_func, uptr new_func, uptr *orig_old_func) {
|
||||||
#ifdef _WIN64
|
#ifdef _WIN64
|
||||||
#error OverrideFunction is not yet supported on x64
|
// TODO(wwchrome): Implement using x64 jmp.
|
||||||
#endif
|
// OverrideFunction is not yet supported on x64.
|
||||||
|
__debugbreak();
|
||||||
|
return false;
|
||||||
|
#else
|
||||||
// Function overriding works basically like this:
|
// Function overriding works basically like this:
|
||||||
// We write "jmp <new_func>" (5 bytes) at the beginning of the 'old_func'
|
// We write "jmp <new_func>" (5 bytes) at the beginning of the 'old_func'
|
||||||
// to override it.
|
// to override it.
|
||||||
|
@ -190,6 +200,7 @@ bool OverrideFunction(uptr old_func, uptr new_func, uptr *orig_old_func) {
|
||||||
return false; // not clear if this failure bothers us.
|
return false; // not clear if this failure bothers us.
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static void **InterestingDLLsAvailable() {
|
static void **InterestingDLLsAvailable() {
|
||||||
|
|
|
@ -171,12 +171,16 @@ INLINE u32 atomic_exchange(volatile atomic_uint32_t *a,
|
||||||
return (u32)_InterlockedExchange((volatile long*)&a->val_dont_use, v);
|
return (u32)_InterlockedExchange((volatile long*)&a->val_dont_use, v);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef _WIN64
|
|
||||||
|
|
||||||
INLINE bool atomic_compare_exchange_strong(volatile atomic_uint8_t *a,
|
INLINE bool atomic_compare_exchange_strong(volatile atomic_uint8_t *a,
|
||||||
u8 *cmp,
|
u8 *cmp,
|
||||||
u8 xchgv,
|
u8 xchgv,
|
||||||
memory_order mo) {
|
memory_order mo) {
|
||||||
|
#ifdef _WIN64
|
||||||
|
// TODO(wwchrome): Implement same functionality without inline asm.
|
||||||
|
// Inline asm not supported in Win64.
|
||||||
|
__debugbreak();
|
||||||
|
return false;
|
||||||
|
#else
|
||||||
(void)mo;
|
(void)mo;
|
||||||
DCHECK(!((uptr)a % sizeof(*a)));
|
DCHECK(!((uptr)a % sizeof(*a)));
|
||||||
u8 cmpv = *cmp;
|
u8 cmpv = *cmp;
|
||||||
|
@ -192,9 +196,8 @@ INLINE bool atomic_compare_exchange_strong(volatile atomic_uint8_t *a,
|
||||||
return true;
|
return true;
|
||||||
*cmp = prev;
|
*cmp = prev;
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
INLINE bool atomic_compare_exchange_strong(volatile atomic_uintptr_t *a,
|
INLINE bool atomic_compare_exchange_strong(volatile atomic_uintptr_t *a,
|
||||||
uptr *cmp,
|
uptr *cmp,
|
||||||
|
|
|
@ -3,6 +3,12 @@ set(ASAN_LIT_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR})
|
||||||
set(ASAN_TESTSUITES)
|
set(ASAN_TESTSUITES)
|
||||||
set(ASAN_DYNAMIC_TESTSUITES)
|
set(ASAN_DYNAMIC_TESTSUITES)
|
||||||
|
|
||||||
|
# TODO(wwchrome): Re-enable Win64 asan tests 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()
|
||||||
|
|
||||||
macro(get_bits_for_arch arch bits)
|
macro(get_bits_for_arch arch bits)
|
||||||
if (${arch} MATCHES "i386|i686|arm|mips|mipsel")
|
if (${arch} MATCHES "i386|i686|arm|mips|mipsel")
|
||||||
set(${bits} 32)
|
set(${bits} 32)
|
||||||
|
@ -102,6 +108,7 @@ set_target_properties(check-asan PROPERTIES FOLDER "ASan tests")
|
||||||
if(COMPILER_RT_ASAN_HAS_STATIC_RUNTIME)
|
if(COMPILER_RT_ASAN_HAS_STATIC_RUNTIME)
|
||||||
# Add check-dynamic-asan target. It is a part of check-all only on Windows,
|
# 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.
|
# where we want to always test both dynamic and static runtime.
|
||||||
|
|
||||||
if(NOT OS_NAME MATCHES "Windows")
|
if(NOT OS_NAME MATCHES "Windows")
|
||||||
set(EXCLUDE_FROM_ALL TRUE)
|
set(EXCLUDE_FROM_ALL TRUE)
|
||||||
endif()
|
endif()
|
||||||
|
@ -115,3 +122,8 @@ if(COMPILER_RT_ASAN_HAS_STATIC_RUNTIME)
|
||||||
set(EXCLUDE_FROM_ALL FALSE)
|
set(EXCLUDE_FROM_ALL FALSE)
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
# TODO(wwchrome): Re-enable the tests for asan Win64 when ready.
|
||||||
|
if(NOT OS_NAME MATCHES "Windows" OR CMAKE_SIZEOF_VOID_P EQUAL 8)
|
||||||
|
set(EXCLUDE_FROM_ALL FALSE)
|
||||||
|
endif()
|
||||||
|
|
|
@ -32,7 +32,11 @@ foreach(arch ${UBSAN_TEST_ARCH})
|
||||||
add_ubsan_testsuite("Standalone" ubsan ${arch})
|
add_ubsan_testsuite("Standalone" ubsan ${arch})
|
||||||
|
|
||||||
if(COMPILER_RT_HAS_ASAN AND ";${ASAN_SUPPORTED_ARCH};" MATCHES ";${arch};")
|
if(COMPILER_RT_HAS_ASAN AND ";${ASAN_SUPPORTED_ARCH};" MATCHES ";${arch};")
|
||||||
add_ubsan_testsuite("AddressSanitizer" asan ${arch})
|
# TODO(wwchrome): Re-enable ubsan for asan win 64-bit when ready.
|
||||||
|
# Disable ubsan with AddressSanitizer tests for Windows 64-bit.
|
||||||
|
if(NOT OS_NAME MATCHES "Windows" OR CMAKE_SIZEOF_VOID_P EQUAL 4)
|
||||||
|
add_ubsan_testsuite("AddressSanitizer" asan ${arch})
|
||||||
|
endif()
|
||||||
endif()
|
endif()
|
||||||
if(COMPILER_RT_HAS_MSAN AND ";${MSAN_SUPPORTED_ARCH};" MATCHES ";${arch};")
|
if(COMPILER_RT_HAS_MSAN AND ";${MSAN_SUPPORTED_ARCH};" MATCHES ";${arch};")
|
||||||
add_ubsan_testsuite("MemorySanitizer" msan ${arch})
|
add_ubsan_testsuite("MemorySanitizer" msan ${arch})
|
||||||
|
|
Loading…
Reference in New Issue