diff options
4 files changed, 127 insertions, 3 deletions
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_allocator64.h b/compiler-rt/lib/sanitizer_common/sanitizer_allocator64.h index e78710d9d58..ca2321ce587 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_allocator64.h +++ b/compiler-rt/lib/sanitizer_common/sanitizer_allocator64.h @@ -152,6 +152,11 @@ class SizeClassAllocator64 { return (reinterpret_cast<uptr>(p) / kRegionSize) % kNumClasses; } + uptr GetActuallyAllocatedSize(void *p) { + CHECK(PointerIsMine(p)); + return SizeClassMap::Size(GetSizeClass(p)); + } + uptr ClassID(uptr size) { return SizeClassMap::ClassID(size); } void *GetMetaData(void *p) { @@ -354,6 +359,10 @@ class LargeMmapAllocator { return false; } + uptr GetActuallyAllocatedSize(void *p) { + return RoundUpMapSize(GetHeader(p)->size) - kPageSize; + } + // At least kPageSize/2 metadata bytes is available. void *GetMetaData(void *p) { return GetHeader(p) + 1; @@ -397,7 +406,9 @@ class CombinedAllocator { secondary_.Init(); } - void *Allocate(AllocatorCache *cache, uptr size, uptr alignment) { + void *Allocate(AllocatorCache *cache, uptr size, uptr alignment, + bool cleared = false) { + if (size == 0) return 0; CHECK_GT(size, 0); if (alignment > 8) size = RoundUpTo(size, alignment); @@ -408,16 +419,37 @@ class CombinedAllocator { res = secondary_.Allocate(size, alignment); if (alignment > 8) CHECK_EQ(reinterpret_cast<uptr>(res) & (alignment - 1), 0); + if (cleared) + internal_memset(res, 0, size); return res; } void Deallocate(AllocatorCache *cache, void *p) { + if (!p) return; if (primary_.PointerIsMine(p)) cache->Deallocate(&primary_, primary_.GetSizeClass(p), p); else secondary_.Deallocate(p); } + void *Reallocate(AllocatorCache *cache, void *p, uptr new_size, + uptr alignment) { + if (!p) + return Allocate(cache, new_size, alignment); + if (!new_size) { + Deallocate(cache, p); + return 0; + } + CHECK(PointerIsMine(p)); + uptr old_size = GetActuallyAllocatedSize(p); + uptr memcpy_size = Min(new_size, old_size); + void *new_p = Allocate(cache, new_size, alignment); + if (new_p) + internal_memcpy(new_p, p, memcpy_size); + Deallocate(cache, p); + return new_p; + } + bool PointerIsMine(void *p) { if (primary_.PointerIsMine(p)) return true; @@ -430,6 +462,12 @@ class CombinedAllocator { return secondary_.GetMetaData(p); } + uptr GetActuallyAllocatedSize(void *p) { + if (primary_.PointerIsMine(p)) + return primary_.GetActuallyAllocatedSize(p); + return secondary_.GetActuallyAllocatedSize(p); + } + uptr TotalMemoryUsed() { return primary_.TotalMemoryUsed() + secondary_.TotalMemoryUsed(); } diff --git a/compiler-rt/lib/sanitizer_common/tests/sanitizer_allocator64_test.cc b/compiler-rt/lib/sanitizer_common/tests/sanitizer_allocator64_test.cc index cbb71dbe037..1410f26ce84 100644 --- a/compiler-rt/lib/sanitizer_common/tests/sanitizer_allocator64_test.cc +++ b/compiler-rt/lib/sanitizer_common/tests/sanitizer_allocator64_test.cc @@ -74,6 +74,7 @@ TEST(SanitizerCommon, SizeClassAllocator64) { void *x = a.Allocate(size, 1); allocated.push_back(x); CHECK(a.PointerIsMine(x)); + CHECK_GE(a.GetActuallyAllocatedSize(x), size); uptr class_id = a.GetSizeClass(x); CHECK_EQ(class_id, SCMap::ClassID(size)); uptr *metadata = reinterpret_cast<uptr*>(a.GetMetaData(x)); @@ -164,6 +165,7 @@ TEST(SanitizerCommon, LargeMmapAllocator) { // Allocate some more, also add metadata. for (int i = 0; i < kNumAllocs; i++) { void *x = a.Allocate(size, 1); + CHECK_GE(a.GetActuallyAllocatedSize(x), size); uptr *meta = reinterpret_cast<uptr*>(a.GetMetaData(x)); *meta = i; allocated[i] = x; diff --git a/compiler-rt/lib/sanitizer_common/tests/sanitizer_allocator64_testlib.cc b/compiler-rt/lib/sanitizer_common/tests/sanitizer_allocator64_testlib.cc new file mode 100644 index 00000000000..e0c85dc04a5 --- /dev/null +++ b/compiler-rt/lib/sanitizer_common/tests/sanitizer_allocator64_testlib.cc @@ -0,0 +1,84 @@ +//===-- sanitizer_allocator64_testlib.cc ----------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// Malloc replacement library based on CombinedAllocator. +// The primary purpose of this file is an end-to-end integration test +// for CombinedAllocator. +//===----------------------------------------------------------------------===// +#include "sanitizer_common/sanitizer_allocator64.h" +#include <stddef.h> +#include <stdio.h> +#include <unistd.h> +#include <assert.h> + +namespace { +static const uptr kAllocatorSpace = 0x600000000000ULL; +static const uptr kAllocatorSize = 0x10000000000; // 1T. + +typedef SizeClassAllocator64<kAllocatorSpace, kAllocatorSize, 16, + DefaultSizeClassMap> PrimaryAllocator; +typedef SizeClassAllocatorLocalCache<PrimaryAllocator::kNumClasses, + PrimaryAllocator> AllocatorCache; +typedef LargeMmapAllocator SecondaryAllocator; +typedef CombinedAllocator<PrimaryAllocator, AllocatorCache, + SecondaryAllocator> Allocator; + +static THREADLOCAL AllocatorCache cache; +static Allocator allocator; + +static int inited = 0; + +__attribute__((constructor)) +void Init() { + if (inited) return; + inited = true; // this must happen before any threads are created. + allocator.Init(); +} + +} // namespace + +namespace __sanitizer { +void NORETURN Die() { + _exit(77); +} +void NORETURN CheckFailed(const char *file, int line, const char *cond, + u64 v1, u64 v2) { + fprintf(stderr, "CheckFailed: %s:%d %s (%lld %lld)\n", + file, line, cond, v1, v2); + Die(); +} +} + +#if 1 +extern "C" { +void *malloc(size_t size) { + assert(inited); + return allocator.Allocate(&cache, size, 8); +} + +void free(void *p) { + assert(inited); + allocator.Deallocate(&cache, p); +} + +void *calloc(size_t nmemb, size_t size) { + assert(inited); + return allocator.Allocate(&cache, nmemb * size, 8, /*cleared=*/true); +} + +void *realloc(void *p, size_t new_size) { + assert(inited); + return allocator.Reallocate(&cache, p, new_size, 8); +} + +void *memalign() { assert(0); } +int posix_memalign() { assert(0); } +void *valloc() { assert(0); } +void *pvalloc() { assert(0); } +} +#endif diff --git a/compiler-rt/lib/tsan/Makefile.old b/compiler-rt/lib/tsan/Makefile.old index 7bcc84e1122..2091f61335e 100644 --- a/compiler-rt/lib/tsan/Makefile.old +++ b/compiler-rt/lib/tsan/Makefile.old @@ -17,7 +17,7 @@ GTEST_INCLUDE=-I$(GTEST_ROOT)/include GTEST_BUILD_DIR=$(GTEST_ROOT)/build GTEST_LIB=$(GTEST_BUILD_DIR)/gtest-all.o -SANITIZER_COMMON_TESTS_SRC=$(wildcard ../sanitizer_common/tests/*.cc) +SANITIZER_COMMON_TESTS_SRC=$(wildcard ../sanitizer_common/tests/*_test.cc) SANITIZER_COMMON_TESTS_OBJ=$(patsubst %.cc,%.o,$(SANITIZER_COMMON_TESTS_SRC)) RTL_TEST_SRC=$(wildcard rtl_tests/*.cc) RTL_TEST_OBJ=$(patsubst %.cc,%.o,$(RTL_TEST_SRC)) @@ -43,7 +43,7 @@ $(LIBTSAN): libtsan libtsan: $(MAKE) -C rtl -f Makefile.old DEBUG=$(DEBUG) -%.o: %.cc $(UNIT_TEST_HDR) libtsan +%.o: %.cc $(UNIT_TEST_HDR) $(LIBTSAN) $(CXX) $(CXXFLAGS) $(CFLAGS) $(INCLUDES) -o $@ -c $< tsan_test: $(UNIT_TEST_OBJ) $(RTL_TEST_OBJ) \ |

