Index: compiler-rt/trunk/lib/asan/asan_activation.cc =================================================================== --- compiler-rt/trunk/lib/asan/asan_activation.cc +++ compiler-rt/trunk/lib/asan/asan_activation.cc @@ -23,20 +23,14 @@ namespace __asan { static struct AsanDeactivatedFlags { - int quarantine_size; - int max_redzone; + AllocatorOptions allocator_options; int malloc_context_size; bool poison_heap; - bool alloc_dealloc_mismatch; - bool allocator_may_return_null; void CopyFrom(const Flags *f, const CommonFlags *cf) { - quarantine_size = f->quarantine_size; - max_redzone = f->max_redzone; + allocator_options.SetFrom(f, cf); malloc_context_size = cf->malloc_context_size; poison_heap = f->poison_heap; - alloc_dealloc_mismatch = f->alloc_dealloc_mismatch; - allocator_may_return_null = cf->allocator_may_return_null; } void OverrideFromActivationFlags() { @@ -44,12 +38,14 @@ CommonFlags cf; // Copy the current activation flags. - f.quarantine_size = quarantine_size; - f.max_redzone = max_redzone; + f.quarantine_size = allocator_options.quarantine_size_mb << 20; + f.redzone = allocator_options.min_redzone; + f.max_redzone = allocator_options.max_redzone; + cf.allocator_may_return_null = allocator_options.may_return_null; + f.alloc_dealloc_mismatch = allocator_options.alloc_dealloc_mismatch; + cf.malloc_context_size = malloc_context_size; f.poison_heap = poison_heap; - f.alloc_dealloc_mismatch = alloc_dealloc_mismatch; - cf.allocator_may_return_null = allocator_may_return_null; // Check if activation flags need to be overriden. // FIXME: Add diagnostic to check that activation flags string doesn't @@ -63,11 +59,13 @@ } void Print() { - Report("quarantine_size %d, max_redzone %d, poison_heap %d, " + Report("quarantine_size_mb %d, max_redzone %d, poison_heap %d, " "malloc_context_size %d, alloc_dealloc_mismatch %d, " "allocator_may_return_null %d\n", - quarantine_size, max_redzone, poison_heap, malloc_context_size, - alloc_dealloc_mismatch, allocator_may_return_null); + allocator_options.quarantine_size_mb, allocator_options.max_redzone, + poison_heap, malloc_context_size, + allocator_options.alloc_dealloc_mismatch, + allocator_options.may_return_null); } } asan_deactivated_flags; @@ -97,16 +95,9 @@ asan_deactivated_flags.OverrideFromActivationFlags(); - // Restore flag values. - // FIXME: this is not atomic, and there may be other threads alive. - flags()->max_redzone = asan_deactivated_flags.max_redzone; - flags()->alloc_dealloc_mismatch = - asan_deactivated_flags.alloc_dealloc_mismatch; - SetCanPoisonMemory(asan_deactivated_flags.poison_heap); SetMallocContextSize(asan_deactivated_flags.malloc_context_size); - ReInitializeAllocator(asan_deactivated_flags.allocator_may_return_null, - asan_deactivated_flags.quarantine_size); + ReInitializeAllocator(asan_deactivated_flags.allocator_options); asan_is_deactivated = false; if (common_flags()->verbosity) { Index: compiler-rt/trunk/lib/asan/asan_allocator.h =================================================================== --- compiler-rt/trunk/lib/asan/asan_allocator.h +++ compiler-rt/trunk/lib/asan/asan_allocator.h @@ -15,6 +15,7 @@ #ifndef ASAN_ALLOCATOR_H #define ASAN_ALLOCATOR_H +#include "asan_flags.h" #include "asan_internal.h" #include "asan_interceptors.h" #include "sanitizer_common/sanitizer_allocator.h" @@ -31,8 +32,18 @@ static const uptr kNumberOfSizeClasses = 255; struct AsanChunk; -void InitializeAllocator(bool may_return_null, uptr quarantine_size); -void ReInitializeAllocator(bool may_return_null, uptr quarantine_size); +struct AllocatorOptions { + u32 quarantine_size_mb; + u16 min_redzone; + u16 max_redzone; + u8 may_return_null; + u8 alloc_dealloc_mismatch; + + void SetFrom(const Flags *f, const CommonFlags *cf); +}; + +void InitializeAllocator(const AllocatorOptions &options); +void ReInitializeAllocator(const AllocatorOptions &options); class AsanChunkView { public: Index: compiler-rt/trunk/lib/asan/asan_allocator.cc =================================================================== --- compiler-rt/trunk/lib/asan/asan_allocator.cc +++ compiler-rt/trunk/lib/asan/asan_allocator.cc @@ -205,6 +205,14 @@ return reinterpret_cast(ms->quarantine_cache); } +void AllocatorOptions::SetFrom(const Flags *f, const CommonFlags *cf) { + quarantine_size_mb = f->quarantine_size >> 20; + min_redzone = f->redzone; + max_redzone = f->max_redzone; + may_return_null = cf->allocator_may_return_null; + alloc_dealloc_mismatch = f->alloc_dealloc_mismatch; +} + struct Allocator { static const uptr kMaxAllowedMallocSize = FIRST_32_SECOND_64(3UL << 30, 64UL << 30); @@ -217,19 +225,42 @@ AllocatorCache fallback_allocator_cache; QuarantineCache fallback_quarantine_cache; + // ------------------- Options -------------------------- + atomic_uint16_t min_redzone; + atomic_uint16_t max_redzone; + atomic_uint8_t alloc_dealloc_mismatch; + + // ------------------- Initialization ------------------------ explicit Allocator(LinkerInitialized) : quarantine(LINKER_INITIALIZED), fallback_quarantine_cache(LINKER_INITIALIZED) {} - // ------------------- Initialization ------------------------ - void Initialize(bool may_return_null, uptr quarantine_size) { - allocator.Init(may_return_null); - quarantine.Init(quarantine_size, kMaxThreadLocalQuarantine); - } - - void ReInitialize(bool may_return_null, uptr quarantine_size) { - allocator.SetMayReturnNull(may_return_null); - quarantine.Init(quarantine_size, kMaxThreadLocalQuarantine); + void CheckOptions(const AllocatorOptions &options) const { + CHECK_GE(options.min_redzone, 16); + CHECK_GE(options.max_redzone, options.min_redzone); + CHECK_LE(options.max_redzone, 2048); + CHECK(IsPowerOfTwo(options.min_redzone)); + CHECK(IsPowerOfTwo(options.max_redzone)); + } + + void SharedInitCode(const AllocatorOptions &options) { + CheckOptions(options); + quarantine.Init((uptr)options.quarantine_size_mb << 20, + kMaxThreadLocalQuarantine); + atomic_store(&alloc_dealloc_mismatch, options.alloc_dealloc_mismatch, + memory_order_release); + atomic_store(&min_redzone, options.min_redzone, memory_order_release); + atomic_store(&max_redzone, options.max_redzone, memory_order_release); + } + + void Initialize(const AllocatorOptions &options) { + allocator.Init(options.may_return_null); + SharedInitCode(options); + } + + void ReInitialize(const AllocatorOptions &options) { + allocator.SetMayReturnNull(options.may_return_null); + SharedInitCode(options); } // -------------------- Helper methods. ------------------------- @@ -242,8 +273,9 @@ user_requested_size <= (1 << 14) - 256 ? 4 : user_requested_size <= (1 << 15) - 512 ? 5 : user_requested_size <= (1 << 16) - 1024 ? 6 : 7; - return Min(Max(rz_log, RZSize2Log(flags()->redzone)), - RZSize2Log(flags()->max_redzone)); + u32 min_rz = atomic_load(&min_redzone, memory_order_acquire); + u32 max_rz = atomic_load(&max_redzone, memory_order_acquire); + return Min(Max(rz_log, RZSize2Log(min_rz)), RZSize2Log(max_rz)); } // We have an address between two chunks, and we want to report just one. @@ -419,9 +451,12 @@ AllocType alloc_type) { CHECK_EQ(m->chunk_state, CHUNK_QUARANTINE); - if (m->alloc_type != alloc_type && flags()->alloc_dealloc_mismatch) - ReportAllocTypeMismatch((uptr)ptr, stack, - (AllocType)m->alloc_type, (AllocType)alloc_type); + if (m->alloc_type != alloc_type) { + if (atomic_load(&alloc_dealloc_mismatch, memory_order_acquire)) { + ReportAllocTypeMismatch((uptr)ptr, stack, (AllocType)m->alloc_type, + (AllocType)alloc_type); + } + } CHECK_GE(m->alloc_tid, 0); if (SANITIZER_WORDSIZE == 64) // On 32-bits this resides in user area. @@ -619,12 +654,12 @@ return GetStackTraceFromId(chunk_->free_context_id); } -void InitializeAllocator(bool may_return_null, uptr quarantine_size) { - instance.Initialize(may_return_null, quarantine_size); +void InitializeAllocator(const AllocatorOptions &options) { + instance.Initialize(options); } -void ReInitializeAllocator(bool may_return_null, uptr quarantine_size) { - instance.ReInitialize(may_return_null, quarantine_size); +void ReInitializeAllocator(const AllocatorOptions &options) { + instance.ReInitialize(options); } AsanChunkView FindHeapChunkByAddress(uptr addr) { Index: compiler-rt/trunk/lib/asan/asan_rtl.cc =================================================================== --- compiler-rt/trunk/lib/asan/asan_rtl.cc +++ compiler-rt/trunk/lib/asan/asan_rtl.cc @@ -391,8 +391,9 @@ AsanTSDInit(PlatformTSDDtor); InstallDeadlySignalHandlers(AsanOnSIGSEGV); - InitializeAllocator(common_flags()->allocator_may_return_null, - flags()->quarantine_size); + AllocatorOptions allocator_options; + allocator_options.SetFrom(flags(), common_flags()); + InitializeAllocator(allocator_options); MaybeStartBackgroudThread();