VirtualBox

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

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

*: scm --fix-header-guard-endif

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