1*68d75effSDimitry Andric //===-- msan_allocator.cpp -------------------------- ---------------------===// 2*68d75effSDimitry Andric // 3*68d75effSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*68d75effSDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 5*68d75effSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*68d75effSDimitry Andric // 7*68d75effSDimitry Andric //===----------------------------------------------------------------------===// 8*68d75effSDimitry Andric // 9*68d75effSDimitry Andric // This file is a part of MemorySanitizer. 10*68d75effSDimitry Andric // 11*68d75effSDimitry Andric // MemorySanitizer allocator. 12*68d75effSDimitry Andric //===----------------------------------------------------------------------===// 13*68d75effSDimitry Andric 14*68d75effSDimitry Andric #include "sanitizer_common/sanitizer_allocator.h" 15*68d75effSDimitry Andric #include "sanitizer_common/sanitizer_allocator_checks.h" 16*68d75effSDimitry Andric #include "sanitizer_common/sanitizer_allocator_interface.h" 17*68d75effSDimitry Andric #include "sanitizer_common/sanitizer_allocator_report.h" 18*68d75effSDimitry Andric #include "sanitizer_common/sanitizer_errno.h" 19*68d75effSDimitry Andric #include "msan.h" 20*68d75effSDimitry Andric #include "msan_allocator.h" 21*68d75effSDimitry Andric #include "msan_origin.h" 22*68d75effSDimitry Andric #include "msan_thread.h" 23*68d75effSDimitry Andric #include "msan_poisoning.h" 24*68d75effSDimitry Andric 25*68d75effSDimitry Andric namespace __msan { 26*68d75effSDimitry Andric 27*68d75effSDimitry Andric struct Metadata { 28*68d75effSDimitry Andric uptr requested_size; 29*68d75effSDimitry Andric }; 30*68d75effSDimitry Andric 31*68d75effSDimitry Andric struct MsanMapUnmapCallback { 32*68d75effSDimitry Andric void OnMap(uptr p, uptr size) const {} 33*68d75effSDimitry Andric void OnUnmap(uptr p, uptr size) const { 34*68d75effSDimitry Andric __msan_unpoison((void *)p, size); 35*68d75effSDimitry Andric 36*68d75effSDimitry Andric // We are about to unmap a chunk of user memory. 37*68d75effSDimitry Andric // Mark the corresponding shadow memory as not needed. 38*68d75effSDimitry Andric uptr shadow_p = MEM_TO_SHADOW(p); 39*68d75effSDimitry Andric ReleaseMemoryPagesToOS(shadow_p, shadow_p + size); 40*68d75effSDimitry Andric if (__msan_get_track_origins()) { 41*68d75effSDimitry Andric uptr origin_p = MEM_TO_ORIGIN(p); 42*68d75effSDimitry Andric ReleaseMemoryPagesToOS(origin_p, origin_p + size); 43*68d75effSDimitry Andric } 44*68d75effSDimitry Andric } 45*68d75effSDimitry Andric }; 46*68d75effSDimitry Andric 47*68d75effSDimitry Andric #if defined(__mips64) 48*68d75effSDimitry Andric static const uptr kMaxAllowedMallocSize = 2UL << 30; 49*68d75effSDimitry Andric 50*68d75effSDimitry Andric struct AP32 { 51*68d75effSDimitry Andric static const uptr kSpaceBeg = 0; 52*68d75effSDimitry Andric static const u64 kSpaceSize = SANITIZER_MMAP_RANGE_SIZE; 53*68d75effSDimitry Andric static const uptr kMetadataSize = sizeof(Metadata); 54*68d75effSDimitry Andric typedef __sanitizer::CompactSizeClassMap SizeClassMap; 55*68d75effSDimitry Andric static const uptr kRegionSizeLog = 20; 56*68d75effSDimitry Andric using AddressSpaceView = LocalAddressSpaceView; 57*68d75effSDimitry Andric typedef MsanMapUnmapCallback MapUnmapCallback; 58*68d75effSDimitry Andric static const uptr kFlags = 0; 59*68d75effSDimitry Andric }; 60*68d75effSDimitry Andric typedef SizeClassAllocator32<AP32> PrimaryAllocator; 61*68d75effSDimitry Andric #elif defined(__x86_64__) 62*68d75effSDimitry Andric #if SANITIZER_NETBSD || \ 63*68d75effSDimitry Andric (SANITIZER_LINUX && !defined(MSAN_LINUX_X86_64_OLD_MAPPING)) 64*68d75effSDimitry Andric static const uptr kAllocatorSpace = 0x700000000000ULL; 65*68d75effSDimitry Andric #else 66*68d75effSDimitry Andric static const uptr kAllocatorSpace = 0x600000000000ULL; 67*68d75effSDimitry Andric #endif 68*68d75effSDimitry Andric static const uptr kMaxAllowedMallocSize = 8UL << 30; 69*68d75effSDimitry Andric 70*68d75effSDimitry Andric struct AP64 { // Allocator64 parameters. Deliberately using a short name. 71*68d75effSDimitry Andric static const uptr kSpaceBeg = kAllocatorSpace; 72*68d75effSDimitry Andric static const uptr kSpaceSize = 0x40000000000; // 4T. 73*68d75effSDimitry Andric static const uptr kMetadataSize = sizeof(Metadata); 74*68d75effSDimitry Andric typedef DefaultSizeClassMap SizeClassMap; 75*68d75effSDimitry Andric typedef MsanMapUnmapCallback MapUnmapCallback; 76*68d75effSDimitry Andric static const uptr kFlags = 0; 77*68d75effSDimitry Andric using AddressSpaceView = LocalAddressSpaceView; 78*68d75effSDimitry Andric }; 79*68d75effSDimitry Andric 80*68d75effSDimitry Andric typedef SizeClassAllocator64<AP64> PrimaryAllocator; 81*68d75effSDimitry Andric 82*68d75effSDimitry Andric #elif defined(__powerpc64__) 83*68d75effSDimitry Andric static const uptr kMaxAllowedMallocSize = 2UL << 30; // 2G 84*68d75effSDimitry Andric 85*68d75effSDimitry Andric struct AP64 { // Allocator64 parameters. Deliberately using a short name. 86*68d75effSDimitry Andric static const uptr kSpaceBeg = 0x300000000000; 87*68d75effSDimitry Andric static const uptr kSpaceSize = 0x020000000000; // 2T. 88*68d75effSDimitry Andric static const uptr kMetadataSize = sizeof(Metadata); 89*68d75effSDimitry Andric typedef DefaultSizeClassMap SizeClassMap; 90*68d75effSDimitry Andric typedef MsanMapUnmapCallback MapUnmapCallback; 91*68d75effSDimitry Andric static const uptr kFlags = 0; 92*68d75effSDimitry Andric using AddressSpaceView = LocalAddressSpaceView; 93*68d75effSDimitry Andric }; 94*68d75effSDimitry Andric 95*68d75effSDimitry Andric typedef SizeClassAllocator64<AP64> PrimaryAllocator; 96*68d75effSDimitry Andric #elif defined(__aarch64__) 97*68d75effSDimitry Andric static const uptr kMaxAllowedMallocSize = 2UL << 30; // 2G 98*68d75effSDimitry Andric 99*68d75effSDimitry Andric struct AP32 { 100*68d75effSDimitry Andric static const uptr kSpaceBeg = 0; 101*68d75effSDimitry Andric static const u64 kSpaceSize = SANITIZER_MMAP_RANGE_SIZE; 102*68d75effSDimitry Andric static const uptr kMetadataSize = sizeof(Metadata); 103*68d75effSDimitry Andric typedef __sanitizer::CompactSizeClassMap SizeClassMap; 104*68d75effSDimitry Andric static const uptr kRegionSizeLog = 20; 105*68d75effSDimitry Andric using AddressSpaceView = LocalAddressSpaceView; 106*68d75effSDimitry Andric typedef MsanMapUnmapCallback MapUnmapCallback; 107*68d75effSDimitry Andric static const uptr kFlags = 0; 108*68d75effSDimitry Andric }; 109*68d75effSDimitry Andric typedef SizeClassAllocator32<AP32> PrimaryAllocator; 110*68d75effSDimitry Andric #endif 111*68d75effSDimitry Andric typedef CombinedAllocator<PrimaryAllocator> Allocator; 112*68d75effSDimitry Andric typedef Allocator::AllocatorCache AllocatorCache; 113*68d75effSDimitry Andric 114*68d75effSDimitry Andric static Allocator allocator; 115*68d75effSDimitry Andric static AllocatorCache fallback_allocator_cache; 116*68d75effSDimitry Andric static StaticSpinMutex fallback_mutex; 117*68d75effSDimitry Andric 118*68d75effSDimitry Andric void MsanAllocatorInit() { 119*68d75effSDimitry Andric SetAllocatorMayReturnNull(common_flags()->allocator_may_return_null); 120*68d75effSDimitry Andric allocator.Init(common_flags()->allocator_release_to_os_interval_ms); 121*68d75effSDimitry Andric } 122*68d75effSDimitry Andric 123*68d75effSDimitry Andric AllocatorCache *GetAllocatorCache(MsanThreadLocalMallocStorage *ms) { 124*68d75effSDimitry Andric CHECK(ms); 125*68d75effSDimitry Andric CHECK_LE(sizeof(AllocatorCache), sizeof(ms->allocator_cache)); 126*68d75effSDimitry Andric return reinterpret_cast<AllocatorCache *>(ms->allocator_cache); 127*68d75effSDimitry Andric } 128*68d75effSDimitry Andric 129*68d75effSDimitry Andric void MsanThreadLocalMallocStorage::CommitBack() { 130*68d75effSDimitry Andric allocator.SwallowCache(GetAllocatorCache(this)); 131*68d75effSDimitry Andric } 132*68d75effSDimitry Andric 133*68d75effSDimitry Andric static void *MsanAllocate(StackTrace *stack, uptr size, uptr alignment, 134*68d75effSDimitry Andric bool zeroise) { 135*68d75effSDimitry Andric if (size > kMaxAllowedMallocSize) { 136*68d75effSDimitry Andric if (AllocatorMayReturnNull()) { 137*68d75effSDimitry Andric Report("WARNING: MemorySanitizer failed to allocate 0x%zx bytes\n", size); 138*68d75effSDimitry Andric return nullptr; 139*68d75effSDimitry Andric } 140*68d75effSDimitry Andric ReportAllocationSizeTooBig(size, kMaxAllowedMallocSize, stack); 141*68d75effSDimitry Andric } 142*68d75effSDimitry Andric MsanThread *t = GetCurrentThread(); 143*68d75effSDimitry Andric void *allocated; 144*68d75effSDimitry Andric if (t) { 145*68d75effSDimitry Andric AllocatorCache *cache = GetAllocatorCache(&t->malloc_storage()); 146*68d75effSDimitry Andric allocated = allocator.Allocate(cache, size, alignment); 147*68d75effSDimitry Andric } else { 148*68d75effSDimitry Andric SpinMutexLock l(&fallback_mutex); 149*68d75effSDimitry Andric AllocatorCache *cache = &fallback_allocator_cache; 150*68d75effSDimitry Andric allocated = allocator.Allocate(cache, size, alignment); 151*68d75effSDimitry Andric } 152*68d75effSDimitry Andric if (UNLIKELY(!allocated)) { 153*68d75effSDimitry Andric SetAllocatorOutOfMemory(); 154*68d75effSDimitry Andric if (AllocatorMayReturnNull()) 155*68d75effSDimitry Andric return nullptr; 156*68d75effSDimitry Andric ReportOutOfMemory(size, stack); 157*68d75effSDimitry Andric } 158*68d75effSDimitry Andric Metadata *meta = 159*68d75effSDimitry Andric reinterpret_cast<Metadata *>(allocator.GetMetaData(allocated)); 160*68d75effSDimitry Andric meta->requested_size = size; 161*68d75effSDimitry Andric if (zeroise) { 162*68d75effSDimitry Andric __msan_clear_and_unpoison(allocated, size); 163*68d75effSDimitry Andric } else if (flags()->poison_in_malloc) { 164*68d75effSDimitry Andric __msan_poison(allocated, size); 165*68d75effSDimitry Andric if (__msan_get_track_origins()) { 166*68d75effSDimitry Andric stack->tag = StackTrace::TAG_ALLOC; 167*68d75effSDimitry Andric Origin o = Origin::CreateHeapOrigin(stack); 168*68d75effSDimitry Andric __msan_set_origin(allocated, size, o.raw_id()); 169*68d75effSDimitry Andric } 170*68d75effSDimitry Andric } 171*68d75effSDimitry Andric MSAN_MALLOC_HOOK(allocated, size); 172*68d75effSDimitry Andric return allocated; 173*68d75effSDimitry Andric } 174*68d75effSDimitry Andric 175*68d75effSDimitry Andric void MsanDeallocate(StackTrace *stack, void *p) { 176*68d75effSDimitry Andric CHECK(p); 177*68d75effSDimitry Andric MSAN_FREE_HOOK(p); 178*68d75effSDimitry Andric Metadata *meta = reinterpret_cast<Metadata *>(allocator.GetMetaData(p)); 179*68d75effSDimitry Andric uptr size = meta->requested_size; 180*68d75effSDimitry Andric meta->requested_size = 0; 181*68d75effSDimitry Andric // This memory will not be reused by anyone else, so we are free to keep it 182*68d75effSDimitry Andric // poisoned. 183*68d75effSDimitry Andric if (flags()->poison_in_free) { 184*68d75effSDimitry Andric __msan_poison(p, size); 185*68d75effSDimitry Andric if (__msan_get_track_origins()) { 186*68d75effSDimitry Andric stack->tag = StackTrace::TAG_DEALLOC; 187*68d75effSDimitry Andric Origin o = Origin::CreateHeapOrigin(stack); 188*68d75effSDimitry Andric __msan_set_origin(p, size, o.raw_id()); 189*68d75effSDimitry Andric } 190*68d75effSDimitry Andric } 191*68d75effSDimitry Andric MsanThread *t = GetCurrentThread(); 192*68d75effSDimitry Andric if (t) { 193*68d75effSDimitry Andric AllocatorCache *cache = GetAllocatorCache(&t->malloc_storage()); 194*68d75effSDimitry Andric allocator.Deallocate(cache, p); 195*68d75effSDimitry Andric } else { 196*68d75effSDimitry Andric SpinMutexLock l(&fallback_mutex); 197*68d75effSDimitry Andric AllocatorCache *cache = &fallback_allocator_cache; 198*68d75effSDimitry Andric allocator.Deallocate(cache, p); 199*68d75effSDimitry Andric } 200*68d75effSDimitry Andric } 201*68d75effSDimitry Andric 202*68d75effSDimitry Andric void *MsanReallocate(StackTrace *stack, void *old_p, uptr new_size, 203*68d75effSDimitry Andric uptr alignment) { 204*68d75effSDimitry Andric Metadata *meta = reinterpret_cast<Metadata*>(allocator.GetMetaData(old_p)); 205*68d75effSDimitry Andric uptr old_size = meta->requested_size; 206*68d75effSDimitry Andric uptr actually_allocated_size = allocator.GetActuallyAllocatedSize(old_p); 207*68d75effSDimitry Andric if (new_size <= actually_allocated_size) { 208*68d75effSDimitry Andric // We are not reallocating here. 209*68d75effSDimitry Andric meta->requested_size = new_size; 210*68d75effSDimitry Andric if (new_size > old_size) { 211*68d75effSDimitry Andric if (flags()->poison_in_malloc) { 212*68d75effSDimitry Andric stack->tag = StackTrace::TAG_ALLOC; 213*68d75effSDimitry Andric PoisonMemory((char *)old_p + old_size, new_size - old_size, stack); 214*68d75effSDimitry Andric } 215*68d75effSDimitry Andric } 216*68d75effSDimitry Andric return old_p; 217*68d75effSDimitry Andric } 218*68d75effSDimitry Andric uptr memcpy_size = Min(new_size, old_size); 219*68d75effSDimitry Andric void *new_p = MsanAllocate(stack, new_size, alignment, false /*zeroise*/); 220*68d75effSDimitry Andric if (new_p) { 221*68d75effSDimitry Andric CopyMemory(new_p, old_p, memcpy_size, stack); 222*68d75effSDimitry Andric MsanDeallocate(stack, old_p); 223*68d75effSDimitry Andric } 224*68d75effSDimitry Andric return new_p; 225*68d75effSDimitry Andric } 226*68d75effSDimitry Andric 227*68d75effSDimitry Andric void *MsanCalloc(StackTrace *stack, uptr nmemb, uptr size) { 228*68d75effSDimitry Andric if (UNLIKELY(CheckForCallocOverflow(size, nmemb))) { 229*68d75effSDimitry Andric if (AllocatorMayReturnNull()) 230*68d75effSDimitry Andric return nullptr; 231*68d75effSDimitry Andric ReportCallocOverflow(nmemb, size, stack); 232*68d75effSDimitry Andric } 233*68d75effSDimitry Andric return MsanAllocate(stack, nmemb * size, sizeof(u64), true); 234*68d75effSDimitry Andric } 235*68d75effSDimitry Andric 236*68d75effSDimitry Andric static uptr AllocationSize(const void *p) { 237*68d75effSDimitry Andric if (!p) return 0; 238*68d75effSDimitry Andric const void *beg = allocator.GetBlockBegin(p); 239*68d75effSDimitry Andric if (beg != p) return 0; 240*68d75effSDimitry Andric Metadata *b = (Metadata *)allocator.GetMetaData(p); 241*68d75effSDimitry Andric return b->requested_size; 242*68d75effSDimitry Andric } 243*68d75effSDimitry Andric 244*68d75effSDimitry Andric void *msan_malloc(uptr size, StackTrace *stack) { 245*68d75effSDimitry Andric return SetErrnoOnNull(MsanAllocate(stack, size, sizeof(u64), false)); 246*68d75effSDimitry Andric } 247*68d75effSDimitry Andric 248*68d75effSDimitry Andric void *msan_calloc(uptr nmemb, uptr size, StackTrace *stack) { 249*68d75effSDimitry Andric return SetErrnoOnNull(MsanCalloc(stack, nmemb, size)); 250*68d75effSDimitry Andric } 251*68d75effSDimitry Andric 252*68d75effSDimitry Andric void *msan_realloc(void *ptr, uptr size, StackTrace *stack) { 253*68d75effSDimitry Andric if (!ptr) 254*68d75effSDimitry Andric return SetErrnoOnNull(MsanAllocate(stack, size, sizeof(u64), false)); 255*68d75effSDimitry Andric if (size == 0) { 256*68d75effSDimitry Andric MsanDeallocate(stack, ptr); 257*68d75effSDimitry Andric return nullptr; 258*68d75effSDimitry Andric } 259*68d75effSDimitry Andric return SetErrnoOnNull(MsanReallocate(stack, ptr, size, sizeof(u64))); 260*68d75effSDimitry Andric } 261*68d75effSDimitry Andric 262*68d75effSDimitry Andric void *msan_reallocarray(void *ptr, uptr nmemb, uptr size, StackTrace *stack) { 263*68d75effSDimitry Andric if (UNLIKELY(CheckForCallocOverflow(size, nmemb))) { 264*68d75effSDimitry Andric errno = errno_ENOMEM; 265*68d75effSDimitry Andric if (AllocatorMayReturnNull()) 266*68d75effSDimitry Andric return nullptr; 267*68d75effSDimitry Andric ReportReallocArrayOverflow(nmemb, size, stack); 268*68d75effSDimitry Andric } 269*68d75effSDimitry Andric return msan_realloc(ptr, nmemb * size, stack); 270*68d75effSDimitry Andric } 271*68d75effSDimitry Andric 272*68d75effSDimitry Andric void *msan_valloc(uptr size, StackTrace *stack) { 273*68d75effSDimitry Andric return SetErrnoOnNull(MsanAllocate(stack, size, GetPageSizeCached(), false)); 274*68d75effSDimitry Andric } 275*68d75effSDimitry Andric 276*68d75effSDimitry Andric void *msan_pvalloc(uptr size, StackTrace *stack) { 277*68d75effSDimitry Andric uptr PageSize = GetPageSizeCached(); 278*68d75effSDimitry Andric if (UNLIKELY(CheckForPvallocOverflow(size, PageSize))) { 279*68d75effSDimitry Andric errno = errno_ENOMEM; 280*68d75effSDimitry Andric if (AllocatorMayReturnNull()) 281*68d75effSDimitry Andric return nullptr; 282*68d75effSDimitry Andric ReportPvallocOverflow(size, stack); 283*68d75effSDimitry Andric } 284*68d75effSDimitry Andric // pvalloc(0) should allocate one page. 285*68d75effSDimitry Andric size = size ? RoundUpTo(size, PageSize) : PageSize; 286*68d75effSDimitry Andric return SetErrnoOnNull(MsanAllocate(stack, size, PageSize, false)); 287*68d75effSDimitry Andric } 288*68d75effSDimitry Andric 289*68d75effSDimitry Andric void *msan_aligned_alloc(uptr alignment, uptr size, StackTrace *stack) { 290*68d75effSDimitry Andric if (UNLIKELY(!CheckAlignedAllocAlignmentAndSize(alignment, size))) { 291*68d75effSDimitry Andric errno = errno_EINVAL; 292*68d75effSDimitry Andric if (AllocatorMayReturnNull()) 293*68d75effSDimitry Andric return nullptr; 294*68d75effSDimitry Andric ReportInvalidAlignedAllocAlignment(size, alignment, stack); 295*68d75effSDimitry Andric } 296*68d75effSDimitry Andric return SetErrnoOnNull(MsanAllocate(stack, size, alignment, false)); 297*68d75effSDimitry Andric } 298*68d75effSDimitry Andric 299*68d75effSDimitry Andric void *msan_memalign(uptr alignment, uptr size, StackTrace *stack) { 300*68d75effSDimitry Andric if (UNLIKELY(!IsPowerOfTwo(alignment))) { 301*68d75effSDimitry Andric errno = errno_EINVAL; 302*68d75effSDimitry Andric if (AllocatorMayReturnNull()) 303*68d75effSDimitry Andric return nullptr; 304*68d75effSDimitry Andric ReportInvalidAllocationAlignment(alignment, stack); 305*68d75effSDimitry Andric } 306*68d75effSDimitry Andric return SetErrnoOnNull(MsanAllocate(stack, size, alignment, false)); 307*68d75effSDimitry Andric } 308*68d75effSDimitry Andric 309*68d75effSDimitry Andric int msan_posix_memalign(void **memptr, uptr alignment, uptr size, 310*68d75effSDimitry Andric StackTrace *stack) { 311*68d75effSDimitry Andric if (UNLIKELY(!CheckPosixMemalignAlignment(alignment))) { 312*68d75effSDimitry Andric if (AllocatorMayReturnNull()) 313*68d75effSDimitry Andric return errno_EINVAL; 314*68d75effSDimitry Andric ReportInvalidPosixMemalignAlignment(alignment, stack); 315*68d75effSDimitry Andric } 316*68d75effSDimitry Andric void *ptr = MsanAllocate(stack, size, alignment, false); 317*68d75effSDimitry Andric if (UNLIKELY(!ptr)) 318*68d75effSDimitry Andric // OOM error is already taken care of by MsanAllocate. 319*68d75effSDimitry Andric return errno_ENOMEM; 320*68d75effSDimitry Andric CHECK(IsAligned((uptr)ptr, alignment)); 321*68d75effSDimitry Andric *memptr = ptr; 322*68d75effSDimitry Andric return 0; 323*68d75effSDimitry Andric } 324*68d75effSDimitry Andric 325*68d75effSDimitry Andric } // namespace __msan 326*68d75effSDimitry Andric 327*68d75effSDimitry Andric using namespace __msan; 328*68d75effSDimitry Andric 329*68d75effSDimitry Andric uptr __sanitizer_get_current_allocated_bytes() { 330*68d75effSDimitry Andric uptr stats[AllocatorStatCount]; 331*68d75effSDimitry Andric allocator.GetStats(stats); 332*68d75effSDimitry Andric return stats[AllocatorStatAllocated]; 333*68d75effSDimitry Andric } 334*68d75effSDimitry Andric 335*68d75effSDimitry Andric uptr __sanitizer_get_heap_size() { 336*68d75effSDimitry Andric uptr stats[AllocatorStatCount]; 337*68d75effSDimitry Andric allocator.GetStats(stats); 338*68d75effSDimitry Andric return stats[AllocatorStatMapped]; 339*68d75effSDimitry Andric } 340*68d75effSDimitry Andric 341*68d75effSDimitry Andric uptr __sanitizer_get_free_bytes() { return 1; } 342*68d75effSDimitry Andric 343*68d75effSDimitry Andric uptr __sanitizer_get_unmapped_bytes() { return 1; } 344*68d75effSDimitry Andric 345*68d75effSDimitry Andric uptr __sanitizer_get_estimated_allocated_size(uptr size) { return size; } 346*68d75effSDimitry Andric 347*68d75effSDimitry Andric int __sanitizer_get_ownership(const void *p) { return AllocationSize(p) != 0; } 348*68d75effSDimitry Andric 349*68d75effSDimitry Andric uptr __sanitizer_get_allocated_size(const void *p) { return AllocationSize(p); } 350