diff options
author | Timur Iskhodzhanov <timurrrr@google.com> | 2012-02-24 15:28:43 +0000 |
---|---|---|
committer | Timur Iskhodzhanov <timurrrr@google.com> | 2012-02-24 15:28:43 +0000 |
commit | 0f9c9a53327e8e68b5865c204b9fb20390a53f57 (patch) | |
tree | 4756479afbc4965e35d05f6bd4e5407dff847952 /compiler-rt | |
parent | 926d101640f128a0bd32be2039c795d4b3b2fb96 (diff) | |
download | bcm5719-llvm-0f9c9a53327e8e68b5865c204b9fb20390a53f57.tar.gz bcm5719-llvm-0f9c9a53327e8e68b5865c204b9fb20390a53f57.zip |
[ASan] Intercept CreateThread on Windows
llvm-svn: 151366
Diffstat (limited to 'compiler-rt')
-rw-r--r-- | compiler-rt/lib/asan/asan_interceptors.cc | 28 | ||||
-rw-r--r-- | compiler-rt/lib/asan/asan_internal.h | 7 | ||||
-rw-r--r-- | compiler-rt/lib/asan/asan_thread.cc | 6 | ||||
-rw-r--r-- | compiler-rt/lib/asan/asan_thread.h | 6 | ||||
-rw-r--r-- | compiler-rt/lib/asan/asan_win.cc | 2 | ||||
-rw-r--r-- | compiler-rt/lib/asan/interception/interception.h | 31 |
6 files changed, 64 insertions, 16 deletions
diff --git a/compiler-rt/lib/asan/asan_interceptors.cc b/compiler-rt/lib/asan/asan_interceptors.cc index cd824452ff3..1d85facd754 100644 --- a/compiler-rt/lib/asan/asan_interceptors.cc +++ b/compiler-rt/lib/asan/asan_interceptors.cc @@ -254,7 +254,7 @@ void operator delete(void *ptr, std::nothrow_t const&) throw() void operator delete[](void *ptr, std::nothrow_t const&) throw() { OPERATOR_DELETE_BODY;} -static void *asan_thread_start(void *arg) { +static thread_return_t THREAD_CALLING_CONV asan_thread_start(void *arg) { AsanThread *t = (AsanThread*)arg; asanThreadRegistry().SetCurrent(t); return t->ThreadStart(); @@ -579,6 +579,27 @@ INTERCEPTOR(size_t, strnlen, const char *s, size_t maxlen) { } #endif +#if defined(_WIN32) +INTERCEPTOR_WINAPI(DWORD, CreateThread, + void* security, size_t stack_size, + DWORD (__stdcall *start_routine)(void*), void* arg, + DWORD flags, void* tid) { + GET_STACK_TRACE_HERE(kStackTraceMax); + int current_tid = asanThreadRegistry().GetCurrentTidOrMinusOne(); + AsanThread *t = AsanThread::Create(current_tid, start_routine, arg, &stack); + asanThreadRegistry().RegisterThread(t); + return REAL(CreateThread)(security, stack_size, + asan_thread_start, t, flags, tid); +} + +namespace __asan { +void InitializeWindowsInterceptors() { + CHECK(INTERCEPT_FUNCTION(CreateThread)); +} + +} // namespace __asan +#endif + // ---------------------- InitializeAsanInterceptors ---------------- {{{1 namespace __asan { void InitializeAsanInterceptors() { @@ -654,6 +675,11 @@ void InitializeAsanInterceptors() { # endif #endif + // Some Windows-specific interceptors. +#if defined(_WIN32) + InitializeWindowsInterceptors(); +#endif + // Some Mac-specific interceptors. #if defined(__APPLE__) CHECK(INTERCEPT_FUNCTION(dispatch_async_f)); diff --git a/compiler-rt/lib/asan/asan_internal.h b/compiler-rt/lib/asan/asan_internal.h index a3c6b383f41..fde24d597a8 100644 --- a/compiler-rt/lib/asan/asan_internal.h +++ b/compiler-rt/lib/asan/asan_internal.h @@ -30,6 +30,7 @@ typedef __int8 int8_t; typedef __int16 int16_t; typedef __int32 int32_t; typedef __int64 int64_t; +typedef unsigned long DWORD; // NOLINT extern "C" void* _ReturnAddress(void); # pragma intrinsic(_ReturnAddress) @@ -265,6 +266,8 @@ const size_t kPageSize = 1UL << kPageSizeBits; const size_t kMmapGranularity = kPageSize; # define GET_CALLER_PC() (uintptr_t)__builtin_return_address(0) # define GET_CURRENT_FRAME() (uintptr_t)__builtin_frame_address(0) +# define THREAD_CALLING_CONV +typedef void* thread_return_t; #else const size_t kMmapGranularity = 1UL << 16; # define GET_CALLER_PC() (uintptr_t)_ReturnAddress() @@ -272,6 +275,8 @@ const size_t kMmapGranularity = 1UL << 16; // FIXME: This macro is still used when printing error reports though it's not // clear if the BP value is needed in the ASan reports on Windows. # define GET_CURRENT_FRAME() (uintptr_t)0xDEADBEEF +# define THREAD_CALLING_CONV __stdcall +typedef DWORD thread_return_t; # ifndef ASAN_USE_EXTERNAL_SYMBOLIZER # define ASAN_USE_EXTERNAL_SYMBOLIZER __asan::WinSymbolize @@ -279,6 +284,8 @@ bool WinSymbolize(const void *addr, char *out_buffer, int buffer_size); # endif #endif +typedef thread_return_t (THREAD_CALLING_CONV *thread_callback_t)(void* arg); + #define GET_BP_PC_SP \ uintptr_t bp = GET_CURRENT_FRAME(); \ uintptr_t pc = GET_CALLER_PC(); \ diff --git a/compiler-rt/lib/asan/asan_thread.cc b/compiler-rt/lib/asan/asan_thread.cc index 6e6436b8144..c829292d008 100644 --- a/compiler-rt/lib/asan/asan_thread.cc +++ b/compiler-rt/lib/asan/asan_thread.cc @@ -26,7 +26,7 @@ AsanThread::AsanThread(LinkerInitialized x) malloc_storage_(x), stats_(x) { } -AsanThread *AsanThread::Create(int parent_tid, void *(*start_routine) (void *), +AsanThread *AsanThread::Create(int parent_tid, thread_callback_t start_routine, void *arg, AsanStackTrace *stack) { size_t size = RoundUpTo(sizeof(AsanThread), kPageSize); AsanThread *thread = (AsanThread*)AsanMmapSomewhereOrDie(size, __FUNCTION__); @@ -80,7 +80,7 @@ void AsanThread::Init() { fake_stack_.Init(stack_size()); } -void *AsanThread::ThreadStart() { +thread_return_t AsanThread::ThreadStart() { Init(); if (!start_routine_) { @@ -91,7 +91,7 @@ void *AsanThread::ThreadStart() { return 0; } - void *res = start_routine_(arg_); + thread_return_t res = start_routine_(arg_); malloc_storage().CommitBack(); this->Destroy(); diff --git a/compiler-rt/lib/asan/asan_thread.h b/compiler-rt/lib/asan/asan_thread.h index 9fc1e26ca6b..09607d91d6e 100644 --- a/compiler-rt/lib/asan/asan_thread.h +++ b/compiler-rt/lib/asan/asan_thread.h @@ -65,12 +65,12 @@ class AsanThreadSummary { class AsanThread { public: explicit AsanThread(LinkerInitialized); // for T0. - static AsanThread *Create(int parent_tid, void *(*start_routine) (void *), + static AsanThread *Create(int parent_tid, thread_callback_t start_routine, void *arg, AsanStackTrace *stack); void Destroy(); void Init(); // Should be called from the thread itself. - void *ThreadStart(); + thread_return_t ThreadStart(); uintptr_t stack_top() { return stack_top_; } uintptr_t stack_bottom() { return stack_bottom_; } @@ -96,7 +96,7 @@ class AsanThread { void SetThreadStackTopAndBottom(); void ClearShadowForThreadStack(); AsanThreadSummary *summary_; - void *(*start_routine_) (void *param); + thread_callback_t start_routine_; void *arg_; uintptr_t stack_top_; uintptr_t stack_bottom_; diff --git a/compiler-rt/lib/asan/asan_win.cc b/compiler-rt/lib/asan/asan_win.cc index 2692b0db5b7..d47ff08e9e0 100644 --- a/compiler-rt/lib/asan/asan_win.cc +++ b/compiler-rt/lib/asan/asan_win.cc @@ -47,7 +47,7 @@ void *AsanMprotect(uintptr_t fixed_addr, size_t size) { } void AsanUnmapOrDie(void *addr, size_t size) { - UNIMPLEMENTED(); + CHECK(VirtualFree(addr, size, MEM_DECOMMIT)); } // ---------------------- IO ---------------- {{{1 diff --git a/compiler-rt/lib/asan/interception/interception.h b/compiler-rt/lib/asan/interception/interception.h index ae56af32f0e..50c03bb1708 100644 --- a/compiler-rt/lib/asan/interception/interception.h +++ b/compiler-rt/lib/asan/interception/interception.h @@ -100,21 +100,37 @@ DECLARE_REAL(ret_type, func, ##__VA_ARGS__); \ extern "C" ret_type WRAP(func)(__VA_ARGS__); +// FIXME(timurrrr): We might need to add DECLARE_REAL_EX etc to support +// different calling conventions later. + +#define DEFINE_REAL_EX(ret_type, convention, func, ...); \ + typedef ret_type (convention *FUNC_TYPE(func))(__VA_ARGS__); \ + namespace __interception { \ + FUNC_TYPE(func) PTR_TO_REAL(func); \ + } + // Generally, you don't need to use DEFINE_REAL by itself, as INTERCEPTOR // macros does its job. In exceptional cases you may need to call REAL(foo) // without defining INTERCEPTOR(..., foo, ...). For example, if you override // foo with an interceptor for other function. +#define DEFAULT_CONVENTION + #define DEFINE_REAL(ret_type, func, ...); \ - typedef ret_type (*FUNC_TYPE(func))(__VA_ARGS__); \ - namespace __interception { \ - FUNC_TYPE(func) PTR_TO_REAL(func); \ - } + DEFINE_REAL_EX(ret_type, DEFAULT_CONVENTION, func, __VA_ARGS__); -#define INTERCEPTOR(ret_type, func, ...) \ - DEFINE_REAL(ret_type, func, __VA_ARGS__); \ +#define INTERCEPTOR_EX(ret_type, convention, func, ...) \ + DEFINE_REAL_EX(ret_type, convention, func, __VA_ARGS__); \ extern "C" \ INTERCEPTOR_ATTRIBUTE \ - ret_type WRAP(func)(__VA_ARGS__) + ret_type convention WRAP(func)(__VA_ARGS__) + +#define INTERCEPTOR(ret_type, func, ...) \ + INTERCEPTOR_EX(ret_type, DEFAULT_CONVENTION, func, __VA_ARGS__) + +#if defined(_WIN32) +# define INTERCEPTOR_WINAPI(ret_type, func, ...) \ + INTERCEPTOR_EX(ret_type, __stdcall, func, __VA_ARGS__) +#endif #define INCLUDED_FROM_INTERCEPTION_LIB @@ -127,7 +143,6 @@ OVERRIDE_FUNCTION_MAC(old_func, new_func) # define INTERCEPT_FUNCTION(func) INTERCEPT_FUNCTION_MAC(func) #else // defined(_WIN32) - // FIXME: deal with interception on Win. # include "interception_win.h" # define INTERCEPT_FUNCTION(func) INTERCEPT_FUNCTION_WIN(func) #endif |