[1] | 1 | /* $Id: alloc-r0drv.cpp 98103 2023-01-17 14:15:46Z vboxsync $ */
|
---|
| 2 | /** @file
|
---|
[8245] | 3 | * IPRT - Memory Allocation, Ring-0 Driver.
|
---|
[1] | 4 | */
|
---|
| 5 |
|
---|
| 6 | /*
|
---|
[98103] | 7 | * Copyright (C) 2006-2023 Oracle and/or its affiliates.
|
---|
[1] | 8 | *
|
---|
[96407] | 9 | * This file is part of VirtualBox base platform packages, as
|
---|
| 10 | * available from https://www.virtualbox.org.
|
---|
[5999] | 11 | *
|
---|
[96407] | 12 | * This program is free software; you can redistribute it and/or
|
---|
| 13 | * modify it under the terms of the GNU General Public License
|
---|
| 14 | * as published by the Free Software Foundation, in version 3 of the
|
---|
| 15 | * License.
|
---|
| 16 | *
|
---|
| 17 | * This program is distributed in the hope that it will be useful, but
|
---|
| 18 | * WITHOUT ANY WARRANTY; without even the implied warranty of
|
---|
| 19 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
---|
| 20 | * General Public License for more details.
|
---|
| 21 | *
|
---|
| 22 | * You should have received a copy of the GNU General Public License
|
---|
| 23 | * along with this program; if not, see <https://www.gnu.org/licenses>.
|
---|
| 24 | *
|
---|
[5999] | 25 | * The contents of this file may alternatively be used under the terms
|
---|
| 26 | * of the Common Development and Distribution License Version 1.0
|
---|
[96407] | 27 | * (CDDL), a copy of it is provided in the "COPYING.CDDL" file included
|
---|
| 28 | * in the VirtualBox distribution, in which case the provisions of the
|
---|
[5999] | 29 | * CDDL are applicable instead of those of the GPL.
|
---|
| 30 | *
|
---|
| 31 | * You may elect to license modified versions of this file under the
|
---|
| 32 | * terms and conditions of either the GPL or the CDDL or both.
|
---|
[96407] | 33 | *
|
---|
| 34 | * SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0
|
---|
[1] | 35 | */
|
---|
| 36 |
|
---|
| 37 |
|
---|
[57358] | 38 | /*********************************************************************************************************************************
|
---|
| 39 | * Header Files *
|
---|
| 40 | *********************************************************************************************************************************/
|
---|
[36190] | 41 | #define RTMEM_NO_WRAP_TO_EF_APIS
|
---|
[21337] | 42 | #include <iprt/mem.h>
|
---|
| 43 | #include "internal/iprt.h"
|
---|
| 44 |
|
---|
[29250] | 45 | #if defined(RT_ARCH_AMD64) || defined(RT_ARCH_X86)
|
---|
| 46 | # include <iprt/asm-amd64-x86.h>
|
---|
| 47 | #endif
|
---|
[1] | 48 | #include <iprt/assert.h>
|
---|
[76346] | 49 | #include <iprt/err.h>
|
---|
[32707] | 50 | #ifdef RT_MORE_STRICT
|
---|
| 51 | # include <iprt/mp.h>
|
---|
| 52 | #endif
|
---|
[1] | 53 | #include <iprt/param.h>
|
---|
[22052] | 54 | #include <iprt/string.h>
|
---|
| 55 | #include <iprt/thread.h>
|
---|
[1] | 56 | #include "r0drv/alloc-r0drv.h"
|
---|
| 57 |
|
---|
| 58 |
|
---|
[57358] | 59 | /*********************************************************************************************************************************
|
---|
| 60 | * Defined Constants And Macros *
|
---|
| 61 | *********************************************************************************************************************************/
|
---|
[7042] | 62 | #ifdef RT_STRICT
|
---|
| 63 | # define RTR0MEM_STRICT
|
---|
| 64 | #endif
|
---|
| 65 |
|
---|
| 66 | #ifdef RTR0MEM_STRICT
|
---|
| 67 | # define RTR0MEM_FENCE_EXTRA 16
|
---|
| 68 | #else
|
---|
| 69 | # define RTR0MEM_FENCE_EXTRA 0
|
---|
| 70 | #endif
|
---|
| 71 |
|
---|
| 72 |
|
---|
[57358] | 73 | /*********************************************************************************************************************************
|
---|
| 74 | * Global Variables *
|
---|
| 75 | *********************************************************************************************************************************/
|
---|
[32707] | 76 | #ifdef RTR0MEM_STRICT
|
---|
| 77 | /** Fence data. */
|
---|
| 78 | static uint8_t const g_abFence[RTR0MEM_FENCE_EXTRA] =
|
---|
| 79 | {
|
---|
| 80 | 0x77, 0x88, 0x66, 0x99, 0x55, 0xaa, 0x44, 0xbb,
|
---|
| 81 | 0x33, 0xcc, 0x22, 0xdd, 0x11, 0xee, 0x00, 0xff
|
---|
| 82 | };
|
---|
| 83 | #endif
|
---|
[31157] | 84 |
|
---|
[32707] | 85 |
|
---|
| 86 | /**
|
---|
| 87 | * Wrapper around rtR0MemAllocEx.
|
---|
| 88 | *
|
---|
| 89 | * @returns Pointer to the allocated memory block header.
|
---|
| 90 | * @param cb The number of bytes to allocate (sans header).
|
---|
| 91 | * @param fFlags The allocation flags.
|
---|
| 92 | */
|
---|
| 93 | DECLINLINE(PRTMEMHDR) rtR0MemAlloc(size_t cb, uint32_t fFlags)
|
---|
| 94 | {
|
---|
| 95 | PRTMEMHDR pHdr;
|
---|
| 96 | int rc = rtR0MemAllocEx(cb, fFlags, &pHdr);
|
---|
| 97 | if (RT_FAILURE(rc))
|
---|
[40938] | 98 | return NULL;
|
---|
[32707] | 99 | return pHdr;
|
---|
| 100 | }
|
---|
| 101 |
|
---|
| 102 |
|
---|
[57432] | 103 | RTDECL(void *) RTMemTmpAllocTag(size_t cb, const char *pszTag) RT_NO_THROW_DEF
|
---|
[1] | 104 | {
|
---|
[31157] | 105 | return RTMemAllocTag(cb, pszTag);
|
---|
[1] | 106 | }
|
---|
[31157] | 107 | RT_EXPORT_SYMBOL(RTMemTmpAllocTag);
|
---|
[1] | 108 |
|
---|
| 109 |
|
---|
[57432] | 110 | RTDECL(void *) RTMemTmpAllocZTag(size_t cb, const char *pszTag) RT_NO_THROW_DEF
|
---|
[1] | 111 | {
|
---|
[31157] | 112 | return RTMemAllocZTag(cb, pszTag);
|
---|
[1] | 113 | }
|
---|
[31157] | 114 | RT_EXPORT_SYMBOL(RTMemTmpAllocZTag);
|
---|
[1] | 115 |
|
---|
| 116 |
|
---|
[57432] | 117 | RTDECL(void) RTMemTmpFree(void *pv) RT_NO_THROW_DEF
|
---|
[1] | 118 | {
|
---|
| 119 | return RTMemFree(pv);
|
---|
| 120 | }
|
---|
[21337] | 121 | RT_EXPORT_SYMBOL(RTMemTmpFree);
|
---|
[1] | 122 |
|
---|
| 123 |
|
---|
[83546] | 124 | RTDECL(void) RTMemTmpFreeZ(void *pv, size_t cb) RT_NO_THROW_DEF
|
---|
| 125 | {
|
---|
| 126 | return RTMemFreeZ(pv, cb);
|
---|
| 127 | }
|
---|
| 128 | RT_EXPORT_SYMBOL(RTMemTmpFreeZ);
|
---|
[31157] | 129 |
|
---|
| 130 |
|
---|
| 131 |
|
---|
[83546] | 132 |
|
---|
| 133 |
|
---|
[57432] | 134 | RTDECL(void *) RTMemAllocTag(size_t cb, const char *pszTag) RT_NO_THROW_DEF
|
---|
[1] | 135 | {
|
---|
[22052] | 136 | PRTMEMHDR pHdr;
|
---|
[22125] | 137 | RT_ASSERT_INTS_ON();
|
---|
[62566] | 138 | RT_NOREF_PV(pszTag);
|
---|
[22052] | 139 |
|
---|
[28298] | 140 | pHdr = rtR0MemAlloc(cb + RTR0MEM_FENCE_EXTRA, 0);
|
---|
[1] | 141 | if (pHdr)
|
---|
[7042] | 142 | {
|
---|
| 143 | #ifdef RTR0MEM_STRICT
|
---|
[14068] | 144 | pHdr->cbReq = (uint32_t)cb; Assert(pHdr->cbReq == cb);
|
---|
[7244] | 145 | memcpy((uint8_t *)(pHdr + 1) + cb, &g_abFence[0], RTR0MEM_FENCE_EXTRA);
|
---|
[7042] | 146 | #endif
|
---|
[1] | 147 | return pHdr + 1;
|
---|
[7042] | 148 | }
|
---|
[1] | 149 | return NULL;
|
---|
| 150 | }
|
---|
[31157] | 151 | RT_EXPORT_SYMBOL(RTMemAllocTag);
|
---|
[1] | 152 |
|
---|
| 153 |
|
---|
[57432] | 154 | RTDECL(void *) RTMemAllocZTag(size_t cb, const char *pszTag) RT_NO_THROW_DEF
|
---|
[1] | 155 | {
|
---|
[22052] | 156 | PRTMEMHDR pHdr;
|
---|
[22125] | 157 | RT_ASSERT_INTS_ON();
|
---|
[62566] | 158 | RT_NOREF_PV(pszTag);
|
---|
[22052] | 159 |
|
---|
[28298] | 160 | pHdr = rtR0MemAlloc(cb + RTR0MEM_FENCE_EXTRA, RTMEMHDR_FLAG_ZEROED);
|
---|
[1] | 161 | if (pHdr)
|
---|
[7042] | 162 | {
|
---|
| 163 | #ifdef RTR0MEM_STRICT
|
---|
[14068] | 164 | pHdr->cbReq = (uint32_t)cb; Assert(pHdr->cbReq == cb);
|
---|
[7244] | 165 | memcpy((uint8_t *)(pHdr + 1) + cb, &g_abFence[0], RTR0MEM_FENCE_EXTRA);
|
---|
[7042] | 166 | return memset(pHdr + 1, 0, cb);
|
---|
| 167 | #else
|
---|
[1] | 168 | return memset(pHdr + 1, 0, pHdr->cb);
|
---|
[7042] | 169 | #endif
|
---|
| 170 | }
|
---|
[1] | 171 | return NULL;
|
---|
| 172 | }
|
---|
[31157] | 173 | RT_EXPORT_SYMBOL(RTMemAllocZTag);
|
---|
[1] | 174 |
|
---|
| 175 |
|
---|
[31157] | 176 | RTDECL(void *) RTMemAllocVarTag(size_t cbUnaligned, const char *pszTag)
|
---|
[28298] | 177 | {
|
---|
| 178 | size_t cbAligned;
|
---|
| 179 | if (cbUnaligned >= 16)
|
---|
| 180 | cbAligned = RT_ALIGN_Z(cbUnaligned, 16);
|
---|
| 181 | else
|
---|
| 182 | cbAligned = RT_ALIGN_Z(cbUnaligned, sizeof(void *));
|
---|
[31157] | 183 | return RTMemAllocTag(cbAligned, pszTag);
|
---|
[28298] | 184 | }
|
---|
[31157] | 185 | RT_EXPORT_SYMBOL(RTMemAllocVarTag);
|
---|
[28298] | 186 |
|
---|
| 187 |
|
---|
[31157] | 188 | RTDECL(void *) RTMemAllocZVarTag(size_t cbUnaligned, const char *pszTag)
|
---|
[28298] | 189 | {
|
---|
| 190 | size_t cbAligned;
|
---|
| 191 | if (cbUnaligned >= 16)
|
---|
| 192 | cbAligned = RT_ALIGN_Z(cbUnaligned, 16);
|
---|
| 193 | else
|
---|
| 194 | cbAligned = RT_ALIGN_Z(cbUnaligned, sizeof(void *));
|
---|
[31157] | 195 | return RTMemAllocZTag(cbAligned, pszTag);
|
---|
[28298] | 196 | }
|
---|
[31157] | 197 | RT_EXPORT_SYMBOL(RTMemAllocZVarTag);
|
---|
[28298] | 198 |
|
---|
| 199 |
|
---|
[57432] | 200 | RTDECL(void *) RTMemReallocTag(void *pvOld, size_t cbNew, const char *pszTag) RT_NO_THROW_DEF
|
---|
[1] | 201 | {
|
---|
[37672] | 202 | PRTMEMHDR pHdrOld;
|
---|
| 203 |
|
---|
[36982] | 204 | /* Free. */
|
---|
| 205 | if (!cbNew && pvOld)
|
---|
| 206 | {
|
---|
[1] | 207 | RTMemFree(pvOld);
|
---|
[36982] | 208 | return NULL;
|
---|
| 209 | }
|
---|
| 210 |
|
---|
| 211 | /* Alloc. */
|
---|
| 212 | if (!pvOld)
|
---|
[31157] | 213 | return RTMemAllocTag(cbNew, pszTag);
|
---|
[36982] | 214 |
|
---|
| 215 | /*
|
---|
| 216 | * Realloc.
|
---|
| 217 | */
|
---|
[37672] | 218 | pHdrOld = (PRTMEMHDR)pvOld - 1;
|
---|
[36982] | 219 | RT_ASSERT_PREEMPTIBLE();
|
---|
| 220 |
|
---|
| 221 | if (pHdrOld->u32Magic == RTMEMHDR_MAGIC)
|
---|
[1] | 222 | {
|
---|
[36982] | 223 | PRTMEMHDR pHdrNew;
|
---|
[22052] | 224 |
|
---|
[36982] | 225 | /* If there is sufficient space in the old block and we don't cause
|
---|
| 226 | substantial internal fragmentation, reuse the old block. */
|
---|
| 227 | if ( pHdrOld->cb >= cbNew + RTR0MEM_FENCE_EXTRA
|
---|
| 228 | && pHdrOld->cb - (cbNew + RTR0MEM_FENCE_EXTRA) <= 128)
|
---|
[1] | 229 | {
|
---|
[36982] | 230 | pHdrOld->cbReq = (uint32_t)cbNew; Assert(pHdrOld->cbReq == cbNew);
|
---|
[7042] | 231 | #ifdef RTR0MEM_STRICT
|
---|
[36982] | 232 | memcpy((uint8_t *)(pHdrOld + 1) + cbNew, &g_abFence[0], RTR0MEM_FENCE_EXTRA);
|
---|
[7042] | 233 | #endif
|
---|
[36982] | 234 | return pvOld;
|
---|
[1] | 235 | }
|
---|
[36982] | 236 |
|
---|
| 237 | /* Allocate a new block and copy over the content. */
|
---|
| 238 | pHdrNew = rtR0MemAlloc(cbNew + RTR0MEM_FENCE_EXTRA, 0);
|
---|
| 239 | if (pHdrNew)
|
---|
| 240 | {
|
---|
| 241 | size_t cbCopy = RT_MIN(pHdrOld->cb, pHdrNew->cb);
|
---|
| 242 | memcpy(pHdrNew + 1, pvOld, cbCopy);
|
---|
| 243 | #ifdef RTR0MEM_STRICT
|
---|
| 244 | pHdrNew->cbReq = (uint32_t)cbNew; Assert(pHdrNew->cbReq == cbNew);
|
---|
| 245 | memcpy((uint8_t *)(pHdrNew + 1) + cbNew, &g_abFence[0], RTR0MEM_FENCE_EXTRA);
|
---|
| 246 | AssertReleaseMsg(!memcmp((uint8_t *)(pHdrOld + 1) + pHdrOld->cbReq, &g_abFence[0], RTR0MEM_FENCE_EXTRA),
|
---|
| 247 | ("pHdr=%p pvOld=%p cbReq=%u cb=%u cbNew=%zu fFlags=%#x\n"
|
---|
| 248 | "fence: %.*Rhxs\n"
|
---|
| 249 | "expected: %.*Rhxs\n",
|
---|
| 250 | pHdrOld, pvOld, pHdrOld->cbReq, pHdrOld->cb, cbNew, pHdrOld->fFlags,
|
---|
| 251 | RTR0MEM_FENCE_EXTRA, (uint8_t *)(pHdrOld + 1) + pHdrOld->cbReq,
|
---|
| 252 | RTR0MEM_FENCE_EXTRA, &g_abFence[0]));
|
---|
| 253 | #endif
|
---|
| 254 | rtR0MemFree(pHdrOld);
|
---|
| 255 | return pHdrNew + 1;
|
---|
| 256 | }
|
---|
[1] | 257 | }
|
---|
[36982] | 258 | else
|
---|
| 259 | AssertMsgFailed(("pHdrOld->u32Magic=%RX32 pvOld=%p cbNew=%#zx\n", pHdrOld->u32Magic, pvOld, cbNew));
|
---|
[1] | 260 |
|
---|
| 261 | return NULL;
|
---|
| 262 | }
|
---|
[31157] | 263 | RT_EXPORT_SYMBOL(RTMemReallocTag);
|
---|
[1] | 264 |
|
---|
| 265 |
|
---|
[57432] | 266 | RTDECL(void) RTMemFree(void *pv) RT_NO_THROW_DEF
|
---|
[1] | 267 | {
|
---|
[217] | 268 | PRTMEMHDR pHdr;
|
---|
[22052] | 269 | RT_ASSERT_INTS_ON();
|
---|
| 270 |
|
---|
[217] | 271 | if (!pv)
|
---|
| 272 | return;
|
---|
| 273 | pHdr = (PRTMEMHDR)pv - 1;
|
---|
[1] | 274 | if (pHdr->u32Magic == RTMEMHDR_MAGIC)
|
---|
| 275 | {
|
---|
[32707] | 276 | Assert(!(pHdr->fFlags & RTMEMHDR_FLAG_ALLOC_EX));
|
---|
[7042] | 277 | #ifdef RTR0MEM_STRICT
|
---|
[7244] | 278 | AssertReleaseMsg(!memcmp((uint8_t *)(pHdr + 1) + pHdr->cbReq, &g_abFence[0], RTR0MEM_FENCE_EXTRA),
|
---|
[36982] | 279 | ("pHdr=%p pv=%p cbReq=%u cb=%u fFlags=%#x\n"
|
---|
[7042] | 280 | "fence: %.*Rhxs\n"
|
---|
| 281 | "expected: %.*Rhxs\n",
|
---|
[36982] | 282 | pHdr, pv, pHdr->cbReq, pHdr->cb, pHdr->fFlags,
|
---|
| 283 | RTR0MEM_FENCE_EXTRA, (uint8_t *)(pHdr + 1) + pHdr->cbReq,
|
---|
[7244] | 284 | RTR0MEM_FENCE_EXTRA, &g_abFence[0]));
|
---|
[7042] | 285 | #endif
|
---|
[28298] | 286 | rtR0MemFree(pHdr);
|
---|
[1] | 287 | }
|
---|
| 288 | else
|
---|
| 289 | AssertMsgFailed(("pHdr->u32Magic=%RX32 pv=%p\n", pHdr->u32Magic, pv));
|
---|
| 290 | }
|
---|
[21337] | 291 | RT_EXPORT_SYMBOL(RTMemFree);
|
---|
[1] | 292 |
|
---|
| 293 |
|
---|
[83546] | 294 | RTDECL(void) RTMemFreeZ(void *pv, size_t cb) RT_NO_THROW_DEF
|
---|
| 295 | {
|
---|
| 296 | PRTMEMHDR pHdr;
|
---|
| 297 | RT_ASSERT_INTS_ON();
|
---|
[31157] | 298 |
|
---|
[83546] | 299 | if (!pv)
|
---|
| 300 | return;
|
---|
| 301 | pHdr = (PRTMEMHDR)pv - 1;
|
---|
| 302 | if (pHdr->u32Magic == RTMEMHDR_MAGIC)
|
---|
| 303 | {
|
---|
| 304 | Assert(!(pHdr->fFlags & RTMEMHDR_FLAG_ALLOC_EX));
|
---|
| 305 | #ifdef RTR0MEM_STRICT
|
---|
| 306 | AssertReleaseMsg(!memcmp((uint8_t *)(pHdr + 1) + pHdr->cbReq, &g_abFence[0], RTR0MEM_FENCE_EXTRA),
|
---|
| 307 | ("pHdr=%p pv=%p cbReq=%u cb=%u fFlags=%#x\n"
|
---|
| 308 | "fence: %.*Rhxs\n"
|
---|
| 309 | "expected: %.*Rhxs\n",
|
---|
| 310 | pHdr, pv, pHdr->cbReq, pHdr->cb, pHdr->fFlags,
|
---|
| 311 | RTR0MEM_FENCE_EXTRA, (uint8_t *)(pHdr + 1) + pHdr->cbReq,
|
---|
| 312 | RTR0MEM_FENCE_EXTRA, &g_abFence[0]));
|
---|
| 313 | #endif
|
---|
| 314 | AssertMsgStmt(cb == pHdr->cbReq, ("cb=%#zx cbReq=%#x\n", cb, pHdr->cbReq), cb = pHdr->cbReq);
|
---|
| 315 | RT_BZERO(pv, cb);
|
---|
| 316 | rtR0MemFree(pHdr);
|
---|
| 317 | }
|
---|
| 318 | else
|
---|
| 319 | AssertMsgFailed(("pHdr->u32Magic=%RX32 pv=%p\n", pHdr->u32Magic, pv));
|
---|
| 320 | }
|
---|
| 321 | RT_EXPORT_SYMBOL(RTMemFreeZ);
|
---|
[31157] | 322 |
|
---|
| 323 |
|
---|
[57432] | 324 | RTDECL(int) RTMemAllocExTag(size_t cb, size_t cbAlignment, uint32_t fFlags, const char *pszTag, void **ppv) RT_NO_THROW_DEF
|
---|
[32674] | 325 | {
|
---|
[32707] | 326 | uint32_t fHdrFlags = RTMEMHDR_FLAG_ALLOC_EX;
|
---|
| 327 | PRTMEMHDR pHdr;
|
---|
| 328 | int rc;
|
---|
[62566] | 329 | RT_NOREF_PV(pszTag);
|
---|
[32707] | 330 |
|
---|
| 331 | RT_ASSERT_PREEMPT_CPUID_VAR();
|
---|
[46565] | 332 | if (!(fFlags & RTMEMALLOCEX_FLAGS_ANY_CTX_ALLOC))
|
---|
[32707] | 333 | RT_ASSERT_INTS_ON();
|
---|
[97909] | 334 | AssertReturn(!(fFlags & RTMEMALLOCEX_FLAGS_EXEC), VERR_INVALID_FLAGS);
|
---|
[32707] | 335 |
|
---|
| 336 | /*
|
---|
| 337 | * Fake up some alignment support.
|
---|
| 338 | */
|
---|
| 339 | AssertMsgReturn(cbAlignment <= sizeof(void *), ("%zu (%#x)\n", cbAlignment, cbAlignment), VERR_UNSUPPORTED_ALIGNMENT);
|
---|
| 340 | if (cb < cbAlignment)
|
---|
| 341 | cb = cbAlignment;
|
---|
| 342 |
|
---|
| 343 | /*
|
---|
| 344 | * Validate and convert flags.
|
---|
| 345 | */
|
---|
[46567] | 346 | AssertMsgReturn(!(fFlags & ~RTMEMALLOCEX_FLAGS_VALID_MASK_R0), ("%#x\n", fFlags), VERR_INVALID_PARAMETER);
|
---|
[32707] | 347 | if (fFlags & RTMEMALLOCEX_FLAGS_ZEROED)
|
---|
| 348 | fHdrFlags |= RTMEMHDR_FLAG_ZEROED;
|
---|
| 349 | if (fFlags & RTMEMALLOCEX_FLAGS_ANY_CTX_ALLOC)
|
---|
| 350 | fHdrFlags |= RTMEMHDR_FLAG_ANY_CTX_ALLOC;
|
---|
| 351 | if (fFlags & RTMEMALLOCEX_FLAGS_ANY_CTX_FREE)
|
---|
| 352 | fHdrFlags |= RTMEMHDR_FLAG_ANY_CTX_FREE;
|
---|
| 353 |
|
---|
| 354 | /*
|
---|
| 355 | * Do the allocation.
|
---|
| 356 | */
|
---|
| 357 | rc = rtR0MemAllocEx(cb + RTR0MEM_FENCE_EXTRA, fHdrFlags, &pHdr);
|
---|
| 358 | if (RT_SUCCESS(rc))
|
---|
| 359 | {
|
---|
| 360 | void *pv;
|
---|
| 361 |
|
---|
| 362 | Assert(pHdr->cbReq == cb + RTR0MEM_FENCE_EXTRA);
|
---|
| 363 | Assert((pHdr->fFlags & fFlags) == fFlags);
|
---|
| 364 |
|
---|
| 365 | /*
|
---|
| 366 | * Calc user pointer, initialize the memory if requested, and if
|
---|
| 367 | * memory strictness is enable set up the fence.
|
---|
| 368 | */
|
---|
| 369 | pv = pHdr + 1;
|
---|
| 370 | *ppv = pv;
|
---|
| 371 | if (fFlags & RTMEMHDR_FLAG_ZEROED)
|
---|
| 372 | memset(pv, 0, pHdr->cb);
|
---|
| 373 |
|
---|
| 374 | #ifdef RTR0MEM_STRICT
|
---|
| 375 | pHdr->cbReq = (uint32_t)cb;
|
---|
| 376 | memcpy((uint8_t *)pv + cb, &g_abFence[0], RTR0MEM_FENCE_EXTRA);
|
---|
| 377 | #endif
|
---|
| 378 | }
|
---|
| 379 |
|
---|
| 380 | RT_ASSERT_PREEMPT_CPUID();
|
---|
| 381 | return rc;
|
---|
[32674] | 382 | }
|
---|
[32707] | 383 | RT_EXPORT_SYMBOL(RTMemAllocExTag);
|
---|
[32674] | 384 |
|
---|
| 385 |
|
---|
[57432] | 386 | RTDECL(void) RTMemFreeEx(void *pv, size_t cb) RT_NO_THROW_DEF
|
---|
[32674] | 387 | {
|
---|
| 388 | PRTMEMHDR pHdr;
|
---|
[62567] | 389 | RT_NOREF_PV(cb);
|
---|
[32674] | 390 |
|
---|
| 391 | if (!pv)
|
---|
| 392 | return;
|
---|
[32707] | 393 |
|
---|
| 394 | AssertPtr(pv);
|
---|
[32674] | 395 | pHdr = (PRTMEMHDR)pv - 1;
|
---|
| 396 | if (pHdr->u32Magic == RTMEMHDR_MAGIC)
|
---|
| 397 | {
|
---|
[32707] | 398 | RT_ASSERT_PREEMPT_CPUID_VAR();
|
---|
| 399 |
|
---|
[32674] | 400 | Assert(pHdr->fFlags & RTMEMHDR_FLAG_ALLOC_EX);
|
---|
[32707] | 401 | if (!(pHdr->fFlags & RTMEMHDR_FLAG_ANY_CTX_FREE))
|
---|
[32674] | 402 | RT_ASSERT_INTS_ON();
|
---|
[32707] | 403 | AssertMsg(pHdr->cbReq == cb, ("cbReq=%zu cb=%zu\n", pHdr->cb, cb));
|
---|
[32674] | 404 |
|
---|
| 405 | #ifdef RTR0MEM_STRICT
|
---|
| 406 | AssertReleaseMsg(!memcmp((uint8_t *)(pHdr + 1) + pHdr->cbReq, &g_abFence[0], RTR0MEM_FENCE_EXTRA),
|
---|
[36982] | 407 | ("pHdr=%p pv=%p cbReq=%u cb=%u fFlags=%#x\n"
|
---|
[32674] | 408 | "fence: %.*Rhxs\n"
|
---|
| 409 | "expected: %.*Rhxs\n",
|
---|
[36982] | 410 | pHdr, pv, pHdr->cbReq, pHdr->cb, pHdr->fFlags,
|
---|
| 411 | RTR0MEM_FENCE_EXTRA, (uint8_t *)(pHdr + 1) + pHdr->cbReq,
|
---|
[32674] | 412 | RTR0MEM_FENCE_EXTRA, &g_abFence[0]));
|
---|
| 413 | #endif
|
---|
| 414 | rtR0MemFree(pHdr);
|
---|
[32707] | 415 | RT_ASSERT_PREEMPT_CPUID();
|
---|
[32674] | 416 | }
|
---|
| 417 | else
|
---|
| 418 | AssertMsgFailed(("pHdr->u32Magic=%RX32 pv=%p\n", pHdr->u32Magic, pv));
|
---|
| 419 | }
|
---|
[32707] | 420 | RT_EXPORT_SYMBOL(RTMemFreeEx);
|
---|
[32674] | 421 |
|
---|