[llvm-commits] [compiler-rt] r162202 - in /compiler-rt/trunk/lib/asan: asan_intercepted_functions.h asan_mac.cc dynamic/asan_interceptors_dynamic.cc

Alexander Potapenko glider at google.com
Mon Aug 20 04:59:27 PDT 2012


Author: glider
Date: Mon Aug 20 06:59:26 2012
New Revision: 162202

URL: http://llvm.org/viewvc/llvm-project?rev=162202&view=rev
Log:
Dynamic interceptors for dispatch_async and dispatch_after.

Added:
    compiler-rt/trunk/lib/asan/asan_mac.cc
      - copied, changed from r162199, compiler-rt/trunk/lib/asan/asan_mac.cc
Modified:
    compiler-rt/trunk/lib/asan/asan_intercepted_functions.h
    compiler-rt/trunk/lib/asan/dynamic/asan_interceptors_dynamic.cc

Modified: compiler-rt/trunk/lib/asan/asan_intercepted_functions.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_intercepted_functions.h?rev=162202&r1=162201&r2=162202&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_intercepted_functions.h (original)
+++ compiler-rt/trunk/lib/asan/asan_intercepted_functions.h Mon Aug 20 06:59:26 2012
@@ -198,6 +198,12 @@
 DECLARE_FUNCTION_AND_WRAPPER(CFStringRef, CFStringCreateCopy,
                              CFAllocatorRef alloc, CFStringRef str);
 DECLARE_FUNCTION_AND_WRAPPER(void, free, void* ptr);
+#if MAC_INTERPOSE_FUNCTIONS
+DECLARE_FUNCTION_AND_WRAPPER(void, dispatch_async,
+                             dispatch_queue_t dq, void (^work)(void));
+DECLARE_FUNCTION_AND_WRAPPER(void, dispatch_after,
+                             dispatch_queue_t dq, void (^work)(void));
+#endif  // MAC_INTERPOSE_FUNCTIONS
 #endif  // __APPLE__
 }  // extern "C"
 #endif

Copied: compiler-rt/trunk/lib/asan/asan_mac.cc (from r162199, compiler-rt/trunk/lib/asan/asan_mac.cc)
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_mac.cc?p2=compiler-rt/trunk/lib/asan/asan_mac.cc&p1=compiler-rt/trunk/lib/asan/asan_mac.cc&r1=162199&r2=162202&rev=162202&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_mac.cc (original)
+++ compiler-rt/trunk/lib/asan/asan_mac.cc Mon Aug 20 06:59:26 2012
@@ -241,6 +241,8 @@
     pthread_workitem_handle_t * itemhandlep, unsigned int *gencountp);
 }  // extern "C"
 
+// For use by only those functions that allocated the context via
+// alloc_asan_context().
 extern "C"
 void asan_dispatch_call_block_and_release(void *block) {
   GET_STACK_TRACE_HERE(kStackTraceMax);
@@ -312,6 +314,66 @@
                                 asan_dispatch_call_block_and_release);
 }
 
+#if MAC_INTERPOSE_FUNCTIONS
+// dispatch_async and TODO tailcall the corresponding dispatch_*_f functions.
+// When wrapping functions with mach_override, they are intercepted
+// automatically. But with dylib interposition this does not work, because the
+// calls within the same library are not interposed.
+// Therefore we need to re-implement dispatch_async and friends.
+
+// See dispatch/dispatch.h.
+#define DISPATCH_TIME_FOREVER (~0ull)
+typedef void (^dispatch_block_t)(void);
+
+// See
+// http://www.opensource.apple.com/source/libdispatch/libdispatch-228.18/src/init.c
+// for the implementation of _dispatch_call_block_copy_and_release().
+static void _dispatch_call_block_and_release(void *block) {
+  void (^b)(void) = (dispatch_block_t)block;
+  b();
+  _Block_release(b);
+}
+
+// See
+// http://www.opensource.apple.com/source/libdispatch/libdispatch-228.18/src/internal.h
+#define fastpath(x) ((typeof(x))__builtin_expect((long)(x), ~0l))
+
+// See
+// http://www.opensource.apple.com/source/libdispatch/libdispatch-228.18/src/init.c
+static dispatch_block_t _dispatch_Block_copy(dispatch_block_t db) {
+  dispatch_block_t rval;
+  if (fastpath(db)) { 
+    while (!fastpath(rval = Block_copy(db))) {
+      sleep(1);
+    }
+    return rval;
+  }
+  CHECK(0 && "NULL was passed where a block should have been");
+  return (dispatch_block_t)NULL;  // Unreachable.
+}
+
+// See
+// http://www.opensource.apple.com/source/libdispatch/libdispatch-228.18/src/queue.c
+// for the implementation of dispatch_async(), dispatch_sync(),
+// dispatch_after().
+INTERCEPTOR(void, dispatch_async,
+            dispatch_queue_t dq, dispatch_block_t work) {
+  WRAP(dispatch_async_f)(dq, _dispatch_Block_copy(work),
+                         _dispatch_call_block_and_release);
+}
+
+INTERCEPTOR(void, dispatch_after,
+            dispatch_time_t when, dispatch_queue_t queue,
+            dispatch_block_t work) {
+  if (when == DISPATCH_TIME_FOREVER) {
+    CHECK(0 && "dispatch_after() called with 'when' == infinity");
+    return;  // Unreachable.
+  }
+  WRAP(dispatch_after_f)(when, queue, _dispatch_Block_copy(work),
+                         _dispatch_call_block_and_release);
+}
+#endif
+
 INTERCEPTOR(void, dispatch_group_async_f, dispatch_group_t group,
                                           dispatch_queue_t dq, void *ctxt,
                                           dispatch_function_t func) {

Modified: compiler-rt/trunk/lib/asan/dynamic/asan_interceptors_dynamic.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/dynamic/asan_interceptors_dynamic.cc?rev=162202&r1=162201&r2=162202&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/dynamic/asan_interceptors_dynamic.cc (original)
+++ compiler-rt/trunk/lib/asan/dynamic/asan_interceptors_dynamic.cc Mon Aug 20 06:59:26 2012
@@ -19,6 +19,11 @@
 
 namespace __asan {
 
+#if !MAC_INTERPOSE_FUNCTIONS
+# error \
+  Dynamic interposing library should be built with -DMAC_INTERPOSE_FUNCTIONS
+#endif
+
 #define INTERPOSE_FUNCTION(function) \
     { reinterpret_cast<const uptr>(WRAP(function)), \
       reinterpret_cast<const uptr>(function) }
@@ -87,6 +92,9 @@
   INTERPOSE_FUNCTION(dispatch_barrier_async_f),
   INTERPOSE_FUNCTION(dispatch_group_async_f),
 
+  INTERPOSE_FUNCTION(dispatch_async),
+  INTERPOSE_FUNCTION(dispatch_after),
+
   INTERPOSE_FUNCTION(__CFInitialize),
   INTERPOSE_FUNCTION(CFStringCreateCopy),
   INTERPOSE_FUNCTION(free),





More information about the llvm-commits mailing list