xref: /freebsd-src/contrib/llvm-project/compiler-rt/lib/msan/msan_allocator.cpp (revision 480093f4440d54b30b3025afeac24b48f2ba7a2e)
168d75effSDimitry Andric //===-- msan_allocator.cpp -------------------------- ---------------------===//
268d75effSDimitry Andric //
368d75effSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
468d75effSDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
568d75effSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
668d75effSDimitry Andric //
768d75effSDimitry Andric //===----------------------------------------------------------------------===//
868d75effSDimitry Andric //
968d75effSDimitry Andric // This file is a part of MemorySanitizer.
1068d75effSDimitry Andric //
1168d75effSDimitry Andric // MemorySanitizer allocator.
1268d75effSDimitry Andric //===----------------------------------------------------------------------===//
1368d75effSDimitry Andric 
1468d75effSDimitry Andric #include "sanitizer_common/sanitizer_allocator.h"
1568d75effSDimitry Andric #include "sanitizer_common/sanitizer_allocator_checks.h"
1668d75effSDimitry Andric #include "sanitizer_common/sanitizer_allocator_interface.h"
1768d75effSDimitry Andric #include "sanitizer_common/sanitizer_allocator_report.h"
1868d75effSDimitry Andric #include "sanitizer_common/sanitizer_errno.h"
1968d75effSDimitry Andric #include "msan.h"
2068d75effSDimitry Andric #include "msan_allocator.h"
2168d75effSDimitry Andric #include "msan_origin.h"
2268d75effSDimitry Andric #include "msan_thread.h"
2368d75effSDimitry Andric #include "msan_poisoning.h"
2468d75effSDimitry Andric 
2568d75effSDimitry Andric namespace __msan {
2668d75effSDimitry Andric 
2768d75effSDimitry Andric struct Metadata {
2868d75effSDimitry Andric   uptr requested_size;
2968d75effSDimitry Andric };
3068d75effSDimitry Andric 
3168d75effSDimitry Andric struct MsanMapUnmapCallback {
3268d75effSDimitry Andric   void OnMap(uptr p, uptr size) const {}
3368d75effSDimitry Andric   void OnUnmap(uptr p, uptr size) const {
3468d75effSDimitry Andric     __msan_unpoison((void *)p, size);
3568d75effSDimitry Andric 
3668d75effSDimitry Andric     // We are about to unmap a chunk of user memory.
3768d75effSDimitry Andric     // Mark the corresponding shadow memory as not needed.
3868d75effSDimitry Andric     uptr shadow_p = MEM_TO_SHADOW(p);
3968d75effSDimitry Andric     ReleaseMemoryPagesToOS(shadow_p, shadow_p + size);
4068d75effSDimitry Andric     if (__msan_get_track_origins()) {
4168d75effSDimitry Andric       uptr origin_p = MEM_TO_ORIGIN(p);
4268d75effSDimitry Andric       ReleaseMemoryPagesToOS(origin_p, origin_p + size);
4368d75effSDimitry Andric     }
4468d75effSDimitry Andric   }
4568d75effSDimitry Andric };
4668d75effSDimitry Andric 
4768d75effSDimitry Andric #if defined(__mips64)
4868d75effSDimitry Andric static const uptr kMaxAllowedMallocSize = 2UL << 30;
4968d75effSDimitry Andric 
5068d75effSDimitry Andric struct AP32 {
5168d75effSDimitry Andric   static const uptr kSpaceBeg = 0;
5268d75effSDimitry Andric   static const u64 kSpaceSize = SANITIZER_MMAP_RANGE_SIZE;
5368d75effSDimitry Andric   static const uptr kMetadataSize = sizeof(Metadata);
5468d75effSDimitry Andric   typedef __sanitizer::CompactSizeClassMap SizeClassMap;
5568d75effSDimitry Andric   static const uptr kRegionSizeLog = 20;
5668d75effSDimitry Andric   using AddressSpaceView = LocalAddressSpaceView;
5768d75effSDimitry Andric   typedef MsanMapUnmapCallback MapUnmapCallback;
5868d75effSDimitry Andric   static const uptr kFlags = 0;
5968d75effSDimitry Andric };
6068d75effSDimitry Andric typedef SizeClassAllocator32<AP32> PrimaryAllocator;
6168d75effSDimitry Andric #elif defined(__x86_64__)
6268d75effSDimitry Andric #if SANITIZER_NETBSD || \
6368d75effSDimitry Andric     (SANITIZER_LINUX && !defined(MSAN_LINUX_X86_64_OLD_MAPPING))
6468d75effSDimitry Andric static const uptr kAllocatorSpace = 0x700000000000ULL;
6568d75effSDimitry Andric #else
6668d75effSDimitry Andric static const uptr kAllocatorSpace = 0x600000000000ULL;
6768d75effSDimitry Andric #endif
6868d75effSDimitry Andric static const uptr kMaxAllowedMallocSize = 8UL << 30;
6968d75effSDimitry Andric 
7068d75effSDimitry Andric struct AP64 {  // Allocator64 parameters. Deliberately using a short name.
7168d75effSDimitry Andric   static const uptr kSpaceBeg = kAllocatorSpace;
7268d75effSDimitry Andric   static const uptr kSpaceSize = 0x40000000000;  // 4T.
7368d75effSDimitry Andric   static const uptr kMetadataSize = sizeof(Metadata);
7468d75effSDimitry Andric   typedef DefaultSizeClassMap SizeClassMap;
7568d75effSDimitry Andric   typedef MsanMapUnmapCallback MapUnmapCallback;
7668d75effSDimitry Andric   static const uptr kFlags = 0;
7768d75effSDimitry Andric   using AddressSpaceView = LocalAddressSpaceView;
7868d75effSDimitry Andric };
7968d75effSDimitry Andric 
8068d75effSDimitry Andric typedef SizeClassAllocator64<AP64> PrimaryAllocator;
8168d75effSDimitry Andric 
8268d75effSDimitry Andric #elif defined(__powerpc64__)
8368d75effSDimitry Andric static const uptr kMaxAllowedMallocSize = 2UL << 30;  // 2G
8468d75effSDimitry Andric 
8568d75effSDimitry Andric struct AP64 {  // Allocator64 parameters. Deliberately using a short name.
8668d75effSDimitry Andric   static const uptr kSpaceBeg = 0x300000000000;
8768d75effSDimitry Andric   static const uptr kSpaceSize = 0x020000000000;  // 2T.
8868d75effSDimitry Andric   static const uptr kMetadataSize = sizeof(Metadata);
8968d75effSDimitry Andric   typedef DefaultSizeClassMap SizeClassMap;
9068d75effSDimitry Andric   typedef MsanMapUnmapCallback MapUnmapCallback;
9168d75effSDimitry Andric   static const uptr kFlags = 0;
9268d75effSDimitry Andric   using AddressSpaceView = LocalAddressSpaceView;
9368d75effSDimitry Andric };
9468d75effSDimitry Andric 
9568d75effSDimitry Andric typedef SizeClassAllocator64<AP64> PrimaryAllocator;
9668d75effSDimitry Andric #elif defined(__aarch64__)
9768d75effSDimitry Andric static const uptr kMaxAllowedMallocSize = 2UL << 30;  // 2G
9868d75effSDimitry Andric 
9968d75effSDimitry Andric struct AP32 {
10068d75effSDimitry Andric   static const uptr kSpaceBeg = 0;
10168d75effSDimitry Andric   static const u64 kSpaceSize = SANITIZER_MMAP_RANGE_SIZE;
10268d75effSDimitry Andric   static const uptr kMetadataSize = sizeof(Metadata);
10368d75effSDimitry Andric   typedef __sanitizer::CompactSizeClassMap SizeClassMap;
10468d75effSDimitry Andric   static const uptr kRegionSizeLog = 20;
10568d75effSDimitry Andric   using AddressSpaceView = LocalAddressSpaceView;
10668d75effSDimitry Andric   typedef MsanMapUnmapCallback MapUnmapCallback;
10768d75effSDimitry Andric   static const uptr kFlags = 0;
10868d75effSDimitry Andric };
10968d75effSDimitry Andric typedef SizeClassAllocator32<AP32> PrimaryAllocator;
11068d75effSDimitry Andric #endif
11168d75effSDimitry Andric typedef CombinedAllocator<PrimaryAllocator> Allocator;
11268d75effSDimitry Andric typedef Allocator::AllocatorCache AllocatorCache;
11368d75effSDimitry Andric 
11468d75effSDimitry Andric static Allocator allocator;
11568d75effSDimitry Andric static AllocatorCache fallback_allocator_cache;
11668d75effSDimitry Andric static StaticSpinMutex fallback_mutex;
11768d75effSDimitry Andric 
118*480093f4SDimitry Andric static uptr max_malloc_size;
119*480093f4SDimitry Andric 
12068d75effSDimitry Andric void MsanAllocatorInit() {
12168d75effSDimitry Andric   SetAllocatorMayReturnNull(common_flags()->allocator_may_return_null);
12268d75effSDimitry Andric   allocator.Init(common_flags()->allocator_release_to_os_interval_ms);
123*480093f4SDimitry Andric   if (common_flags()->max_allocation_size_mb)
124*480093f4SDimitry Andric     max_malloc_size = Min(common_flags()->max_allocation_size_mb << 20,
125*480093f4SDimitry Andric                           kMaxAllowedMallocSize);
126*480093f4SDimitry Andric   else
127*480093f4SDimitry Andric     max_malloc_size = kMaxAllowedMallocSize;
12868d75effSDimitry Andric }
12968d75effSDimitry Andric 
13068d75effSDimitry Andric AllocatorCache *GetAllocatorCache(MsanThreadLocalMallocStorage *ms) {
13168d75effSDimitry Andric   CHECK(ms);
13268d75effSDimitry Andric   CHECK_LE(sizeof(AllocatorCache), sizeof(ms->allocator_cache));
13368d75effSDimitry Andric   return reinterpret_cast<AllocatorCache *>(ms->allocator_cache);
13468d75effSDimitry Andric }
13568d75effSDimitry Andric 
13668d75effSDimitry Andric void MsanThreadLocalMallocStorage::CommitBack() {
13768d75effSDimitry Andric   allocator.SwallowCache(GetAllocatorCache(this));
13868d75effSDimitry Andric }
13968d75effSDimitry Andric 
14068d75effSDimitry Andric static void *MsanAllocate(StackTrace *stack, uptr size, uptr alignment,
14168d75effSDimitry Andric                           bool zeroise) {
142*480093f4SDimitry Andric   if (size > max_malloc_size) {
14368d75effSDimitry Andric     if (AllocatorMayReturnNull()) {
14468d75effSDimitry Andric       Report("WARNING: MemorySanitizer failed to allocate 0x%zx bytes\n", size);
14568d75effSDimitry Andric       return nullptr;
14668d75effSDimitry Andric     }
147*480093f4SDimitry Andric     ReportAllocationSizeTooBig(size, max_malloc_size, stack);
14868d75effSDimitry Andric   }
14968d75effSDimitry Andric   MsanThread *t = GetCurrentThread();
15068d75effSDimitry Andric   void *allocated;
15168d75effSDimitry Andric   if (t) {
15268d75effSDimitry Andric     AllocatorCache *cache = GetAllocatorCache(&t->malloc_storage());
15368d75effSDimitry Andric     allocated = allocator.Allocate(cache, size, alignment);
15468d75effSDimitry Andric   } else {
15568d75effSDimitry Andric     SpinMutexLock l(&fallback_mutex);
15668d75effSDimitry Andric     AllocatorCache *cache = &fallback_allocator_cache;
15768d75effSDimitry Andric     allocated = allocator.Allocate(cache, size, alignment);
15868d75effSDimitry Andric   }
15968d75effSDimitry Andric   if (UNLIKELY(!allocated)) {
16068d75effSDimitry Andric     SetAllocatorOutOfMemory();
16168d75effSDimitry Andric     if (AllocatorMayReturnNull())
16268d75effSDimitry Andric       return nullptr;
16368d75effSDimitry Andric     ReportOutOfMemory(size, stack);
16468d75effSDimitry Andric   }
16568d75effSDimitry Andric   Metadata *meta =
16668d75effSDimitry Andric       reinterpret_cast<Metadata *>(allocator.GetMetaData(allocated));
16768d75effSDimitry Andric   meta->requested_size = size;
16868d75effSDimitry Andric   if (zeroise) {
16968d75effSDimitry Andric     __msan_clear_and_unpoison(allocated, size);
17068d75effSDimitry Andric   } else if (flags()->poison_in_malloc) {
17168d75effSDimitry Andric     __msan_poison(allocated, size);
17268d75effSDimitry Andric     if (__msan_get_track_origins()) {
17368d75effSDimitry Andric       stack->tag = StackTrace::TAG_ALLOC;
17468d75effSDimitry Andric       Origin o = Origin::CreateHeapOrigin(stack);
17568d75effSDimitry Andric       __msan_set_origin(allocated, size, o.raw_id());
17668d75effSDimitry Andric     }
17768d75effSDimitry Andric   }
17868d75effSDimitry Andric   MSAN_MALLOC_HOOK(allocated, size);
17968d75effSDimitry Andric   return allocated;
18068d75effSDimitry Andric }
18168d75effSDimitry Andric 
18268d75effSDimitry Andric void MsanDeallocate(StackTrace *stack, void *p) {
18368d75effSDimitry Andric   CHECK(p);
18468d75effSDimitry Andric   MSAN_FREE_HOOK(p);
18568d75effSDimitry Andric   Metadata *meta = reinterpret_cast<Metadata *>(allocator.GetMetaData(p));
18668d75effSDimitry Andric   uptr size = meta->requested_size;
18768d75effSDimitry Andric   meta->requested_size = 0;
18868d75effSDimitry Andric   // This memory will not be reused by anyone else, so we are free to keep it
18968d75effSDimitry Andric   // poisoned.
19068d75effSDimitry Andric   if (flags()->poison_in_free) {
19168d75effSDimitry Andric     __msan_poison(p, size);
19268d75effSDimitry Andric     if (__msan_get_track_origins()) {
19368d75effSDimitry Andric       stack->tag = StackTrace::TAG_DEALLOC;
19468d75effSDimitry Andric       Origin o = Origin::CreateHeapOrigin(stack);
19568d75effSDimitry Andric       __msan_set_origin(p, size, o.raw_id());
19668d75effSDimitry Andric     }
19768d75effSDimitry Andric   }
19868d75effSDimitry Andric   MsanThread *t = GetCurrentThread();
19968d75effSDimitry Andric   if (t) {
20068d75effSDimitry Andric     AllocatorCache *cache = GetAllocatorCache(&t->malloc_storage());
20168d75effSDimitry Andric     allocator.Deallocate(cache, p);
20268d75effSDimitry Andric   } else {
20368d75effSDimitry Andric     SpinMutexLock l(&fallback_mutex);
20468d75effSDimitry Andric     AllocatorCache *cache = &fallback_allocator_cache;
20568d75effSDimitry Andric     allocator.Deallocate(cache, p);
20668d75effSDimitry Andric   }
20768d75effSDimitry Andric }
20868d75effSDimitry Andric 
20968d75effSDimitry Andric void *MsanReallocate(StackTrace *stack, void *old_p, uptr new_size,
21068d75effSDimitry Andric                      uptr alignment) {
21168d75effSDimitry Andric   Metadata *meta = reinterpret_cast<Metadata*>(allocator.GetMetaData(old_p));
21268d75effSDimitry Andric   uptr old_size = meta->requested_size;
21368d75effSDimitry Andric   uptr actually_allocated_size = allocator.GetActuallyAllocatedSize(old_p);
21468d75effSDimitry Andric   if (new_size <= actually_allocated_size) {
21568d75effSDimitry Andric     // We are not reallocating here.
21668d75effSDimitry Andric     meta->requested_size = new_size;
21768d75effSDimitry Andric     if (new_size > old_size) {
21868d75effSDimitry Andric       if (flags()->poison_in_malloc) {
21968d75effSDimitry Andric         stack->tag = StackTrace::TAG_ALLOC;
22068d75effSDimitry Andric         PoisonMemory((char *)old_p + old_size, new_size - old_size, stack);
22168d75effSDimitry Andric       }
22268d75effSDimitry Andric     }
22368d75effSDimitry Andric     return old_p;
22468d75effSDimitry Andric   }
22568d75effSDimitry Andric   uptr memcpy_size = Min(new_size, old_size);
22668d75effSDimitry Andric   void *new_p = MsanAllocate(stack, new_size, alignment, false /*zeroise*/);
22768d75effSDimitry Andric   if (new_p) {
22868d75effSDimitry Andric     CopyMemory(new_p, old_p, memcpy_size, stack);
22968d75effSDimitry Andric     MsanDeallocate(stack, old_p);
23068d75effSDimitry Andric   }
23168d75effSDimitry Andric   return new_p;
23268d75effSDimitry Andric }
23368d75effSDimitry Andric 
23468d75effSDimitry Andric void *MsanCalloc(StackTrace *stack, uptr nmemb, uptr size) {
23568d75effSDimitry Andric   if (UNLIKELY(CheckForCallocOverflow(size, nmemb))) {
23668d75effSDimitry Andric     if (AllocatorMayReturnNull())
23768d75effSDimitry Andric       return nullptr;
23868d75effSDimitry Andric     ReportCallocOverflow(nmemb, size, stack);
23968d75effSDimitry Andric   }
24068d75effSDimitry Andric   return MsanAllocate(stack, nmemb * size, sizeof(u64), true);
24168d75effSDimitry Andric }
24268d75effSDimitry Andric 
24368d75effSDimitry Andric static uptr AllocationSize(const void *p) {
24468d75effSDimitry Andric   if (!p) return 0;
24568d75effSDimitry Andric   const void *beg = allocator.GetBlockBegin(p);
24668d75effSDimitry Andric   if (beg != p) return 0;
24768d75effSDimitry Andric   Metadata *b = (Metadata *)allocator.GetMetaData(p);
24868d75effSDimitry Andric   return b->requested_size;
24968d75effSDimitry Andric }
25068d75effSDimitry Andric 
25168d75effSDimitry Andric void *msan_malloc(uptr size, StackTrace *stack) {
25268d75effSDimitry Andric   return SetErrnoOnNull(MsanAllocate(stack, size, sizeof(u64), false));
25368d75effSDimitry Andric }
25468d75effSDimitry Andric 
25568d75effSDimitry Andric void *msan_calloc(uptr nmemb, uptr size, StackTrace *stack) {
25668d75effSDimitry Andric   return SetErrnoOnNull(MsanCalloc(stack, nmemb, size));
25768d75effSDimitry Andric }
25868d75effSDimitry Andric 
25968d75effSDimitry Andric void *msan_realloc(void *ptr, uptr size, StackTrace *stack) {
26068d75effSDimitry Andric   if (!ptr)
26168d75effSDimitry Andric     return SetErrnoOnNull(MsanAllocate(stack, size, sizeof(u64), false));
26268d75effSDimitry Andric   if (size == 0) {
26368d75effSDimitry Andric     MsanDeallocate(stack, ptr);
26468d75effSDimitry Andric     return nullptr;
26568d75effSDimitry Andric   }
26668d75effSDimitry Andric   return SetErrnoOnNull(MsanReallocate(stack, ptr, size, sizeof(u64)));
26768d75effSDimitry Andric }
26868d75effSDimitry Andric 
26968d75effSDimitry Andric void *msan_reallocarray(void *ptr, uptr nmemb, uptr size, StackTrace *stack) {
27068d75effSDimitry Andric   if (UNLIKELY(CheckForCallocOverflow(size, nmemb))) {
27168d75effSDimitry Andric     errno = errno_ENOMEM;
27268d75effSDimitry Andric     if (AllocatorMayReturnNull())
27368d75effSDimitry Andric       return nullptr;
27468d75effSDimitry Andric     ReportReallocArrayOverflow(nmemb, size, stack);
27568d75effSDimitry Andric   }
27668d75effSDimitry Andric   return msan_realloc(ptr, nmemb * size, stack);
27768d75effSDimitry Andric }
27868d75effSDimitry Andric 
27968d75effSDimitry Andric void *msan_valloc(uptr size, StackTrace *stack) {
28068d75effSDimitry Andric   return SetErrnoOnNull(MsanAllocate(stack, size, GetPageSizeCached(), false));
28168d75effSDimitry Andric }
28268d75effSDimitry Andric 
28368d75effSDimitry Andric void *msan_pvalloc(uptr size, StackTrace *stack) {
28468d75effSDimitry Andric   uptr PageSize = GetPageSizeCached();
28568d75effSDimitry Andric   if (UNLIKELY(CheckForPvallocOverflow(size, PageSize))) {
28668d75effSDimitry Andric     errno = errno_ENOMEM;
28768d75effSDimitry Andric     if (AllocatorMayReturnNull())
28868d75effSDimitry Andric       return nullptr;
28968d75effSDimitry Andric     ReportPvallocOverflow(size, stack);
29068d75effSDimitry Andric   }
29168d75effSDimitry Andric   // pvalloc(0) should allocate one page.
29268d75effSDimitry Andric   size = size ? RoundUpTo(size, PageSize) : PageSize;
29368d75effSDimitry Andric   return SetErrnoOnNull(MsanAllocate(stack, size, PageSize, false));
29468d75effSDimitry Andric }
29568d75effSDimitry Andric 
29668d75effSDimitry Andric void *msan_aligned_alloc(uptr alignment, uptr size, StackTrace *stack) {
29768d75effSDimitry Andric   if (UNLIKELY(!CheckAlignedAllocAlignmentAndSize(alignment, size))) {
29868d75effSDimitry Andric     errno = errno_EINVAL;
29968d75effSDimitry Andric     if (AllocatorMayReturnNull())
30068d75effSDimitry Andric       return nullptr;
30168d75effSDimitry Andric     ReportInvalidAlignedAllocAlignment(size, alignment, stack);
30268d75effSDimitry Andric   }
30368d75effSDimitry Andric   return SetErrnoOnNull(MsanAllocate(stack, size, alignment, false));
30468d75effSDimitry Andric }
30568d75effSDimitry Andric 
30668d75effSDimitry Andric void *msan_memalign(uptr alignment, uptr size, StackTrace *stack) {
30768d75effSDimitry Andric   if (UNLIKELY(!IsPowerOfTwo(alignment))) {
30868d75effSDimitry Andric     errno = errno_EINVAL;
30968d75effSDimitry Andric     if (AllocatorMayReturnNull())
31068d75effSDimitry Andric       return nullptr;
31168d75effSDimitry Andric     ReportInvalidAllocationAlignment(alignment, stack);
31268d75effSDimitry Andric   }
31368d75effSDimitry Andric   return SetErrnoOnNull(MsanAllocate(stack, size, alignment, false));
31468d75effSDimitry Andric }
31568d75effSDimitry Andric 
31668d75effSDimitry Andric int msan_posix_memalign(void **memptr, uptr alignment, uptr size,
31768d75effSDimitry Andric                         StackTrace *stack) {
31868d75effSDimitry Andric   if (UNLIKELY(!CheckPosixMemalignAlignment(alignment))) {
31968d75effSDimitry Andric     if (AllocatorMayReturnNull())
32068d75effSDimitry Andric       return errno_EINVAL;
32168d75effSDimitry Andric     ReportInvalidPosixMemalignAlignment(alignment, stack);
32268d75effSDimitry Andric   }
32368d75effSDimitry Andric   void *ptr = MsanAllocate(stack, size, alignment, false);
32468d75effSDimitry Andric   if (UNLIKELY(!ptr))
32568d75effSDimitry Andric     // OOM error is already taken care of by MsanAllocate.
32668d75effSDimitry Andric     return errno_ENOMEM;
32768d75effSDimitry Andric   CHECK(IsAligned((uptr)ptr, alignment));
32868d75effSDimitry Andric   *memptr = ptr;
32968d75effSDimitry Andric   return 0;
33068d75effSDimitry Andric }
33168d75effSDimitry Andric 
33268d75effSDimitry Andric } // namespace __msan
33368d75effSDimitry Andric 
33468d75effSDimitry Andric using namespace __msan;
33568d75effSDimitry Andric 
33668d75effSDimitry Andric uptr __sanitizer_get_current_allocated_bytes() {
33768d75effSDimitry Andric   uptr stats[AllocatorStatCount];
33868d75effSDimitry Andric   allocator.GetStats(stats);
33968d75effSDimitry Andric   return stats[AllocatorStatAllocated];
34068d75effSDimitry Andric }
34168d75effSDimitry Andric 
34268d75effSDimitry Andric uptr __sanitizer_get_heap_size() {
34368d75effSDimitry Andric   uptr stats[AllocatorStatCount];
34468d75effSDimitry Andric   allocator.GetStats(stats);
34568d75effSDimitry Andric   return stats[AllocatorStatMapped];
34668d75effSDimitry Andric }
34768d75effSDimitry Andric 
34868d75effSDimitry Andric uptr __sanitizer_get_free_bytes() { return 1; }
34968d75effSDimitry Andric 
35068d75effSDimitry Andric uptr __sanitizer_get_unmapped_bytes() { return 1; }
35168d75effSDimitry Andric 
35268d75effSDimitry Andric uptr __sanitizer_get_estimated_allocated_size(uptr size) { return size; }
35368d75effSDimitry Andric 
35468d75effSDimitry Andric int __sanitizer_get_ownership(const void *p) { return AllocationSize(p) != 0; }
35568d75effSDimitry Andric 
35668d75effSDimitry Andric uptr __sanitizer_get_allocated_size(const void *p) { return AllocationSize(p); }
357