]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm-project/compiler-rt/lib/scudo/standalone/wrappers_c.inc
Merge llvm, clang, compiler-rt, libc++, libunwind, lld, lldb and openmp
[FreeBSD/FreeBSD.git] / contrib / llvm-project / compiler-rt / lib / scudo / standalone / wrappers_c.inc
1 //===-- wrappers_c.inc ------------------------------------------*- C++ -*-===//
2 //
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
6 //
7 //===----------------------------------------------------------------------===//
8
9 #ifndef SCUDO_PREFIX
10 #error "Define SCUDO_PREFIX prior to including this file!"
11 #endif
12
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)
18 #endif
19
20 INTERFACE WEAK void *SCUDO_PREFIX(calloc)(size_t nmemb, size_t size) {
21   scudo::uptr Product;
22   if (UNLIKELY(scudo::checkForCallocOverflow(size, nmemb, &Product))) {
23     if (SCUDO_ALLOCATOR.canReturnNull()) {
24       errno = ENOMEM;
25       return nullptr;
26     }
27     scudo::reportCallocOverflow(nmemb, size);
28   }
29   return scudo::setErrnoOnNull(SCUDO_ALLOCATOR.allocate(
30       Product, scudo::Chunk::Origin::Malloc, SCUDO_MALLOC_ALIGNMENT, true));
31 }
32
33 INTERFACE WEAK void SCUDO_PREFIX(free)(void *ptr) {
34   SCUDO_ALLOCATOR.deallocate(ptr, scudo::Chunk::Origin::Malloc);
35 }
36
37 INTERFACE WEAK struct SCUDO_MALLINFO SCUDO_PREFIX(mallinfo)(void) {
38   struct SCUDO_MALLINFO Info = {};
39   scudo::StatCounters Stats;
40   SCUDO_ALLOCATOR.getStats(Stats);
41   Info.uordblks =
42       static_cast<__scudo_mallinfo_data_t>(Stats[scudo::StatAllocated]);
43   return Info;
44 }
45
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));
49 }
50
51 #if SCUDO_ANDROID
52 INTERFACE WEAK size_t SCUDO_PREFIX(malloc_usable_size)(const void *ptr) {
53 #else
54 INTERFACE WEAK size_t SCUDO_PREFIX(malloc_usable_size)(void *ptr) {
55 #endif
56   return SCUDO_ALLOCATOR.getUsableSize(ptr);
57 }
58
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.
61   if (SCUDO_ANDROID) {
62     if (UNLIKELY(!alignment)) {
63       alignment = 1U;
64     } else {
65       if (UNLIKELY(!scudo::isPowerOfTwo(alignment)))
66         alignment = scudo::roundUpToPowerOfTwo(alignment);
67     }
68   } else {
69     if (UNLIKELY(!scudo::isPowerOfTwo(alignment))) {
70       if (SCUDO_ALLOCATOR.canReturnNull()) {
71         errno = EINVAL;
72         return nullptr;
73       }
74       scudo::reportAlignmentNotPowerOfTwo(alignment);
75     }
76   }
77   return SCUDO_ALLOCATOR.allocate(size, scudo::Chunk::Origin::Memalign,
78                                   alignment);
79 }
80
81 INTERFACE WEAK int SCUDO_PREFIX(posix_memalign)(void **memptr, size_t alignment,
82                                                 size_t size) {
83   if (UNLIKELY(scudo::checkPosixMemalignAlignment(alignment))) {
84     if (!SCUDO_ALLOCATOR.canReturnNull())
85       scudo::reportInvalidPosixMemalignAlignment(alignment);
86     return EINVAL;
87   }
88   void *Ptr =
89       SCUDO_ALLOCATOR.allocate(size, scudo::Chunk::Origin::Memalign, alignment);
90   if (UNLIKELY(!Ptr))
91     return ENOMEM;
92   *memptr = Ptr;
93   return 0;
94 }
95
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()) {
100       errno = ENOMEM;
101       return nullptr;
102     }
103     scudo::reportPvallocOverflow(size);
104   }
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));
109 }
110
111 INTERFACE WEAK void *SCUDO_PREFIX(realloc)(void *ptr, size_t size) {
112   if (!ptr)
113     return scudo::setErrnoOnNull(SCUDO_ALLOCATOR.allocate(
114         size, scudo::Chunk::Origin::Malloc, SCUDO_MALLOC_ALIGNMENT));
115   if (size == 0) {
116     SCUDO_ALLOCATOR.deallocate(ptr, scudo::Chunk::Origin::Malloc);
117     return nullptr;
118   }
119   return scudo::setErrnoOnNull(
120       SCUDO_ALLOCATOR.reallocate(ptr, size, SCUDO_MALLOC_ALIGNMENT));
121 }
122
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()));
126 }
127
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
132 #else
133 #define SCUDO_ITERATE malloc_iterate
134 #endif
135
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);
140   return 0;
141 }
142
143 INTERFACE WEAK void SCUDO_PREFIX(malloc_disable)() {
144   SCUDO_ALLOCATOR.disable();
145 }
146
147 INTERFACE WEAK void SCUDO_PREFIX(malloc_enable)() { SCUDO_ALLOCATOR.enable(); }
148
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.
152     return 1;
153   } else if (param == M_PURGE) {
154     SCUDO_ALLOCATOR.releaseToOS();
155     return 1;
156   }
157   return 0;
158 }
159
160 INTERFACE WEAK void *SCUDO_PREFIX(aligned_alloc)(size_t alignment,
161                                                  size_t size) {
162   if (UNLIKELY(scudo::checkAlignedAllocAlignmentAndSize(alignment, size))) {
163     if (SCUDO_ALLOCATOR.canReturnNull()) {
164       errno = EINVAL;
165       return nullptr;
166     }
167     scudo::reportInvalidAlignedAllocAlignment(alignment, size);
168   }
169   return scudo::setErrnoOnNull(
170       SCUDO_ALLOCATOR.allocate(size, scudo::Chunk::Origin::Malloc, alignment));
171 }
172
173 INTERFACE WEAK int SCUDO_PREFIX(malloc_info)(int, FILE *) {
174   errno = ENOTSUP;
175   return -1;
176 }