1 //===-- wrappers_c.inc ------------------------------------------*- C++ -*-===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
10 #error "Define SCUDO_PREFIX prior to including this file!"
13 // malloc-type functions have to be aligned to std::max_align_t. This is
14 // distinct from (1U << SCUDO_MIN_ALIGNMENT_LOG), since C++ new-type functions
15 // do not have to abide by the same requirement.
16 #ifndef SCUDO_MALLOC_ALIGNMENT
17 #define SCUDO_MALLOC_ALIGNMENT FIRST_32_SECOND_64(8U, 16U)
20 INTERFACE WEAK void *SCUDO_PREFIX(calloc)(size_t nmemb, size_t size) {
22 if (UNLIKELY(scudo::checkForCallocOverflow(size, nmemb, &Product))) {
23 if (SCUDO_ALLOCATOR.canReturnNull()) {
27 scudo::reportCallocOverflow(nmemb, size);
29 return scudo::setErrnoOnNull(SCUDO_ALLOCATOR.allocate(
30 Product, scudo::Chunk::Origin::Malloc, SCUDO_MALLOC_ALIGNMENT, true));
33 INTERFACE WEAK void SCUDO_PREFIX(free)(void *ptr) {
34 SCUDO_ALLOCATOR.deallocate(ptr, scudo::Chunk::Origin::Malloc);
37 INTERFACE WEAK struct SCUDO_MALLINFO SCUDO_PREFIX(mallinfo)(void) {
38 struct SCUDO_MALLINFO Info = {};
39 scudo::StatCounters Stats;
40 SCUDO_ALLOCATOR.getStats(Stats);
42 static_cast<__scudo_mallinfo_data_t>(Stats[scudo::StatAllocated]);
46 INTERFACE WEAK void *SCUDO_PREFIX(malloc)(size_t size) {
47 return scudo::setErrnoOnNull(SCUDO_ALLOCATOR.allocate(
48 size, scudo::Chunk::Origin::Malloc, SCUDO_MALLOC_ALIGNMENT));
52 INTERFACE WEAK size_t SCUDO_PREFIX(malloc_usable_size)(const void *ptr) {
54 INTERFACE WEAK size_t SCUDO_PREFIX(malloc_usable_size)(void *ptr) {
56 return SCUDO_ALLOCATOR.getUsableSize(ptr);
59 INTERFACE WEAK void *SCUDO_PREFIX(memalign)(size_t alignment, size_t size) {
60 // Android rounds up the alignment to a power of two if it isn't one.
62 if (UNLIKELY(!alignment)) {
65 if (UNLIKELY(!scudo::isPowerOfTwo(alignment)))
66 alignment = scudo::roundUpToPowerOfTwo(alignment);
69 if (UNLIKELY(!scudo::isPowerOfTwo(alignment))) {
70 if (SCUDO_ALLOCATOR.canReturnNull()) {
74 scudo::reportAlignmentNotPowerOfTwo(alignment);
77 return SCUDO_ALLOCATOR.allocate(size, scudo::Chunk::Origin::Memalign,
81 INTERFACE WEAK int SCUDO_PREFIX(posix_memalign)(void **memptr, size_t alignment,
83 if (UNLIKELY(scudo::checkPosixMemalignAlignment(alignment))) {
84 if (!SCUDO_ALLOCATOR.canReturnNull())
85 scudo::reportInvalidPosixMemalignAlignment(alignment);
89 SCUDO_ALLOCATOR.allocate(size, scudo::Chunk::Origin::Memalign, alignment);
96 INTERFACE WEAK void *SCUDO_PREFIX(pvalloc)(size_t size) {
97 const scudo::uptr PageSize = scudo::getPageSizeCached();
98 if (UNLIKELY(scudo::checkForPvallocOverflow(size, PageSize))) {
99 if (SCUDO_ALLOCATOR.canReturnNull()) {
103 scudo::reportPvallocOverflow(size);
105 // pvalloc(0) should allocate one page.
106 return scudo::setErrnoOnNull(SCUDO_ALLOCATOR.allocate(
107 size ? scudo::roundUpTo(size, PageSize) : PageSize,
108 scudo::Chunk::Origin::Memalign, PageSize));
111 INTERFACE WEAK void *SCUDO_PREFIX(realloc)(void *ptr, size_t size) {
113 return scudo::setErrnoOnNull(SCUDO_ALLOCATOR.allocate(
114 size, scudo::Chunk::Origin::Malloc, SCUDO_MALLOC_ALIGNMENT));
116 SCUDO_ALLOCATOR.deallocate(ptr, scudo::Chunk::Origin::Malloc);
119 return scudo::setErrnoOnNull(
120 SCUDO_ALLOCATOR.reallocate(ptr, size, SCUDO_MALLOC_ALIGNMENT));
123 INTERFACE WEAK void *SCUDO_PREFIX(valloc)(size_t size) {
124 return scudo::setErrnoOnNull(SCUDO_ALLOCATOR.allocate(
125 size, scudo::Chunk::Origin::Memalign, scudo::getPageSizeCached()));
128 // Bionic wants a function named PREFIX_iterate and not PREFIX_malloc_iterate
129 // which is somewhat inconsistent with the rest, workaround that.
130 #if SCUDO_ANDROID && _BIONIC
131 #define SCUDO_ITERATE iterate
133 #define SCUDO_ITERATE malloc_iterate
136 INTERFACE WEAK int SCUDO_PREFIX(SCUDO_ITERATE)(
137 uintptr_t base, size_t size,
138 void (*callback)(uintptr_t base, size_t size, void *arg), void *arg) {
139 SCUDO_ALLOCATOR.iterateOverChunks(base, size, callback, arg);
143 INTERFACE WEAK void SCUDO_PREFIX(malloc_disable)() {
144 SCUDO_ALLOCATOR.disable();
147 INTERFACE WEAK void SCUDO_PREFIX(malloc_enable)() { SCUDO_ALLOCATOR.enable(); }
149 INTERFACE WEAK int SCUDO_PREFIX(mallopt)(int param, UNUSED int value) {
150 if (param == M_DECAY_TIME) {
151 // TODO(kostyak): set release_to_os_interval_ms accordingly.
153 } else if (param == M_PURGE) {
154 SCUDO_ALLOCATOR.releaseToOS();
160 INTERFACE WEAK void *SCUDO_PREFIX(aligned_alloc)(size_t alignment,
162 if (UNLIKELY(scudo::checkAlignedAllocAlignmentAndSize(alignment, size))) {
163 if (SCUDO_ALLOCATOR.canReturnNull()) {
167 scudo::reportInvalidAlignedAllocAlignment(alignment, size);
169 return scudo::setErrnoOnNull(
170 SCUDO_ALLOCATOR.allocate(size, scudo::Chunk::Origin::Malloc, alignment));
173 INTERFACE WEAK int SCUDO_PREFIX(malloc_info)(int, FILE *) {