VirtualBox

source: vbox/trunk/include/iprt/mem.h@ 78377

Last change on this file since 78377 was 78334, checked in by vboxsync, 6 years ago

IPRT/mem: Added RTMemPageAllocEx so we can try lock memory and try prevent it from being part of dumps/cores.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 37.6 KB
Line 
1/** @file
2 * IPRT - Memory Management and Manipulation.
3 */
4
5/*
6 * Copyright (C) 2006-2019 Oracle Corporation
7 *
8 * This file is part of VirtualBox Open Source Edition (OSE), as
9 * available from http://www.virtualbox.org. This file is free software;
10 * you can redistribute it and/or modify it under the terms of the GNU
11 * General Public License (GPL) as published by the Free Software
12 * Foundation, in version 2 as it comes in the "COPYING" file of the
13 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
14 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
15 *
16 * The contents of this file may alternatively be used under the terms
17 * of the Common Development and Distribution License Version 1.0
18 * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
19 * VirtualBox OSE distribution, in which case the provisions of the
20 * CDDL are applicable instead of those of the GPL.
21 *
22 * You may elect to license modified versions of this file under the
23 * terms and conditions of either the GPL or the CDDL or both.
24 */
25
26#ifndef IPRT_INCLUDED_mem_h
27#define IPRT_INCLUDED_mem_h
28#ifndef RT_WITHOUT_PRAGMA_ONCE
29# pragma once
30#endif
31
32
33#include <iprt/cdefs.h>
34#include <iprt/types.h>
35
36#ifdef IPRT_WITH_GCC_SANITIZER
37# include <sanitizer/lsan_interface.h>
38#endif
39
40#ifdef IN_RC
41# error "There are no RTMem APIs available Guest Context!"
42#endif
43
44
45/** @defgroup grp_rt_mem RTMem - Memory Management and Manipulation
46 * @ingroup grp_rt
47 * @{
48 */
49
50RT_C_DECLS_BEGIN
51
52/** @def RTMEM_ALIGNMENT
53 * The alignment of the memory blocks returned by RTMemAlloc(), RTMemAllocZ(),
54 * RTMemRealloc(), RTMemTmpAlloc() and RTMemTmpAllocZ() for allocations greater
55 * than RTMEM_ALIGNMENT.
56 *
57 * @note This alignment is not forced if the electric fence is active!
58 */
59#if defined(RT_OS_OS2)
60# define RTMEM_ALIGNMENT 4
61#else
62# define RTMEM_ALIGNMENT 8
63#endif
64
65/** @def RTMEM_TAG
66 * The default allocation tag used by the RTMem allocation APIs.
67 *
68 * When not defined before the inclusion of iprt/mem.h or iprt/memobj.h, this
69 * will default to the pointer to the current file name. The memory API will
70 * make of use of this as pointer to a volatile but read-only string.
71 * The alternative tag includes the line number for a more-detailed analysis.
72 */
73#ifndef RTMEM_TAG
74# if 0
75# define RTMEM_TAG (__FILE__ ":" RT_XSTR(__LINE__))
76# else
77# define RTMEM_TAG (__FILE__)
78# endif
79#endif
80
81
82/** @name Allocate temporary memory.
83 * @{ */
84/**
85 * Allocates temporary memory with default tag.
86 *
87 * Temporary memory blocks are used for not too large memory blocks which
88 * are believed not to stick around for too long. Using this API instead
89 * of RTMemAlloc() not only gives the heap manager room for optimization
90 * but makes the code easier to read.
91 *
92 * @returns Pointer to the allocated memory.
93 * @returns NULL on failure, assertion raised in strict builds.
94 * @param cb Size in bytes of the memory block to allocated.
95 */
96#define RTMemTmpAlloc(cb) RTMemTmpAllocTag((cb), RTMEM_TAG)
97
98/**
99 * Allocates temporary memory with custom tag.
100 *
101 * Temporary memory blocks are used for not too large memory blocks which
102 * are believed not to stick around for too long. Using this API instead
103 * of RTMemAlloc() not only gives the heap manager room for optimization
104 * but makes the code easier to read.
105 *
106 * @returns Pointer to the allocated memory.
107 * @returns NULL on failure, assertion raised in strict builds.
108 * @param cb Size in bytes of the memory block to allocated.
109 * @param pszTag Allocation tag used for statistics and such.
110 */
111RTDECL(void *) RTMemTmpAllocTag(size_t cb, const char *pszTag) RT_NO_THROW_PROTO;
112
113/**
114 * Allocates zero'd temporary memory with default tag.
115 *
116 * Same as RTMemTmpAlloc() but the memory will be zero'd.
117 *
118 * @returns Pointer to the allocated memory.
119 * @returns NULL on failure, assertion raised in strict builds.
120 * @param cb Size in bytes of the memory block to allocated.
121 */
122#define RTMemTmpAllocZ(cb) RTMemTmpAllocZTag((cb), RTMEM_TAG)
123
124/**
125 * Allocates zero'd temporary memory with custom tag.
126 *
127 * Same as RTMemTmpAlloc() but the memory will be zero'd.
128 *
129 * @returns Pointer to the allocated memory.
130 * @returns NULL on failure, assertion raised in strict builds.
131 * @param cb Size in bytes of the memory block to allocated.
132 * @param pszTag Allocation tag used for statistics and such.
133 */
134RTDECL(void *) RTMemTmpAllocZTag(size_t cb, const char *pszTag) RT_NO_THROW_PROTO;
135
136/**
137 * Free temporary memory.
138 *
139 * @param pv Pointer to memory block.
140 */
141RTDECL(void) RTMemTmpFree(void *pv) RT_NO_THROW_PROTO;
142
143/** @} */
144
145
146/**
147 * Allocates memory with default tag.
148 *
149 * @returns Pointer to the allocated memory.
150 * @returns NULL on failure, assertion raised in strict builds.
151 * @param cb Size in bytes of the memory block to allocated.
152 */
153#define RTMemAlloc(cb) RTMemAllocTag((cb), RTMEM_TAG)
154
155/**
156 * Allocates memory with custom tag.
157 *
158 * @returns Pointer to the allocated memory.
159 * @returns NULL on failure, assertion raised in strict builds.
160 * @param cb Size in bytes of the memory block to allocated.
161 * @param pszTag Allocation tag used for statistics and such.
162 */
163RTDECL(void *) RTMemAllocTag(size_t cb, const char *pszTag) RT_NO_THROW_PROTO;
164
165/**
166 * Allocates zero'd memory with default tag.
167 *
168 * Instead of memset(pv, 0, sizeof()) use this when you want zero'd
169 * memory. This keeps the code smaller and the heap can skip the memset
170 * in about 0.42% of calls :-).
171 *
172 * @returns Pointer to the allocated memory.
173 * @returns NULL on failure.
174 * @param cb Size in bytes of the memory block to allocated.
175 */
176#define RTMemAllocZ(cb) RTMemAllocZTag((cb), RTMEM_TAG)
177
178/**
179 * Allocates zero'd memory with custom tag.
180 *
181 * Instead of memset(pv, 0, sizeof()) use this when you want zero'd
182 * memory. This keeps the code smaller and the heap can skip the memset
183 * in about 0.42% of calls :-).
184 *
185 * @returns Pointer to the allocated memory.
186 * @returns NULL on failure.
187 * @param cb Size in bytes of the memory block to allocated.
188 * @param pszTag Allocation tag used for statistics and such.
189 */
190RTDECL(void *) RTMemAllocZTag(size_t cb, const char *pszTag) RT_NO_THROW_PROTO;
191
192/**
193 * Wrapper around RTMemAlloc for automatically aligning variable sized
194 * allocations so that the various electric fence heaps works correctly.
195 *
196 * @returns See RTMemAlloc.
197 * @param cbUnaligned The unaligned size.
198 */
199#define RTMemAllocVar(cbUnaligned) RTMemAllocVarTag((cbUnaligned), RTMEM_TAG)
200
201/**
202 * Wrapper around RTMemAllocTag for automatically aligning variable sized
203 * allocations so that the various electric fence heaps works correctly.
204 *
205 * @returns See RTMemAlloc.
206 * @param cbUnaligned The unaligned size.
207 * @param pszTag Allocation tag used for statistics and such.
208 */
209RTDECL(void *) RTMemAllocVarTag(size_t cbUnaligned, const char *pszTag) RT_NO_THROW_PROTO;
210
211/**
212 * Wrapper around RTMemAllocZ for automatically aligning variable sized
213 * allocations so that the various electric fence heaps works correctly.
214 *
215 * @returns See RTMemAllocZ.
216 * @param cbUnaligned The unaligned size.
217 */
218#define RTMemAllocZVar(cbUnaligned) RTMemAllocZVarTag((cbUnaligned), RTMEM_TAG)
219
220/**
221 * Wrapper around RTMemAllocZTag for automatically aligning variable sized
222 * allocations so that the various electric fence heaps works correctly.
223 *
224 * @returns See RTMemAllocZ.
225 * @param cbUnaligned The unaligned size.
226 * @param pszTag Allocation tag used for statistics and such.
227 */
228RTDECL(void *) RTMemAllocZVarTag(size_t cbUnaligned, const char *pszTag) RT_NO_THROW_PROTO;
229
230/**
231 * Duplicates a chunk of memory into a new heap block (default tag).
232 *
233 * @returns New heap block with the duplicate data.
234 * @returns NULL if we're out of memory.
235 * @param pvSrc The memory to duplicate.
236 * @param cb The amount of memory to duplicate.
237 */
238#define RTMemDup(pvSrc, cb) RTMemDupTag((pvSrc), (cb), RTMEM_TAG)
239
240/**
241 * Duplicates a chunk of memory into a new heap block (custom tag).
242 *
243 * @returns New heap block with the duplicate data.
244 * @returns NULL if we're out of memory.
245 * @param pvSrc The memory to duplicate.
246 * @param cb The amount of memory to duplicate.
247 * @param pszTag Allocation tag used for statistics and such.
248 */
249RTDECL(void *) RTMemDupTag(const void *pvSrc, size_t cb, const char *pszTag) RT_NO_THROW_PROTO;
250
251/**
252 * Duplicates a chunk of memory into a new heap block with some additional
253 * zeroed memory (default tag).
254 *
255 * @returns New heap block with the duplicate data.
256 * @returns NULL if we're out of memory.
257 * @param pvSrc The memory to duplicate.
258 * @param cbSrc The amount of memory to duplicate.
259 * @param cbExtra The amount of extra memory to allocate and zero.
260 */
261#define RTMemDupEx(pvSrc, cbSrc, cbExtra) RTMemDupExTag((pvSrc), (cbSrc), (cbExtra), RTMEM_TAG)
262
263/**
264 * Duplicates a chunk of memory into a new heap block with some additional
265 * zeroed memory (default tag).
266 *
267 * @returns New heap block with the duplicate data.
268 * @returns NULL if we're out of memory.
269 * @param pvSrc The memory to duplicate.
270 * @param cbSrc The amount of memory to duplicate.
271 * @param cbExtra The amount of extra memory to allocate and zero.
272 * @param pszTag Allocation tag used for statistics and such.
273 */
274RTDECL(void *) RTMemDupExTag(const void *pvSrc, size_t cbSrc, size_t cbExtra, const char *pszTag) RT_NO_THROW_PROTO;
275
276/**
277 * Reallocates memory with default tag.
278 *
279 * @returns Pointer to the allocated memory.
280 * @returns NULL on failure.
281 * @param pvOld The memory block to reallocate.
282 * @param cbNew The new block size (in bytes).
283 */
284#define RTMemRealloc(pvOld, cbNew) RTMemReallocTag((pvOld), (cbNew), RTMEM_TAG)
285
286/**
287 * Reallocates memory with custom tag.
288 *
289 * @returns Pointer to the allocated memory.
290 * @returns NULL on failure.
291 * @param pvOld The memory block to reallocate.
292 * @param cbNew The new block size (in bytes).
293 * @param pszTag Allocation tag used for statistics and such.
294 */
295RTDECL(void *) RTMemReallocTag(void *pvOld, size_t cbNew, const char *pszTag) RT_NO_THROW_PROTO;
296
297/**
298 * Frees memory.
299 *
300 * @param pv Pointer to memory block.
301 */
302RTDECL(void) RTMemFree(void *pv) RT_NO_THROW_PROTO;
303
304
305
306/** @name RTR0MemAllocEx and RTR0MemAllocExTag flags.
307 * @{ */
308/** The returned memory should be zeroed. */
309#define RTMEMALLOCEX_FLAGS_ZEROED RT_BIT(0)
310/** It must be load code into the returned memory block and execute it. */
311#define RTMEMALLOCEX_FLAGS_EXEC RT_BIT(1)
312/** Allocation from any context.
313 * Will return VERR_NOT_SUPPORTED if not supported. */
314#define RTMEMALLOCEX_FLAGS_ANY_CTX_ALLOC RT_BIT(2)
315/** Allocate the memory such that it can be freed from any context.
316 * Will return VERR_NOT_SUPPORTED if not supported. */
317#define RTMEMALLOCEX_FLAGS_ANY_CTX_FREE RT_BIT(3)
318/** Allocate and free from any context.
319 * Will return VERR_NOT_SUPPORTED if not supported. */
320#define RTMEMALLOCEX_FLAGS_ANY_CTX (RTMEMALLOCEX_FLAGS_ANY_CTX_ALLOC | RTMEMALLOCEX_FLAGS_ANY_CTX_FREE)
321/** Reachable by 16-bit address.
322 * Will return VERR_NOT_SUPPORTED if not supported. */
323#define RTMEMALLOCEX_FLAGS_16BIT_REACH RT_BIT(4)
324/** Reachable by 32-bit address.
325 * Will return VERR_NOT_SUPPORTED if not supported. */
326#define RTMEMALLOCEX_FLAGS_32BIT_REACH RT_BIT(5)
327/** Mask of valid flags. */
328#define RTMEMALLOCEX_FLAGS_VALID_MASK UINT32_C(0x0000003f)
329/** Mask of valid flags for ring-0. */
330#define RTMEMALLOCEX_FLAGS_VALID_MASK_R0 UINT32_C(0x0000000f)
331/** @} */
332
333/**
334 * Extended heap allocation API, default tag.
335 *
336 * @returns IPRT status code.
337 * @retval VERR_NO_MEMORY if we're out of memory.
338 * @retval VERR_NO_EXEC_MEMORY if we're out of executable memory.
339 * @retval VERR_NOT_SUPPORTED if any of the specified flags are unsupported.
340 *
341 * @param cb The amount of memory to allocate.
342 * @param cbAlignment The alignment requirements. Use 0 to indicate
343 * default alignment.
344 * @param fFlags A combination of the RTMEMALLOCEX_FLAGS_XXX
345 * defines.
346 * @param ppv Where to return the memory.
347 */
348#define RTMemAllocEx(cb, cbAlignment, fFlags, ppv) RTMemAllocExTag((cb), (cbAlignment), (fFlags), RTMEM_TAG, (ppv))
349
350/**
351 * Extended heap allocation API, custom tag.
352 *
353 * Depending on the implementation, using this function may add extra overhead,
354 * so use the simpler APIs where ever possible.
355 *
356 * @returns IPRT status code.
357 * @retval VERR_NO_MEMORY if we're out of memory.
358 * @retval VERR_NO_EXEC_MEMORY if we're out of executable memory.
359 * @retval VERR_NOT_SUPPORTED if any of the specified flags are unsupported.
360 *
361 * @param cb The amount of memory to allocate.
362 * @param cbAlignment The alignment requirements. Use 0 to indicate
363 * default alignment.
364 * @param fFlags A combination of the RTMEMALLOCEX_FLAGS_XXX
365 * defines.
366 * @param pszTag The tag.
367 * @param ppv Where to return the memory.
368 */
369RTDECL(int) RTMemAllocExTag(size_t cb, size_t cbAlignment, uint32_t fFlags, const char *pszTag, void **ppv) RT_NO_THROW_PROTO;
370
371/**
372 * For freeing memory allocated by RTMemAllocEx or RTMemAllocExTag.
373 *
374 * @param pv What to free, NULL is fine.
375 * @param cb The amount of allocated memory.
376 */
377RTDECL(void) RTMemFreeEx(void *pv, size_t cb) RT_NO_THROW_PROTO;
378
379
380
381/**
382 * Allocates memory which may contain code (default tag).
383 *
384 * @returns Pointer to the allocated memory.
385 * @returns NULL on failure.
386 * @param cb Size in bytes of the memory block to allocate.
387 */
388#define RTMemExecAlloc(cb) RTMemExecAllocTag((cb), RTMEM_TAG)
389
390/**
391 * Allocates memory which may contain code (custom tag).
392 *
393 * @returns Pointer to the allocated memory.
394 * @returns NULL on failure.
395 * @param cb Size in bytes of the memory block to allocate.
396 * @param pszTag Allocation tag used for statistics and such.
397 */
398RTDECL(void *) RTMemExecAllocTag(size_t cb, const char *pszTag) RT_NO_THROW_PROTO;
399
400/**
401 * Free executable/read/write memory allocated by RTMemExecAlloc().
402 *
403 * @param pv Pointer to memory block.
404 * @param cb The allocation size.
405 */
406RTDECL(void) RTMemExecFree(void *pv, size_t cb) RT_NO_THROW_PROTO;
407
408#if defined(IN_RING0) && defined(RT_ARCH_AMD64) && defined(RT_OS_LINUX)
409/**
410 * Donate read+write+execute memory to the exec heap.
411 *
412 * This API is specific to AMD64 and Linux/GNU. A kernel module that desires to
413 * use RTMemExecAlloc on AMD64 Linux/GNU will have to donate some statically
414 * allocated memory in the module if it wishes for GCC generated code to work.
415 * GCC can only generate modules that work in the address range ~2GB to ~0
416 * currently.
417 *
418 * The API only accept one single donation.
419 *
420 * @returns IPRT status code.
421 * @param pvMemory Pointer to the memory block.
422 * @param cb The size of the memory block.
423 */
424RTR0DECL(int) RTR0MemExecDonate(void *pvMemory, size_t cb) RT_NO_THROW_PROTO;
425#endif /* R0+AMD64+LINUX */
426
427/**
428 * Allocate page aligned memory with default tag.
429 *
430 * @returns Pointer to the allocated memory.
431 * @returns NULL if we're out of memory.
432 * @param cb Size of the memory block. Will be rounded up to page size.
433 */
434#define RTMemPageAlloc(cb) RTMemPageAllocTag((cb), RTMEM_TAG)
435
436/**
437 * Allocate page aligned memory with custom tag.
438 *
439 * @returns Pointer to the allocated memory.
440 * @returns NULL if we're out of memory.
441 * @param cb Size of the memory block. Will be rounded up to page size.
442 * @param pszTag Allocation tag used for statistics and such.
443 */
444RTDECL(void *) RTMemPageAllocTag(size_t cb, const char *pszTag) RT_NO_THROW_PROTO;
445
446/**
447 * Allocate zero'd page aligned memory with default tag.
448 *
449 * @returns Pointer to the allocated memory.
450 * @returns NULL if we're out of memory.
451 * @param cb Size of the memory block. Will be rounded up to page size.
452 */
453#define RTMemPageAllocZ(cb) RTMemPageAllocZTag((cb), RTMEM_TAG)
454
455/**
456 * Allocate zero'd page aligned memory with custom tag.
457 *
458 * @returns Pointer to the allocated memory.
459 * @returns NULL if we're out of memory.
460 * @param cb Size of the memory block. Will be rounded up to page size.
461 * @param pszTag Allocation tag used for statistics and such.
462 */
463RTDECL(void *) RTMemPageAllocZTag(size_t cb, const char *pszTag) RT_NO_THROW_PROTO;
464
465/**
466 * Allocate page aligned memory with default tag, extended version.
467 *
468 * @returns Pointer to the allocated memory.
469 * @returns NULL if we're out of memory.
470 * @param cb Size of the memory block. Will be rounded up to page size.
471 * @param fFlags RTMEMPAGEALLOC_F_XXX.
472 */
473#define RTMemPageAllocEx(cb, fFlags) RTMemPageAllocExTag((cb), (fFlags), RTMEM_TAG)
474
475/**
476 * Allocate page aligned memory with custom tag, extended version.
477 *
478 * @returns Pointer to the allocated memory.
479 * @returns NULL if we're out of memory.
480 * @param cb Size of the memory block. Will be rounded up to page size.
481 * @param fFlags RTMEMPAGEALLOC_F_XXX.
482 * @param pszTag Allocation tag used for statistics and such.
483 */
484RTDECL(void *) RTMemPageAllocExTag(size_t cb, uint32_t fFlags, const char *pszTag) RT_NO_THROW_PROTO;
485
486/** @name RTMEMPAGEALLOC_F_XXX - flags for RTMemPageAllocEx() and RTMemPageAllocExTag()
487 * @{ */
488/** Zero the allocation. */
489#define RTMEMPAGEALLOC_F_ZERO RT_BIT_32(0)
490/** Try lock the allocation (failure ignored). */
491#define RTMEMPAGEALLOC_F_ADVISE_LOCKED RT_BIT_32(1)
492/** Try prevent the memory from ending up in a dump/core. */
493#define RTMEMPAGEALLOC_F_ADVISE_NO_DUMP RT_BIT_32(2)
494/** Valid bit mask. */
495#define RTMEMPAGEALLOC_F_VALID_MASK UINT32_C(0x00000007)
496/** @} */
497
498/**
499 * Free a memory block allocated with RTMemPageAlloc() or RTMemPageAllocZ().
500 *
501 * @param pv Pointer to the block as it was returned by the allocation function.
502 * NULL will be ignored.
503 * @param cb The allocation size. Will be rounded up to page size.
504 * Ignored if @a pv is NULL.
505 */
506RTDECL(void) RTMemPageFree(void *pv, size_t cb) RT_NO_THROW_PROTO;
507
508/** Page level protection flags for RTMemProtect().
509 * @{
510 */
511/** No access at all. */
512#define RTMEM_PROT_NONE 0
513/** Read access. */
514#define RTMEM_PROT_READ 1
515/** Write access. */
516#define RTMEM_PROT_WRITE 2
517/** Execute access. */
518#define RTMEM_PROT_EXEC 4
519/** @} */
520
521/**
522 * Change the page level protection of a memory region.
523 *
524 * @returns iprt status code.
525 * @param pv Start of the region. Will be rounded down to nearest page boundary.
526 * @param cb Size of the region. Will be rounded up to the nearest page boundary.
527 * @param fProtect The new protection, a combination of the RTMEM_PROT_* defines.
528 */
529RTDECL(int) RTMemProtect(void *pv, size_t cb, unsigned fProtect) RT_NO_THROW_PROTO;
530
531/**
532 * Goes thru some pains to make sure the specified memory block is thoroughly
533 * scrambled.
534 *
535 * @param pv The start of the memory block.
536 * @param cb The size of the memory block.
537 * @param cMinPasses The minimum number of passes to make.
538 */
539RTDECL(void) RTMemWipeThoroughly(void *pv, size_t cb, size_t cMinPasses) RT_NO_THROW_PROTO;
540
541
542/** @def RTMEM_WILL_LEAK
543 * Macro for hinting that a memory allocation @a a_pv will leak.
544 *
545 * @note This shall only be used in code that doesn't allocate the object.
546 * Code allocating memory knowing it will leak shall start the allocation
547 * tag string with 'will-leak:'.
548 */
549/** @def RTMEM_MAY_LEAK
550 * Macro for hinting that a memory allocation @a a_pv may leak.
551 *
552 * @note This shall only be used in code that doesn't allocate the object.
553 * Code allocating memory knowing it may leak shall start the allocation
554 * tag string with 'may-leak:'.
555 */
556#ifdef IPRT_WITH_GCC_SANITIZER
557# define RTMEM_WILL_LEAK(a_pv) __lsan_ignore_object(a_pv)
558# define RTMEM_MAY_LEAK(a_pv) __lsan_ignore_object(a_pv)
559#else
560# define RTMEM_WILL_LEAK(a_pv) do { } while (0)
561# define RTMEM_MAY_LEAK(a_pv) do { } while (0)
562#endif
563
564
565#ifdef IN_RING0
566
567/**
568 * Allocates physical contiguous memory (below 4GB).
569 * The allocation is page aligned and the content is undefined.
570 *
571 * @returns Pointer to the memory block. This is page aligned.
572 * @param pPhys Where to store the physical address.
573 * @param cb The allocation size in bytes. This is always
574 * rounded up to PAGE_SIZE.
575 */
576RTR0DECL(void *) RTMemContAlloc(PRTCCPHYS pPhys, size_t cb) RT_NO_THROW_PROTO;
577
578/**
579 * Frees memory allocated ysing RTMemContAlloc().
580 *
581 * @param pv Pointer to return from RTMemContAlloc().
582 * @param cb The cb parameter passed to RTMemContAlloc().
583 */
584RTR0DECL(void) RTMemContFree(void *pv, size_t cb) RT_NO_THROW_PROTO;
585
586/**
587 * Copy memory from an user mode buffer into a kernel buffer.
588 *
589 * @retval VINF_SUCCESS on success.
590 * @retval VERR_ACCESS_DENIED on error.
591 *
592 * @param pvDst The kernel mode destination address.
593 * @param R3PtrSrc The user mode source address.
594 * @param cb The number of bytes to copy.
595 */
596RTR0DECL(int) RTR0MemUserCopyFrom(void *pvDst, RTR3PTR R3PtrSrc, size_t cb);
597
598/**
599 * Copy memory from a kernel buffer into a user mode one.
600 *
601 * @retval VINF_SUCCESS on success.
602 * @retval VERR_ACCESS_DENIED on error.
603 *
604 * @param R3PtrDst The user mode destination address.
605 * @param pvSrc The kernel mode source address.
606 * @param cb The number of bytes to copy.
607 */
608RTR0DECL(int) RTR0MemUserCopyTo(RTR3PTR R3PtrDst, void const *pvSrc, size_t cb);
609
610/**
611 * Tests if the specified address is in the user addressable range.
612 *
613 * This function does not check whether the memory at that address is accessible
614 * or anything of that sort, only if the address it self is in the user mode
615 * range.
616 *
617 * @returns true if it's in the user addressable range. false if not.
618 * @param R3Ptr The user mode pointer to test.
619 *
620 * @remarks Some systems may have overlapping kernel and user address ranges.
621 * One prominent example of this is the x86 version of Mac OS X. Use
622 * RTR0MemAreKrnlAndUsrDifferent() to check.
623 */
624RTR0DECL(bool) RTR0MemUserIsValidAddr(RTR3PTR R3Ptr);
625
626/**
627 * Tests if the specified address is in the kernel mode range.
628 *
629 * This function does not check whether the memory at that address is accessible
630 * or anything of that sort, only if the address it self is in the kernel mode
631 * range.
632 *
633 * @returns true if it's in the kernel range. false if not.
634 * @param pv The alleged kernel mode pointer.
635 *
636 * @remarks Some systems may have overlapping kernel and user address ranges.
637 * One prominent example of this is the x86 version of Mac OS X. Use
638 * RTR0MemAreKrnlAndUsrDifferent() to check.
639 */
640RTR0DECL(bool) RTR0MemKernelIsValidAddr(void *pv);
641
642/**
643 * Are user mode and kernel mode address ranges distinctly different.
644 *
645 * This determines whether RTR0MemKernelIsValidAddr and RTR0MemUserIsValidAddr
646 * can be used for deciding whether some arbitrary address is a user mode or a
647 * kernel mode one.
648 *
649 * @returns true if they are, false if not.
650 */
651RTR0DECL(bool) RTR0MemAreKrnlAndUsrDifferent(void);
652
653/**
654 * Copy memory from an potentially unsafe kernel mode location and into a safe
655 * (kernel) buffer.
656 *
657 * @retval VINF_SUCCESS on success.
658 * @retval VERR_ACCESS_DENIED on error.
659 * @retval VERR_NOT_SUPPORTED if not (yet) supported.
660 *
661 * @param pvDst The destination address (safe).
662 * @param pvSrc The source address (potentially unsafe).
663 * @param cb The number of bytes to copy.
664 */
665RTR0DECL(int) RTR0MemKernelCopyFrom(void *pvDst, void const *pvSrc, size_t cb);
666
667/**
668 * Copy from a safe (kernel) buffer and to a potentially unsafe kenrel mode
669 * location.
670 *
671 * @retval VINF_SUCCESS on success.
672 * @retval VERR_ACCESS_DENIED on error.
673 * @retval VERR_NOT_SUPPORTED if not (yet) supported.
674 *
675 * @param pvDst The destination address (potentially unsafe).
676 * @param pvSrc The source address (safe).
677 * @param cb The number of bytes to copy.
678 */
679RTR0DECL(int) RTR0MemKernelCopyTo(void *pvDst, void const *pvSrc, size_t cb);
680
681#endif /* IN_RING0 */
682
683
684/** @name Electrical Fence Version of some APIs.
685 * @{
686 */
687
688/**
689 * Same as RTMemTmpAllocTag() except that it's fenced.
690 *
691 * @returns Pointer to the allocated memory.
692 * @returns NULL on failure.
693 * @param cb Size in bytes of the memory block to allocate.
694 * @param pszTag Allocation tag used for statistics and such.
695 * @param SRC_POS The source position where call is being made from.
696 * Use RT_SRC_POS when possible. Optional.
697 */
698RTDECL(void *) RTMemEfTmpAlloc(size_t cb, const char *pszTag, RT_SRC_POS_DECL) RT_NO_THROW_PROTO;
699
700/**
701 * Same as RTMemTmpAllocZTag() except that it's fenced.
702 *
703 * @returns Pointer to the allocated memory.
704 * @returns NULL on failure.
705 * @param cb Size in bytes of the memory block to allocate.
706 * @param pszTag Allocation tag used for statistics and such.
707 * @param SRC_POS The source position where call is being made from. Use
708 * RT_SRC_POS when possible. Optional.
709 */
710RTDECL(void *) RTMemEfTmpAllocZ(size_t cb, const char *pszTag, RT_SRC_POS_DECL) RT_NO_THROW_PROTO;
711
712/**
713 * Same as RTMemTmpFree() except that it's for fenced memory.
714 *
715 * @param pv Pointer to memory block.
716 * @param SRC_POS The source position where call is being made from. Use
717 * RT_SRC_POS when possible. Optional.
718 */
719RTDECL(void) RTMemEfTmpFree(void *pv, RT_SRC_POS_DECL) RT_NO_THROW_PROTO;
720
721/**
722 * Same as RTMemAllocTag() except that it's fenced.
723 *
724 * @returns Pointer to the allocated memory. Free with RTMemEfFree().
725 * @returns NULL on failure.
726 * @param cb Size in bytes of the memory block to allocate.
727 * @param pszTag Allocation tag used for statistics and such.
728 * @param SRC_POS The source position where call is being made from. Use
729 * RT_SRC_POS when possible. Optional.
730 */
731RTDECL(void *) RTMemEfAlloc(size_t cb, const char *pszTag, RT_SRC_POS_DECL) RT_NO_THROW_PROTO;
732
733/**
734 * Same as RTMemAllocZTag() except that it's fenced.
735 *
736 * @returns Pointer to the allocated memory.
737 * @returns NULL on failure.
738 * @param cb Size in bytes of the memory block to allocate.
739 * @param pszTag Allocation tag used for statistics and such.
740 * @param SRC_POS The source position where call is being made from. Use
741 * RT_SRC_POS when possible. Optional.
742 */
743RTDECL(void *) RTMemEfAllocZ(size_t cb, const char *pszTag, RT_SRC_POS_DECL) RT_NO_THROW_PROTO;
744
745/**
746 * Same as RTMemAllocVarTag() except that it's fenced.
747 *
748 * @returns Pointer to the allocated memory. Free with RTMemEfFree().
749 * @returns NULL on failure.
750 * @param cbUnaligned Size in bytes of the memory block to allocate.
751 * @param pszTag Allocation tag used for statistics and such.
752 * @param SRC_POS The source position where call is being made from. Use
753 * RT_SRC_POS when possible. Optional.
754 */
755RTDECL(void *) RTMemEfAllocVar(size_t cbUnaligned, const char *pszTag, RT_SRC_POS_DECL) RT_NO_THROW_PROTO;
756
757/**
758 * Same as RTMemAllocZVarTag() except that it's fenced.
759 *
760 * @returns Pointer to the allocated memory.
761 * @returns NULL on failure.
762 * @param cbUnaligned Size in bytes of the memory block to allocate.
763 * @param pszTag Allocation tag used for statistics and such.
764 * @param SRC_POS The source position where call is being made from. Use
765 * RT_SRC_POS when possible. Optional.
766 */
767RTDECL(void *) RTMemEfAllocZVar(size_t cbUnaligned, const char *pszTag, RT_SRC_POS_DECL) RT_NO_THROW_PROTO;
768
769/**
770 * Same as RTMemReallocTag() except that it's fenced.
771 *
772 * @returns Pointer to the allocated memory.
773 * @returns NULL on failure.
774 * @param pvOld The memory block to reallocate.
775 * @param cbNew The new block size (in bytes).
776 * @param pszTag Allocation tag used for statistics and such.
777 * @param SRC_POS The source position where call is being made from. Use
778 * RT_SRC_POS when possible. Optional.
779 */
780RTDECL(void *) RTMemEfRealloc(void *pvOld, size_t cbNew, const char *pszTag, RT_SRC_POS_DECL) RT_NO_THROW_PROTO;
781
782/**
783 * Free memory allocated by any of the RTMemEf* allocators.
784 *
785 * @param pv Pointer to memory block.
786 * @param SRC_POS The source position where call is being made from. Use
787 * RT_SRC_POS when possible. Optional.
788 */
789RTDECL(void) RTMemEfFree(void *pv, RT_SRC_POS_DECL) RT_NO_THROW_PROTO;
790
791/**
792 * Same as RTMemDupTag() except that it's fenced.
793 *
794 * @returns New heap block with the duplicate data.
795 * @returns NULL if we're out of memory.
796 * @param pvSrc The memory to duplicate.
797 * @param cb The amount of memory to duplicate.
798 * @param pszTag Allocation tag used for statistics and such.
799 * @param SRC_POS The source position where call is being made from. Use
800 * RT_SRC_POS when possible. Optional.
801 */
802RTDECL(void *) RTMemEfDup(const void *pvSrc, size_t cb, const char *pszTag, RT_SRC_POS_DECL) RT_NO_THROW_PROTO;
803
804/**
805 * Same as RTMemEfDupExTag except that it's fenced.
806 *
807 * @returns New heap block with the duplicate data.
808 * @returns NULL if we're out of memory.
809 * @param pvSrc The memory to duplicate.
810 * @param cbSrc The amount of memory to duplicate.
811 * @param cbExtra The amount of extra memory to allocate and zero.
812 * @param pszTag Allocation tag used for statistics and such.
813 * @param SRC_POS The source position where call is being made from. Use
814 * RT_SRC_POS when possible. Optional.
815 */
816RTDECL(void *) RTMemEfDupEx(const void *pvSrc, size_t cbSrc, size_t cbExtra, const char *pszTag, RT_SRC_POS_DECL) RT_NO_THROW_PROTO;
817
818/** @def RTMEM_WRAP_SOME_NEW_AND_DELETE_TO_EF
819 * Define RTMEM_WRAP_SOME_NEW_AND_DELETE_TO_EF to enable electric fence new and
820 * delete operators for classes which uses the RTMEMEF_NEW_AND_DELETE_OPERATORS
821 * macro.
822 */
823/** @def RTMEMEF_NEW_AND_DELETE_OPERATORS
824 * Defines the electric fence new and delete operators for a class when
825 * RTMEM_WRAP_SOME_NEW_AND_DELETE_TO_EF is define.
826 */
827/** @def RTR0MEMEF_NEW_AND_DELETE_OPERATORS_IOKIT
828 * Defines the electric fence new and delete operators for an IOKit class when
829 * RTMEM_WRAP_SOME_NEW_AND_DELETE_TO_EF is define.
830 *
831 * This differs from RTMEMEF_NEW_AND_DELETE_OPERATORS in that the memory we
832 * allocate is initialized to zero. It is also assuming we don't have nothrow
833 * variants and exceptions, so fewer variations.
834 */
835#if defined(RTMEM_WRAP_SOME_NEW_AND_DELETE_TO_EF) && !defined(RTMEM_NO_WRAP_SOME_NEW_AND_DELETE_TO_EF)
836# if defined(RT_EXCEPTIONS_ENABLED)
837# define RTMEMEF_NEW_AND_DELETE_OPERATORS() \
838 void *operator new(size_t cb) RT_THROW(std::bad_alloc) \
839 { \
840 void *pv = RTMemEfAlloc(cb, RTMEM_TAG, RT_SRC_POS); \
841 if (RT_LIKELY(pv)) \
842 return pv; \
843 throw std::bad_alloc(); \
844 } \
845 void *operator new(size_t cb, const std::nothrow_t &nothrow_constant) RT_NO_THROW_DEF \
846 { \
847 NOREF(nothrow_constant); \
848 return RTMemEfAlloc(cb, RTMEM_TAG, RT_SRC_POS); \
849 } \
850 void *operator new[](size_t cb) RT_THROW(std::bad_alloc) \
851 { \
852 void *pv = RTMemEfAlloc(cb, RTMEM_TAG, RT_SRC_POS); \
853 if (RT_LIKELY(pv)) \
854 return pv; \
855 throw std::bad_alloc(); \
856 } \
857 void *operator new[](size_t cb, const std::nothrow_t &nothrow_constant) RT_NO_THROW_DEF \
858 { \
859 NOREF(nothrow_constant); \
860 return RTMemEfAlloc(cb, RTMEM_TAG, RT_SRC_POS); \
861 } \
862 \
863 void operator delete(void *pv) RT_NO_THROW_DEF \
864 { \
865 RTMemEfFree(pv, RT_SRC_POS); \
866 } \
867 void operator delete(void *pv, const std::nothrow_t &nothrow_constant) RT_NO_THROW_DEF \
868 { \
869 NOREF(nothrow_constant); \
870 RTMemEfFree(pv, RT_SRC_POS); \
871 } \
872 void operator delete[](void *pv) RT_NO_THROW_DEF \
873 { \
874 RTMemEfFree(pv, RT_SRC_POS); \
875 } \
876 void operator delete[](void *pv, const std::nothrow_t &nothrow_constant) RT_NO_THROW_DEF \
877 { \
878 NOREF(nothrow_constant); \
879 RTMemEfFree(pv, RT_SRC_POS); \
880 } \
881 \
882 typedef int UsingElectricNewAndDeleteOperators
883# else
884# define RTMEMEF_NEW_AND_DELETE_OPERATORS() \
885 void *operator new(size_t cb) \
886 { \
887 return RTMemEfAlloc(cb, RTMEM_TAG, RT_SRC_POS); \
888 } \
889 void *operator new(size_t cb, const std::nothrow_t &nothrow_constant) \
890 { \
891 NOREF(nothrow_constant); \
892 return RTMemEfAlloc(cb, RTMEM_TAG, RT_SRC_POS); \
893 } \
894 void *operator new[](size_t cb) \
895 { \
896 return RTMemEfAlloc(cb, RTMEM_TAG, RT_SRC_POS); \
897 } \
898 void *operator new[](size_t cb, const std::nothrow_t &nothrow_constant) \
899 { \
900 NOREF(nothrow_constant); \
901 return RTMemEfAlloc(cb, RTMEM_TAG, RT_SRC_POS); \
902 } \
903 \
904 void operator delete(void *pv) \
905 { \
906 RTMemEfFree(pv, RT_SRC_POS); \
907 } \
908 void operator delete(void *pv, const std::nothrow_t &nothrow_constant) \
909 { \
910 NOREF(nothrow_constant); \
911 RTMemEfFree(pv, RT_SRC_POS); \
912 } \
913 void operator delete[](void *pv) \
914 { \
915 RTMemEfFree(pv, RT_SRC_POS); \
916 } \
917 void operator delete[](void *pv, const std::nothrow_t &nothrow_constant) \
918 { \
919 NOREF(nothrow_constant); \
920 RTMemEfFree(pv, RT_SRC_POS); \
921 } \
922 \
923 typedef int UsingElectricNewAndDeleteOperators
924# endif
925# define RTR0MEMEF_NEW_AND_DELETE_OPERATORS_IOKIT() \
926 void *operator new(size_t cb) \
927 { \
928 return RTMemEfAllocZ(cb, RTMEM_TAG, RT_SRC_POS); \
929 } \
930 void *operator new[](size_t cb) \
931 { \
932 return RTMemEfAllocZ(cb, RTMEM_TAG, RT_SRC_POS); \
933 } \
934 \
935 void operator delete(void *pv) \
936 { \
937 RTMemEfFree(pv, RT_SRC_POS); \
938 } \
939 void operator delete[](void *pv) \
940 { \
941 RTMemEfFree(pv, RT_SRC_POS); \
942 } \
943 \
944 typedef int UsingElectricNewAndDeleteOperators
945#else
946# define RTMEMEF_NEW_AND_DELETE_OPERATORS() \
947 typedef int UsingDefaultNewAndDeleteOperators
948# define RTR0MEMEF_NEW_AND_DELETE_OPERATORS_IOKIT() \
949 typedef int UsingDefaultNewAndDeleteOperators
950#endif
951#ifdef DOXYGEN_RUNNING
952# define RTMEM_WRAP_SOME_NEW_AND_DELETE_TO_EF
953#endif
954
955/** @def RTMEM_WRAP_TO_EF_APIS
956 * Define RTMEM_WRAP_TO_EF_APIS to wrap RTMem APIs to RTMemEf APIs.
957 */
958#if defined(RTMEM_WRAP_TO_EF_APIS) && !defined(RTMEM_NO_WRAP_TO_EF_APIS) \
959 && ( defined(IN_RING3) || ( defined(IN_RING0) && !defined(IN_RING0_AGNOSTIC) && (defined(RT_OS_DARWIN) || 0) ) )
960# define RTMemTmpAllocTag(cb, pszTag) RTMemEfTmpAlloc((cb), (pszTag), RT_SRC_POS)
961# define RTMemTmpAllocZTag(cb, pszTag) RTMemEfTmpAllocZ((cb), (pszTag), RT_SRC_POS)
962# define RTMemTmpFree(pv) RTMemEfTmpFree((pv), RT_SRC_POS)
963# define RTMemAllocTag(cb, pszTag) RTMemEfAlloc((cb), (pszTag), RT_SRC_POS)
964# define RTMemAllocZTag(cb, pszTag) RTMemEfAllocZ((cb), (pszTag), RT_SRC_POS)
965# define RTMemAllocVarTag(cbUnaligned, pszTag) RTMemEfAllocVar((cbUnaligned), (pszTag), RT_SRC_POS)
966# define RTMemAllocZVarTag(cbUnaligned, pszTag) RTMemEfAllocZVar((cbUnaligned), (pszTag), RT_SRC_POS)
967# define RTMemReallocTag(pvOld, cbNew, pszTag) RTMemEfRealloc((pvOld), (cbNew), (pszTag), RT_SRC_POS)
968# define RTMemFree(pv) RTMemEfFree((pv), RT_SRC_POS)
969# define RTMemDupTag(pvSrc, cb, pszTag) RTMemEfDup((pvSrc), (cb), (pszTag), RT_SRC_POS)
970# define RTMemDupExTag(pvSrc, cbSrc, cbExtra, pszTag) RTMemEfDupEx((pvSrc), (cbSrc), (cbExtra), (pszTag), RT_SRC_POS)
971#endif
972#ifdef DOXYGEN_RUNNING
973# define RTMEM_WRAP_TO_EF_APIS
974#endif
975
976/**
977 * Fenced drop-in replacement for RTMemTmpAllocTag.
978 * @copydoc RTMemTmpAllocTag
979 */
980RTDECL(void *) RTMemEfTmpAllocNP(size_t cb, const char *pszTag) RT_NO_THROW_PROTO;
981
982/**
983 * Fenced drop-in replacement for RTMemTmpAllocZTag.
984 * @copydoc RTMemTmpAllocZTag
985 */
986RTDECL(void *) RTMemEfTmpAllocZNP(size_t cb, const char *pszTag) RT_NO_THROW_PROTO;
987
988/**
989 * Fenced drop-in replacement for RTMemTmpFreeTag.
990 * @copydoc RTMemTmpFree
991 */
992RTDECL(void) RTMemEfTmpFreeNP(void *pv) RT_NO_THROW_PROTO;
993
994/**
995 * Fenced drop-in replacement for RTMemAllocTag.
996 * @copydoc RTMemAllocTag
997 */
998RTDECL(void *) RTMemEfAllocNP(size_t cb, const char *pszTag) RT_NO_THROW_PROTO;
999
1000/**
1001 * Fenced drop-in replacement for RTMemAllocZTag.
1002 * @copydoc RTMemAllocZTag
1003 */
1004RTDECL(void *) RTMemEfAllocZNP(size_t cb, const char *pszTag) RT_NO_THROW_PROTO;
1005
1006/**
1007 * Fenced drop-in replacement for RTMemAllocVarTag
1008 * @copydoc RTMemAllocVarTag
1009 */
1010RTDECL(void *) RTMemEfAllocVarNP(size_t cbUnaligned, const char *pszTag) RT_NO_THROW_PROTO;
1011
1012/**
1013 * Fenced drop-in replacement for RTMemAllocZVarTag.
1014 * @copydoc RTMemAllocZVarTag
1015 */
1016RTDECL(void *) RTMemEfAllocZVarNP(size_t cbUnaligned, const char *pszTag) RT_NO_THROW_PROTO;
1017
1018/**
1019 * Fenced drop-in replacement for RTMemReallocTag.
1020 * @copydoc RTMemReallocTag
1021 */
1022RTDECL(void *) RTMemEfReallocNP(void *pvOld, size_t cbNew, const char *pszTag) RT_NO_THROW_PROTO;
1023
1024/**
1025 * Fenced drop-in replacement for RTMemFree.
1026 * @copydoc RTMemFree
1027 */
1028RTDECL(void) RTMemEfFreeNP(void *pv) RT_NO_THROW_PROTO;
1029
1030/**
1031 * Fenced drop-in replacement for RTMemDupExTag.
1032 * @copydoc RTMemDupTag
1033 */
1034RTDECL(void *) RTMemEfDupNP(const void *pvSrc, size_t cb, const char *pszTag) RT_NO_THROW_PROTO;
1035
1036/**
1037 * Fenced drop-in replacement for RTMemDupExTag.
1038 * @copydoc RTMemDupExTag
1039 */
1040RTDECL(void *) RTMemEfDupExNP(const void *pvSrc, size_t cbSrc, size_t cbExtra, const char *pszTag) RT_NO_THROW_PROTO;
1041
1042/** @} */
1043
1044RT_C_DECLS_END
1045
1046/** @} */
1047
1048
1049#endif /* !IPRT_INCLUDED_mem_h */
1050
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