VirtualBox

source: vbox/trunk/src/VBox/Runtime/r3/alloc.cpp

Last change on this file was 106061, checked in by vboxsync, 2 months ago

Copyright year updates by scm.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id Revision
File size: 9.7 KB
Line 
1/* $Id: alloc.cpp 106061 2024-09-16 14:03:52Z vboxsync $ */
2/** @file
3 * IPRT - Memory Allocation.
4 */
5
6/*
7 * Copyright (C) 2006-2024 Oracle and/or its affiliates.
8 *
9 * This file is part of VirtualBox base platform packages, as
10 * available from https://www.virtualbox.org.
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation, in version 3 of the
15 * License.
16 *
17 * This program is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, see <https://www.gnu.org/licenses>.
24 *
25 * The contents of this file may alternatively be used under the terms
26 * of the Common Development and Distribution License Version 1.0
27 * (CDDL), a copy of it is provided in the "COPYING.CDDL" file included
28 * in the VirtualBox distribution, in which case the provisions of the
29 * CDDL are applicable instead of those of the GPL.
30 *
31 * You may elect to license modified versions of this file under the
32 * terms and conditions of either the GPL or the CDDL or both.
33 *
34 * SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0
35 */
36
37
38/*********************************************************************************************************************************
39* Defined Constants And Macros *
40*********************************************************************************************************************************/
41#if defined(RTMEM_WRAP_TO_EF_APIS) && !defined(RTMEM_NO_WRAP_TO_EF_APIS)
42# undef RTMEM_WRAP_TO_EF_APIS
43# define RTALLOC_USE_EFENCE 1
44#endif
45
46/*#define RTMEMALLOC_USE_TRACKER*/
47/* Don't enable the tracker when building the minimal IPRT. */
48#ifdef RT_MINI
49# undef RTMEMALLOC_USE_TRACKER
50#endif
51
52#if defined(RTMEMALLOC_USE_TRACKER) && defined(RTALLOC_USE_EFENCE)
53# error "Cannot define both RTMEMALLOC_USE_TRACKER and RTALLOC_USE_EFENCE!"
54#endif
55
56
57/*********************************************************************************************************************************
58* Header Files *
59*********************************************************************************************************************************/
60#include "alloc-ef.h"
61#include <iprt/mem.h>
62
63#include <iprt/asm.h>
64#include <iprt/assert.h>
65#ifdef RTMEMALLOC_USE_TRACKER
66# include <iprt/memtracker.h>
67#endif
68#include <iprt/param.h>
69#include <iprt/string.h>
70#include "internal/mem.h"
71
72#include <stdlib.h>
73
74#undef RTMemTmpAlloc
75#undef RTMemTmpAllocTag
76#undef RTMemTmpAllocZ
77#undef RTMemTmpAllocZTag
78#undef RTMemTmpFree
79#undef RTMemTmpFreeZ
80#undef RTMemAlloc
81#undef RTMemAllocTag
82#undef RTMemAllocZ
83#undef RTMemAllocZTag
84#undef RTMemAllocVar
85#undef RTMemAllocVarTag
86#undef RTMemAllocZVar
87#undef RTMemAllocZVarTag
88#undef RTMemRealloc
89#undef RTMemReallocTag
90#undef RTMemFree
91#undef RTMemFreeZ
92#undef RTMemDup
93#undef RTMemDupTag
94#undef RTMemDupEx
95#undef RTMemDupExTag
96
97#undef RTALLOC_USE_EFENCE
98
99
100#ifdef IPRT_WITH_GCC_SANITIZER
101/**
102 * Checks if @a pszTag is a leak tag.
103 *
104 * @returns true if leak tag, false if not.
105 * @param pszTag Tage to inspect.
106 */
107DECLINLINE(bool) rtMemIsLeakTag(const char *pszTag)
108{
109 char ch = *pszTag;
110 if (ch != 'w')
111 { /* likely */ }
112 else
113 return pszTag[1] == 'i'
114 && pszTag[2] == 'l'
115 && pszTag[3] == 'l'
116 && pszTag[4] == '-'
117 && pszTag[5] == 'l'
118 && pszTag[6] == 'e'
119 && pszTag[7] == 'a'
120 && pszTag[8] == 'k';
121 if (ch != 'm')
122 return false;
123 return pszTag[1] == 'm'
124 && pszTag[2] == 'a'
125 && pszTag[3] == 'y'
126 && pszTag[4] == '-'
127 && pszTag[5] == 'l'
128 && pszTag[6] == 'e'
129 && pszTag[7] == 'a'
130 && pszTag[8] == 'k';
131}
132#endif /* IPRT_WITH_GCC_SANITIZER */
133
134
135RTDECL(void *) RTMemTmpAllocTag(size_t cb, const char *pszTag) RT_NO_THROW_DEF
136{
137 return RTMemAllocTag(cb, pszTag);
138}
139
140
141RTDECL(void *) RTMemTmpAllocZTag(size_t cb, const char *pszTag) RT_NO_THROW_DEF
142{
143 return RTMemAllocZTag(cb, pszTag);
144}
145
146
147RTDECL(void) RTMemTmpFree(void *pv) RT_NO_THROW_DEF
148{
149 RTMemFree(pv);
150}
151
152
153RTDECL(void) RTMemTmpFreeZ(void *pv, size_t cb) RT_NO_THROW_DEF
154{
155 RTMemFreeZ(pv, cb);
156}
157
158
159RTDECL(void *) RTMemAllocTag(size_t cb, const char *pszTag) RT_NO_THROW_DEF
160{
161#ifdef RTALLOC_USE_EFENCE
162 void *pv = rtR3MemAlloc("Alloc", RTMEMTYPE_RTMEMALLOC, cb, cb, pszTag, ASMReturnAddress(), NULL, 0, NULL);
163
164#else /* !RTALLOC_USE_EFENCE */
165
166 AssertMsg(cb, ("Allocating ZERO bytes is really not a good idea! Good luck with the next assertion!\n"));
167# ifdef RTMEMALLOC_USE_TRACKER
168 void *pv = RTMemTrackerHdrAlloc(malloc(cb + sizeof(RTMEMTRACKERHDR)), cb, pszTag, ASMReturnAddress(), RTMEMTRACKERMETHOD_ALLOC);
169# else
170 void *pv = malloc(cb); NOREF(pszTag);
171# endif
172 AssertMsg(pv, ("malloc(%#zx) failed!!!\n", cb));
173 AssertMsg( cb < RTMEM_ALIGNMENT
174 || !((uintptr_t)pv & (RTMEM_ALIGNMENT - 1))
175 || ( (cb & RTMEM_ALIGNMENT) + ((uintptr_t)pv & RTMEM_ALIGNMENT)) == RTMEM_ALIGNMENT
176 , ("pv=%p RTMEM_ALIGNMENT=%#x\n", pv, RTMEM_ALIGNMENT));
177#endif /* !RTALLOC_USE_EFENCE */
178#ifdef IPRT_WITH_GCC_SANITIZER
179 if (rtMemIsLeakTag(pszTag))
180 __lsan_ignore_object(pv);
181#endif
182 return pv;
183}
184
185
186RTDECL(void *) RTMemAllocZTag(size_t cb, const char *pszTag) RT_NO_THROW_DEF
187{
188#ifdef RTALLOC_USE_EFENCE
189 void *pv = rtR3MemAlloc("AllocZ", RTMEMTYPE_RTMEMALLOCZ, cb, cb, pszTag, ASMReturnAddress(), NULL, 0, NULL);
190
191#else /* !RTALLOC_USE_EFENCE */
192
193 AssertMsg(cb, ("Allocating ZERO bytes is really not a good idea! Good luck with the next assertion!\n"));
194
195# ifdef RTMEMALLOC_USE_TRACKER
196 void *pv = RTMemTrackerHdrAlloc(calloc(1, cb + sizeof(RTMEMTRACKERHDR)), cb, pszTag, ASMReturnAddress(), RTMEMTRACKERMETHOD_ALLOCZ);
197#else
198 void *pv = calloc(1, cb); NOREF(pszTag);
199#endif
200 AssertMsg(pv, ("calloc(1,%#zx) failed!!!\n", cb));
201 AssertMsg( cb < RTMEM_ALIGNMENT
202 || !((uintptr_t)pv & (RTMEM_ALIGNMENT - 1))
203 || ( (cb & RTMEM_ALIGNMENT) + ((uintptr_t)pv & RTMEM_ALIGNMENT)) == RTMEM_ALIGNMENT
204 , ("pv=%p RTMEM_ALIGNMENT=%#x\n", pv, RTMEM_ALIGNMENT));
205#endif /* !RTALLOC_USE_EFENCE */
206#ifdef IPRT_WITH_GCC_SANITIZER
207 if (rtMemIsLeakTag(pszTag))
208 __lsan_ignore_object(pv);
209#endif
210 return pv;
211}
212
213
214RTDECL(void *) RTMemAllocVarTag(size_t cbUnaligned, const char *pszTag) RT_NO_THROW_DEF
215{
216 size_t cbAligned;
217 if (cbUnaligned >= 16)
218 cbAligned = RT_ALIGN_Z(cbUnaligned, 16);
219 else
220 cbAligned = RT_ALIGN_Z(cbUnaligned, sizeof(void *));
221#ifdef RTALLOC_USE_EFENCE
222 void *pv = rtR3MemAlloc("AllocVar", RTMEMTYPE_RTMEMALLOC, cbUnaligned, cbAligned, pszTag, ASMReturnAddress(), NULL, 0, NULL);
223#else
224 void *pv = RTMemAllocTag(cbAligned, pszTag);
225#endif
226 return pv;
227}
228
229
230RTDECL(void *) RTMemAllocZVarTag(size_t cbUnaligned, const char *pszTag) RT_NO_THROW_DEF
231{
232 size_t cbAligned;
233 if (cbUnaligned >= 16)
234 cbAligned = RT_ALIGN_Z(cbUnaligned, 16);
235 else
236 cbAligned = RT_ALIGN_Z(cbUnaligned, sizeof(void *));
237#ifdef RTALLOC_USE_EFENCE
238 void *pv = rtR3MemAlloc("AllocZVar", RTMEMTYPE_RTMEMALLOCZ, cbUnaligned, cbAligned, pszTag, ASMReturnAddress(), NULL, 0, NULL);
239#else
240 void *pv = RTMemAllocZTag(cbAligned, pszTag);
241#endif
242 return pv;
243}
244
245
246RTDECL(void *) RTMemReallocTag(void *pvOld, size_t cbNew, const char *pszTag) RT_NO_THROW_DEF
247{
248#ifdef RTALLOC_USE_EFENCE
249 void *pv = rtR3MemRealloc("Realloc", RTMEMTYPE_RTMEMREALLOC, pvOld, cbNew, pszTag, ASMReturnAddress(), NULL, 0, NULL);
250
251#else /* !RTALLOC_USE_EFENCE */
252# ifdef RT_STRICT
253 const uintptr_t uOld = (uintptr_t)pvOld; /* overzealous gcc 12 complains it's used over realloc */
254# endif
255
256# ifdef RTMEMALLOC_USE_TRACKER
257 void *pvRealOld = RTMemTrackerHdrReallocPrep(pvOld, 0, pszTag, ASMReturnAddress());
258 size_t cbRealNew = cbNew || !pvRealOld ? cbNew + sizeof(RTMEMTRACKERHDR) : 0;
259 void *pvNew = realloc(pvRealOld, cbRealNew);
260 void *pv = RTMemTrackerHdrReallocDone(pvNew, cbNew, pvOld, pszTag, ASMReturnAddress());
261# else
262 void *pv = realloc(pvOld, cbNew); NOREF(pszTag);
263# endif
264 AssertMsg(pv || !cbNew, ("realloc(%p, %#zx) failed!!!\n", uOld, cbNew));
265 AssertMsg( cbNew < RTMEM_ALIGNMENT
266 || !((uintptr_t)pv & (RTMEM_ALIGNMENT - 1))
267 || ( (cbNew & RTMEM_ALIGNMENT) + ((uintptr_t)pv & RTMEM_ALIGNMENT)) == RTMEM_ALIGNMENT
268 , ("pv=%p RTMEM_ALIGNMENT=%#x\n", pv, RTMEM_ALIGNMENT));
269#endif /* !RTALLOC_USE_EFENCE */
270 return pv;
271}
272
273
274RTDECL(void) RTMemFree(void *pv) RT_NO_THROW_DEF
275{
276 if (pv)
277#ifdef RTALLOC_USE_EFENCE
278 rtR3MemFree("Free", RTMEMTYPE_RTMEMFREE, pv, 0, ASMReturnAddress(), NULL, 0, NULL);
279#else
280# ifdef RTMEMALLOC_USE_TRACKER
281 pv = RTMemTrackerHdrFree(pv, 0, NULL, ASMReturnAddress(), RTMEMTRACKERMETHOD_FREE);
282# endif
283 free(pv);
284#endif
285}
286
287
288RTDECL(void) RTMemFreeZ(void *pv, size_t cb) RT_NO_THROW_DEF
289{
290 if (pv)
291 {
292#ifdef RTALLOC_USE_EFENCE
293 rtR3MemFree("Free", RTMEMTYPE_RTMEMFREEZ, pv, cb, ASMReturnAddress(), NULL, 0, NULL);
294#else
295# ifdef RTMEMALLOC_USE_TRACKER
296 pv = RTMemTrackerHdrFree(pv, cb, NULL, ASMReturnAddress(), RTMEMTRACKERMETHOD_FREE);
297# endif
298 RT_BZERO(pv, cb);
299 free(pv);
300#endif
301 }
302}
303
304
305
306DECLHIDDEN(void *) rtMemBaseAlloc(size_t cb)
307{
308 Assert(cb > 0 && cb < _1M);
309 return malloc(cb);
310}
311
312
313DECLHIDDEN(void) rtMemBaseFree(void *pv)
314{
315 free(pv);
316}
317
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette