1c99de512472c5635e554d983c225aa3a92a20202Sergey Matveev//=-- lsan_allocator.cc ---------------------------------------------------===//
2c99de512472c5635e554d983c225aa3a92a20202Sergey Matveev//
3c99de512472c5635e554d983c225aa3a92a20202Sergey Matveev//                     The LLVM Compiler Infrastructure
4c99de512472c5635e554d983c225aa3a92a20202Sergey Matveev//
5c99de512472c5635e554d983c225aa3a92a20202Sergey Matveev// This file is distributed under the University of Illinois Open Source
6c99de512472c5635e554d983c225aa3a92a20202Sergey Matveev// License. See LICENSE.TXT for details.
7c99de512472c5635e554d983c225aa3a92a20202Sergey Matveev//
8c99de512472c5635e554d983c225aa3a92a20202Sergey Matveev//===----------------------------------------------------------------------===//
9c99de512472c5635e554d983c225aa3a92a20202Sergey Matveev//
10c99de512472c5635e554d983c225aa3a92a20202Sergey Matveev// This file is a part of LeakSanitizer.
11c99de512472c5635e554d983c225aa3a92a20202Sergey Matveev// See lsan_allocator.h for details.
12c99de512472c5635e554d983c225aa3a92a20202Sergey Matveev//
13c99de512472c5635e554d983c225aa3a92a20202Sergey Matveev//===----------------------------------------------------------------------===//
14c99de512472c5635e554d983c225aa3a92a20202Sergey Matveev
15c99de512472c5635e554d983c225aa3a92a20202Sergey Matveev#include "lsan_allocator.h"
16c99de512472c5635e554d983c225aa3a92a20202Sergey Matveev
17c99de512472c5635e554d983c225aa3a92a20202Sergey Matveev#include "sanitizer_common/sanitizer_allocator.h"
186d1862363c88c183b0ed7740fca876342cf0474bStephen Hines#include "sanitizer_common/sanitizer_allocator_interface.h"
19c99de512472c5635e554d983c225aa3a92a20202Sergey Matveev#include "sanitizer_common/sanitizer_internal_defs.h"
20c99de512472c5635e554d983c225aa3a92a20202Sergey Matveev#include "sanitizer_common/sanitizer_stackdepot.h"
21c99de512472c5635e554d983c225aa3a92a20202Sergey Matveev#include "sanitizer_common/sanitizer_stacktrace.h"
22c99de512472c5635e554d983c225aa3a92a20202Sergey Matveev#include "lsan_common.h"
23c99de512472c5635e554d983c225aa3a92a20202Sergey Matveev
2412f610efe6f48efb2d03b985b3b2a36d4556fca7Sergey Matveevextern "C" void *memset(void *ptr, int value, uptr num);
2512f610efe6f48efb2d03b985b3b2a36d4556fca7Sergey Matveev
26c99de512472c5635e554d983c225aa3a92a20202Sergey Matveevnamespace __lsan {
27c99de512472c5635e554d983c225aa3a92a20202Sergey Matveev
28c99de512472c5635e554d983c225aa3a92a20202Sergey Matveevstruct ChunkMetadata {
29c99de512472c5635e554d983c225aa3a92a20202Sergey Matveev  bool allocated : 8;  // Must be first.
30c99de512472c5635e554d983c225aa3a92a20202Sergey Matveev  ChunkTag tag : 2;
31c99de512472c5635e554d983c225aa3a92a20202Sergey Matveev  uptr requested_size : 54;
32c99de512472c5635e554d983c225aa3a92a20202Sergey Matveev  u32 stack_trace_id;
33c99de512472c5635e554d983c225aa3a92a20202Sergey Matveev};
34c99de512472c5635e554d983c225aa3a92a20202Sergey Matveev
3586277eb844c4983c81de62d7c050e92fe7155788Stephen Hines#if defined(__mips64)
3686277eb844c4983c81de62d7c050e92fe7155788Stephen Hinesstatic const uptr kMaxAllowedMallocSize = 4UL << 30;
3786277eb844c4983c81de62d7c050e92fe7155788Stephen Hinesstatic const uptr kRegionSizeLog = 20;
3886277eb844c4983c81de62d7c050e92fe7155788Stephen Hinesstatic const uptr kNumRegions = SANITIZER_MMAP_RANGE_SIZE >> kRegionSizeLog;
3986277eb844c4983c81de62d7c050e92fe7155788Stephen Hinestypedef TwoLevelByteMap<(kNumRegions >> 12), 1 << 12> ByteMap;
4086277eb844c4983c81de62d7c050e92fe7155788Stephen Hinestypedef CompactSizeClassMap SizeClassMap;
4186277eb844c4983c81de62d7c050e92fe7155788Stephen Hinestypedef SizeClassAllocator32<0, SANITIZER_MMAP_RANGE_SIZE,
4286277eb844c4983c81de62d7c050e92fe7155788Stephen Hines    sizeof(ChunkMetadata), SizeClassMap, kRegionSizeLog, ByteMap>
4386277eb844c4983c81de62d7c050e92fe7155788Stephen Hines    PrimaryAllocator;
4486277eb844c4983c81de62d7c050e92fe7155788Stephen Hines#else
4586277eb844c4983c81de62d7c050e92fe7155788Stephen Hinesstatic const uptr kMaxAllowedMallocSize = 8UL << 30;
4686277eb844c4983c81de62d7c050e92fe7155788Stephen Hinesstatic const uptr kAllocatorSpace = 0x600000000000ULL;
4786277eb844c4983c81de62d7c050e92fe7155788Stephen Hinesstatic const uptr kAllocatorSize = 0x40000000000ULL; // 4T.
48c99de512472c5635e554d983c225aa3a92a20202Sergey Matveevtypedef SizeClassAllocator64<kAllocatorSpace, kAllocatorSize,
4912f610efe6f48efb2d03b985b3b2a36d4556fca7Sergey Matveev        sizeof(ChunkMetadata), DefaultSizeClassMap> PrimaryAllocator;
5086277eb844c4983c81de62d7c050e92fe7155788Stephen Hines#endif
51c99de512472c5635e554d983c225aa3a92a20202Sergey Matveevtypedef SizeClassAllocatorLocalCache<PrimaryAllocator> AllocatorCache;
52c99de512472c5635e554d983c225aa3a92a20202Sergey Matveevtypedef LargeMmapAllocator<> SecondaryAllocator;
53c99de512472c5635e554d983c225aa3a92a20202Sergey Matveevtypedef CombinedAllocator<PrimaryAllocator, AllocatorCache,
54c99de512472c5635e554d983c225aa3a92a20202Sergey Matveev          SecondaryAllocator> Allocator;
55c99de512472c5635e554d983c225aa3a92a20202Sergey Matveev
56c99de512472c5635e554d983c225aa3a92a20202Sergey Matveevstatic Allocator allocator;
57c99de512472c5635e554d983c225aa3a92a20202Sergey Matveevstatic THREADLOCAL AllocatorCache cache;
58c99de512472c5635e554d983c225aa3a92a20202Sergey Matveev
59c99de512472c5635e554d983c225aa3a92a20202Sergey Matveevvoid InitializeAllocator() {
6086277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  allocator.InitLinkerInitialized(common_flags()->allocator_may_return_null);
61c99de512472c5635e554d983c225aa3a92a20202Sergey Matveev}
62c99de512472c5635e554d983c225aa3a92a20202Sergey Matveev
63c99de512472c5635e554d983c225aa3a92a20202Sergey Matveevvoid AllocatorThreadFinish() {
64c99de512472c5635e554d983c225aa3a92a20202Sergey Matveev  allocator.SwallowCache(&cache);
65c99de512472c5635e554d983c225aa3a92a20202Sergey Matveev}
66c99de512472c5635e554d983c225aa3a92a20202Sergey Matveev
676d1862363c88c183b0ed7740fca876342cf0474bStephen Hinesstatic ChunkMetadata *Metadata(const void *p) {
68ac78d0087281e9b40bb043f827fbde8c05c6505aSergey Matveev  return reinterpret_cast<ChunkMetadata *>(allocator.GetMetaData(p));
69c99de512472c5635e554d983c225aa3a92a20202Sergey Matveev}
70c99de512472c5635e554d983c225aa3a92a20202Sergey Matveev
71c99de512472c5635e554d983c225aa3a92a20202Sergey Matveevstatic void RegisterAllocation(const StackTrace &stack, void *p, uptr size) {
72c99de512472c5635e554d983c225aa3a92a20202Sergey Matveev  if (!p) return;
73c99de512472c5635e554d983c225aa3a92a20202Sergey Matveev  ChunkMetadata *m = Metadata(p);
74c99de512472c5635e554d983c225aa3a92a20202Sergey Matveev  CHECK(m);
75200afbd8ba4904241c1ebcef4fa79d739ca01f73Sergey Matveev  m->tag = DisabledInThisThread() ? kIgnored : kDirectlyLeaked;
766d1862363c88c183b0ed7740fca876342cf0474bStephen Hines  m->stack_trace_id = StackDepotPut(stack);
77c99de512472c5635e554d983c225aa3a92a20202Sergey Matveev  m->requested_size = size;
78ac78d0087281e9b40bb043f827fbde8c05c6505aSergey Matveev  atomic_store(reinterpret_cast<atomic_uint8_t *>(m), 1, memory_order_relaxed);
79c99de512472c5635e554d983c225aa3a92a20202Sergey Matveev}
80c99de512472c5635e554d983c225aa3a92a20202Sergey Matveev
81c99de512472c5635e554d983c225aa3a92a20202Sergey Matveevstatic void RegisterDeallocation(void *p) {
82c99de512472c5635e554d983c225aa3a92a20202Sergey Matveev  if (!p) return;
83c99de512472c5635e554d983c225aa3a92a20202Sergey Matveev  ChunkMetadata *m = Metadata(p);
84c99de512472c5635e554d983c225aa3a92a20202Sergey Matveev  CHECK(m);
85ac78d0087281e9b40bb043f827fbde8c05c6505aSergey Matveev  atomic_store(reinterpret_cast<atomic_uint8_t *>(m), 0, memory_order_relaxed);
86c99de512472c5635e554d983c225aa3a92a20202Sergey Matveev}
87c99de512472c5635e554d983c225aa3a92a20202Sergey Matveev
88c99de512472c5635e554d983c225aa3a92a20202Sergey Matveevvoid *Allocate(const StackTrace &stack, uptr size, uptr alignment,
89c99de512472c5635e554d983c225aa3a92a20202Sergey Matveev               bool cleared) {
90c99de512472c5635e554d983c225aa3a92a20202Sergey Matveev  if (size == 0)
91c99de512472c5635e554d983c225aa3a92a20202Sergey Matveev    size = 1;
92c99de512472c5635e554d983c225aa3a92a20202Sergey Matveev  if (size > kMaxAllowedMallocSize) {
93ef89d6b576bd8f5084b70e2d908cd53c37fab9f9Sergey Matveev    Report("WARNING: LeakSanitizer failed to allocate %zu bytes\n", size);
94ef89d6b576bd8f5084b70e2d908cd53c37fab9f9Sergey Matveev    return 0;
95c99de512472c5635e554d983c225aa3a92a20202Sergey Matveev  }
9612f610efe6f48efb2d03b985b3b2a36d4556fca7Sergey Matveev  void *p = allocator.Allocate(&cache, size, alignment, false);
9712f610efe6f48efb2d03b985b3b2a36d4556fca7Sergey Matveev  // Do not rely on the allocator to clear the memory (it's slow).
9812f610efe6f48efb2d03b985b3b2a36d4556fca7Sergey Matveev  if (cleared && allocator.FromPrimary(p))
9912f610efe6f48efb2d03b985b3b2a36d4556fca7Sergey Matveev    memset(p, 0, size);
100c99de512472c5635e554d983c225aa3a92a20202Sergey Matveev  RegisterAllocation(stack, p, size);
1016d1862363c88c183b0ed7740fca876342cf0474bStephen Hines  if (&__sanitizer_malloc_hook) __sanitizer_malloc_hook(p, size);
102c99de512472c5635e554d983c225aa3a92a20202Sergey Matveev  return p;
103c99de512472c5635e554d983c225aa3a92a20202Sergey Matveev}
104c99de512472c5635e554d983c225aa3a92a20202Sergey Matveev
105c99de512472c5635e554d983c225aa3a92a20202Sergey Matveevvoid Deallocate(void *p) {
1066d1862363c88c183b0ed7740fca876342cf0474bStephen Hines  if (&__sanitizer_free_hook) __sanitizer_free_hook(p);
107c99de512472c5635e554d983c225aa3a92a20202Sergey Matveev  RegisterDeallocation(p);
108c99de512472c5635e554d983c225aa3a92a20202Sergey Matveev  allocator.Deallocate(&cache, p);
109c99de512472c5635e554d983c225aa3a92a20202Sergey Matveev}
110c99de512472c5635e554d983c225aa3a92a20202Sergey Matveev
111c99de512472c5635e554d983c225aa3a92a20202Sergey Matveevvoid *Reallocate(const StackTrace &stack, void *p, uptr new_size,
112c99de512472c5635e554d983c225aa3a92a20202Sergey Matveev                 uptr alignment) {
113c99de512472c5635e554d983c225aa3a92a20202Sergey Matveev  RegisterDeallocation(p);
114c99de512472c5635e554d983c225aa3a92a20202Sergey Matveev  if (new_size > kMaxAllowedMallocSize) {
115ef89d6b576bd8f5084b70e2d908cd53c37fab9f9Sergey Matveev    Report("WARNING: LeakSanitizer failed to allocate %zu bytes\n", new_size);
116ef89d6b576bd8f5084b70e2d908cd53c37fab9f9Sergey Matveev    allocator.Deallocate(&cache, p);
117ef89d6b576bd8f5084b70e2d908cd53c37fab9f9Sergey Matveev    return 0;
118c99de512472c5635e554d983c225aa3a92a20202Sergey Matveev  }
119c99de512472c5635e554d983c225aa3a92a20202Sergey Matveev  p = allocator.Reallocate(&cache, p, new_size, alignment);
120c99de512472c5635e554d983c225aa3a92a20202Sergey Matveev  RegisterAllocation(stack, p, new_size);
121c99de512472c5635e554d983c225aa3a92a20202Sergey Matveev  return p;
122c99de512472c5635e554d983c225aa3a92a20202Sergey Matveev}
123c99de512472c5635e554d983c225aa3a92a20202Sergey Matveev
124c99de512472c5635e554d983c225aa3a92a20202Sergey Matveevvoid GetAllocatorCacheRange(uptr *begin, uptr *end) {
125c99de512472c5635e554d983c225aa3a92a20202Sergey Matveev  *begin = (uptr)&cache;
126c99de512472c5635e554d983c225aa3a92a20202Sergey Matveev  *end = *begin + sizeof(cache);
127c99de512472c5635e554d983c225aa3a92a20202Sergey Matveev}
128c99de512472c5635e554d983c225aa3a92a20202Sergey Matveev
1296d1862363c88c183b0ed7740fca876342cf0474bStephen Hinesuptr GetMallocUsableSize(const void *p) {
130c99de512472c5635e554d983c225aa3a92a20202Sergey Matveev  ChunkMetadata *m = Metadata(p);
131c99de512472c5635e554d983c225aa3a92a20202Sergey Matveev  if (!m) return 0;
132c99de512472c5635e554d983c225aa3a92a20202Sergey Matveev  return m->requested_size;
133c99de512472c5635e554d983c225aa3a92a20202Sergey Matveev}
134c99de512472c5635e554d983c225aa3a92a20202Sergey Matveev
135c99de512472c5635e554d983c225aa3a92a20202Sergey Matveev///// Interface to the common LSan module. /////
136c99de512472c5635e554d983c225aa3a92a20202Sergey Matveev
137c99de512472c5635e554d983c225aa3a92a20202Sergey Matveevvoid LockAllocator() {
138c99de512472c5635e554d983c225aa3a92a20202Sergey Matveev  allocator.ForceLock();
139c99de512472c5635e554d983c225aa3a92a20202Sergey Matveev}
140c99de512472c5635e554d983c225aa3a92a20202Sergey Matveev
141c99de512472c5635e554d983c225aa3a92a20202Sergey Matveevvoid UnlockAllocator() {
142c99de512472c5635e554d983c225aa3a92a20202Sergey Matveev  allocator.ForceUnlock();
143c99de512472c5635e554d983c225aa3a92a20202Sergey Matveev}
144c99de512472c5635e554d983c225aa3a92a20202Sergey Matveev
145c99de512472c5635e554d983c225aa3a92a20202Sergey Matveevvoid GetAllocatorGlobalRange(uptr *begin, uptr *end) {
146c99de512472c5635e554d983c225aa3a92a20202Sergey Matveev  *begin = (uptr)&allocator;
147c99de512472c5635e554d983c225aa3a92a20202Sergey Matveev  *end = *begin + sizeof(allocator);
148c99de512472c5635e554d983c225aa3a92a20202Sergey Matveev}
149c99de512472c5635e554d983c225aa3a92a20202Sergey Matveev
150ac78d0087281e9b40bb043f827fbde8c05c6505aSergey Matveevuptr PointsIntoChunk(void* p) {
151ac78d0087281e9b40bb043f827fbde8c05c6505aSergey Matveev  uptr addr = reinterpret_cast<uptr>(p);
152ac78d0087281e9b40bb043f827fbde8c05c6505aSergey Matveev  uptr chunk = reinterpret_cast<uptr>(allocator.GetBlockBeginFastLocked(p));
153c99de512472c5635e554d983c225aa3a92a20202Sergey Matveev  if (!chunk) return 0;
154c99de512472c5635e554d983c225aa3a92a20202Sergey Matveev  // LargeMmapAllocator considers pointers to the meta-region of a chunk to be
155c99de512472c5635e554d983c225aa3a92a20202Sergey Matveev  // valid, but we don't want that.
156ac78d0087281e9b40bb043f827fbde8c05c6505aSergey Matveev  if (addr < chunk) return 0;
157ac78d0087281e9b40bb043f827fbde8c05c6505aSergey Matveev  ChunkMetadata *m = Metadata(reinterpret_cast<void *>(chunk));
158c99de512472c5635e554d983c225aa3a92a20202Sergey Matveev  CHECK(m);
1592d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  if (!m->allocated)
1602d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    return 0;
1612d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  if (addr < chunk + m->requested_size)
1622d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    return chunk;
1632d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  if (IsSpecialCaseOfOperatorNew0(chunk, m->requested_size, addr))
164c99de512472c5635e554d983c225aa3a92a20202Sergey Matveev    return chunk;
165c99de512472c5635e554d983c225aa3a92a20202Sergey Matveev  return 0;
166c99de512472c5635e554d983c225aa3a92a20202Sergey Matveev}
167c99de512472c5635e554d983c225aa3a92a20202Sergey Matveev
168ac78d0087281e9b40bb043f827fbde8c05c6505aSergey Matveevuptr GetUserBegin(uptr chunk) {
169ac78d0087281e9b40bb043f827fbde8c05c6505aSergey Matveev  return chunk;
17029b756851c04df07f1584dfd77021dd2f37a7391Sergey Matveev}
17129b756851c04df07f1584dfd77021dd2f37a7391Sergey Matveev
172ac78d0087281e9b40bb043f827fbde8c05c6505aSergey MatveevLsanMetadata::LsanMetadata(uptr chunk) {
173ac78d0087281e9b40bb043f827fbde8c05c6505aSergey Matveev  metadata_ = Metadata(reinterpret_cast<void *>(chunk));
174c99de512472c5635e554d983c225aa3a92a20202Sergey Matveev  CHECK(metadata_);
175c99de512472c5635e554d983c225aa3a92a20202Sergey Matveev}
176c99de512472c5635e554d983c225aa3a92a20202Sergey Matveev
177c99de512472c5635e554d983c225aa3a92a20202Sergey Matveevbool LsanMetadata::allocated() const {
178c99de512472c5635e554d983c225aa3a92a20202Sergey Matveev  return reinterpret_cast<ChunkMetadata *>(metadata_)->allocated;
179c99de512472c5635e554d983c225aa3a92a20202Sergey Matveev}
180c99de512472c5635e554d983c225aa3a92a20202Sergey Matveev
181c99de512472c5635e554d983c225aa3a92a20202Sergey MatveevChunkTag LsanMetadata::tag() const {
182c99de512472c5635e554d983c225aa3a92a20202Sergey Matveev  return reinterpret_cast<ChunkMetadata *>(metadata_)->tag;
183c99de512472c5635e554d983c225aa3a92a20202Sergey Matveev}
184c99de512472c5635e554d983c225aa3a92a20202Sergey Matveev
185c99de512472c5635e554d983c225aa3a92a20202Sergey Matveevvoid LsanMetadata::set_tag(ChunkTag value) {
186c99de512472c5635e554d983c225aa3a92a20202Sergey Matveev  reinterpret_cast<ChunkMetadata *>(metadata_)->tag = value;
187c99de512472c5635e554d983c225aa3a92a20202Sergey Matveev}
188c99de512472c5635e554d983c225aa3a92a20202Sergey Matveev
189c99de512472c5635e554d983c225aa3a92a20202Sergey Matveevuptr LsanMetadata::requested_size() const {
190c99de512472c5635e554d983c225aa3a92a20202Sergey Matveev  return reinterpret_cast<ChunkMetadata *>(metadata_)->requested_size;
191c99de512472c5635e554d983c225aa3a92a20202Sergey Matveev}
192c99de512472c5635e554d983c225aa3a92a20202Sergey Matveev
193c99de512472c5635e554d983c225aa3a92a20202Sergey Matveevu32 LsanMetadata::stack_trace_id() const {
194c99de512472c5635e554d983c225aa3a92a20202Sergey Matveev  return reinterpret_cast<ChunkMetadata *>(metadata_)->stack_trace_id;
195c99de512472c5635e554d983c225aa3a92a20202Sergey Matveev}
196c99de512472c5635e554d983c225aa3a92a20202Sergey Matveev
197ac78d0087281e9b40bb043f827fbde8c05c6505aSergey Matveevvoid ForEachChunk(ForEachChunkCallback callback, void *arg) {
198ac78d0087281e9b40bb043f827fbde8c05c6505aSergey Matveev  allocator.ForEachChunk(callback, arg);
199c99de512472c5635e554d983c225aa3a92a20202Sergey Matveev}
200c99de512472c5635e554d983c225aa3a92a20202Sergey Matveev
201cd571e07fd1179383188c70338fa0dc1c452cb19Sergey MatveevIgnoreObjectResult IgnoreObjectLocked(const void *p) {
202cd571e07fd1179383188c70338fa0dc1c452cb19Sergey Matveev  void *chunk = allocator.GetBlockBegin(p);
203cd571e07fd1179383188c70338fa0dc1c452cb19Sergey Matveev  if (!chunk || p < chunk) return kIgnoreObjectInvalid;
204cd571e07fd1179383188c70338fa0dc1c452cb19Sergey Matveev  ChunkMetadata *m = Metadata(chunk);
205cd571e07fd1179383188c70338fa0dc1c452cb19Sergey Matveev  CHECK(m);
206cd571e07fd1179383188c70338fa0dc1c452cb19Sergey Matveev  if (m->allocated && (uptr)p < (uptr)chunk + m->requested_size) {
207b3b46dad13a2111a51fb1a67f36c8b633410e9b7Sergey Matveev    if (m->tag == kIgnored)
208cd571e07fd1179383188c70338fa0dc1c452cb19Sergey Matveev      return kIgnoreObjectAlreadyIgnored;
209b3b46dad13a2111a51fb1a67f36c8b633410e9b7Sergey Matveev    m->tag = kIgnored;
210cd571e07fd1179383188c70338fa0dc1c452cb19Sergey Matveev    return kIgnoreObjectSuccess;
211cd571e07fd1179383188c70338fa0dc1c452cb19Sergey Matveev  } else {
212cd571e07fd1179383188c70338fa0dc1c452cb19Sergey Matveev    return kIgnoreObjectInvalid;
213cd571e07fd1179383188c70338fa0dc1c452cb19Sergey Matveev  }
214cd571e07fd1179383188c70338fa0dc1c452cb19Sergey Matveev}
215c99de512472c5635e554d983c225aa3a92a20202Sergey Matveev}  // namespace __lsan
2166d1862363c88c183b0ed7740fca876342cf0474bStephen Hines
2176d1862363c88c183b0ed7740fca876342cf0474bStephen Hinesusing namespace __lsan;
2186d1862363c88c183b0ed7740fca876342cf0474bStephen Hines
2196d1862363c88c183b0ed7740fca876342cf0474bStephen Hinesextern "C" {
2206d1862363c88c183b0ed7740fca876342cf0474bStephen HinesSANITIZER_INTERFACE_ATTRIBUTE
2216d1862363c88c183b0ed7740fca876342cf0474bStephen Hinesuptr __sanitizer_get_current_allocated_bytes() {
2226d1862363c88c183b0ed7740fca876342cf0474bStephen Hines  uptr stats[AllocatorStatCount];
2236d1862363c88c183b0ed7740fca876342cf0474bStephen Hines  allocator.GetStats(stats);
2246d1862363c88c183b0ed7740fca876342cf0474bStephen Hines  return stats[AllocatorStatAllocated];
2256d1862363c88c183b0ed7740fca876342cf0474bStephen Hines}
2266d1862363c88c183b0ed7740fca876342cf0474bStephen Hines
2276d1862363c88c183b0ed7740fca876342cf0474bStephen HinesSANITIZER_INTERFACE_ATTRIBUTE
2286d1862363c88c183b0ed7740fca876342cf0474bStephen Hinesuptr __sanitizer_get_heap_size() {
2296d1862363c88c183b0ed7740fca876342cf0474bStephen Hines  uptr stats[AllocatorStatCount];
2306d1862363c88c183b0ed7740fca876342cf0474bStephen Hines  allocator.GetStats(stats);
2316d1862363c88c183b0ed7740fca876342cf0474bStephen Hines  return stats[AllocatorStatMapped];
2326d1862363c88c183b0ed7740fca876342cf0474bStephen Hines}
2336d1862363c88c183b0ed7740fca876342cf0474bStephen Hines
2346d1862363c88c183b0ed7740fca876342cf0474bStephen HinesSANITIZER_INTERFACE_ATTRIBUTE
2356d1862363c88c183b0ed7740fca876342cf0474bStephen Hinesuptr __sanitizer_get_free_bytes() { return 0; }
2366d1862363c88c183b0ed7740fca876342cf0474bStephen Hines
2376d1862363c88c183b0ed7740fca876342cf0474bStephen HinesSANITIZER_INTERFACE_ATTRIBUTE
2386d1862363c88c183b0ed7740fca876342cf0474bStephen Hinesuptr __sanitizer_get_unmapped_bytes() { return 0; }
2396d1862363c88c183b0ed7740fca876342cf0474bStephen Hines
2406d1862363c88c183b0ed7740fca876342cf0474bStephen HinesSANITIZER_INTERFACE_ATTRIBUTE
2416d1862363c88c183b0ed7740fca876342cf0474bStephen Hinesuptr __sanitizer_get_estimated_allocated_size(uptr size) { return size; }
2426d1862363c88c183b0ed7740fca876342cf0474bStephen Hines
2436d1862363c88c183b0ed7740fca876342cf0474bStephen HinesSANITIZER_INTERFACE_ATTRIBUTE
2446d1862363c88c183b0ed7740fca876342cf0474bStephen Hinesint __sanitizer_get_ownership(const void *p) { return Metadata(p) != 0; }
2456d1862363c88c183b0ed7740fca876342cf0474bStephen Hines
2466d1862363c88c183b0ed7740fca876342cf0474bStephen HinesSANITIZER_INTERFACE_ATTRIBUTE
2476d1862363c88c183b0ed7740fca876342cf0474bStephen Hinesuptr __sanitizer_get_allocated_size(const void *p) {
2486d1862363c88c183b0ed7740fca876342cf0474bStephen Hines  return GetMallocUsableSize(p);
2496d1862363c88c183b0ed7740fca876342cf0474bStephen Hines}
2506d1862363c88c183b0ed7740fca876342cf0474bStephen Hines}  // extern "C"
251