Skip to content

Commit 00f3f6e

Browse files
committed
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
1 parent 0364f67 commit 00f3f6e

File tree

6 files changed

+57
-12
lines changed

6 files changed

+57
-12
lines changed

compiler-rt/cmake/config-ix.cmake

+2-4
Original file line numberDiff line numberDiff line change
@@ -429,15 +429,13 @@ else()
429429
set(COMPILER_RT_HAS_SANITIZER_COMMON FALSE)
430430
endif()
431431

432-
if (COMPILER_RT_HAS_SANITIZER_COMMON AND
433-
(NOT OS_NAME MATCHES "Windows" OR CMAKE_SIZEOF_VOID_P EQUAL 4))
432+
if (COMPILER_RT_HAS_SANITIZER_COMMON)
434433
set(COMPILER_RT_HAS_INTERCEPTION TRUE)
435434
else()
436435
set(COMPILER_RT_HAS_INTERCEPTION FALSE)
437436
endif()
438437

439-
if (COMPILER_RT_HAS_SANITIZER_COMMON AND ASAN_SUPPORTED_ARCH AND
440-
(NOT OS_NAME MATCHES "Windows" OR CMAKE_SIZEOF_VOID_P EQUAL 4))
438+
if (COMPILER_RT_HAS_SANITIZER_COMMON AND ASAN_SUPPORTED_ARCH)
441439
set(COMPILER_RT_HAS_ASAN TRUE)
442440
else()
443441
set(COMPILER_RT_HAS_ASAN FALSE)

compiler-rt/lib/asan/asan_win.cc

+17
Original file line numberDiff line numberDiff line change
@@ -46,11 +46,20 @@ void __sanitizer_default_free_hook(void *ptr) { }
4646
const char* __asan_default_default_options() { return ""; }
4747
const char* __asan_default_default_suppressions() { return ""; }
4848
void __asan_default_on_error() {}
49+
// 64-bit msvc will not prepend an underscore for symbols.
50+
#ifdef _WIN64
51+
#pragma comment(linker, "/alternatename:__sanitizer_malloc_hook=__sanitizer_default_malloc_hook") // NOLINT
52+
#pragma comment(linker, "/alternatename:__sanitizer_free_hook=__sanitizer_default_free_hook") // NOLINT
53+
#pragma comment(linker, "/alternatename:__asan_default_options=__asan_default_default_options") // NOLINT
54+
#pragma comment(linker, "/alternatename:__asan_default_suppressions=__asan_default_default_suppressions") // NOLINT
55+
#pragma comment(linker, "/alternatename:__asan_on_error=__asan_default_on_error") // NOLINT
56+
#else
4957
#pragma comment(linker, "/alternatename:___sanitizer_malloc_hook=___sanitizer_default_malloc_hook") // NOLINT
5058
#pragma comment(linker, "/alternatename:___sanitizer_free_hook=___sanitizer_default_free_hook") // NOLINT
5159
#pragma comment(linker, "/alternatename:___asan_default_options=___asan_default_default_options") // NOLINT
5260
#pragma comment(linker, "/alternatename:___asan_default_suppressions=___asan_default_default_suppressions") // NOLINT
5361
#pragma comment(linker, "/alternatename:___asan_on_error=___asan_default_on_error") // NOLINT
62+
#endif
5463
// }}}
5564
} // extern "C"
5665

@@ -61,6 +70,9 @@ INTERCEPTOR_WINAPI(void, RaiseException, void *a, void *b, void *c, void *d) {
6170
REAL(RaiseException)(a, b, c, d);
6271
}
6372

