[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