VirtualBox

Changeset 101162 in vbox for trunk/src/VBox/Runtime/r3/win


Ignore:
Timestamp:
Sep 18, 2023 8:03:52 PM (17 months ago)
Author:
vboxsync
Message:

IPRT/mem: Use mempage /w heap code everwhere all the time. bugref:10370

Location:
trunk/src/VBox/Runtime/r3/win
Files:
1 copied
1 moved

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Runtime/r3/win/RTMemProtect-win.cpp

    r101161 r101162  
    11/* $Id$ */
    22/** @file
    3  * IPRT - Memory Allocation, Windows.
     3 * IPRT - RTMemProtect, Windows.
    44 */
    55
     
    3939*   Header Files                                                                                                                 *
    4040*********************************************************************************************************************************/
    41 #ifdef IPRT_NO_CRT
    42 # define USE_VIRTUAL_ALLOC
    43 #endif
    4441#define LOG_GROUP RTLOGGROUP_MEM
    4542#include <iprt/win/windows.h>
    4643
    47 #include <iprt/alloc.h>
     44#include <iprt/mem.h>
    4845#include <iprt/assert.h>
    4946#include <iprt/param.h>
    50 #include <iprt/string.h>
    5147#include <iprt/errcore.h>
    5248
    53 #ifndef USE_VIRTUAL_ALLOC
    54 # include <malloc.h>
    55 #endif
    56 
    57 
    58 /** @todo merge the page alloc code with the heap-based mmap stuff as
    59  *        _aligned_malloc just isn't well suited for exec. */
    60 
    61 
    62 RTDECL(void *) RTMemPageAllocTag(size_t cb, const char *pszTag) RT_NO_THROW_DEF
    63 {
    64     RT_NOREF_PV(pszTag);
    65 
    66 #ifdef USE_VIRTUAL_ALLOC
    67     void *pv = VirtualAlloc(NULL, RT_ALIGN_Z(cb, PAGE_SIZE), MEM_COMMIT, PAGE_READWRITE);
    68 #else
    69     void *pv = _aligned_malloc(RT_ALIGN_Z(cb, PAGE_SIZE), PAGE_SIZE);
    70 #endif
    71     AssertMsg(pv, ("cb=%d lasterr=%d\n", cb, GetLastError()));
    72     return pv;
    73 }
    74 
    75 
    76 RTDECL(void *) RTMemPageAllocExTag(size_t cb, uint32_t fFlags, const char *pszTag) RT_NO_THROW_DEF
    77 {
    78     size_t const cbAligned = RT_ALIGN_Z(cb, PAGE_SIZE);
    79     RT_NOREF_PV(pszTag);
    80     AssertReturn(!(fFlags & ~RTMEMPAGEALLOC_F_VALID_MASK), NULL);
    81 
    82 #ifdef USE_VIRTUAL_ALLOC
    83     void *pv = VirtualAlloc(NULL, cbAligned, MEM_COMMIT,
    84                             !(fFlags & RTMEMPAGEALLOC_F_EXECUTABLE) ? PAGE_READWRITE : PAGE_EXECUTE_READWRITE);
    85 #else
    86     void *pv = _aligned_malloc(cbAligned, PAGE_SIZE);
    87 #endif
    88     AssertMsgReturn(pv, ("cb=%d lasterr=%d\n", cb, GetLastError()), NULL);
    89 
    90 #ifndef USE_VIRTUAL_ALLOC
    91     if (fFlags & RTMEMPAGEALLOC_F_EXECUTABLE)
    92     {
    93         DWORD      fIgn = 0;
    94         BOOL const fRc  = VirtualProtect(pv, cbAligned, PAGE_EXECUTE_READWRITE, &fIgn);
    95         AssertMsgReturnStmt(fRc, ("%p LB %#zx: %#u\n", pv, cbAligned, GetLastError()), _aligned_free(pv), NULL);
    96     }
    97 #endif
    98 
    99     if (fFlags & RTMEMPAGEALLOC_F_ADVISE_LOCKED)
    100     {
    101         /** @todo check why we get ERROR_WORKING_SET_QUOTA here. */
    102         BOOL const fOkay = VirtualLock(pv, cbAligned);
    103         AssertMsg(fOkay || GetLastError() == ERROR_WORKING_SET_QUOTA, ("pv=%p cb=%d lasterr=%d\n", pv, cb, GetLastError()));
    104         NOREF(fOkay);
    105     }
    106 
    107     if (fFlags & RTMEMPAGEALLOC_F_ZERO)
    108         RT_BZERO(pv, cbAligned);
    109 
    110     return pv;
    111 }
    112 
    113 
    114 RTDECL(void *) RTMemPageAllocZTag(size_t cb, const char *pszTag) RT_NO_THROW_DEF
    115 {
    116     RT_NOREF_PV(pszTag);
    117 
    118 #ifdef USE_VIRTUAL_ALLOC
    119     void *pv = VirtualAlloc(NULL, RT_ALIGN_Z(cb, PAGE_SIZE), MEM_COMMIT, PAGE_READWRITE);
    120 #else
    121     void *pv = _aligned_malloc(RT_ALIGN_Z(cb, PAGE_SIZE), PAGE_SIZE);
    122 #endif
    123     if (pv)
    124     {
    125         memset(pv, 0, RT_ALIGN_Z(cb, PAGE_SIZE));
    126         return pv;
    127     }
    128     AssertMsgFailed(("cb=%d lasterr=%d\n", cb, GetLastError()));
    129     return NULL;
    130 }
    131 
    132 
    133 RTDECL(void) RTMemPageFree(void *pv, size_t cb) RT_NO_THROW_DEF
    134 {
    135     RT_NOREF_PV(cb);
    136 
    137     if (pv)
    138     {
    139 #ifdef USE_VIRTUAL_ALLOC
    140         if (!VirtualFree(pv, 0, MEM_RELEASE))
    141             AssertMsgFailed(("pv=%p lasterr=%d\n", pv, GetLastError()));
    142 #else
    143         /** @todo The exec version of this doesn't really work well... */
    144         MEMORY_BASIC_INFORMATION MemInfo = { NULL };
    145         SIZE_T cbRet = VirtualQuery(pv, &MemInfo, sizeof(MemInfo));
    146         Assert(cbRet > 0);
    147         if (cbRet > 0 && MemInfo.Protect == PAGE_EXECUTE_READWRITE)
    148         {
    149             DWORD      fIgn = 0;
    150             BOOL const fRc  = VirtualProtect(pv, cb, PAGE_READWRITE, &fIgn);
    151             Assert(fRc); RT_NOREF(fRc);
    152         }
    153         _aligned_free(pv);
    154 #endif
    155     }
    156 }
    15749
    15850
  • trunk/src/VBox/Runtime/r3/win/mempage-native-win.cpp

    • Property svn:mergeinfo set to (toggle deleted branches)
      /branches/VBox-3.0/src/VBox/Runtime/r3/win/alloc-win.cpp58652,​70973
      /branches/VBox-3.2/src/VBox/Runtime/r3/win/alloc-win.cpp66309,​66318
      /branches/VBox-4.0/src/VBox/Runtime/r3/win/alloc-win.cpp70873
      /branches/VBox-4.1/src/VBox/Runtime/r3/win/alloc-win.cpp74233,​78414,​78691,​81841,​82127,​85941,​85944-85947,​85949-85950,​85953,​86701,​86728,​87009
      /branches/VBox-4.2/src/VBox/Runtime/r3/win/alloc-win.cpp86229-86230,​86234,​86529,​91503-91504,​91506-91508,​91510,​91514-91515,​91521,​108112,​108114,​108127
      /branches/VBox-4.3/src/VBox/Runtime/r3/win/alloc-win.cpp89714,​91223,​93628-93629,​94066,​94839,​94897,​95154,​95164,​95167,​95295,​95338,​95353-95354,​95356,​95367,​95451,​95475,​95477,​95480,​95507,​95640,​95659,​95661,​95663,​98913-98914
      /branches/VBox-4.3/trunk/src/VBox/Runtime/r3/win/alloc-win.cpp91223
      /branches/VBox-5.0/src/VBox/Runtime/r3/win/alloc-win.cpp104938,​104943,​104950,​104987-104988,​104990,​106453
      /branches/VBox-5.1/src/VBox/Runtime/r3/win/alloc-win.cpp112367,​116543,​116550,​116568,​116573
      /branches/VBox-5.2/src/VBox/Runtime/r3/win/alloc-win.cpp119536,​120083,​120099,​120213,​120221,​120239,​123597-123598,​123600-123601,​123755,​124263,​124273,​124277-124279,​124284-124286,​124288-124290,​125768,​125779-125780,​125812,​127158-127159,​127162-127167,​127180
      /branches/VBox-6.0/src/VBox/Runtime/r3/win/alloc-win.cpp130474-130475,​130477,​130479,​131352
      /branches/VBox-6.1/src/VBox/Runtime/r3/win/alloc-win.cpp141521,​141567-141568,​141588-141590,​141592-141595,​141652,​141920,​158257-158259
      /branches/VBox-7.0/src/VBox/Runtime/r3/win/alloc-win.cpp156229,​156768
      /branches/aeichner/vbox-chromium-cleanup/src/VBox/Runtime/r3/win/alloc-win.cpp129818-129851,​129853-129861,​129871-129872,​129876,​129880,​129882,​130013-130015,​130094-130095
      /branches/andy/draganddrop/src/VBox/Runtime/r3/win/alloc-win.cpp90781-91268
      /branches/andy/guestctrl20/src/VBox/Runtime/r3/win/alloc-win.cpp78916,​78930
      /branches/andy/pdmaudio/src/VBox/Runtime/r3/win/alloc-win.cpp94582,​94641,​94654,​94688,​94778,​94783,​94816,​95197,​95215-95216,​95250,​95279,​95505-95506,​95543,​95694,​96323,​96470-96471,​96582,​96587,​96802-96803,​96817,​96904,​96967,​96999,​97020-97021,​97025,​97050,​97099
      /branches/bird/hardenedwindows/src/VBox/Runtime/r3/win/alloc-win.cpp92692-94610
      /branches/dsen/gui/src/VBox/Runtime/r3/win/alloc-win.cpp79076-79078,​79089,​79109-79110,​79112-79113,​79127-79130,​79134,​79141,​79151,​79155,​79157-79159,​79193,​79197
      /branches/dsen/gui2/src/VBox/Runtime/r3/win/alloc-win.cpp79224,​79228,​79233,​79235,​79258,​79262-79263,​79273,​79341,​79345,​79354,​79357,​79387-79388,​79559-79569,​79572-79573,​79578,​79581-79582,​79590-79591,​79598-79599,​79602-79603,​79605-79606,​79632,​79635,​79637,​79644
      /branches/dsen/gui3/src/VBox/Runtime/r3/win/alloc-win.cpp79645-79692
      /branches/dsen/gui4/src/VBox/Runtime/r3/win/alloc-win.cpp155183-155185,​155187,​155198,​155200-155201,​155205,​155228,​155235,​155243,​155248,​155282,​155285,​155287-155288,​155311,​155316,​155336,​155342,​155344,​155437-155438,​155441,​155443,​155488,​155509-155513,​155526-155527,​155559,​155572,​155576-155577,​155592-155593
    r101154 r101162  
    11/* $Id$ */
    22/** @file
    3  * IPRT - Memory Allocation, Windows.
     3 * IPRT - rtMemPageNative*, Windows implementation.
    44 */
    55
    66/*
    7  * Copyright (C) 2006-2023 Oracle and/or its affiliates.
     7 * Copyright (C) 2023 Oracle and/or its affiliates.
    88 *
    99 * This file is part of VirtualBox base platform packages, as
     
    3939*   Header Files                                                                                                                 *
    4040*********************************************************************************************************************************/
    41 #ifdef IPRT_NO_CRT
    42 # define USE_VIRTUAL_ALLOC
    43 #endif
    44 #define LOG_GROUP RTLOGGROUP_MEM
    4541#include <iprt/win/windows.h>
    4642
    47 #include <iprt/alloc.h>
     43#include "internal/iprt.h"
     44#include <iprt/mem.h>
     45
    4846#include <iprt/assert.h>
     47#include <iprt/errcore.h>
    4948#include <iprt/param.h>
    5049#include <iprt/string.h>
    51 #include <iprt/errcore.h>
    52 
    53 #ifndef USE_VIRTUAL_ALLOC
    54 # include <malloc.h>
    55 #endif
     50#include "internal/mem.h"
    5651
    5752
    58 /** @todo merge the page alloc code with the heap-based mmap stuff as
    59  *        _aligned_malloc just isn't well suited for exec. */
    6053
    61 
    62 RTDECL(void *) RTMemPageAllocTag(size_t cb, const char *pszTag) RT_NO_THROW_DEF
     54DECLHIDDEN(int) rtMemPageNativeAlloc(size_t cb, uint32_t fFlags, void **ppvRet)
    6355{
    64     RT_NOREF_PV(pszTag);
    65 
    66 #ifdef USE_VIRTUAL_ALLOC
    67     void *pv = VirtualAlloc(NULL, RT_ALIGN_Z(cb, PAGE_SIZE), MEM_COMMIT, PAGE_READWRITE);
    68 #else
    69     void *pv = _aligned_malloc(RT_ALIGN_Z(cb, PAGE_SIZE), PAGE_SIZE);
    70 #endif
    71     AssertMsg(pv, ("cb=%d lasterr=%d\n", cb, GetLastError()));
    72     return pv;
     56    void *pv = VirtualAlloc(NULL, cb, MEM_COMMIT,
     57                            !(fFlags & RTMEMPAGEALLOC_F_EXECUTABLE) ? PAGE_READWRITE : PAGE_EXECUTE_READWRITE);
     58    *ppvRet = pv;
     59    if (RT_LIKELY(pv != NULL))
     60        return VINF_SUCCESS;
     61    return RTErrConvertFromWin32(GetLastError());
    7362}
    7463
    7564
    76 RTDECL(void *) RTMemPageAllocExTag(size_t cb, uint32_t fFlags, const char *pszTag) RT_NO_THROW_DEF
     65DECLHIDDEN(int) rtMemPageNativeFree(void *pv, size_t cb)
    7766{
    78     size_t const cbAligned = RT_ALIGN_Z(cb, PAGE_SIZE);
    79     RT_NOREF_PV(pszTag);
    80     AssertReturn(!(fFlags & ~RTMEMPAGEALLOC_F_VALID_MASK), NULL);
     67    if (RT_LIKELY(VirtualFree(pv, 0, MEM_RELEASE)))
     68        return VINF_SUCCESS;
     69    int rc = RTErrConvertFromWin32(GetLastError());
     70    AssertMsgFailed(("rc=%d pv=%p cb=%#zx lasterr=%u\n", rc, pv, cb, GetLastError()));
     71    RT_NOREF(cb);
     72    return rc;
     73}
    8174
    82 #ifdef USE_VIRTUAL_ALLOC
    83     void *pv = VirtualAlloc(NULL, cbAligned, MEM_COMMIT,
    84                             !(fFlags & RTMEMPAGEALLOC_F_EXECUTABLE) ? PAGE_READWRITE : PAGE_EXECUTE_READWRITE);
    85 #else
    86     void *pv = _aligned_malloc(cbAligned, PAGE_SIZE);
    87 #endif
    88     AssertMsgReturn(pv, ("cb=%d lasterr=%d\n", cb, GetLastError()), NULL);
    8975
    90 #ifndef USE_VIRTUAL_ALLOC
    91     if (fFlags & RTMEMPAGEALLOC_F_EXECUTABLE)
    92     {
    93         DWORD      fIgn = 0;
    94         BOOL const fRc  = VirtualProtect(pv, cbAligned, PAGE_EXECUTE_READWRITE, &fIgn);
    95         AssertMsgReturnStmt(fRc, ("%p LB %#zx: %#u\n", pv, cbAligned, GetLastError()), _aligned_free(pv), NULL);
    96     }
    97 #endif
     76DECLHIDDEN(uint32_t) rtMemPageNativeApplyFlags(void *pv, size_t cb, uint32_t fFlags)
     77{
     78    uint32_t fRet = 0;
    9879
    9980    if (fFlags & RTMEMPAGEALLOC_F_ADVISE_LOCKED)
    10081    {
    10182        /** @todo check why we get ERROR_WORKING_SET_QUOTA here. */
    102         BOOL const fOkay = VirtualLock(pv, cbAligned);
     83        BOOL const fOkay = VirtualLock(pv, cb);
    10384        AssertMsg(fOkay || GetLastError() == ERROR_WORKING_SET_QUOTA, ("pv=%p cb=%d lasterr=%d\n", pv, cb, GetLastError()));
    104         NOREF(fOkay);
     85        if (fOkay)
     86            fRet |= RTMEMPAGEALLOC_F_ADVISE_LOCKED;
    10587    }
    10688
    107     if (fFlags & RTMEMPAGEALLOC_F_ZERO)
    108         RT_BZERO(pv, cbAligned);
     89    /** @todo Any way to apply RTMEMPAGEALLOC_F_ADVISE_NO_DUMP on windows? */
    10990
    110     return pv;
     91    return fRet;
    11192}
    11293
    11394
    114 RTDECL(void *) RTMemPageAllocZTag(size_t cb, const char *pszTag) RT_NO_THROW_DEF
     95DECLHIDDEN(void) rtMemPageNativeRevertFlags(void *pv, size_t cb, uint32_t fFlags)
    11596{
    116     RT_NOREF_PV(pszTag);
    117 
    118 #ifdef USE_VIRTUAL_ALLOC
    119     void *pv = VirtualAlloc(NULL, RT_ALIGN_Z(cb, PAGE_SIZE), MEM_COMMIT, PAGE_READWRITE);
    120 #else
    121     void *pv = _aligned_malloc(RT_ALIGN_Z(cb, PAGE_SIZE), PAGE_SIZE);
    122 #endif
    123     if (pv)
     97    if (fFlags & RTMEMPAGEALLOC_F_ADVISE_LOCKED)
    12498    {
    125         memset(pv, 0, RT_ALIGN_Z(cb, PAGE_SIZE));
    126         return pv;
    127     }
    128     AssertMsgFailed(("cb=%d lasterr=%d\n", cb, GetLastError()));
    129     return NULL;
    130 }
    131 
    132 
    133 RTDECL(void) RTMemPageFree(void *pv, size_t cb) RT_NO_THROW_DEF
    134 {
    135     RT_NOREF_PV(cb);
    136 
    137     if (pv)
    138     {
    139 #ifdef USE_VIRTUAL_ALLOC
    140         if (!VirtualFree(pv, 0, MEM_RELEASE))
    141             AssertMsgFailed(("pv=%p lasterr=%d\n", pv, GetLastError()));
    142 #else
    143         /** @todo The exec version of this doesn't really work well... */
    144         MEMORY_BASIC_INFORMATION MemInfo = { NULL };
    145         SIZE_T cbRet = VirtualQuery(pv, &MemInfo, sizeof(MemInfo));
    146         Assert(cbRet > 0);
    147         if (cbRet > 0 && MemInfo.Protect == PAGE_EXECUTE_READWRITE)
    148         {
    149             DWORD      fIgn = 0;
    150             BOOL const fRc  = VirtualProtect(pv, cb, PAGE_READWRITE, &fIgn);
    151             Assert(fRc); RT_NOREF(fRc);
    152         }
    153         _aligned_free(pv);
    154 #endif
     99        /** @todo check why we get ERROR_NOT_LOCKED here... */
     100        BOOL const fOkay = VirtualUnlock(pv, cb);
     101        AssertMsg(fOkay || GetLastError() == ERROR_NOT_LOCKED, ("pv=%p cb=%d lasterr=%d\n", pv, cb, GetLastError()));
     102        RT_NOREF(fOkay);
    155103    }
    156104}
    157105
    158 
    159 RTDECL(int) RTMemProtect(void *pv, size_t cb, unsigned fProtect) RT_NO_THROW_DEF
    160 {
    161     /*
    162      * Validate input.
    163      */
    164     if (cb == 0)
    165     {
    166         AssertMsgFailed(("!cb\n"));
    167         return VERR_INVALID_PARAMETER;
    168     }
    169     if (fProtect & ~(RTMEM_PROT_NONE | RTMEM_PROT_READ | RTMEM_PROT_WRITE | RTMEM_PROT_EXEC))
    170     {
    171         AssertMsgFailed(("fProtect=%#x\n", fProtect));
    172         return VERR_INVALID_PARAMETER;
    173     }
    174 
    175     /*
    176      * Convert the flags.
    177      */
    178     int fProt;
    179     Assert(!RTMEM_PROT_NONE);
    180     switch (fProtect & (RTMEM_PROT_NONE | RTMEM_PROT_READ | RTMEM_PROT_WRITE | RTMEM_PROT_EXEC))
    181     {
    182         case RTMEM_PROT_NONE:
    183             fProt = PAGE_NOACCESS;
    184             break;
    185 
    186         case RTMEM_PROT_READ:
    187             fProt = PAGE_READONLY;
    188             break;
    189 
    190         case RTMEM_PROT_READ | RTMEM_PROT_WRITE:
    191             fProt = PAGE_READWRITE;
    192             break;
    193 
    194         case RTMEM_PROT_READ | RTMEM_PROT_WRITE | RTMEM_PROT_EXEC:
    195             fProt = PAGE_EXECUTE_READWRITE;
    196             break;
    197 
    198         case RTMEM_PROT_READ | RTMEM_PROT_EXEC:
    199             fProt = PAGE_EXECUTE_READWRITE;
    200             break;
    201 
    202         case RTMEM_PROT_WRITE:
    203             fProt = PAGE_READWRITE;
    204             break;
    205 
    206         case RTMEM_PROT_WRITE | RTMEM_PROT_EXEC:
    207             fProt = PAGE_EXECUTE_READWRITE;
    208             break;
    209 
    210         case RTMEM_PROT_EXEC:
    211             fProt = PAGE_EXECUTE_READWRITE;
    212             break;
    213 
    214         /* If the compiler had any brains it would warn about this case. */
    215         default:
    216             AssertMsgFailed(("fProtect=%#x\n", fProtect));
    217             return VERR_INTERNAL_ERROR;
    218     }
    219 
    220     /*
    221      * Align the request.
    222      */
    223     cb += (uintptr_t)pv & PAGE_OFFSET_MASK;
    224     pv = (void *)((uintptr_t)pv & ~(uintptr_t)PAGE_OFFSET_MASK);
    225 
    226     /*
    227      * Change the page attributes.
    228      */
    229     DWORD fFlags = 0;
    230     if (VirtualProtect(pv, cb, fProt, &fFlags))
    231         return VINF_SUCCESS;
    232     return RTErrConvertFromWin32(GetLastError());
    233 }
    234 
Note: See TracChangeset for help on using the changeset viewer.

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