[llvm-commits] [compiler-rt] r148116 - in /compiler-rt/trunk/lib/asan: asan_interceptors.cc asan_mac.cc asan_mac.h

Alexander Potapenko glider at google.com
Fri Jan 13 08:13:58 PST 2012


Author: glider
Date: Fri Jan 13 10:13:58 2012
New Revision: 148116

URL: http://llvm.org/viewvc/llvm-project?rev=148116&view=rev
Log:
This patch adds two methods, __asan_allocate_island and __asan_deallocate_island
and switches our interceptors to using them instead of the default
vm_allocate-based approach used by mach_override_ptr.

To simplify the code, a fixed memory mapping is used for the allocation pool --
note that we can't mmap an arbitrary chunk of memory, because the shadow memory hasn't been mapped yet
(for the reasons discussed in http://code.google.com/p/address-sanitizer/issues/detail?id=24, we cannot map the shadow earlier)

The patch drops the program startup time from several second to half a second,
which speeds up the execution of ASan tests noticeably.
Because of the virtual memory size occupied by the programs it's hard
to speed up the shutdown time, which would've also helped the tests.

Modified:
    compiler-rt/trunk/lib/asan/asan_interceptors.cc
    compiler-rt/trunk/lib/asan/asan_mac.cc
    compiler-rt/trunk/lib/asan/asan_mac.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=148116&r1=148115&r2=148116&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_interceptors.cc (original)
+++ compiler-rt/trunk/lib/asan/asan_interceptors.cc Fri Jan 13 10:13:58 2012
@@ -43,24 +43,25 @@
 // After interception, the calls to system functions will be substituted by
 // calls to our interceptors. We store pointers to system function f()
 // in __asan::real_f().
-//
-// TODO(glider): mach_override_ptr() tends to spend too much time
-// in allocateBranchIsland(). This should be ok for real-word
-// application, but slows down our tests which fork too many children.
 #ifdef __APPLE__
 #include "mach_override/mach_override.h"
 #define WRAPPER_NAME(x) "wrap_"#x
 
-#define OVERRIDE_FUNCTION(oldfunc, newfunc)                             \
-  CHECK(0 == __asan_mach_override_ptr((void*)(oldfunc),                        \
-                                      (void*)(newfunc),                        \
-                                      (void**)&real_##oldfunc));               \
-  CHECK(real_##oldfunc != NULL);
-
-#define OVERRIDE_FUNCTION_IF_EXISTS(oldfunc, newfunc)                   \
-  do { __asan_mach_override_ptr((void*)(oldfunc),                              \
-                                (void*)(newfunc),                              \
-                                (void**)&real_##oldfunc); } while (0)
+#define OVERRIDE_FUNCTION(oldfunc, newfunc)                                   \
+  do {CHECK(0 == __asan_mach_override_ptr_custom((void*)(oldfunc),            \
+                                                 (void*)(newfunc),            \
+                                                 (void**)&real_##oldfunc,     \
+                                                 __asan_allocate_island,      \
+                                                 __asan_deallocate_island));  \
+  CHECK(real_##oldfunc != NULL);   } while(0)
+
+#define OVERRIDE_FUNCTION_IF_EXISTS(oldfunc, newfunc)               \
+  do { __asan_mach_override_ptr_custom((void*)(oldfunc),            \
+                                       (void*)(newfunc),            \
+                                       (void**)&real_##oldfunc,     \
+                                       __asan_allocate_island,      \
+                                       __asan_deallocate_island);   \
+  } while (0)
 
 #define INTERCEPT_FUNCTION(func)                                        \
   OVERRIDE_FUNCTION(func, WRAP(func))

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=148116&r1=148115&r2=148116&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_mac.cc (original)
+++ compiler-rt/trunk/lib/asan/asan_mac.cc Fri Jan 13 10:13:58 2012
@@ -32,6 +32,8 @@
 
 namespace __asan {
 
+void *island_allocator_pos = NULL;
+
 extern dispatch_async_f_f real_dispatch_async_f;
 extern dispatch_sync_f_f real_dispatch_sync_f;
 extern dispatch_after_f_f real_dispatch_after_f;
@@ -172,6 +174,37 @@
   OSSpinLockUnlock((OSSpinLock*)&opaque_storage_);
 }
 
+// The range of pages to be used by __asan_mach_override_ptr for escape
+// islands.
+// TODO(glider): instead of mapping a fixed range we must find a range of
+// unmapped pages in vmmap and take them.
+#define kIslandEnd (0x7fffffdf0000 - kPageSize)
+#define kIslandBeg (kIslandEnd - 256 * kPageSize)
+
+extern "C"
+mach_error_t __asan_allocate_island(void **ptr,
+                                    size_t unused_size,
+                                    void *unused_hint) {
+  if (!island_allocator_pos) {
+    if ((void*)-1 == asan_mmap((void*)kIslandBeg, kIslandEnd - kIslandBeg,
+                               PROT_READ | PROT_WRITE | PROT_EXEC,
+                               MAP_PRIVATE | MAP_ANON | MAP_FIXED,
+                               -1, 0)) {
+      return KERN_NO_SPACE;
+    }
+    island_allocator_pos = (void*)kIslandBeg;
+  };
+  *ptr = island_allocator_pos;
+  island_allocator_pos = (char*)island_allocator_pos + kPageSize;
+  return err_none;
+}
+
+extern "C"
+mach_error_t __asan_deallocate_island(void *ptr) {
+  // Do nothing.
+  // TODO(glider): allow to free and reuse the island memory.
+  return err_none;
+}
 
 // Support for the following functions from libdispatch on Mac OS:
 //   dispatch_async_f()

Modified: compiler-rt/trunk/lib/asan/asan_mac.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_mac.h?rev=148116&r1=148115&r2=148116&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_mac.h (original)
+++ compiler-rt/trunk/lib/asan/asan_mac.h Fri Jan 13 10:13:58 2012
@@ -20,6 +20,7 @@
 
 // TODO(glider): need to check if the OS X version is 10.6 or greater.
 #include <dispatch/dispatch.h>
+#include <mach/mach_error.h>
 #include <setjmp.h>
 
 typedef void* pthread_workqueue_t;
@@ -54,6 +55,15 @@
 
 
 extern "C" {
+
+// Allocate memory for the escape island. This cannot be moved to
+// mach_override, because the allocator needs to know about the ASan shadow
+// mappings.
+// TODO(glider): in order to place a relative jump the allocated memory should
+// be within 2 Gb from the hint address.
+mach_error_t __asan_allocate_island(void **ptr, size_t unused_size, void *unused_hint);
+mach_error_t __asan_deallocate_island(void *ptr);
+
 // dispatch_barrier_async_f() is not declared in <dispatch/dispatch.h>.
 void dispatch_barrier_async_f(dispatch_queue_t dq,
                               void *ctxt, dispatch_function_t func);





More information about the llvm-commits mailing list