diff options
| -rw-r--r-- | compiler-rt/lib/asan/asan_interceptors.cc | 80 | ||||
| -rw-r--r-- | compiler-rt/lib/asan/asan_malloc_win.cc | 1 | ||||
| -rw-r--r-- | compiler-rt/lib/asan/asan_win.cc | 4 | ||||
| -rw-r--r-- | compiler-rt/lib/asan/interception/interception.h | 5 | ||||
| -rw-r--r-- | compiler-rt/lib/asan/interception/interception_win.cc | 36 | ||||
| -rw-r--r-- | compiler-rt/lib/asan/interception/interception_win.h | 33 |
6 files changed, 119 insertions, 40 deletions
diff --git a/compiler-rt/lib/asan/asan_interceptors.cc b/compiler-rt/lib/asan/asan_interceptors.cc index b1f7ef494e8..cd824452ff3 100644 --- a/compiler-rt/lib/asan/asan_interceptors.cc +++ b/compiler-rt/lib/asan/asan_interceptors.cc @@ -25,12 +25,6 @@ #include <new> -#if defined(_WIN32) -// FIXME: remove when we start intercepting on Windows. Currently it's needed to -// define memset/memcpy intrinsics. -# include <intrin.h> -#endif // _WIN32 - #if defined(__APPLE__) // FIXME(samsonov): Gradually replace system headers with declarations of // intercepted functions. @@ -299,6 +293,7 @@ INTERCEPTOR(void, longjmp, void *env, int val) { REAL(longjmp)(env, val); } +#if !defined(_WIN32) INTERCEPTOR(void, _longjmp, void *env, int val) { __asan_handle_no_return(); REAL(_longjmp)(env, val); @@ -308,6 +303,7 @@ INTERCEPTOR(void, siglongjmp, void *env, int val) { __asan_handle_no_return(); REAL(siglongjmp)(env, val); } +#endif #if ASAN_HAS_EXCEPTIONS == 1 #ifdef __APPLE__ @@ -586,13 +582,10 @@ INTERCEPTOR(size_t, strnlen, const char *s, size_t maxlen) { // ---------------------- InitializeAsanInterceptors ---------------- {{{1 namespace __asan { void InitializeAsanInterceptors() { -#ifndef __APPLE__ - CHECK(INTERCEPT_FUNCTION(index)); -#else - CHECK(OVERRIDE_FUNCTION(index, WRAP(strchr))); -#endif + // Intercept mem* functions. CHECK(INTERCEPT_FUNCTION(memcmp)); CHECK(INTERCEPT_FUNCTION(memmove)); + CHECK(INTERCEPT_FUNCTION(memset)); #ifdef __APPLE__ // Wrap memcpy() on OS X 10.6 only, because on 10.7 memcpy() and memmove() // are resolved into memmove$VARIANT$sse42. @@ -608,47 +601,67 @@ void InitializeAsanInterceptors() { // Always wrap memcpy() on non-Darwin platforms. CHECK(INTERCEPT_FUNCTION(memcpy)); #endif - CHECK(INTERCEPT_FUNCTION(memset)); - CHECK(INTERCEPT_FUNCTION(strcasecmp)); + + // Intercept str* functions. CHECK(INTERCEPT_FUNCTION(strcat)); // NOLINT CHECK(INTERCEPT_FUNCTION(strchr)); CHECK(INTERCEPT_FUNCTION(strcmp)); CHECK(INTERCEPT_FUNCTION(strcpy)); // NOLINT - CHECK(INTERCEPT_FUNCTION(strdup)); CHECK(INTERCEPT_FUNCTION(strlen)); - CHECK(INTERCEPT_FUNCTION(strncasecmp)); CHECK(INTERCEPT_FUNCTION(strncmp)); CHECK(INTERCEPT_FUNCTION(strncpy)); +#if !defined(_WIN32) + CHECK(INTERCEPT_FUNCTION(strcasecmp)); + CHECK(INTERCEPT_FUNCTION(strdup)); + CHECK(INTERCEPT_FUNCTION(strncasecmp)); +# ifndef __APPLE__ + CHECK(INTERCEPT_FUNCTION(index)); +# else + CHECK(OVERRIDE_FUNCTION(index, WRAP(strchr))); +# endif +#endif +#if !defined(__APPLE__) + CHECK(INTERCEPT_FUNCTION(strnlen)); +#endif -#ifndef ANDROID + // Intecept signal- and jump-related functions. + CHECK(INTERCEPT_FUNCTION(longjmp)); +#if !defined(ANDROID) && !defined(_WIN32) CHECK(INTERCEPT_FUNCTION(sigaction)); CHECK(INTERCEPT_FUNCTION(signal)); #endif - CHECK(INTERCEPT_FUNCTION(longjmp)); +#if !defined(_WIN32) CHECK(INTERCEPT_FUNCTION(_longjmp)); INTERCEPT_FUNCTION(__cxa_throw); - CHECK(INTERCEPT_FUNCTION(pthread_create)); - -#ifdef _WIN32 - // FIXME: We don't intercept properly on Windows yet, so use the original - // functions for now. - REAL(memcpy) = memcpy; - REAL(memset) = memset; +# if !defined(__APPLE__) + // On Darwin siglongjmp tailcalls longjmp, so we don't want to intercept it + // there. + CHECK(INTERCEPT_FUNCTION(siglongjmp)); +# endif #endif -#ifdef __APPLE__ - CHECK(INTERCEPT_FUNCTION(dispatch_async_f)); - CHECK(INTERCEPT_FUNCTION(dispatch_sync_f)); - CHECK(INTERCEPT_FUNCTION(dispatch_after_f)); - CHECK(INTERCEPT_FUNCTION(dispatch_barrier_async_f)); - CHECK(INTERCEPT_FUNCTION(dispatch_group_async_f)); + // Intercept threading-related functions +#if !defined(_WIN32) + CHECK(INTERCEPT_FUNCTION(pthread_create)); +# if defined(__APPLE__) // We don't need to intercept pthread_workqueue_additem_np() to support the // libdispatch API, but it helps us to debug the unsupported functions. Let's // intercept it only during verbose runs. if (FLAG_v >= 2) { CHECK(INTERCEPT_FUNCTION(pthread_workqueue_additem_np)); } +# endif +#endif + + // Some Mac-specific interceptors. +#if defined(__APPLE__) + CHECK(INTERCEPT_FUNCTION(dispatch_async_f)); + CHECK(INTERCEPT_FUNCTION(dispatch_sync_f)); + CHECK(INTERCEPT_FUNCTION(dispatch_after_f)); + CHECK(INTERCEPT_FUNCTION(dispatch_barrier_async_f)); + CHECK(INTERCEPT_FUNCTION(dispatch_group_async_f)); + // Normally CFStringCreateCopy should not copy constant CF strings. // Replacing the default CFAllocator causes constant strings to be copied // rather than just returned, which leads to bugs in big applications like @@ -657,15 +670,8 @@ void InitializeAsanInterceptors() { // Until this problem is fixed we need to check that the string is // non-constant before calling CFStringCreateCopy. CHECK(INTERCEPT_FUNCTION(CFStringCreateCopy)); -#else - // On Darwin siglongjmp tailcalls longjmp, so we don't want to intercept it - // there. - CHECK(INTERCEPT_FUNCTION(siglongjmp)); #endif -#ifndef __APPLE__ - CHECK(INTERCEPT_FUNCTION(strnlen)); -#endif if (FLAG_v > 0) { Printf("AddressSanitizer: libc interceptors initialized\n"); } diff --git a/compiler-rt/lib/asan/asan_malloc_win.cc b/compiler-rt/lib/asan/asan_malloc_win.cc index b4ce1222936..40429f481e2 100644 --- a/compiler-rt/lib/asan/asan_malloc_win.cc +++ b/compiler-rt/lib/asan/asan_malloc_win.cc @@ -21,6 +21,7 @@ namespace __asan { void ReplaceSystemMalloc() { // FIXME: investigate whether any action is needed. + // Currenlty, we fail to intercept malloc() called from intercepted _strdup(). } } // namespace __asan diff --git a/compiler-rt/lib/asan/asan_win.cc b/compiler-rt/lib/asan/asan_win.cc index 60e21ca4c68..86bcc2c26a0 100644 --- a/compiler-rt/lib/asan/asan_win.cc +++ b/compiler-rt/lib/asan/asan_win.cc @@ -214,7 +214,9 @@ void AsanTSDSet(void *tsd) { // ---------------------- Various stuff ---------------- {{{1 void *AsanDoesNotSupportStaticLinkage() { - // FIXME: shall we do anything here on Windows? +#if !defined(_DLL) || defined(_DEBUG) +#error Please build the runtime with /MD +#endif return NULL; } diff --git a/compiler-rt/lib/asan/interception/interception.h b/compiler-rt/lib/asan/interception/interception.h index c7cbd0f5635..ae56af32f0e 100644 --- a/compiler-rt/lib/asan/interception/interception.h +++ b/compiler-rt/lib/asan/interception/interception.h @@ -77,7 +77,7 @@ # define INTERCEPTOR_ATTRIBUTE #elif defined(_WIN32) // TODO(timurrrr): we're likely to use something else later on Windows. -# define WRAP(x) wrap_##x +# define WRAP(x) x # define WRAPPER_NAME(x) #x # define INTERCEPTOR_ATTRIBUTE #else @@ -128,7 +128,8 @@ # define INTERCEPT_FUNCTION(func) INTERCEPT_FUNCTION_MAC(func) #else // defined(_WIN32) // FIXME: deal with interception on Win. -# define INTERCEPT_FUNCTION(func) true +# include "interception_win.h" +# define INTERCEPT_FUNCTION(func) INTERCEPT_FUNCTION_WIN(func) #endif #undef INCLUDED_FROM_INTERCEPTION_LIB diff --git a/compiler-rt/lib/asan/interception/interception_win.cc b/compiler-rt/lib/asan/interception/interception_win.cc new file mode 100644 index 00000000000..a3f0f2b0c0b --- /dev/null +++ b/compiler-rt/lib/asan/interception/interception_win.cc @@ -0,0 +1,36 @@ +//===-- interception_linux.cc -----------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file is a part of AddressSanitizer, an address sanity checker. +// +// Windows-specific interception methods. +//===----------------------------------------------------------------------===// + +#ifdef _WIN32 + +#include <windows.h> + +namespace __interception { + +bool GetRealFunctionAddress(const char *func_name, void **func_addr) { + const char *DLLS[] = { + "msvcr80.dll", + "msvcr90.dll", + "kernel32.dll", + NULL + }; + *func_addr = NULL; + for (size_t i = 0; *func_addr == NULL && DLLS[i]; ++i) { + *func_addr = GetProcAddress(GetModuleHandleA(DLLS[i]), func_name); + } + return (*func_addr != NULL); +} +} // namespace __interception + +#endif // _WIN32 diff --git a/compiler-rt/lib/asan/interception/interception_win.h b/compiler-rt/lib/asan/interception/interception_win.h new file mode 100644 index 00000000000..fb7988eac70 --- /dev/null +++ b/compiler-rt/lib/asan/interception/interception_win.h @@ -0,0 +1,33 @@ +//===-- interception_linux.h ------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file is a part of AddressSanitizer, an address sanity checker. +// +// Windows-specific interception methods. +//===----------------------------------------------------------------------===// + +#ifdef _WIN32 + +#if !defined(INCLUDED_FROM_INTERCEPTION_LIB) +# error "interception_win.h should be included from interception library only" +#endif + +#ifndef INTERCEPTION_WIN_H +#define INTERCEPTION_WIN_H + +namespace __interception { +// returns true if a function with the given name was found. +bool GetRealFunctionAddress(const char *func_name, void **func_addr); +} // namespace __interception + +#define INTERCEPT_FUNCTION_WIN(func) \ + ::__interception::GetRealFunctionAddress(#func, (void**)&REAL(func)) + +#endif // INTERCEPTION_WIN_H +#endif // _WIN32 |

