VirtualBox

Changeset 46739 in vbox for trunk/src/VBox/Runtime


Ignore:
Timestamp:
Jun 23, 2013 4:10:25 PM (12 years ago)
Author:
vboxsync
Message:

reorged the allocex bits in ring3.

Location:
trunk/src/VBox/Runtime
Files:
1 added
3 edited
2 copied

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Runtime/Makefile.kmk

    r46646 r46739  
    494494        r3/alloc-ef.cpp \
    495495        r3/alloc.cpp \
     496        r3/allocex.cpp \
    496497        r3/dir.cpp \
    497498        r3/dir2.cpp \
     
    582583        generic/RTThreadGetNativeState-generic.cpp \
    583584        nt/RTErrConvertFromNtStatus.cpp \
    584         r3/generic/allocex-r3-generic.cpp \
    585585        r3/posix/env-posix.cpp \
    586586        r3/win/RTHandleGetStandard-win.cpp \
     
    590590        r3/win/RTSystemQueryTotalRam-win.cpp \
    591591        r3/win/alloc-win.cpp \
     592        r3/win/allocex-win.cpp \
    592593        r3/win/dir-win.cpp \
    593594        r3/win/errvars-win.cpp \
  • trunk/src/VBox/Runtime/r3/allocex.cpp

    r46729 r46739  
    3636#include <iprt/string.h>
    3737#include "internal/magics.h"
    38 
    39 #include <sys/mman.h>
    40 
    41 
    42 /*******************************************************************************
    43 *   Structures and Typedefs                                                    *
    44 *******************************************************************************/
    45 /**
    46  * Heading for extended memory allocations in ring-3.
    47  */
    48 typedef struct RTMEMHDRR3
    49 {
    50     /** Magic (RTMEMHDR_MAGIC). */
    51     uint32_t    u32Magic;
    52     /** Block flags (RTMEMALLOCEX_FLAGS_*). */
    53     uint32_t    fFlags;
    54     /** The actual size of the block, header not included. */
    55     uint32_t    cb;
    56     /** The requested allocation size. */
    57     uint32_t    cbReq;
    58 } RTMEMHDRR3;
    59 /** Pointer to a ring-3 extended memory header. */
    60 typedef RTMEMHDRR3 *PRTMEMHDRR3;
    61 
    62 
    63 /**
    64  * Allocates memory with upper boundrary.
    65  *
    66  * @returns Pointer to mmap allocation.
    67  * @param   cbAlloc             Number of bytes to alloacate.
    68  * @param   fFlags              Allocation flags.
    69  */
    70 static void *rtMemAllocExAllocLow(size_t cbAlloc, uint32_t fFlags)
    71 {
    72     int   fProt = PROT_READ | PROT_WRITE | (fFlags & RTMEMALLOCEX_FLAGS_EXEC ? PROT_EXEC : 0);
    73     void *pv    = NULL;
    74     if (fFlags & RTMEMALLOCEX_FLAGS_16BIT_REACH)
    75     {
    76         AssertReturn(cbAlloc < _64K, NULL);
    77 
    78         /*
    79          * Try with every possible address hint since the possible range is very limited.
    80          */
    81         uintptr_t uAddr     = fFlags & RTMEMALLOCEX_FLAGS_16BIT_REACH ? 0x1000  : _1M;
    82         uintptr_t uAddrLast = _64K - uAddr - cbAlloc;
    83         while (uAddr <= uAddrLast)
    84         {
    85             pv = mmap((void *)uAddr, cbAlloc, fProt, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
    86             if (pv && (uintptr_t)pv <= uAddrLast)
    87                 break;
    88             if (pv)
    89             {
    90                 munmap(pv, cbAlloc);
    91                 pv = NULL;
    92             }
    93             uAddr += _4K;
    94         }
    95     }
    96     else
    97     {
    98 #if ARCH_BITS == 32
    99         pv = mmap(NULL, cbAlloc, fProt, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
    100 
    101 #elif defined(RT_OS_LINUX)
    102 # ifdef MAP_32BIT
    103         pv = mmap(NULL, cbAlloc, fProt, MAP_PRIVATE | MAP_ANONYMOUS | MAP_32BIT, -1, 0);
    104         if (pv)
    105             return pv;
    106 # endif
    107 
    108         /** @todo On linux, we need an accurate hint. Since I don't need this branch of
    109          *        the code right now, I won't bother starting to parse
    110          *        /proc/curproc/mmap right now... */
    111         pv = NULL;
    112 #else
    113         pv = NULL;
    114 #endif
    115     }
    116     return pv;
    117 }
     38#include "allocex.h"
    11839
    11940
     
    14768    void *pv;
    14869    if (fFlags & (RTMEMALLOCEX_FLAGS_16BIT_REACH | RTMEMALLOCEX_FLAGS_32BIT_REACH))
    149         pv = rtMemAllocExAllocLow(cbAligned + sizeof(RTMEMHDRR3), fFlags);
     70    {
     71        int rc;
     72        if (fFlags & RTMEMALLOCEX_FLAGS_16BIT_REACH)
     73            rc = rtMemAllocEx16BitReach(cbAligned + sizeof(RTMEMHDRR3), fFlags, &pv);
     74        else
     75            rc = rtMemAllocEx32BitReach(cbAligned + sizeof(RTMEMHDRR3), fFlags, &pv);
     76        if (RT_FAILURE(rc))
     77            return rc;
     78    }
    15079    else if (fFlags & RTMEMALLOCEX_FLAGS_EXEC)
    15180    {
     
    16796    pHdr->u32Magic  = RTMEMHDR_MAGIC;
    16897    pHdr->fFlags    = fFlags;
    169     pHdr->cb        = cbAligned;
    170     pHdr->cbReq     = cb;
     98    pHdr->cb        = (uint32_t)cbAligned;
     99    pHdr->cbReq     = (uint32_t)cb;
    171100
    172101    *ppv = pHdr + 1;
     
    188117
    189118    if (pHdr->fFlags & (RTMEMALLOCEX_FLAGS_16BIT_REACH | RTMEMALLOCEX_FLAGS_32BIT_REACH))
    190         munmap(pHdr, pHdr->cb + sizeof(*pHdr));
     119        rtMemFreeExYyBitReach(pHdr, pHdr->cb + sizeof(*pHdr), pHdr->fFlags);
    191120    else if (pHdr->fFlags & RTMEMALLOCEX_FLAGS_EXEC)
    192121        RTMemExecFree(pHdr, pHdr->cb + sizeof(*pHdr));
  • trunk/src/VBox/Runtime/r3/generic/allocex-r3-generic.cpp

    r46568 r46739  
    11/* $Id$ */
    22/** @file
    3  * IPRT - Memory Allocation, Extended Alloc and Free Functions for Ring-3, generic.
     3 * IPRT - Memory Allocation, Extended Alloc Workers, generic.
    44 */
    55
     
    3434
    3535#include <iprt/assert.h>
    36 #include <iprt/string.h>
    37 #include "internal/magics.h"
    38 
    39 
    40 /*******************************************************************************
    41 *   Structures and Typedefs                                                    *
    42 *******************************************************************************/
    43 /**
    44  * Heading for extended memory allocations in ring-3.
    45  */
    46 typedef struct RTMEMHDRR3
    47 {
    48     /** Magic (RTMEMHDR_MAGIC). */
    49     uint32_t    u32Magic;
    50     /** Block flags (RTMEMALLOCEX_FLAGS_*). */
    51     uint32_t    fFlags;
    52     /** The actual size of the block, header not included. */
    53     uint32_t    cb;
    54     /** The requested allocation size. */
    55     uint32_t    cbReq;
    56 } RTMEMHDRR3;
    57 /** Pointer to a ring-3 extended memory header. */
    58 typedef RTMEMHDRR3 *PRTMEMHDRR3;
     36#include "../allocex-r3.h"
    5937
    6038
    6139
    62 RTDECL(int) RTMemAllocExTag(size_t cb, size_t cbAlignment, uint32_t fFlags, const char *pszTag, void **ppv) RT_NO_THROW
     40DECLHIDDEN(int) rtMemAllocEx16BitReach(size_t cbAlloc, uint32_t fFlags, void **ppv)
    6341{
    64     /*
    65      * Validate and adjust input.
    66      */
    67     AssertMsgReturn(!(fFlags & ~RTMEMALLOCEX_FLAGS_VALID_MASK), ("%#x\n", fFlags), VERR_INVALID_PARAMETER);
    68     AssertReturn(cb > 0, VERR_INVALID_PARAMETER);
    69     AssertReturn(RT_IS_POWER_OF_TWO(cbAlignment), VERR_INVALID_PARAMETER);
    70     AssertMsgReturn(cbAlignment <= sizeof(void *), ("%zu (%#x)\n", cbAlignment, cbAlignment), VERR_UNSUPPORTED_ALIGNMENT);
    71 
    72     if (fFlags & (RTMEMALLOCEX_FLAGS_16BIT_REACH | RTMEMALLOCEX_FLAGS_32BIT_REACH | RTMEMALLOCEX_FLAGS_ANY_CTX))
    73         return VERR_NOT_SUPPORTED;
    74 
    75     /*
    76      * Align the request.
    77      */
    78     size_t cbAligned = cb;
    79     if (cbAlignment)
    80         cbAligned = RT_ALIGN_Z(cb, cbAlignment);
    81     else
    82         cbAligned = RT_ALIGN_Z(cb, sizeof(uint64_t));
    83     AssertMsgReturn(cbAligned >= cb && cbAligned <= ~(size_t)0, ("cbAligned=%#zx cb=%#zx", cbAligned, cb),
    84                     VERR_INVALID_PARAMETER);
    85 
    86     /*
    87      * Allocate the requested memory.
    88      */
    89     void *pv;
    90     if (fFlags & RTMEMALLOCEX_FLAGS_EXEC)
    91     {
    92         pv = RTMemExecAlloc(cbAligned + sizeof(RTMEMHDRR3));
    93         if ((fFlags & RTMEMALLOCEX_FLAGS_ZEROED) && pv)
    94             RT_BZERO(pv, cbAligned + sizeof(RTMEMHDRR3));
    95     }
    96     else if (fFlags & RTMEMALLOCEX_FLAGS_ZEROED)
    97         pv = RTMemAllocZ(cbAligned + sizeof(RTMEMHDRR3));
    98     else
    99         pv = RTMemAlloc(cbAligned + sizeof(RTMEMHDRR3));
    100     if (!pv)
    101         return VERR_NO_MEMORY;
    102 
    103     /*
    104      * Fill in the header and return.
    105      */
    106     PRTMEMHDRR3 pHdr = (PRTMEMHDRR3)pv;
    107     pHdr->u32Magic  = RTMEMHDR_MAGIC;
    108     pHdr->fFlags    = fFlags;
    109     pHdr->cb        = (uint32_t)cbAligned;
    110     pHdr->cbReq     = (uint32_t)cb;
    111 
    112     *ppv = pHdr + 1;
    113     return VINF_SUCCESS;
     42    return VERR_NOT_SUPPORTED;
    11443}
    115 RT_EXPORT_SYMBOL(RTMemAllocExTag);
    11644
    11745
    118 RTDECL(void) RTMemFreeEx(void *pv, size_t cb) RT_NO_THROW
     46DECLHIDDEN(int) rtMemAllocEx32BitReach(size_t cbAlloc, uint32_t fFlags, void **ppv)
    11947{
    120     if (!pv)
    121         return;
    122     AssertPtr(pv);
     48    return VERR_NOT_SUPPORTED;
     49}
    12350
    124     PRTMEMHDRR3 pHdr = (PRTMEMHDRR3)pv - 1;
    125     AssertMsg(pHdr->u32Magic == RTMEMHDR_MAGIC, ("pHdr->u32Magic=%RX32 pv=%p cb=%#x\n", pHdr->u32Magic, pv, cb));
    126     pHdr->u32Magic = RTMEMHDR_MAGIC_DEAD;
    127     Assert(pHdr->cbReq == cb);
    12851
    129     if (pHdr->fFlags & RTMEMALLOCEX_FLAGS_EXEC)
    130         RTMemExecFree(pHdr, pHdr->cb + sizeof(*pHdr));
    131     else
    132         RTMemFree(pHdr);
     52DECLHIDDEN(void) rtMemFreeExYyBitReach(void *pv, size_t cb, uint32_t fFlags)
     53{
     54    AssertFailed();
    13355}
    134 RT_EXPORT_SYMBOL(RTMemFreeEx);
    13556
  • trunk/src/VBox/Runtime/r3/posix/allocex-r3-posix.cpp

    r46729 r46739  
    11/* $Id$ */
    22/** @file
    3  * IPRT - Memory Allocation, Extended Alloc and Free Functions for Ring-3, posix.
     3 * IPRT - Memory Allocation, Extended Alloc Workers, posix.
    44 */
    55
     
    3535#include <iprt/assert.h>
    3636#include <iprt/string.h>
    37 #include "internal/magics.h"
     37#include "../allocex.h"
    3838
    3939#include <sys/mman.h>
    4040
    4141
    42 /*******************************************************************************
    43 *   Structures and Typedefs                                                    *
    44 *******************************************************************************/
    45 /**
    46  * Heading for extended memory allocations in ring-3.
    47  */
    48 typedef struct RTMEMHDRR3
     42DECLHIDDEN(int) rtMemAllocEx16BitReach(size_t cbAlloc, uint32_t fFlags, void **ppv)
    4943{
    50     /** Magic (RTMEMHDR_MAGIC). */
    51     uint32_t    u32Magic;
    52     /** Block flags (RTMEMALLOCEX_FLAGS_*). */
    53     uint32_t    fFlags;
    54     /** The actual size of the block, header not included. */
    55     uint32_t    cb;
    56     /** The requested allocation size. */
    57     uint32_t    cbReq;
    58 } RTMEMHDRR3;
    59 /** Pointer to a ring-3 extended memory header. */
    60 typedef RTMEMHDRR3 *PRTMEMHDRR3;
     44    AssertReturn(cbAlloc < _64K, NULL);
     45
     46    /*
     47     * Try with every possible address hint since the possible range is very limited.
     48     */
     49    int       fProt     = PROT_READ | PROT_WRITE | (fFlags & RTMEMALLOCEX_FLAGS_EXEC ? PROT_EXEC : 0);
     50    uintptr_t uAddr     = 0x1000;
     51    uintptr_t uAddrLast = _64K - uAddr - cbAlloc;
     52    while (uAddr <= uAddrLast)
     53    {
     54        void *pv = mmap((void *)uAddr, cbAlloc, fProt, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
     55        if (pv && (uintptr_t)pv <= uAddrLast)
     56        {
     57            *ppv = pv;
     58            return VINF_SUCCESS;
     59        }
     60
     61        if (pv)
     62        {
     63            munmap(pv, cbAlloc);
     64            pv = NULL;
     65        }
     66        uAddr += _4K;
     67    }
     68
     69    return VERR_NO_MEMORY;
     70}
    6171
    6272
    63 /**
    64  * Allocates memory with upper boundrary.
    65  *
    66  * @returns Pointer to mmap allocation.
    67  * @param   cbAlloc             Number of bytes to alloacate.
    68  * @param   fFlags              Allocation flags.
    69  */
    70 static void *rtMemAllocExAllocLow(size_t cbAlloc, uint32_t fFlags)
     73DECLHIDDEN(int) rtMemAllocEx32BitReach(size_t cbAlloc, uint32_t fFlags, void **ppv)
    7174{
    72     int   fProt = PROT_READ | PROT_WRITE | (fFlags & RTMEMALLOCEX_FLAGS_EXEC ? PROT_EXEC : 0);
    73     void *pv    = NULL;
    74     if (fFlags & RTMEMALLOCEX_FLAGS_16BIT_REACH)
     75    int     fProt = PROT_READ | PROT_WRITE | (fFlags & RTMEMALLOCEX_FLAGS_EXEC ? PROT_EXEC : 0);
     76#if ARCH_BITS == 32
     77    void   *pv = mmap(NULL, cbAlloc, fProt, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
     78    if (pv)
    7579    {
    76         AssertReturn(cbAlloc < _64K, NULL);
    77 
    78         /*
    79          * Try with every possible address hint since the possible range is very limited.
    80          */
    81         uintptr_t uAddr     = fFlags & RTMEMALLOCEX_FLAGS_16BIT_REACH ? 0x1000  : _1M;
    82         uintptr_t uAddrLast = _64K - uAddr - cbAlloc;
    83         while (uAddr <= uAddrLast)
    84         {
    85             pv = mmap((void *)uAddr, cbAlloc, fProt, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
    86             if (pv && (uintptr_t)pv <= uAddrLast)
    87                 break;
    88             if (pv)
    89             {
    90                 munmap(pv, cbAlloc);
    91                 pv = NULL;
    92             }
    93             uAddr += _4K;
    94         }
     80        *ppv = pv;
     81        return VINF_SUCCESS;
    9582    }
    96     else
    97     {
    98 #if ARCH_BITS == 32
    99         pv = mmap(NULL, cbAlloc, fProt, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
     83    return VERR_NO_MEMORY;
    10084
    10185#elif defined(RT_OS_LINUX)
    10286# ifdef MAP_32BIT
    103         pv = mmap(NULL, cbAlloc, fProt, MAP_PRIVATE | MAP_ANONYMOUS | MAP_32BIT, -1, 0);
    104         if (pv)
    105             return pv;
     87    void *pv = mmap(NULL, cbAlloc, fProt, MAP_PRIVATE | MAP_ANONYMOUS | MAP_32BIT, -1, 0);
     88    if (pv)
     89    {
     90        *ppv = pv;
     91        return VINF_SUCCESS;
     92    }
    10693# endif
    10794
    108         /** @todo On linux, we need an accurate hint. Since I don't need this branch of
    109          *        the code right now, I won't bother starting to parse
    110          *        /proc/curproc/mmap right now... */
    111         pv = NULL;
     95    /** @todo On linux, we need an accurate hint. Since I don't need this branch of
     96     *        the code right now, I won't bother starting to parse
     97     *        /proc/curproc/mmap right now... */
    11298#else
    113         pv = NULL;
    11499#endif
    115     }
    116     return pv;
     100    return VERR_NOT_SUPPORTED;
    117101}
    118102
    119103
    120 RTDECL(int) RTMemAllocExTag(size_t cb, size_t cbAlignment, uint32_t fFlags, const char *pszTag, void **ppv) RT_NO_THROW
     104DECLHIDDEN(void) rtMemFreeExYyBitReach(void *pv, size_t cb, uint32_t fFlags)
    121105{
    122     /*
    123      * Validate and adjust input.
    124      */
    125     AssertMsgReturn(!(fFlags & ~RTMEMALLOCEX_FLAGS_VALID_MASK), ("%#x\n", fFlags), VERR_INVALID_PARAMETER);
    126     AssertReturn(cb > 0, VERR_INVALID_PARAMETER);
    127     AssertReturn(RT_IS_POWER_OF_TWO(cbAlignment), VERR_INVALID_PARAMETER);
    128     AssertMsgReturn(cbAlignment <= sizeof(void *), ("%zu (%#x)\n", cbAlignment, cbAlignment), VERR_UNSUPPORTED_ALIGNMENT);
     106    munmap(pv, cb);
     107}
    129108
    130     if (fFlags & RTMEMALLOCEX_FLAGS_ANY_CTX)
    131         return VERR_NOT_SUPPORTED;
    132 
    133     /*
    134      * Align the request.
    135      */
    136     size_t cbAligned = cb;
    137     if (cbAlignment)
    138         cbAligned = RT_ALIGN_Z(cb, cbAlignment);
    139     else
    140         cbAligned = RT_ALIGN_Z(cb, sizeof(uint64_t));
    141     AssertMsgReturn(cbAligned >= cb && cbAligned <= ~(size_t)0, ("cbAligned=%#zx cb=%#zx", cbAligned, cb),
    142                     VERR_INVALID_PARAMETER);
    143 
    144     /*
    145      * Allocate the requested memory.
    146      */
    147     void *pv;
    148     if (fFlags & (RTMEMALLOCEX_FLAGS_16BIT_REACH | RTMEMALLOCEX_FLAGS_32BIT_REACH))
    149         pv = rtMemAllocExAllocLow(cbAligned + sizeof(RTMEMHDRR3), fFlags);
    150     else if (fFlags & RTMEMALLOCEX_FLAGS_EXEC)
    151     {
    152         pv = RTMemExecAlloc(cbAligned + sizeof(RTMEMHDRR3));
    153         if ((fFlags & RTMEMALLOCEX_FLAGS_ZEROED) && pv)
    154             RT_BZERO(pv, cbAligned + sizeof(RTMEMHDRR3));
    155     }
    156     else if (fFlags & RTMEMALLOCEX_FLAGS_ZEROED)
    157         pv = RTMemAllocZ(cbAligned + sizeof(RTMEMHDRR3));
    158     else
    159         pv = RTMemAlloc(cbAligned + sizeof(RTMEMHDRR3));
    160     if (!pv)
    161         return VERR_NO_MEMORY;
    162 
    163     /*
    164      * Fill in the header and return.
    165      */
    166     PRTMEMHDRR3 pHdr = (PRTMEMHDRR3)pv;
    167     pHdr->u32Magic  = RTMEMHDR_MAGIC;
    168     pHdr->fFlags    = fFlags;
    169     pHdr->cb        = cbAligned;
    170     pHdr->cbReq     = cb;
    171 
    172     *ppv = pHdr + 1;
    173     return VINF_SUCCESS;
    174 }
    175 RT_EXPORT_SYMBOL(RTMemAllocExTag);
    176 
    177 
    178 RTDECL(void) RTMemFreeEx(void *pv, size_t cb) RT_NO_THROW
    179 {
    180     if (!pv)
    181         return;
    182     AssertPtr(pv);
    183 
    184     PRTMEMHDRR3 pHdr = (PRTMEMHDRR3)pv - 1;
    185     AssertMsg(pHdr->u32Magic == RTMEMHDR_MAGIC, ("pHdr->u32Magic=%RX32 pv=%p cb=%#x\n", pHdr->u32Magic, pv, cb));
    186     pHdr->u32Magic = RTMEMHDR_MAGIC_DEAD;
    187     Assert(pHdr->cbReq == cb);
    188 
    189     if (pHdr->fFlags & (RTMEMALLOCEX_FLAGS_16BIT_REACH | RTMEMALLOCEX_FLAGS_32BIT_REACH))
    190         munmap(pHdr, pHdr->cb + sizeof(*pHdr));
    191     else if (pHdr->fFlags & RTMEMALLOCEX_FLAGS_EXEC)
    192         RTMemExecFree(pHdr, pHdr->cb + sizeof(*pHdr));
    193     else
    194         RTMemFree(pHdr);
    195 }
    196 RT_EXPORT_SYMBOL(RTMemFreeEx);
    197 
  • trunk/src/VBox/Runtime/r3/win/allocex-win.cpp

    r46729 r46739  
    11/* $Id$ */
    22/** @file
    3  * IPRT - Memory Allocation, Extended Alloc and Free Functions for Ring-3, generic.
     3 * IPRT - Memory Allocation, Extended Alloc Workers, Windows.
    44 */
    55
     
    3535#include <iprt/assert.h>
    3636#include <iprt/string.h>
    37 #include "internal/magics.h"
     37#include <iprt/param.h>
     38#include "../allocex.h"
     39
     40#include <Windows.h>
    3841
    3942
    40 /*******************************************************************************
    41 *   Structures and Typedefs                                                    *
    42 *******************************************************************************/
    43 /**
    44  * Heading for extended memory allocations in ring-3.
    45  */
    46 typedef struct RTMEMHDRR3
     43static int rtMemAllocExInRange(size_t cbAlloc, uint32_t fFlags, void **ppv, uintptr_t uAddr, uintptr_t uAddrLast)
    4744{
    48     /** Magic (RTMEMHDR_MAGIC). */
    49     uint32_t    u32Magic;
    50     /** Block flags (RTMEMALLOCEX_FLAGS_*). */
    51     uint32_t    fFlags;
    52     /** The actual size of the block, header not included. */
    53     uint32_t    cb;
    54     /** The requested allocation size. */
    55     uint32_t    cbReq;
    56 } RTMEMHDRR3;
    57 /** Pointer to a ring-3 extended memory header. */
    58 typedef RTMEMHDRR3 *PRTMEMHDRR3;
     45    /*
     46     * Try with every possible address hint since the possible range is very limited.
     47     */
     48    DWORD     fPageProt = (fFlags & RTMEMALLOCEX_FLAGS_EXEC ? PAGE_EXECUTE_READWRITE : PAGE_READWRITE);
     49    while (uAddr <= uAddrLast)
     50    {
     51        MEMORY_BASIC_INFORMATION MemInfo;
     52        SIZE_T cbRange = VirtualQuery((void *)uAddr, &MemInfo, sizeof(MemInfo));
     53        AssertReturn(cbRange == sizeof(MemInfo), VERR_NOT_SUPPORTED);
     54        Assert(MemInfo.RegionSize > 0);
     55
     56        if (   MemInfo.State == MEM_FREE
     57            && MemInfo.RegionSize >= cbAlloc)
     58        {
     59            void *pv = VirtualAlloc((void *)uAddr, cbAlloc, MEM_RESERVE | MEM_COMMIT, fPageProt);
     60            if ((uintptr_t)pv == uAddr)
     61            {
     62                *ppv = pv;
     63                return VINF_SUCCESS;
     64            }
     65            AssertStmt(!pv, VirtualFree(pv, cbAlloc, MEM_RELEASE));
     66        }
     67
     68        /* skip ahead */
     69        uintptr_t uAddrNext = (uintptr_t)MemInfo.BaseAddress + MemInfo.RegionSize;
     70        if (uAddrNext <= uAddr)
     71            break;
     72        uAddr += uAddrNext;
     73    }
     74
     75    return VERR_NO_MEMORY;
     76}
    5977
    6078
     79DECLHIDDEN(int) rtMemAllocEx16BitReach(size_t cbAlloc, uint32_t fFlags, void **ppv)
     80{
     81    cbAlloc = RT_ALIGN_Z(cbAlloc, PAGE_SIZE);
     82    AssertReturn(cbAlloc <= _64K - PAGE_SIZE, VERR_NO_MEMORY);
    6183
    62 RTDECL(int) RTMemAllocExTag(size_t cb, size_t cbAlignment, uint32_t fFlags, const char *pszTag, void **ppv) RT_NO_THROW
     84    /* Seems this doesn't work on W7/64... */
     85    return rtMemAllocExInRange(cbAlloc, fFlags, ppv, PAGE_SIZE, _64K - cbAlloc);
     86}
     87
     88
     89DECLHIDDEN(int) rtMemAllocEx32BitReach(size_t cbAlloc, uint32_t fFlags, void **ppv)
    6390{
    64     /*
    65      * Validate and adjust input.
    66      */
    67     AssertMsgReturn(!(fFlags & ~RTMEMALLOCEX_FLAGS_VALID_MASK), ("%#x\n", fFlags), VERR_INVALID_PARAMETER);
    68     AssertReturn(cb > 0, VERR_INVALID_PARAMETER);
    69     AssertReturn(RT_IS_POWER_OF_TWO(cbAlignment), VERR_INVALID_PARAMETER);
    70     AssertMsgReturn(cbAlignment <= sizeof(void *), ("%zu (%#x)\n", cbAlignment, cbAlignment), VERR_UNSUPPORTED_ALIGNMENT);
    71 
    72     if (fFlags & (RTMEMALLOCEX_FLAGS_16BIT_REACH | RTMEMALLOCEX_FLAGS_32BIT_REACH | RTMEMALLOCEX_FLAGS_ANY_CTX))
    73         return VERR_NOT_SUPPORTED;
     91    cbAlloc = RT_ALIGN_Z(cbAlloc, PAGE_SIZE);
     92    AssertReturn(cbAlloc <= _2G+_1G, VERR_NO_MEMORY);
    7493
    7594    /*
    76      * Align the request.
     95     * Just try first.
    7796     */
    78     size_t cbAligned = cb;
    79     if (cbAlignment)
    80         cbAligned = RT_ALIGN_Z(cb, cbAlignment);
    81     else
    82         cbAligned = RT_ALIGN_Z(cb, sizeof(uint64_t));
    83     AssertMsgReturn(cbAligned >= cb && cbAligned <= ~(size_t)0, ("cbAligned=%#zx cb=%#zx", cbAligned, cb),
    84                     VERR_INVALID_PARAMETER);
     97    DWORD     fPageProt = (fFlags & RTMEMALLOCEX_FLAGS_EXEC ? PAGE_EXECUTE_READWRITE : PAGE_READWRITE);
     98    void *pv = VirtualAlloc(NULL, cbAlloc, MEM_RESERVE | MEM_COMMIT, fPageProt);
     99    if (!pv)
     100        return VERR_NO_MEMORY;
     101    if ((uintptr_t)pv + cbAlloc - 1 < _4G)
     102    {
     103        *ppv = pv;
     104        return VINF_SUCCESS;
     105    }
     106    VirtualFree(pv, cbAlloc, MEM_RELEASE);
    85107
    86108    /*
    87      * Allocate the requested memory.
     109     * No luck, do address scan based allocation.
    88110     */
    89     void *pv;
    90     if (fFlags & RTMEMALLOCEX_FLAGS_EXEC)
    91     {
    92         pv = RTMemExecAlloc(cbAligned + sizeof(RTMEMHDRR3));
    93         if ((fFlags & RTMEMALLOCEX_FLAGS_ZEROED) && pv)
    94             RT_BZERO(pv, cbAligned + sizeof(RTMEMHDRR3));
    95     }
    96     else if (fFlags & RTMEMALLOCEX_FLAGS_ZEROED)
    97         pv = RTMemAllocZ(cbAligned + sizeof(RTMEMHDRR3));
    98     else
    99         pv = RTMemAlloc(cbAligned + sizeof(RTMEMHDRR3));
    100     if (!pv)
    101         return VERR_NO_MEMORY;
    102 
    103     /*
    104      * Fill in the header and return.
    105      */
    106     PRTMEMHDRR3 pHdr = (PRTMEMHDRR3)pv;
    107     pHdr->u32Magic  = RTMEMHDR_MAGIC;
    108     pHdr->fFlags    = fFlags;
    109     pHdr->cb        = (uint32_t)cbAligned;
    110     pHdr->cbReq     = (uint32_t)cb;
    111 
    112     *ppv = pHdr + 1;
    113     return VINF_SUCCESS;
     111    return rtMemAllocExInRange(cbAlloc, fFlags, ppv, _64K, _4G - cbAlloc);
    114112}
    115 RT_EXPORT_SYMBOL(RTMemAllocExTag);
    116113
    117114
    118 RTDECL(void) RTMemFreeEx(void *pv, size_t cb) RT_NO_THROW
     115DECLHIDDEN(void) rtMemFreeExYyBitReach(void *pv, size_t cb, uint32_t fFlags)
    119116{
    120     if (!pv)
    121         return;
    122     AssertPtr(pv);
     117    BOOL fRc = VirtualFree(pv, cb, MEM_RELEASE);
     118    Assert(fRc);
     119}
    123120
    124     PRTMEMHDRR3 pHdr = (PRTMEMHDRR3)pv - 1;
    125     AssertMsg(pHdr->u32Magic == RTMEMHDR_MAGIC, ("pHdr->u32Magic=%RX32 pv=%p cb=%#x\n", pHdr->u32Magic, pv, cb));
    126     pHdr->u32Magic = RTMEMHDR_MAGIC_DEAD;
    127     Assert(pHdr->cbReq == cb);
    128 
    129     if (pHdr->fFlags & RTMEMALLOCEX_FLAGS_EXEC)
    130         RTMemExecFree(pHdr, pHdr->cb + sizeof(*pHdr));
    131     else
    132         RTMemFree(pHdr);
    133 }
    134 RT_EXPORT_SYMBOL(RTMemFreeEx);
    135 
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