VirtualBox

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

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

iprt/mem.h: Added RTMEM_WILL_LEAK and RTMEM_MAY_LEAK macros for marking memory as leaked on higher levels. Made VBOX_GCC_SANITIZER_FLAGS define an IPRT friendly indicator, is VBOX_XXXX is still stricly forbidden in Runtime/.

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