diff --git a/compiler-rt/lib/asan/asan_allocator.cpp b/compiler-rt/lib/asan/asan_allocator.cpp index c28e71c13885..98698476329a 100644 --- a/compiler-rt/lib/asan/asan_allocator.cpp +++ b/compiler-rt/lib/asan/asan_allocator.cpp @@ -248,6 +248,15 @@ void AsanMapUnmapCallback::OnMap(uptr p, uptr size) const { thread_stats.mmaps++; thread_stats.mmaped += size; } + +void AsanMapUnmapCallback::OnMapSecondary(uptr p, uptr size) const { + PoisonShadow(p, size, kAsanHeapLeftRedzoneMagic); + // Statistics. + AsanStats &thread_stats = GetCurrentThreadStats(); + thread_stats.mmaps++; + thread_stats.mmaped += size; +} + void AsanMapUnmapCallback::OnUnmap(uptr p, uptr size) const { PoisonShadow(p, size, 0); // We are about to unmap a chunk of user memory. diff --git a/compiler-rt/lib/asan/asan_allocator.h b/compiler-rt/lib/asan/asan_allocator.h index 6a12a6c60252..f6c3547506a8 100644 --- a/compiler-rt/lib/asan/asan_allocator.h +++ b/compiler-rt/lib/asan/asan_allocator.h @@ -114,6 +114,7 @@ class AsanChunkFifoList: public IntrusiveList { struct AsanMapUnmapCallback { void OnMap(uptr p, uptr size) const; + void OnMapSecondary(uptr p, uptr size) const; void OnUnmap(uptr p, uptr size) const; }; diff --git a/compiler-rt/lib/dfsan/dfsan_allocator.cpp b/compiler-rt/lib/dfsan/dfsan_allocator.cpp index a3bed535dc08..6306e152392e 100644 --- a/compiler-rt/lib/dfsan/dfsan_allocator.cpp +++ b/compiler-rt/lib/dfsan/dfsan_allocator.cpp @@ -30,6 +30,7 @@ struct Metadata { struct DFsanMapUnmapCallback { void OnMap(uptr p, uptr size) const { dfsan_set_label(0, (void *)p, size); } + void OnMapSecondary(uptr p, uptr size) const { OnMap(p, size); } void OnUnmap(uptr p, uptr size) const { dfsan_set_label(0, (void *)p, size); } }; diff --git a/compiler-rt/lib/hwasan/hwasan_allocator.h b/compiler-rt/lib/hwasan/hwasan_allocator.h index efe253de1258..093736d0e921 100644 --- a/compiler-rt/lib/hwasan/hwasan_allocator.h +++ b/compiler-rt/lib/hwasan/hwasan_allocator.h @@ -54,6 +54,7 @@ static_assert(sizeof(Metadata) == 16); struct HwasanMapUnmapCallback { void OnMap(uptr p, uptr size) const { UpdateMemoryUsage(); } + void OnMapSecondary(uptr p, uptr size) const { UpdateMemoryUsage(); } void OnUnmap(uptr p, uptr size) const { // We are about to unmap a chunk of user memory. // It can return as user-requested mmap() or another thread stack. diff --git a/compiler-rt/lib/memprof/memprof_allocator.h b/compiler-rt/lib/memprof/memprof_allocator.h index 001502cde08a..e11dc6174fea 100644 --- a/compiler-rt/lib/memprof/memprof_allocator.h +++ b/compiler-rt/lib/memprof/memprof_allocator.h @@ -39,6 +39,7 @@ void InitializeAllocator(); struct MemprofMapUnmapCallback { void OnMap(uptr p, uptr size) const; + void OnMapSecondary(uptr p, uptr size) const { OnMap(p, size); } void OnUnmap(uptr p, uptr size) const; }; diff --git a/compiler-rt/lib/msan/msan_allocator.cpp b/compiler-rt/lib/msan/msan_allocator.cpp index be0714dbf47e..1556e20f5332 100644 --- a/compiler-rt/lib/msan/msan_allocator.cpp +++ b/compiler-rt/lib/msan/msan_allocator.cpp @@ -30,6 +30,7 @@ struct Metadata { struct MsanMapUnmapCallback { void OnMap(uptr p, uptr size) const {} + void OnMapSecondary(uptr p, uptr size) const {} void OnUnmap(uptr p, uptr size) const { __msan_unpoison((void *)p, size); diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_allocator.h b/compiler-rt/lib/sanitizer_common/sanitizer_allocator.h index 166a0539e4ba..72a7c83c4dab 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_allocator.h +++ b/compiler-rt/lib/sanitizer_common/sanitizer_allocator.h @@ -64,6 +64,7 @@ inline void RandomShuffle(T *a, u32 n, u32 *rand_state) { struct NoOpMapUnmapCallback { void OnMap(uptr p, uptr size) const {} + void OnMapSecondary(uptr p, uptr size) const {} void OnUnmap(uptr p, uptr size) const {} }; diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_allocator_secondary.h b/compiler-rt/lib/sanitizer_common/sanitizer_allocator_secondary.h index 157645555604..648b1ab21f6b 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_allocator_secondary.h +++ b/compiler-rt/lib/sanitizer_common/sanitizer_allocator_secondary.h @@ -99,7 +99,7 @@ class LargeMmapAllocator { if (!map_beg) return nullptr; CHECK(IsAligned(map_beg, page_size_)); - MapUnmapCallback().OnMap(map_beg, map_size); + MapUnmapCallback().OnMapSecondary(map_beg, map_size); uptr map_end = map_beg + map_size; uptr res = map_beg + page_size_; if (res & (alignment - 1)) // Align. diff --git a/compiler-rt/lib/sanitizer_common/tests/sanitizer_allocator_test.cpp b/compiler-rt/lib/sanitizer_common/tests/sanitizer_allocator_test.cpp index 5a47fc11e6d0..28969d014c6a 100644 --- a/compiler-rt/lib/sanitizer_common/tests/sanitizer_allocator_test.cpp +++ b/compiler-rt/lib/sanitizer_common/tests/sanitizer_allocator_test.cpp @@ -476,11 +476,15 @@ TEST(SanitizerCommon, SizeClassAllocator32CompactGetBlockBegin) { #endif // SANITIZER_CAN_USE_ALLOCATOR64 struct TestMapUnmapCallback { - static int map_count, unmap_count; + static int map_count, map_secondary_count, unmap_count; void OnMap(uptr p, uptr size) const { map_count++; } + void OnMapSecondary(uptr p, uptr size) const { map_secondary_count++; } void OnUnmap(uptr p, uptr size) const { unmap_count++; } + + static void Reset() { map_count = map_secondary_count = unmap_count = 0; } }; int TestMapUnmapCallback::map_count; +int TestMapUnmapCallback::map_secondary_count; int TestMapUnmapCallback::unmap_count; #if SANITIZER_CAN_USE_ALLOCATOR64 @@ -500,12 +504,12 @@ struct AP64WithCallback { }; TEST(SanitizerCommon, SizeClassAllocator64MapUnmapCallback) { - TestMapUnmapCallback::map_count = 0; - TestMapUnmapCallback::unmap_count = 0; + TestMapUnmapCallback::Reset(); typedef SizeClassAllocator64> Allocator64WithCallBack; Allocator64WithCallBack *a = new Allocator64WithCallBack; a->Init(kReleaseToOSIntervalNever); EXPECT_EQ(TestMapUnmapCallback::map_count, 1); // Allocator state. + EXPECT_EQ(TestMapUnmapCallback::map_secondary_count, 0); typename Allocator64WithCallBack::AllocatorCache cache; memset(&cache, 0, sizeof(cache)); cache.Init(0); @@ -516,6 +520,7 @@ TEST(SanitizerCommon, SizeClassAllocator64MapUnmapCallback) { a->GetFromAllocator(&stats, 30, chunks, kNumChunks); // State + alloc + metadata + freearray. EXPECT_EQ(TestMapUnmapCallback::map_count, 4); + EXPECT_EQ(TestMapUnmapCallback::map_secondary_count, 0); a->TestOnlyUnmap(); EXPECT_EQ(TestMapUnmapCallback::unmap_count, 1); // The whole thing. delete a; @@ -536,12 +541,12 @@ struct AP32WithCallback { }; TEST(SanitizerCommon, SizeClassAllocator32MapUnmapCallback) { - TestMapUnmapCallback::map_count = 0; - TestMapUnmapCallback::unmap_count = 0; + TestMapUnmapCallback::Reset(); typedef SizeClassAllocator32> Allocator32WithCallBack; Allocator32WithCallBack *a = new Allocator32WithCallBack; a->Init(kReleaseToOSIntervalNever); EXPECT_EQ(TestMapUnmapCallback::map_count, 0); + EXPECT_EQ(TestMapUnmapCallback::map_secondary_count, 0); Allocator32WithCallBack::AllocatorCache cache; memset(&cache, 0, sizeof(cache)); cache.Init(0); @@ -549,23 +554,21 @@ TEST(SanitizerCommon, SizeClassAllocator32MapUnmapCallback) { stats.Init(); a->AllocateBatch(&stats, &cache, 32); EXPECT_EQ(TestMapUnmapCallback::map_count, 1); + EXPECT_EQ(TestMapUnmapCallback::map_secondary_count, 0); a->TestOnlyUnmap(); EXPECT_EQ(TestMapUnmapCallback::unmap_count, 1); delete a; - // fprintf(stderr, "Map: %d Unmap: %d\n", - // TestMapUnmapCallback::map_count, - // TestMapUnmapCallback::unmap_count); } TEST(SanitizerCommon, LargeMmapAllocatorMapUnmapCallback) { - TestMapUnmapCallback::map_count = 0; - TestMapUnmapCallback::unmap_count = 0; + TestMapUnmapCallback::Reset(); LargeMmapAllocator a; a.Init(); AllocatorStats stats; stats.Init(); void *x = a.Allocate(&stats, 1 << 20, 1); - EXPECT_EQ(TestMapUnmapCallback::map_count, 1); + EXPECT_EQ(TestMapUnmapCallback::map_count, 0); + EXPECT_EQ(TestMapUnmapCallback::map_secondary_count, 1); a.Deallocate(&stats, x); EXPECT_EQ(TestMapUnmapCallback::unmap_count, 1); } diff --git a/compiler-rt/lib/tsan/rtl/tsan_mman.cpp b/compiler-rt/lib/tsan/rtl/tsan_mman.cpp index 7b9dc81a3f6c..f2cdb4fe04e7 100644 --- a/compiler-rt/lib/tsan/rtl/tsan_mman.cpp +++ b/compiler-rt/lib/tsan/rtl/tsan_mman.cpp @@ -25,6 +25,7 @@ namespace __tsan { struct MapUnmapCallback { void OnMap(uptr p, uptr size) const { } + void OnMapSecondary(uptr p, uptr size) const {}; void OnUnmap(uptr p, uptr size) const { // We are about to unmap a chunk of user memory. // Mark the corresponding shadow memory as not needed.