diff options
author | Kostya Serebryany <kcc@google.com> | 2012-12-17 06:31:53 +0000 |
---|---|---|
committer | Kostya Serebryany <kcc@google.com> | 2012-12-17 06:31:53 +0000 |
commit | 0a504ec7c360ecfaad8db8607862bc69ed77abfa (patch) | |
tree | e7af6def71e48bd686c62729eb9170376f6128fc /lib | |
parent | d9b740452db50b47ca16abdc0f5e4bc2abf3afa9 (diff) | |
download | compiler-rt-0a504ec7c360ecfaad8db8607862bc69ed77abfa.tar.gz compiler-rt-0a504ec7c360ecfaad8db8607862bc69ed77abfa.tar.bz2 compiler-rt-0a504ec7c360ecfaad8db8607862bc69ed77abfa.tar.xz |
[asan] asan_alocator2: implement free() stacks and actually make malloc/free stacks work
git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@170310 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r-- | lib/asan/asan_allocator2.cc | 43 |
1 files changed, 29 insertions, 14 deletions
diff --git a/lib/asan/asan_allocator2.cc b/lib/asan/asan_allocator2.cc index 7b58fda7..e41dab86 100644 --- a/lib/asan/asan_allocator2.cc +++ b/lib/asan/asan_allocator2.cc @@ -96,13 +96,13 @@ struct ChunkBase { uptr from_memalign : 1; // 2-nd 8 bytes uptr user_requested_size; - // End of ChunkHeader. + // Header2 (intersects with user memory). // 3-rd 8 bytes. These overlap with the user memory. AsanChunk *next; }; static const uptr kChunkHeaderSize = 16; -COMPILER_CHECK(sizeof(ChunkBase) == 24); +static const uptr kChunkHeader2Size = 8; #elif SANITIZER_WORDSIZE == 32 struct ChunkBase { @@ -111,15 +111,16 @@ struct ChunkBase { uptr from_memalign : 1; uptr alloc_tid : 23; uptr user_requested_size; - // End of ChunkHeader. + // Header2 (intersects with user memory). // 2-nd 8 bytes. These overlap with the user memory. AsanChunk *next; uptr free_tid; }; -COMPILER_CHECK(sizeof(ChunkBase) == 16); static const uptr kChunkHeaderSize = 8; +static const uptr kChunkHeader2Size = 8; #endif +COMPILER_CHECK(sizeof(ChunkBase) == kChunkHeaderSize + kChunkHeader2Size); static uptr ComputeRZSize(uptr user_requested_size) { // FIXME: implement adaptive redzones. @@ -130,14 +131,20 @@ struct AsanChunk: ChunkBase { uptr Beg() { return reinterpret_cast<uptr>(this) + kChunkHeaderSize; } uptr UsedSize() { return user_requested_size; } // We store the alloc/free stack traces in the chunk itself. - uptr AllocStackBeg() { - return Beg() - ComputeRZSize(user_requested_size); + u32 *AllocStackBeg() { + return (u32*)(Beg() - ComputeRZSize(UsedSize())); } uptr AllocStackSize() { - return ComputeRZSize(user_requested_size) - kChunkHeaderSize; + return (ComputeRZSize(UsedSize()) - kChunkHeaderSize) / sizeof(u32); + } + u32 *FreeStackBeg() { + return (u32*)(Beg() + kChunkHeader2Size); + } + uptr FreeStackSize() { + uptr available = Max(RoundUpTo(UsedSize(), SHADOW_GRANULARITY), + ComputeRZSize(UsedSize())); + return (available - kChunkHeader2Size) / sizeof(u32); } - uptr FreeStackBeg(); - uptr FreeStackSize(); }; uptr AsanChunkView::Beg() { return chunk_->Beg(); } @@ -152,7 +159,8 @@ void AsanChunkView::GetAllocStack(StackTrace *stack) { } void AsanChunkView::GetFreeStack(StackTrace *stack) { - stack->size = 0; + StackTrace::UncompressStack(stack, chunk_->FreeStackBeg(), + chunk_->FreeStackSize()); } static const uptr kReturnOnZeroMalloc = 0x0123; // Zero page is protected. @@ -219,6 +227,11 @@ static void Deallocate(void *ptr, StackTrace *stack) { if (p == 0 || p == kReturnOnZeroMalloc) return; uptr chunk_beg = p - kChunkHeaderSize; AsanChunk *m = reinterpret_cast<AsanChunk *>(chunk_beg); + CHECK_GE(m->alloc_tid, 0); + CHECK_EQ(m->free_tid, kInvalidTid); + AsanThread *t = asanThreadRegistry().GetCurrent(); + m->free_tid = t ? t->tid() : 0; + StackTrace::CompressStack(stack, m->FreeStackBeg(), m->FreeStackSize()); uptr alloc_beg = p - ComputeRZSize(m->user_requested_size); if (m->from_memalign) alloc_beg = reinterpret_cast<uptr>(allocator.GetBlockBegin(ptr)); @@ -226,12 +239,14 @@ static void Deallocate(void *ptr, StackTrace *stack) { PoisonShadow(m->Beg(), RoundUpTo(m->user_requested_size, SHADOW_GRANULARITY), kAsanHeapFreeMagic); ASAN_FREE_HOOK(ptr); + if (!p) allocator.Deallocate(&cache, reinterpret_cast<void *>(alloc_beg)); } AsanChunkView FindHeapChunkByAddress(uptr address) { - UNIMPLEMENTED(); - return AsanChunkView(0); + uptr alloc_beg = (uptr)allocator.GetBlockBegin((void*)address); + return AsanChunkView((AsanChunk *)(alloc_beg + ComputeRZSize(0) + - kChunkHeaderSize)); } void AsanThreadLocalMallocStorage::CommitBack() { @@ -261,13 +276,13 @@ void *asan_calloc(uptr nmemb, uptr size, StackTrace *stack) { } void *asan_realloc(void *p, uptr size, StackTrace *stack) { - if (p == 0) { + if (p == 0) return Allocate(size, 8, stack); if (size == 0) { Deallocate(p, stack); return 0; } - UNIMPLEMENTED; + UNIMPLEMENTED(); // return Reallocate((u8*)p, size, stack); } |