[compiler-rt] r232377 - [ASan] NFC: Factor out platform-specific interceptors

Timur Iskhodzhanov timurrrr at google.com
Mon Mar 16 07:22:54 PDT 2015


Author: timurrrr
Date: Mon Mar 16 09:22:53 2015
New Revision: 232377

URL: http://llvm.org/viewvc/llvm-project?rev=232377&view=rev
Log:
[ASan] NFC: Factor out platform-specific interceptors

Reviewed at http://reviews.llvm.org/D8321


Modified:
    compiler-rt/trunk/lib/asan/asan_interceptors.cc
    compiler-rt/trunk/lib/asan/asan_interceptors.h
    compiler-rt/trunk/lib/asan/asan_linux.cc
    compiler-rt/trunk/lib/asan/asan_mac.cc
    compiler-rt/trunk/lib/asan/asan_win.cc
    compiler-rt/trunk/lib/interception/interception.h

Modified: compiler-rt/trunk/lib/asan/asan_interceptors.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_interceptors.cc?rev=232377&r1=232376&r2=232377&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_interceptors.cc (original)
+++ compiler-rt/trunk/lib/asan/asan_interceptors.cc Mon Mar 16 09:22:53 2015
@@ -120,17 +120,6 @@ using namespace __asan;  // NOLINT
 DECLARE_REAL_AND_INTERCEPTOR(void *, malloc, uptr)
 DECLARE_REAL_AND_INTERCEPTOR(void, free, void *)
 
