1*76559068SAndroid Build Coastguard Worker//===-- wrappers_c.inc ------------------------------------------*- C++ -*-===// 2*76559068SAndroid Build Coastguard Worker// 3*76559068SAndroid Build Coastguard Worker// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*76559068SAndroid Build Coastguard Worker// See https://llvm.org/LICENSE.txt for license information. 5*76559068SAndroid Build Coastguard Worker// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*76559068SAndroid Build Coastguard Worker// 7*76559068SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===// 8*76559068SAndroid Build Coastguard Worker 9*76559068SAndroid Build Coastguard Worker#ifndef SCUDO_PREFIX 10*76559068SAndroid Build Coastguard Worker#error "Define SCUDO_PREFIX prior to including this file!" 11*76559068SAndroid Build Coastguard Worker#endif 12*76559068SAndroid Build Coastguard Worker 13*76559068SAndroid Build Coastguard Worker// malloc-type functions have to be aligned to std::max_align_t. This is 14*76559068SAndroid Build Coastguard Worker// distinct from (1U << SCUDO_MIN_ALIGNMENT_LOG), since C++ new-type functions 15*76559068SAndroid Build Coastguard Worker// do not have to abide by the same requirement. 16*76559068SAndroid Build Coastguard Worker#ifndef SCUDO_MALLOC_ALIGNMENT 17*76559068SAndroid Build Coastguard Worker#define SCUDO_MALLOC_ALIGNMENT FIRST_32_SECOND_64(8U, 16U) 18*76559068SAndroid Build Coastguard Worker#endif 19*76559068SAndroid Build Coastguard Worker 20*76559068SAndroid Build Coastguard Workerstatic void reportAllocation(void *ptr, size_t size) { 21*76559068SAndroid Build Coastguard Worker if (SCUDO_ENABLE_HOOKS) 22*76559068SAndroid Build Coastguard Worker if (__scudo_allocate_hook && ptr) 23*76559068SAndroid Build Coastguard Worker __scudo_allocate_hook(ptr, size); 24*76559068SAndroid Build Coastguard Worker} 25*76559068SAndroid Build Coastguard Workerstatic void reportDeallocation(void *ptr) { 26*76559068SAndroid Build Coastguard Worker if (SCUDO_ENABLE_HOOKS) 27*76559068SAndroid Build Coastguard Worker if (__scudo_deallocate_hook) 28*76559068SAndroid Build Coastguard Worker __scudo_deallocate_hook(ptr); 29*76559068SAndroid Build Coastguard Worker} 30*76559068SAndroid Build Coastguard Workerstatic void reportReallocAllocation(void *old_ptr, void *new_ptr, size_t size) { 31*76559068SAndroid Build Coastguard Worker DCHECK_NE(new_ptr, nullptr); 32*76559068SAndroid Build Coastguard Worker 33*76559068SAndroid Build Coastguard Worker if (SCUDO_ENABLE_HOOKS) { 34*76559068SAndroid Build Coastguard Worker if (__scudo_realloc_allocate_hook) 35*76559068SAndroid Build Coastguard Worker __scudo_realloc_allocate_hook(old_ptr, new_ptr, size); 36*76559068SAndroid Build Coastguard Worker else if (__scudo_allocate_hook) 37*76559068SAndroid Build Coastguard Worker __scudo_allocate_hook(new_ptr, size); 38*76559068SAndroid Build Coastguard Worker } 39*76559068SAndroid Build Coastguard Worker} 40*76559068SAndroid Build Coastguard Workerstatic void reportReallocDeallocation(void *old_ptr) { 41*76559068SAndroid Build Coastguard Worker if (SCUDO_ENABLE_HOOKS) { 42*76559068SAndroid Build Coastguard Worker if (__scudo_realloc_deallocate_hook) 43*76559068SAndroid Build Coastguard Worker __scudo_realloc_deallocate_hook(old_ptr); 44*76559068SAndroid Build Coastguard Worker else if (__scudo_deallocate_hook) 45*76559068SAndroid Build Coastguard Worker __scudo_deallocate_hook(old_ptr); 46*76559068SAndroid Build Coastguard Worker } 47*76559068SAndroid Build Coastguard Worker} 48*76559068SAndroid Build Coastguard Worker 49*76559068SAndroid Build Coastguard Workerextern "C" { 50*76559068SAndroid Build Coastguard Worker 51*76559068SAndroid Build Coastguard WorkerINTERFACE WEAK void *SCUDO_PREFIX(calloc)(size_t nmemb, size_t size) { 52*76559068SAndroid Build Coastguard Worker scudo::uptr Product; 53*76559068SAndroid Build Coastguard Worker if (UNLIKELY(scudo::checkForCallocOverflow(size, nmemb, &Product))) { 54*76559068SAndroid Build Coastguard Worker if (SCUDO_ALLOCATOR.canReturnNull()) { 55*76559068SAndroid Build Coastguard Worker errno = ENOMEM; 56*76559068SAndroid Build Coastguard Worker return nullptr; 57*76559068SAndroid Build Coastguard Worker } 58*76559068SAndroid Build Coastguard Worker scudo::reportCallocOverflow(nmemb, size); 59*76559068SAndroid Build Coastguard Worker } 60*76559068SAndroid Build Coastguard Worker void *Ptr = SCUDO_ALLOCATOR.allocate(Product, scudo::Chunk::Origin::Malloc, 61*76559068SAndroid Build Coastguard Worker SCUDO_MALLOC_ALIGNMENT, true); 62*76559068SAndroid Build Coastguard Worker reportAllocation(Ptr, Product); 63*76559068SAndroid Build Coastguard Worker return scudo::setErrnoOnNull(Ptr); 64*76559068SAndroid Build Coastguard Worker} 65*76559068SAndroid Build Coastguard Worker 66*76559068SAndroid Build Coastguard WorkerINTERFACE WEAK void SCUDO_PREFIX(free)(void *ptr) { 67*76559068SAndroid Build Coastguard Worker reportDeallocation(ptr); 68*76559068SAndroid Build Coastguard Worker SCUDO_ALLOCATOR.deallocate(ptr, scudo::Chunk::Origin::Malloc); 69*76559068SAndroid Build Coastguard Worker} 70*76559068SAndroid Build Coastguard Worker 71*76559068SAndroid Build Coastguard WorkerINTERFACE WEAK struct SCUDO_MALLINFO SCUDO_PREFIX(mallinfo)(void) { 72*76559068SAndroid Build Coastguard Worker struct SCUDO_MALLINFO Info = {}; 73*76559068SAndroid Build Coastguard Worker scudo::StatCounters Stats; 74*76559068SAndroid Build Coastguard Worker SCUDO_ALLOCATOR.getStats(Stats); 75*76559068SAndroid Build Coastguard Worker // Space allocated in mmapped regions (bytes) 76*76559068SAndroid Build Coastguard Worker Info.hblkhd = static_cast<__scudo_mallinfo_data_t>(Stats[scudo::StatMapped]); 77*76559068SAndroid Build Coastguard Worker // Maximum total allocated space (bytes) 78*76559068SAndroid Build Coastguard Worker Info.usmblks = Info.hblkhd; 79*76559068SAndroid Build Coastguard Worker // Space in freed fastbin blocks (bytes) 80*76559068SAndroid Build Coastguard Worker Info.fsmblks = static_cast<__scudo_mallinfo_data_t>(Stats[scudo::StatFree]); 81*76559068SAndroid Build Coastguard Worker // Total allocated space (bytes) 82*76559068SAndroid Build Coastguard Worker Info.uordblks = 83*76559068SAndroid Build Coastguard Worker static_cast<__scudo_mallinfo_data_t>(Stats[scudo::StatAllocated]); 84*76559068SAndroid Build Coastguard Worker // Total free space (bytes) 85*76559068SAndroid Build Coastguard Worker Info.fordblks = Info.fsmblks; 86*76559068SAndroid Build Coastguard Worker return Info; 87*76559068SAndroid Build Coastguard Worker} 88*76559068SAndroid Build Coastguard Worker 89*76559068SAndroid Build Coastguard Worker// On Android, mallinfo2 is an alias of mallinfo, so don't define both. 90*76559068SAndroid Build Coastguard Worker#if !SCUDO_ANDROID 91*76559068SAndroid Build Coastguard WorkerINTERFACE WEAK struct __scudo_mallinfo2 SCUDO_PREFIX(mallinfo2)(void) { 92*76559068SAndroid Build Coastguard Worker struct __scudo_mallinfo2 Info = {}; 93*76559068SAndroid Build Coastguard Worker scudo::StatCounters Stats; 94*76559068SAndroid Build Coastguard Worker SCUDO_ALLOCATOR.getStats(Stats); 95*76559068SAndroid Build Coastguard Worker // Space allocated in mmapped regions (bytes) 96*76559068SAndroid Build Coastguard Worker Info.hblkhd = Stats[scudo::StatMapped]; 97*76559068SAndroid Build Coastguard Worker // Maximum total allocated space (bytes) 98*76559068SAndroid Build Coastguard Worker Info.usmblks = Info.hblkhd; 99*76559068SAndroid Build Coastguard Worker // Space in freed fastbin blocks (bytes) 100*76559068SAndroid Build Coastguard Worker Info.fsmblks = Stats[scudo::StatFree]; 101*76559068SAndroid Build Coastguard Worker // Total allocated space (bytes) 102*76559068SAndroid Build Coastguard Worker Info.uordblks = Stats[scudo::StatAllocated]; 103*76559068SAndroid Build Coastguard Worker // Total free space (bytes) 104*76559068SAndroid Build Coastguard Worker Info.fordblks = Info.fsmblks; 105*76559068SAndroid Build Coastguard Worker return Info; 106*76559068SAndroid Build Coastguard Worker} 107*76559068SAndroid Build Coastguard Worker#endif 108*76559068SAndroid Build Coastguard Worker 109*76559068SAndroid Build Coastguard WorkerINTERFACE WEAK void *SCUDO_PREFIX(malloc)(size_t size) { 110*76559068SAndroid Build Coastguard Worker void *Ptr = SCUDO_ALLOCATOR.allocate(size, scudo::Chunk::Origin::Malloc, 111*76559068SAndroid Build Coastguard Worker SCUDO_MALLOC_ALIGNMENT); 112*76559068SAndroid Build Coastguard Worker reportAllocation(Ptr, size); 113*76559068SAndroid Build Coastguard Worker return scudo::setErrnoOnNull(Ptr); 114*76559068SAndroid Build Coastguard Worker} 115*76559068SAndroid Build Coastguard Worker 116*76559068SAndroid Build Coastguard Worker#if SCUDO_ANDROID 117*76559068SAndroid Build Coastguard WorkerINTERFACE WEAK size_t SCUDO_PREFIX(malloc_usable_size)(const void *ptr) { 118*76559068SAndroid Build Coastguard Worker#else 119*76559068SAndroid Build Coastguard WorkerINTERFACE WEAK size_t SCUDO_PREFIX(malloc_usable_size)(void *ptr) { 120*76559068SAndroid Build Coastguard Worker#endif 121*76559068SAndroid Build Coastguard Worker return SCUDO_ALLOCATOR.getUsableSize(ptr); 122*76559068SAndroid Build Coastguard Worker} 123*76559068SAndroid Build Coastguard Worker 124*76559068SAndroid Build Coastguard WorkerINTERFACE WEAK void *SCUDO_PREFIX(memalign)(size_t alignment, size_t size) { 125*76559068SAndroid Build Coastguard Worker // Android rounds up the alignment to a power of two if it isn't one. 126*76559068SAndroid Build Coastguard Worker if (SCUDO_ANDROID) { 127*76559068SAndroid Build Coastguard Worker if (UNLIKELY(!alignment)) { 128*76559068SAndroid Build Coastguard Worker alignment = 1U; 129*76559068SAndroid Build Coastguard Worker } else { 130*76559068SAndroid Build Coastguard Worker if (UNLIKELY(!scudo::isPowerOfTwo(alignment))) 131*76559068SAndroid Build Coastguard Worker alignment = scudo::roundUpPowerOfTwo(alignment); 132*76559068SAndroid Build Coastguard Worker } 133*76559068SAndroid Build Coastguard Worker } else { 134*76559068SAndroid Build Coastguard Worker if (UNLIKELY(!scudo::isPowerOfTwo(alignment))) { 135*76559068SAndroid Build Coastguard Worker if (SCUDO_ALLOCATOR.canReturnNull()) { 136*76559068SAndroid Build Coastguard Worker errno = EINVAL; 137*76559068SAndroid Build Coastguard Worker return nullptr; 138*76559068SAndroid Build Coastguard Worker } 139*76559068SAndroid Build Coastguard Worker scudo::reportAlignmentNotPowerOfTwo(alignment); 140*76559068SAndroid Build Coastguard Worker } 141*76559068SAndroid Build Coastguard Worker } 142*76559068SAndroid Build Coastguard Worker void *Ptr = 143*76559068SAndroid Build Coastguard Worker SCUDO_ALLOCATOR.allocate(size, scudo::Chunk::Origin::Memalign, alignment); 144*76559068SAndroid Build Coastguard Worker reportAllocation(Ptr, size); 145*76559068SAndroid Build Coastguard Worker return Ptr; 146*76559068SAndroid Build Coastguard Worker} 147*76559068SAndroid Build Coastguard Worker 148*76559068SAndroid Build Coastguard WorkerINTERFACE WEAK int SCUDO_PREFIX(posix_memalign)(void **memptr, size_t alignment, 149*76559068SAndroid Build Coastguard Worker size_t size) { 150*76559068SAndroid Build Coastguard Worker if (UNLIKELY(scudo::checkPosixMemalignAlignment(alignment))) { 151*76559068SAndroid Build Coastguard Worker if (!SCUDO_ALLOCATOR.canReturnNull()) 152*76559068SAndroid Build Coastguard Worker scudo::reportInvalidPosixMemalignAlignment(alignment); 153*76559068SAndroid Build Coastguard Worker return EINVAL; 154*76559068SAndroid Build Coastguard Worker } 155*76559068SAndroid Build Coastguard Worker void *Ptr = 156*76559068SAndroid Build Coastguard Worker SCUDO_ALLOCATOR.allocate(size, scudo::Chunk::Origin::Memalign, alignment); 157*76559068SAndroid Build Coastguard Worker if (UNLIKELY(!Ptr)) 158*76559068SAndroid Build Coastguard Worker return ENOMEM; 159*76559068SAndroid Build Coastguard Worker reportAllocation(Ptr, size); 160*76559068SAndroid Build Coastguard Worker 161*76559068SAndroid Build Coastguard Worker *memptr = Ptr; 162*76559068SAndroid Build Coastguard Worker return 0; 163*76559068SAndroid Build Coastguard Worker} 164*76559068SAndroid Build Coastguard Worker 165*76559068SAndroid Build Coastguard WorkerINTERFACE WEAK void *SCUDO_PREFIX(pvalloc)(size_t size) { 166*76559068SAndroid Build Coastguard Worker const scudo::uptr PageSize = scudo::getPageSizeCached(); 167*76559068SAndroid Build Coastguard Worker if (UNLIKELY(scudo::checkForPvallocOverflow(size, PageSize))) { 168*76559068SAndroid Build Coastguard Worker if (SCUDO_ALLOCATOR.canReturnNull()) { 169*76559068SAndroid Build Coastguard Worker errno = ENOMEM; 170*76559068SAndroid Build Coastguard Worker return nullptr; 171*76559068SAndroid Build Coastguard Worker } 172*76559068SAndroid Build Coastguard Worker scudo::reportPvallocOverflow(size); 173*76559068SAndroid Build Coastguard Worker } 174*76559068SAndroid Build Coastguard Worker // pvalloc(0) should allocate one page. 175*76559068SAndroid Build Coastguard Worker void *Ptr = 176*76559068SAndroid Build Coastguard Worker SCUDO_ALLOCATOR.allocate(size ? scudo::roundUp(size, PageSize) : PageSize, 177*76559068SAndroid Build Coastguard Worker scudo::Chunk::Origin::Memalign, PageSize); 178*76559068SAndroid Build Coastguard Worker reportAllocation(Ptr, scudo::roundUp(size, PageSize)); 179*76559068SAndroid Build Coastguard Worker 180*76559068SAndroid Build Coastguard Worker return scudo::setErrnoOnNull(Ptr); 181*76559068SAndroid Build Coastguard Worker} 182*76559068SAndroid Build Coastguard Worker 183*76559068SAndroid Build Coastguard WorkerINTERFACE WEAK void *SCUDO_PREFIX(realloc)(void *ptr, size_t size) { 184*76559068SAndroid Build Coastguard Worker if (!ptr) { 185*76559068SAndroid Build Coastguard Worker void *Ptr = SCUDO_ALLOCATOR.allocate(size, scudo::Chunk::Origin::Malloc, 186*76559068SAndroid Build Coastguard Worker SCUDO_MALLOC_ALIGNMENT); 187*76559068SAndroid Build Coastguard Worker reportAllocation(Ptr, size); 188*76559068SAndroid Build Coastguard Worker return scudo::setErrnoOnNull(Ptr); 189*76559068SAndroid Build Coastguard Worker } 190*76559068SAndroid Build Coastguard Worker if (size == 0) { 191*76559068SAndroid Build Coastguard Worker reportDeallocation(ptr); 192*76559068SAndroid Build Coastguard Worker SCUDO_ALLOCATOR.deallocate(ptr, scudo::Chunk::Origin::Malloc); 193*76559068SAndroid Build Coastguard Worker return nullptr; 194*76559068SAndroid Build Coastguard Worker } 195*76559068SAndroid Build Coastguard Worker 196*76559068SAndroid Build Coastguard Worker // Given that the reporting of deallocation and allocation are not atomic, we 197*76559068SAndroid Build Coastguard Worker // always pretend the old pointer will be released so that the user doesn't 198*76559068SAndroid Build Coastguard Worker // need to worry about the false double-use case from the view of hooks. 199*76559068SAndroid Build Coastguard Worker // 200*76559068SAndroid Build Coastguard Worker // For example, assume that `realloc` releases the old pointer and allocates a 201*76559068SAndroid Build Coastguard Worker // new pointer. Before the reporting of both operations has been done, another 202*76559068SAndroid Build Coastguard Worker // thread may get the old pointer from `malloc`. It may be misinterpreted as 203*76559068SAndroid Build Coastguard Worker // double-use if it's not handled properly on the hook side. 204*76559068SAndroid Build Coastguard Worker reportReallocDeallocation(ptr); 205*76559068SAndroid Build Coastguard Worker void *NewPtr = SCUDO_ALLOCATOR.reallocate(ptr, size, SCUDO_MALLOC_ALIGNMENT); 206*76559068SAndroid Build Coastguard Worker if (NewPtr != nullptr) { 207*76559068SAndroid Build Coastguard Worker // Note that even if NewPtr == ptr, the size has changed. We still need to 208*76559068SAndroid Build Coastguard Worker // report the new size. 209*76559068SAndroid Build Coastguard Worker reportReallocAllocation(/*OldPtr=*/ptr, NewPtr, size); 210*76559068SAndroid Build Coastguard Worker } else { 211*76559068SAndroid Build Coastguard Worker // If `realloc` fails, the old pointer is not released. Report the old 212*76559068SAndroid Build Coastguard Worker // pointer as allocated again. 213*76559068SAndroid Build Coastguard Worker reportReallocAllocation(/*OldPtr=*/ptr, /*NewPtr=*/ptr, 214*76559068SAndroid Build Coastguard Worker SCUDO_ALLOCATOR.getAllocSize(ptr)); 215*76559068SAndroid Build Coastguard Worker } 216*76559068SAndroid Build Coastguard Worker 217*76559068SAndroid Build Coastguard Worker return scudo::setErrnoOnNull(NewPtr); 218*76559068SAndroid Build Coastguard Worker} 219*76559068SAndroid Build Coastguard Worker 220*76559068SAndroid Build Coastguard WorkerINTERFACE WEAK void *SCUDO_PREFIX(valloc)(size_t size) { 221*76559068SAndroid Build Coastguard Worker void *Ptr = SCUDO_ALLOCATOR.allocate(size, scudo::Chunk::Origin::Memalign, 222*76559068SAndroid Build Coastguard Worker scudo::getPageSizeCached()); 223*76559068SAndroid Build Coastguard Worker reportAllocation(Ptr, size); 224*76559068SAndroid Build Coastguard Worker 225*76559068SAndroid Build Coastguard Worker return scudo::setErrnoOnNull(Ptr); 226*76559068SAndroid Build Coastguard Worker} 227*76559068SAndroid Build Coastguard Worker 228*76559068SAndroid Build Coastguard WorkerINTERFACE WEAK int SCUDO_PREFIX(malloc_iterate)( 229*76559068SAndroid Build Coastguard Worker uintptr_t base, size_t size, 230*76559068SAndroid Build Coastguard Worker void (*callback)(uintptr_t base, size_t size, void *arg), void *arg) { 231*76559068SAndroid Build Coastguard Worker SCUDO_ALLOCATOR.iterateOverChunks(base, size, callback, arg); 232*76559068SAndroid Build Coastguard Worker return 0; 233*76559068SAndroid Build Coastguard Worker} 234*76559068SAndroid Build Coastguard Worker 235*76559068SAndroid Build Coastguard WorkerINTERFACE WEAK void SCUDO_PREFIX(malloc_enable)() { SCUDO_ALLOCATOR.enable(); } 236*76559068SAndroid Build Coastguard Worker 237*76559068SAndroid Build Coastguard WorkerINTERFACE WEAK void SCUDO_PREFIX(malloc_disable)() { 238*76559068SAndroid Build Coastguard Worker SCUDO_ALLOCATOR.disable(); 239*76559068SAndroid Build Coastguard Worker} 240*76559068SAndroid Build Coastguard Worker 241*76559068SAndroid Build Coastguard Workervoid SCUDO_PREFIX(malloc_postinit)() { 242*76559068SAndroid Build Coastguard Worker SCUDO_ALLOCATOR.initGwpAsan(); 243*76559068SAndroid Build Coastguard Worker pthread_atfork(SCUDO_PREFIX(malloc_disable), SCUDO_PREFIX(malloc_enable), 244*76559068SAndroid Build Coastguard Worker SCUDO_PREFIX(malloc_enable)); 245*76559068SAndroid Build Coastguard Worker} 246*76559068SAndroid Build Coastguard Worker 247*76559068SAndroid Build Coastguard WorkerINTERFACE WEAK int SCUDO_PREFIX(mallopt)(int param, int value) { 248*76559068SAndroid Build Coastguard Worker if (param == M_DECAY_TIME) { 249*76559068SAndroid Build Coastguard Worker if (SCUDO_ANDROID) { 250*76559068SAndroid Build Coastguard Worker // Before changing the interval, reset the memory usage status by doing a 251*76559068SAndroid Build Coastguard Worker // M_PURGE call so that we can minimize the impact of any unreleased pages 252*76559068SAndroid Build Coastguard Worker // introduced by interval transition. 253*76559068SAndroid Build Coastguard Worker SCUDO_ALLOCATOR.releaseToOS(scudo::ReleaseToOS::Force); 254*76559068SAndroid Build Coastguard Worker 255*76559068SAndroid Build Coastguard Worker // The values allowed on Android are {-1, 0, 1}. "1" means the longest 256*76559068SAndroid Build Coastguard Worker // interval. 257*76559068SAndroid Build Coastguard Worker CHECK(value >= -1 && value <= 1); 258*76559068SAndroid Build Coastguard Worker if (value == 1) 259*76559068SAndroid Build Coastguard Worker value = INT32_MAX; 260*76559068SAndroid Build Coastguard Worker } 261*76559068SAndroid Build Coastguard Worker 262*76559068SAndroid Build Coastguard Worker SCUDO_ALLOCATOR.setOption(scudo::Option::ReleaseInterval, 263*76559068SAndroid Build Coastguard Worker static_cast<scudo::sptr>(value)); 264*76559068SAndroid Build Coastguard Worker return 1; 265*76559068SAndroid Build Coastguard Worker } else if (param == M_PURGE) { 266*76559068SAndroid Build Coastguard Worker SCUDO_ALLOCATOR.releaseToOS(scudo::ReleaseToOS::Force); 267*76559068SAndroid Build Coastguard Worker return 1; 268*76559068SAndroid Build Coastguard Worker } else if (param == M_PURGE_ALL) { 269*76559068SAndroid Build Coastguard Worker SCUDO_ALLOCATOR.releaseToOS(scudo::ReleaseToOS::ForceAll); 270*76559068SAndroid Build Coastguard Worker return 1; 271*76559068SAndroid Build Coastguard Worker } else if (param == M_LOG_STATS) { 272*76559068SAndroid Build Coastguard Worker SCUDO_ALLOCATOR.printStats(); 273*76559068SAndroid Build Coastguard Worker SCUDO_ALLOCATOR.printFragmentationInfo(); 274*76559068SAndroid Build Coastguard Worker return 1; 275*76559068SAndroid Build Coastguard Worker } else { 276*76559068SAndroid Build Coastguard Worker scudo::Option option; 277*76559068SAndroid Build Coastguard Worker switch (param) { 278*76559068SAndroid Build Coastguard Worker case M_MEMTAG_TUNING: 279*76559068SAndroid Build Coastguard Worker option = scudo::Option::MemtagTuning; 280*76559068SAndroid Build Coastguard Worker break; 281*76559068SAndroid Build Coastguard Worker case M_THREAD_DISABLE_MEM_INIT: 282*76559068SAndroid Build Coastguard Worker option = scudo::Option::ThreadDisableMemInit; 283*76559068SAndroid Build Coastguard Worker break; 284*76559068SAndroid Build Coastguard Worker case M_CACHE_COUNT_MAX: 285*76559068SAndroid Build Coastguard Worker option = scudo::Option::MaxCacheEntriesCount; 286*76559068SAndroid Build Coastguard Worker break; 287*76559068SAndroid Build Coastguard Worker case M_CACHE_SIZE_MAX: 288*76559068SAndroid Build Coastguard Worker option = scudo::Option::MaxCacheEntrySize; 289*76559068SAndroid Build Coastguard Worker break; 290*76559068SAndroid Build Coastguard Worker case M_TSDS_COUNT_MAX: 291*76559068SAndroid Build Coastguard Worker option = scudo::Option::MaxTSDsCount; 292*76559068SAndroid Build Coastguard Worker break; 293*76559068SAndroid Build Coastguard Worker default: 294*76559068SAndroid Build Coastguard Worker return 0; 295*76559068SAndroid Build Coastguard Worker } 296*76559068SAndroid Build Coastguard Worker return SCUDO_ALLOCATOR.setOption(option, static_cast<scudo::sptr>(value)); 297*76559068SAndroid Build Coastguard Worker } 298*76559068SAndroid Build Coastguard Worker} 299*76559068SAndroid Build Coastguard Worker 300*76559068SAndroid Build Coastguard WorkerINTERFACE WEAK void *SCUDO_PREFIX(aligned_alloc)(size_t alignment, 301*76559068SAndroid Build Coastguard Worker size_t size) { 302*76559068SAndroid Build Coastguard Worker if (UNLIKELY(scudo::checkAlignedAllocAlignmentAndSize(alignment, size))) { 303*76559068SAndroid Build Coastguard Worker if (SCUDO_ALLOCATOR.canReturnNull()) { 304*76559068SAndroid Build Coastguard Worker errno = EINVAL; 305*76559068SAndroid Build Coastguard Worker return nullptr; 306*76559068SAndroid Build Coastguard Worker } 307*76559068SAndroid Build Coastguard Worker scudo::reportInvalidAlignedAllocAlignment(alignment, size); 308*76559068SAndroid Build Coastguard Worker } 309*76559068SAndroid Build Coastguard Worker 310*76559068SAndroid Build Coastguard Worker void *Ptr = 311*76559068SAndroid Build Coastguard Worker SCUDO_ALLOCATOR.allocate(size, scudo::Chunk::Origin::Malloc, alignment); 312*76559068SAndroid Build Coastguard Worker reportAllocation(Ptr, size); 313*76559068SAndroid Build Coastguard Worker 314*76559068SAndroid Build Coastguard Worker return scudo::setErrnoOnNull(Ptr); 315*76559068SAndroid Build Coastguard Worker} 316*76559068SAndroid Build Coastguard Worker 317*76559068SAndroid Build Coastguard WorkerINTERFACE WEAK int SCUDO_PREFIX(malloc_info)(UNUSED int options, FILE *stream) { 318*76559068SAndroid Build Coastguard Worker const scudo::uptr max_size = 319*76559068SAndroid Build Coastguard Worker decltype(SCUDO_ALLOCATOR)::PrimaryT::SizeClassMap::MaxSize; 320*76559068SAndroid Build Coastguard Worker auto *sizes = static_cast<scudo::uptr *>( 321*76559068SAndroid Build Coastguard Worker SCUDO_PREFIX(calloc)(max_size, sizeof(scudo::uptr))); 322*76559068SAndroid Build Coastguard Worker auto callback = [](uintptr_t, size_t size, void *arg) { 323*76559068SAndroid Build Coastguard Worker auto *sizes = reinterpret_cast<scudo::uptr *>(arg); 324*76559068SAndroid Build Coastguard Worker if (size < max_size) 325*76559068SAndroid Build Coastguard Worker sizes[size]++; 326*76559068SAndroid Build Coastguard Worker }; 327*76559068SAndroid Build Coastguard Worker 328*76559068SAndroid Build Coastguard Worker SCUDO_ALLOCATOR.disable(); 329*76559068SAndroid Build Coastguard Worker SCUDO_ALLOCATOR.iterateOverChunks(0, -1ul, callback, sizes); 330*76559068SAndroid Build Coastguard Worker SCUDO_ALLOCATOR.enable(); 331*76559068SAndroid Build Coastguard Worker 332*76559068SAndroid Build Coastguard Worker fputs("<malloc version=\"scudo-1\">\n", stream); 333*76559068SAndroid Build Coastguard Worker for (scudo::uptr i = 0; i != max_size; ++i) 334*76559068SAndroid Build Coastguard Worker if (sizes[i]) 335*76559068SAndroid Build Coastguard Worker fprintf(stream, "<alloc size=\"%zu\" count=\"%zu\"/>\n", i, sizes[i]); 336*76559068SAndroid Build Coastguard Worker fputs("</malloc>\n", stream); 337*76559068SAndroid Build Coastguard Worker SCUDO_PREFIX(free)(sizes); 338*76559068SAndroid Build Coastguard Worker return 0; 339*76559068SAndroid Build Coastguard Worker} 340*76559068SAndroid Build Coastguard Worker 341*76559068SAndroid Build Coastguard Worker// Disable memory tagging for the heap. The caller must disable memory tag 342*76559068SAndroid Build Coastguard Worker// checks globally (e.g. by clearing TCF0 on aarch64) before calling this 343*76559068SAndroid Build Coastguard Worker// function, and may not re-enable them after calling the function. 344*76559068SAndroid Build Coastguard WorkerINTERFACE WEAK void SCUDO_PREFIX(malloc_disable_memory_tagging)() { 345*76559068SAndroid Build Coastguard Worker SCUDO_ALLOCATOR.disableMemoryTagging(); 346*76559068SAndroid Build Coastguard Worker} 347*76559068SAndroid Build Coastguard Worker 348*76559068SAndroid Build Coastguard Worker// Sets whether scudo records stack traces and other metadata for allocations 349*76559068SAndroid Build Coastguard Worker// and deallocations. This function only has an effect if the allocator and 350*76559068SAndroid Build Coastguard Worker// hardware support memory tagging. 351*76559068SAndroid Build Coastguard WorkerINTERFACE WEAK void 352*76559068SAndroid Build Coastguard WorkerSCUDO_PREFIX(malloc_set_track_allocation_stacks)(int track) { 353*76559068SAndroid Build Coastguard Worker SCUDO_ALLOCATOR.setTrackAllocationStacks(track); 354*76559068SAndroid Build Coastguard Worker} 355*76559068SAndroid Build Coastguard Worker 356*76559068SAndroid Build Coastguard Worker// Sets whether scudo zero-initializes all allocated memory. 357*76559068SAndroid Build Coastguard WorkerINTERFACE WEAK void SCUDO_PREFIX(malloc_set_zero_contents)(int zero_contents) { 358*76559068SAndroid Build Coastguard Worker SCUDO_ALLOCATOR.setFillContents(zero_contents ? scudo::ZeroFill 359*76559068SAndroid Build Coastguard Worker : scudo::NoFill); 360*76559068SAndroid Build Coastguard Worker} 361*76559068SAndroid Build Coastguard Worker 362*76559068SAndroid Build Coastguard Worker// Sets whether scudo pattern-initializes all allocated memory. 363*76559068SAndroid Build Coastguard WorkerINTERFACE WEAK void 364*76559068SAndroid Build Coastguard WorkerSCUDO_PREFIX(malloc_set_pattern_fill_contents)(int pattern_fill_contents) { 365*76559068SAndroid Build Coastguard Worker SCUDO_ALLOCATOR.setFillContents( 366*76559068SAndroid Build Coastguard Worker pattern_fill_contents ? scudo::PatternOrZeroFill : scudo::NoFill); 367*76559068SAndroid Build Coastguard Worker} 368*76559068SAndroid Build Coastguard Worker 369*76559068SAndroid Build Coastguard Worker// Sets whether scudo adds a small amount of slack at the end of large 370*76559068SAndroid Build Coastguard Worker// allocations, before the guard page. This can be enabled to work around buggy 371*76559068SAndroid Build Coastguard Worker// applications that read a few bytes past the end of their allocation. 372*76559068SAndroid Build Coastguard WorkerINTERFACE WEAK void 373*76559068SAndroid Build Coastguard WorkerSCUDO_PREFIX(malloc_set_add_large_allocation_slack)(int add_slack) { 374*76559068SAndroid Build Coastguard Worker SCUDO_ALLOCATOR.setAddLargeAllocationSlack(add_slack); 375*76559068SAndroid Build Coastguard Worker} 376*76559068SAndroid Build Coastguard Worker 377*76559068SAndroid Build Coastguard Worker} // extern "C" 378