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

Kostya Serebryany kcc at google.com
Fri Jan 13 10:22:41 PST 2012


On Fri, Jan 13, 2012 at 8:13 AM, Alexander Potapenko <glider at google.com>wrote:

> 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,
>
Nice improvement!
The startup time on 64-bit Mac was irritating.


> 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;
>

This could be made static, even though it is inside __asan namespace.


> +
>  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)
>

Don't you need to use constants from asan_mapping.h?
The current constants don't seem correct for 32-bits (although they may
"magically" work).



> +#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);
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20120113/f6cb4845/attachment.html>


More information about the llvm-commits mailing list