-#if !SANITIZER_MAC
-#define ASAN_INTERCEPT_FUNC(name)                                        \
-  do {                                                                   \
-    if ((!INTERCEPT_FUNCTION(name) || !REAL(name)))                      \
-      VReport(1, "AddressSanitizer: failed to intercept '" #name "'\n"); \
-  } while (0)
-#else
-// OS X interceptors don't need to be initialized with INTERCEPT_FUNCTION.
-#define ASAN_INTERCEPT_FUNC(name)
-#endif  // SANITIZER_MAC
-
 #define ASAN_INTERCEPTOR_ENTER(ctx, func)                                      \
   AsanInterceptorContext _ctx = {#func};                                       \
   ctx = (void *)&_ctx;                                                         \
@@ -206,12 +195,6 @@ struct ThreadStartParam {
 };
 
 static thread_return_t THREAD_CALLING_CONV asan_thread_start(void *arg) {
-#if SANITIZER_WINDOWS
-  // FIXME: this is a bandaid fix for PR22025.
-  AsanThread *t = (AsanThread*)arg;
-  SetCurrentThread(t);
-  return t->ThreadStart(GetTid(), /* signal_thread_is_registered */ nullptr);
-#else
   ThreadStartParam *param = reinterpret_cast<ThreadStartParam *>(arg);
   AsanThread *t = nullptr;
   while ((t = reinterpret_cast<AsanThread *>(
@@ -219,7 +202,6 @@ static thread_return_t THREAD_CALLING_CO
     internal_sched_yield();
   SetCurrentThread(t);
   return t->ThreadStart(GetTid(), &param->is_registered);
-#endif
 }
 
 #if ASAN_INTERCEPT_PTHREAD_CREATE
@@ -363,30 +345,6 @@ INTERCEPTOR(void, __cxa_throw, void *a,
 }
 #endif
 
-#if SANITIZER_WINDOWS
-INTERCEPTOR_WINAPI(void, RaiseException, void *a, void *b, void *c, void *d) {
-  CHECK(REAL(RaiseException));
-  __asan_handle_no_return();
-  REAL(RaiseException)(a, b, c, d);
-}
-
-INTERCEPTOR(int, _except_handler3, void *a, void *b, void *c, void *d) {
-  CHECK(REAL(_except_handler3));
-  __asan_handle_no_return();
-  return REAL(_except_handler3)(a, b, c, d);
-}
-
-#if ASAN_DYNAMIC
-// This handler is named differently in -MT and -MD CRTs.
-#define _except_handler4 _except_handler4_common
-#endif
-INTERCEPTOR(int, _except_handler4, void *a, void *b, void *c, void *d) {
-  CHECK(REAL(_except_handler4));
-  __asan_handle_no_return();
-  return REAL(_except_handler4)(a, b, c, d);
-}
-#endif
-
 static inline int CharCmp(unsigned char c1, unsigned char c2) {
   return (c1 == c2) ? 0 : (c1 < c2) ? -1 : 1;
 }
@@ -813,82 +771,6 @@ INTERCEPTOR(int, fork, void) {
 }
 #endif  // ASAN_INTERCEPT_FORK
 
-#if SANITIZER_WINDOWS
-INTERCEPTOR_WINAPI(DWORD, CreateThread,
-                   void* security, uptr stack_size,
-                   DWORD (__stdcall *start_routine)(void*), void* arg,
-                   DWORD thr_flags, void* tid) {
-  // Strict init-order checking is thread-hostile.
-  if (flags()->strict_init_order)
-    StopInitOrderChecking();
-  GET_STACK_TRACE_THREAD;
-  // FIXME: The CreateThread interceptor is not the same as a pthread_create
-  // one.  This is a bandaid fix for PR22025.
-  bool detached = false;  // FIXME: how can we determine it on Windows?
-  u32 current_tid = GetCurrentTidOrInvalid();
-  AsanThread *t =
-        AsanThread::Create(start_routine, arg, current_tid, &stack, detached);
-  return REAL(CreateThread)(security, stack_size,
-                            asan_thread_start, t, thr_flags, tid);
-}
-
-struct UserWorkItemInfo {
-  DWORD (__stdcall *function)(void *arg);
-  void *arg;
-  u32 parent_tid;
-};
-
-static BlockingMutex mu_for_thread_tracking(LINKER_INITIALIZED);
-
-// QueueUserWorkItem may silently create a thread we should keep track of.
-// We achieve this by wrapping the user-supplied work items with our function.
-static DWORD __stdcall QueueUserWorkItemWrapper(void *arg) {
-  UserWorkItemInfo *item = (UserWorkItemInfo *)arg;
-
-  {
-    // FIXME: GetCurrentThread relies on TSD, which might not play well with
-    // system thread pools.  We might want to use something like reference
-    // counting to zero out GetCurrentThread() underlying storage when the last
-    // work item finishes?  Or can we disable reclaiming of threads in the pool?
-    BlockingMutexLock l(&mu_for_thread_tracking);
-    AsanThread *t = GetCurrentThread();
-    if (!t) {
-      GET_STACK_TRACE_THREAD;
-      t = AsanThread::Create(/* start_routine */ nullptr, /* arg */ nullptr,
-                             item->parent_tid, &stack, /* detached */ true);
-      t->Init();
-      asanThreadRegistry().StartThread(t->tid(), 0, 0);
-      SetCurrentThread(t);
-    }
-  }
-
-  DWORD ret = item->function(item->arg);
-  delete item;
-  return ret;
-}
-
-INTERCEPTOR_WINAPI(DWORD, QueueUserWorkItem, DWORD(__stdcall *function)(void *),
-                   void *arg, DWORD flags) {
-  UserWorkItemInfo *work_item_info = new UserWorkItemInfo;
-  work_item_info->function = function;
-  work_item_info->arg = arg;
-  work_item_info->parent_tid = GetCurrentTidOrInvalid();
-  return REAL(QueueUserWorkItem)(QueueUserWorkItemWrapper, work_item_info,
-                                 flags);
-}
-
-namespace __asan {
-void InitializeWindowsInterceptors() {
-  ASAN_INTERCEPT_FUNC(CreateThread);
-  ASAN_INTERCEPT_FUNC(QueueUserWorkItem);
-  ASAN_INTERCEPT_FUNC(RaiseException);
-  ASAN_INTERCEPT_FUNC(_except_handler3);
-  ASAN_INTERCEPT_FUNC(_except_handler4);
-}
-
-}  // namespace __asan
-#endif
-
 // ---------------------- InitializeAsanInterceptors ---------------- {{{1
 namespace __asan {
 void InitializeAsanInterceptors() {
@@ -971,10 +853,7 @@ void InitializeAsanInterceptors() {
   ASAN_INTERCEPT_FUNC(fork);
 #endif
 
-  // Some Windows-specific interceptors.
-#if SANITIZER_WINDOWS
-  InitializeWindowsInterceptors();
-#endif
+  InitializePlatformInterceptors();
 
   VReport(1, "AddressSanitizer: libc interceptors initialized\n");
 }

Modified: compiler-rt/trunk/lib/asan/asan_interceptors.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_interceptors.h?rev=232377&r1=232376&r2=232377&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_interceptors.h (original)
+++ compiler-rt/trunk/lib/asan/asan_interceptors.h Mon Mar 16 09:22:53 2015
@@ -92,9 +92,21 @@ struct sigaction;
 DECLARE_REAL(int, sigaction, int signum, const struct sigaction *act,
                              struct sigaction *oldact)
 
+#if !SANITIZER_MAC
+#define ASAN_INTERCEPT_FUNC(name)                                        \
+  do {                                                                   \
+    if ((!INTERCEPT_FUNCTION(name) || !REAL(name)))                      \
+      VReport(1, "AddressSanitizer: failed to intercept '" #name "'\n"); \
+  } while (0)
+#else
+// OS X interceptors don't need to be initialized with INTERCEPT_FUNCTION.
+#define ASAN_INTERCEPT_FUNC(name)
+#endif  // SANITIZER_MAC
+
 namespace __asan {
 
 void InitializeAsanInterceptors();
+void InitializePlatformInterceptors();
 
 #define ENSURE_ASAN_INITED() do { \
   CHECK(!asan_init_is_running); \

Modified: compiler-rt/trunk/lib/asan/asan_linux.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_linux.cc?rev=232377&r1=232376&r2=232377&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_linux.cc (original)
+++ compiler-rt/trunk/lib/asan/asan_linux.cc Mon Mar 16 09:22:53 2015
@@ -68,6 +68,8 @@ asan_rt_version_t  __asan_rt_version;
 
 namespace __asan {
 
+void InitializePlatformInterceptors() {}
+
 void DisableReexec() {
   // No need to re-exec on Linux.
 }

Modified: compiler-rt/trunk/lib/asan/asan_mac.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_mac.cc?rev=232377&r1=232376&r2=232377&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_mac.cc (original)
+++ compiler-rt/trunk/lib/asan/asan_mac.cc Mon Mar 16 09:22:53 2015
@@ -40,6 +40,8 @@
 
 namespace __asan {
 
+void InitializePlatformInterceptors() {}
+
 bool PlatformHasDifferentMemcpyAndMemmove() {
   // On OS X 10.7 memcpy() and memmove() are both resolved
   // into memmove$VARIANT$sse42.

Modified: compiler-rt/trunk/lib/asan/asan_win.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_win.cc?rev=232377&r1=232376&r2=232377&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_win.cc (original)
+++ compiler-rt/trunk/lib/asan/asan_win.cc Mon Mar 16 09:22:53 2015
@@ -22,10 +22,13 @@
 #include "asan_interceptors.h"
 #include "asan_internal.h"
 #include "asan_report.h"
+#include "asan_stack.h"
 #include "asan_thread.h"
 #include "sanitizer_common/sanitizer_libc.h"
 #include "sanitizer_common/sanitizer_mutex.h"
 
+using namespace __asan;  // NOLINT
+
 extern "C" {
 SANITIZER_INTERFACE_ATTRIBUTE
 int __asan_should_detect_stack_use_after_return() {
@@ -33,6 +36,7 @@ int __asan_should_detect_stack_use_after
   return __asan_option_detect_stack_use_after_return;
 }
 
+// -------------------- A workaround for the abscence of weak symbols ----- {{{
 // We don't have a direct equivalent of weak symbols when using MSVC, but we can
 // use the /alternatename directive to tell the linker to default a specific
 // symbol to a specific value, which works nicely for allocator hooks and
@@ -47,11 +51,115 @@ void __asan_default_on_error() {}
 #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
+// }}}
 }  // extern "C"
 
+// ---------------------- Windows-specific inteceptors ---------------- {{{
+INTERCEPTOR_WINAPI(void, RaiseException, void *a, void *b, void *c, void *d) {
+  CHECK(REAL(RaiseException));
+  __asan_handle_no_return();
+  REAL(RaiseException)(a, b, c, d);
+}
+
+INTERCEPTOR(int, _except_handler3, void *a, void *b, void *c, void *d) {
+  CHECK(REAL(_except_handler3));
+  __asan_handle_no_return();
+  return REAL(_except_handler3)(a, b, c, d);
+}
+
+#if ASAN_DYNAMIC
+// This handler is named differently in -MT and -MD CRTs.
+#define _except_handler4 _except_handler4_common
+#endif
+INTERCEPTOR(int, _except_handler4, void *a, void *b, void *c, void *d) {
+  CHECK(REAL(_except_handler4));
+  __asan_handle_no_return();
+  return REAL(_except_handler4)(a, b, c, d);
+}
+
+static thread_return_t THREAD_CALLING_CONV asan_thread_start(void *arg) {
+  AsanThread *t = (AsanThread*)arg;
+  SetCurrentThread(t);
+  return t->ThreadStart(GetTid(), /* signal_thread_is_registered */ nullptr);
+}
+
+INTERCEPTOR_WINAPI(DWORD, CreateThread,
+                   void* security, uptr stack_size,
+                   DWORD (__stdcall *start_routine)(void*), void* arg,
+                   DWORD thr_flags, void* tid) {
+  // Strict init-order checking is thread-hostile.
+  if (flags()->strict_init_order)
+    StopInitOrderChecking();
+  GET_STACK_TRACE_THREAD;
+  // FIXME: The CreateThread interceptor is not the same as a pthread_create
+  // one.  This is a bandaid fix for PR22025.
+  bool detached = false;  // FIXME: how can we determine it on Windows?
+  u32 current_tid = GetCurrentTidOrInvalid();
+  AsanThread *t =
+        AsanThread::Create(start_routine, arg, current_tid, &stack, detached);
+  return REAL(CreateThread)(security, stack_size,
+                            asan_thread_start, t, thr_flags, tid);
+}
+
+namespace {
+struct UserWorkItemInfo {
+  DWORD (__stdcall *function)(void *arg);
+  void *arg;
+  u32 parent_tid;
+};
+
+BlockingMutex mu_for_thread_tracking(LINKER_INITIALIZED);
+
+// QueueUserWorkItem may silently create a thread we should keep track of.
+// We achieve this by wrapping the user-supplied work items with our function.
+DWORD __stdcall QueueUserWorkItemWrapper(void *arg) {
+  UserWorkItemInfo *item = (UserWorkItemInfo *)arg;
+
+  {
+    // FIXME: GetCurrentThread relies on TSD, which might not play well with
+    // system thread pools.  We might want to use something like reference
+    // counting to zero out GetCurrentThread() underlying storage when the last
+    // work item finishes?  Or can we disable reclaiming of threads in the pool?
+    BlockingMutexLock l(&mu_for_thread_tracking);
+    AsanThread *t = __asan::GetCurrentThread();
+    if (!t) {
+      GET_STACK_TRACE_THREAD;
+      t = AsanThread::Create(/* start_routine */ nullptr, /* arg */ nullptr,
+                             item->parent_tid, &stack, /* detached */ true);
+      t->Init();
+      asanThreadRegistry().StartThread(t->tid(), 0, 0);
+      SetCurrentThread(t);
+    }
+  }
+
+  DWORD ret = item->function(item->arg);
+  delete item;
+  return ret;
+}
+}  // namespace
+
+INTERCEPTOR_WINAPI(BOOL, QueueUserWorkItem, LPTHREAD_START_ROUTINE function,
+                   PVOID arg, ULONG flags) {
+  UserWorkItemInfo *work_item_info = new UserWorkItemInfo;
+  work_item_info->function = function;
+  work_item_info->arg = arg;
+  work_item_info->parent_tid = GetCurrentTidOrInvalid();
+  return REAL(QueueUserWorkItem)(QueueUserWorkItemWrapper,
+                                 work_item_info, flags);
+}
+// }}}
+
 namespace __asan {
 
-// ---------------------- TSD ---------------- {{{1
+void InitializePlatformInterceptors() {
+  ASAN_INTERCEPT_FUNC(CreateThread);
+  ASAN_INTERCEPT_FUNC(QueueUserWorkItem);
+  ASAN_INTERCEPT_FUNC(RaiseException);
+  ASAN_INTERCEPT_FUNC(_except_handler3);
+  ASAN_INTERCEPT_FUNC(_except_handler4);
+}
+
+// ---------------------- TSD ---------------- {{{
 static bool tsd_key_inited = false;
 
 static __declspec(thread) void *fake_tsd = 0;
@@ -74,7 +182,9 @@ void AsanTSDSet(void *tsd) {
 void PlatformTSDDtor(void *tsd) {
   AsanThread::TSDDtor(tsd);
 }
-// ---------------------- Various stuff ---------------- {{{1
+// }}}
+
+// ---------------------- Various stuff ---------------- {{{
 void DisableReexec() {
   // No need to re-exec on Windows.
 }
@@ -160,7 +270,7 @@ int __asan_set_seh_filter() {
 static __declspec(allocate(".CRT$XIZ"))
     int (*__intercept_seh)() = __asan_set_seh_filter;
 #endif
-
+// }}}
 }  // namespace __asan
 
 #endif  // _WIN32

Modified: compiler-rt/trunk/lib/interception/interception.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/interception/interception.h?rev=232377&r1=232376&r2=232377&view=diff
==============================================================================
--- compiler-rt/trunk/lib/interception/interception.h (original)
+++ compiler-rt/trunk/lib/interception/interception.h Mon Mar 16 09:22:53 2015
@@ -219,7 +219,6 @@ const interpose_substitution substitutio
     namespace __interception { \
       FUNC_TYPE(func) PTR_TO_REAL(func); \
     } \
-    DECLARE_WRAPPER_WINAPI(ret_type, func, __VA_ARGS__) \
     extern "C" \
     INTERCEPTOR_ATTRIBUTE \
     ret_type __stdcall WRAP(func)(__VA_ARGS__)





More information about the llvm-commits mailing list