73+
// TODO(wwchrome): Win64 has no _except_handler3/4.
74+
// Need to implement _C_specific_handler instead.
75+
#ifndef _WIN64
6476
INTERCEPTOR(int, _except_handler3, void *a, void *b, void *c, void *d) {
6577
CHECK(REAL(_except_handler3));
6678
__asan_handle_no_return();
@@ -76,6 +88,7 @@ INTERCEPTOR(int, _except_handler4, void *a, void *b, void *c, void *d) {
7688
__asan_handle_no_return();
7789
return REAL(_except_handler4)(a, b, c, d);
7890
}
91+
#endif
7992

8093
static thread_return_t THREAD_CALLING_CONV asan_thread_start(void *arg) {
8194
AsanThread *t = (AsanThread*)arg;
@@ -139,8 +152,12 @@ namespace __asan {
139152
void InitializePlatformInterceptors() {
140153
ASAN_INTERCEPT_FUNC(CreateThread);
141154
ASAN_INTERCEPT_FUNC(RaiseException);
155+
156+
// TODO(wwchrome): Win64 uses _C_specific_handler instead.
157+
#ifndef _WIN64
142158
ASAN_INTERCEPT_FUNC(_except_handler3);
143159
ASAN_INTERCEPT_FUNC(_except_handler4);
160+
#endif
144161

145162
// NtWaitForWorkViaWorkerFactory is always linked dynamically.
146163
CHECK(::__interception::OverrideFunction(

compiler-rt/lib/interception/interception_win.cc

+14-3
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ static void _memcpy(void *dst, void *src, size_t sz) {
3636
}
3737

3838
static void WriteJumpInstruction(char *jmp_from, char *to) {
39-
// jmp XXYYZZWW = E9 WW ZZ YY XX, where XXYYZZWW is an offset fromt jmp_from
39+
// jmp XXYYZZWW = E9 WW ZZ YY XX, where XXYYZZWW is an offset from jmp_from
4040
// to the next instruction to the destination.
4141
ptrdiff_t offset = to - jmp_from - 5;
4242
*jmp_from = '\xE9';
@@ -68,6 +68,12 @@ static char *GetMemoryForTrampoline(size_t size) {
6868

6969
// Returns 0 on error.
7070
static size_t RoundUpToInstrBoundary(size_t size, char *code) {
71+
#ifdef _WIN64
72+
// TODO(wwchrome): Implement similar logic for x64 instructions.
73+
// Win64 RoundUpToInstrBoundary is not supported yet.
74+
__debugbreak();
75+
return 0;
76+
#else
7177
size_t cursor = 0;
7278
while (cursor < size) {
7379
switch (code[cursor]) {
@@ -140,12 +146,16 @@ static size_t RoundUpToInstrBoundary(size_t size, char *code) {
140146
}
141147

142148
return cursor;
149+
#endif
143150
}
144151

145152
bool OverrideFunction(uptr old_func, uptr new_func, uptr *orig_old_func) {
146153
#ifdef _WIN64
147-
#error OverrideFunction is not yet supported on x64
148-
#endif
154+
// TODO(wwchrome): Implement using x64 jmp.
155+
// OverrideFunction is not yet supported on x64.
156+
__debugbreak();
157+
return false;
158+
#else
149159
// Function overriding works basically like this:
150160
// We write "jmp <new_func>" (5 bytes) at the beginning of the 'old_func'
151161
// to override it.
@@ -190,6 +200,7 @@ bool OverrideFunction(uptr old_func, uptr new_func, uptr *orig_old_func) {
190200
return false; // not clear if this failure bothers us.
191201

192202
return true;
203+
#endif
193204
}
194205

195206
static void **InterestingDLLsAvailable() {

compiler-rt/lib/sanitizer_common/sanitizer_atomic_msvc.h

+7-4
Original file line numberDiff line numberDiff line change
@@ -171,12 +171,16 @@ INLINE u32 atomic_exchange(volatile atomic_uint32_t *a,
171171
return (u32)_InterlockedExchange((volatile long*)&a->val_dont_use, v);
172172
}
173173

174-
#ifndef _WIN64
175-
176174
INLINE bool atomic_compare_exchange_strong(volatile atomic_uint8_t *a,
177175
u8 *cmp,
178176
u8 xchgv,
179177
memory_order mo) {
178+
#ifdef _WIN64
179+
// TODO(wwchrome): Implement same functionality without inline asm.
180+
// Inline asm not supported in Win64.
181+
__debugbreak();
182+
return false;
183+
#else
180184
(void)mo;
181185
DCHECK(!((uptr)a % sizeof(*a)));
182186
u8 cmpv = *cmp;
@@ -192,9 +196,8 @@ INLINE bool atomic_compare_exchange_strong(volatile atomic_uint8_t *a,
192196
return true;
193197
*cmp = prev;
194198
return false;
195-
}
196-
197199
#endif
200+
}
198201

199202
INLINE bool atomic_compare_exchange_strong(volatile atomic_uintptr_t *a,
200203
uptr *cmp,

compiler-rt/test/asan/CMakeLists.txt

+12
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,12 @@ set(ASAN_LIT_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR})
33
set(ASAN_TESTSUITES)
44
set(ASAN_DYNAMIC_TESTSUITES)
55

6+
# TODO(wwchrome): Re-enable Win64 asan tests when ready.
7+
# Disable tests for asan Win64 temporarily.
8+
if(NOT OS_NAME MATCHES "Windows" OR CMAKE_SIZEOF_VOID_P EQUAL 8)
9+
set(EXCLUDE_FROM_ALL TRUE)
10+
endif()
11+
612
macro(get_bits_for_arch arch bits)
713
if (${arch} MATCHES "i386|i686|arm|mips|mipsel")
814
set(${bits} 32)
@@ -102,6 +108,7 @@ set_target_properties(check-asan PROPERTIES FOLDER "ASan tests")
102108
if(COMPILER_RT_ASAN_HAS_STATIC_RUNTIME)
103109
# Add check-dynamic-asan target. It is a part of check-all only on Windows,
104110
# where we want to always test both dynamic and static runtime.
111+
105112
if(NOT OS_NAME MATCHES "Windows")
106113
set(EXCLUDE_FROM_ALL TRUE)
107114
endif()
@@ -115,3 +122,8 @@ if(COMPILER_RT_ASAN_HAS_STATIC_RUNTIME)
115122
set(EXCLUDE_FROM_ALL FALSE)
116123
endif()
117124
endif()
125+
126+
# TODO(wwchrome): Re-enable the tests for asan Win64 when ready.
127+
if(NOT OS_NAME MATCHES "Windows" OR CMAKE_SIZEOF_VOID_P EQUAL 8)
128+
set(EXCLUDE_FROM_ALL FALSE)
129+
endif()

compiler-rt/test/ubsan/CMakeLists.txt

+5-1
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,11 @@ foreach(arch ${UBSAN_TEST_ARCH})
3232
add_ubsan_testsuite("Standalone" ubsan ${arch})
3333

3434
if(COMPILER_RT_HAS_ASAN AND ";${ASAN_SUPPORTED_ARCH};" MATCHES ";${arch};")
35-
add_ubsan_testsuite("AddressSanitizer" asan ${arch})
35+
# TODO(wwchrome): Re-enable ubsan for asan win 64-bit when ready.
36+
# Disable ubsan with AddressSanitizer tests for Windows 64-bit.
37+
if(NOT OS_NAME MATCHES "Windows" OR CMAKE_SIZEOF_VOID_P EQUAL 4)
38+
add_ubsan_testsuite("AddressSanitizer" asan ${arch})
39+
endif()
3640
endif()
3741
if(COMPILER_RT_HAS_MSAN AND ";${MSAN_SUPPORTED_ARCH};" MATCHES ";${arch};")
3842
add_ubsan_testsuite("MemorySanitizer" msan ${arch})

0 commit comments

Comments
 (0)