Index: /trunk/include/iprt/mangling.h
===================================================================
--- /trunk/include/iprt/mangling.h	(revision 46566)
+++ /trunk/include/iprt/mangling.h	(revision 46567)
@@ -812,5 +812,5 @@
 # define RTMd5ToString                                  RT_MANGLER(RTMd5ToString)
 # define RTMd5Update                                    RT_MANGLER(RTMd5Update)
-# define RTMemAllocExTag                                RT_MANGLER(RTMemAllocExTag) /* r0drv */
+# define RTMemAllocExTag                                RT_MANGLER(RTMemAllocExTag)
 # define RTMemAllocTag                                  RT_MANGLER(RTMemAllocTag)
 # define RTMemAllocVarTag                               RT_MANGLER(RTMemAllocVarTag)
@@ -852,5 +852,5 @@
 # define RTMemExecFree                                  RT_MANGLER(RTMemExecFree)
 # define RTMemFree                                      RT_MANGLER(RTMemFree)
-# define RTMemFreeEx                                    RT_MANGLER(RTMemFreeEx)     /* r0drv */
+# define RTMemFreeEx                                    RT_MANGLER(RTMemFreeEx)
 # define RTMemPageAllocTag                              RT_MANGLER(RTMemPageAllocTag)
 # define RTMemPageAllocZTag                             RT_MANGLER(RTMemPageAllocZTag)
Index: /trunk/include/iprt/mem.h
===================================================================
--- /trunk/include/iprt/mem.h	(revision 46566)
+++ /trunk/include/iprt/mem.h	(revision 46567)
@@ -314,6 +314,14 @@
  * Will return VERR_NOT_SUPPORTED if not supported. */
 #define RTMEMALLOCEX_FLAGS_ANY_CTX          (RTMEMALLOCEX_FLAGS_ANY_CTX_ALLOC | RTMEMALLOCEX_FLAGS_ANY_CTX_FREE)
+/** Reachable by 16-bit address.
+ * Will return VERR_NOT_SUPPORTED if not supported.  */
+#define RTMEMALLOCEX_FLAGS_16BIT_REACH      RT_BIT(4)
+/** Reachable by 32-bit address.
+ * Will return VERR_NOT_SUPPORTED if not supported.  */
+#define RTMEMALLOCEX_FLAGS_32BIT_REACH      RT_BIT(5)
 /** Mask of valid flags. */
-#define RTMEMALLOCEX_FLAGS_VALID_MASK       UINT32_C(0x0000000f)
+#define RTMEMALLOCEX_FLAGS_VALID_MASK       UINT32_C(0x0000003f)
+/** Mask of valid flags for ring-0. */
+#define RTMEMALLOCEX_FLAGS_VALID_MASK_R0    UINT32_C(0x0000000f)
 /** @}  */
 
@@ -337,4 +345,7 @@
 /**
  * Extended heap allocation API, custom tag.
+ *
+ * Depending on the implementation, using this function may add extra overhead,
+ * so use the simpler APIs where ever possible.
  *
  * @returns IPRT status code.
@@ -358,4 +369,9 @@
  * @param   pv                  What to free, NULL is fine.
  * @param   cb                  The amount of allocated memory.
+ * @param   fFlags              The flags specified when allocating the memory.
+ *                              Whether the exact flags are requires depends on
+ *                              the implementation, but in general, ring-0
+ *                              doesn't require anything while ring-3 requires
+ *                              RTMEMALLOCEX_FLAGS_EXEC if used.
  */
 RTDECL(void) RTMemFreeEx(void *pv, size_t cb) RT_NO_THROW;
Index: /trunk/src/VBox/Runtime/Makefile.kmk
===================================================================
--- /trunk/src/VBox/Runtime/Makefile.kmk	(revision 46566)
+++ /trunk/src/VBox/Runtime/Makefile.kmk	(revision 46567)
@@ -583,4 +583,5 @@
 	generic/RTThreadGetNativeState-generic.cpp \
 	nt/RTErrConvertFromNtStatus.cpp \
+	r3/generic/allocex-r3-generic.cpp \
 	r3/posix/env-posix.cpp \
 	r3/win/RTHandleGetStandard-win.cpp \
@@ -638,4 +639,5 @@
 	generic/utf16locale-generic.cpp \
 	generic/uuid-generic.cpp \
+	r3/generic/allocex-r3-generic.cpp \
 	r3/linux/RTThreadGetNativeState-linux.cpp \
 	r3/linux/mp-linux.cpp \
@@ -735,4 +737,5 @@
 	generic/RTThreadGetNativeState-generic.cpp \
 	os2/RTErrConvertFromOS2.cpp \
+	r3/generic/allocex-r3-generic.cpp \
 	r3/os2/filelock-os2.cpp \
 	r3/os2/mp-os2.cpp \
@@ -808,4 +811,5 @@
 	r3/darwin/time-darwin.cpp \
 	r3/darwin/RTPathUserDocuments-darwin.cpp \
+	r3/generic/allocex-r3-generic.cpp \
 	r3/posix/RTFileQueryFsSizes-posix.cpp \
 	r3/posix/RTHandleGetStandard-posix.cpp \
@@ -868,4 +872,5 @@
 	r3/freebsd/mp-freebsd.cpp \
 	r3/freebsd/rtProcInitExePath-freebsd.cpp \
+	r3/generic/allocex-r3-generic.cpp \
 	r3/posix/RTFileQueryFsSizes-posix.cpp \
 	r3/posix/RTHandleGetStandard-posix.cpp \
@@ -928,4 +933,5 @@
 	generic/uuid-generic.cpp \
 	generic/RTThreadGetNativeState-generic.cpp \
+	r3/generic/allocex-r3-generic.cpp \
 	r3/posix/RTFileQueryFsSizes-posix.cpp \
 	r3/posix/RTHandleGetStandard-posix.cpp \
@@ -1003,4 +1009,5 @@
 	r3/haiku/rtProcInitExePath-haiku.cpp \
 	r3/haiku/time-haiku.cpp \
+	r3/generic/allocex-r3-generic.cpp \
 	r3/posix/RTFileQueryFsSizes-posix.cpp \
 	r3/posix/RTHandleGetStandard-posix.cpp \
Index: /trunk/src/VBox/Runtime/include/internal/magics.h
===================================================================
--- /trunk/src/VBox/Runtime/include/internal/magics.h	(revision 46566)
+++ /trunk/src/VBox/Runtime/include/internal/magics.h	(revision 46567)
@@ -115,4 +115,6 @@
 /** The magic value for heap blocks. (Edgar Allan Poe) */
 #define RTMEMHDR_MAGIC                  UINT32_C(0x18090119)
+/** The magic value for heap blocks after freeing. */
+#define RTMEMHDR_MAGIC_DEAD             UINT32_C(0x18491007)
 /** The value of RTPIPEINTERNAL::u32Magic. (Frank Schaetzing) */
 #define RTPIPE_MAGIC                    UINT32_C(0x19570528)
Index: /trunk/src/VBox/Runtime/r0drv/alloc-r0drv.cpp
===================================================================
--- /trunk/src/VBox/Runtime/r0drv/alloc-r0drv.cpp	(revision 46566)
+++ /trunk/src/VBox/Runtime/r0drv/alloc-r0drv.cpp	(revision 46567)
@@ -350,5 +350,5 @@
      * Validate and convert flags.
      */
-    AssertMsgReturn(!(fFlags & ~RTMEMALLOCEX_FLAGS_VALID_MASK), ("%#x\n", fFlags), VERR_INVALID_PARAMETER);
+    AssertMsgReturn(!(fFlags & ~RTMEMALLOCEX_FLAGS_VALID_MASK_R0), ("%#x\n", fFlags), VERR_INVALID_PARAMETER);
     if (fFlags & RTMEMALLOCEX_FLAGS_ZEROED)
         fHdrFlags |= RTMEMHDR_FLAG_ZEROED;
Index: /trunk/src/VBox/Runtime/r3/generic/allocex-r3-generic.cpp
===================================================================
--- /trunk/src/VBox/Runtime/r3/generic/allocex-r3-generic.cpp	(revision 46567)
+++ /trunk/src/VBox/Runtime/r3/generic/allocex-r3-generic.cpp	(revision 46567)
@@ -0,0 +1,135 @@
+/* $Id$ */
+/** @file
+ * IPRT - Memory Allocation, Extended Alloc and Free Functions for Ring-3, generic.
+ */
+
+/*
+ * Copyright (C) 2006-2013 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+
+/*******************************************************************************
+*   Header Files                                                               *
+*******************************************************************************/
+#define RTMEM_NO_WRAP_TO_EF_APIS
+#include <iprt/mem.h>
+#include "internal/iprt.h"
+
+#include <iprt/assert.h>
+#include <iprt/string.h>
+#include "internal/magics.h"
+
+
+/*******************************************************************************
+*   Structures and Typedefs                                                    *
+*******************************************************************************/
+/**
+ * Heading for extended memory allocations in ring-3.
+ */
+typedef struct RTMEMHDRR3
+{
+    /** Magic (RTMEMHDR_MAGIC). */
+    uint32_t    u32Magic;
+    /** Block flags (RTMEMALLOCEX_FLAGS_*). */
+    uint32_t    fFlags;
+    /** The actual size of the block, header not included. */
+    uint32_t    cb;
+    /** The requested allocation size. */
+    uint32_t    cbReq;
+} RTMEMHDRR3;
+/** Pointer to a ring-3 extended memory header. */
+typedef RTMEMHDRR3 *PRTMEMHDRR3;
+
+
+
+RTDECL(int) RTMemAllocExTag(size_t cb, size_t cbAlignment, uint32_t fFlags, const char *pszTag, void **ppv) RT_NO_THROW
+{
+    /*
+     * Validate and adjust input.
+     */
+    AssertMsgReturn(!(fFlags & ~RTMEMALLOCEX_FLAGS_VALID_MASK), ("%#x\n", fFlags), VERR_INVALID_PARAMETER);
+    AssertReturn(cb > 0, VERR_INVALID_PARAMETER);
+    AssertReturn(RT_IS_POWER_OF_TWO(cbAlignment), VERR_INVALID_PARAMETER);
+    AssertMsgReturn(cbAlignment <= sizeof(void *), ("%zu (%#x)\n", cbAlignment, cbAlignment), VERR_UNSUPPORTED_ALIGNMENT);
+
+    if (fFlags & (RTMEMALLOCEX_FLAGS_16BIT_REACH | RTMEMALLOCEX_FLAGS_32BIT_REACH | RTMEMALLOCEX_FLAGS_ANY_CTX))
+        return VERR_NOT_SUPPORTED;
+
+    /*
+     * Align the request.
+     */
+    size_t cbAligned = cb;
+    if (cbAlignment)
+        cbAligned = RT_ALIGN_Z(cb, cbAlignment);
+    else
+        cbAligned = RT_ALIGN_Z(cb, sizeof(uint64_t));
+    AssertMsgReturn(cbAligned >= cb && cbAligned <= ~(size_t)0 / 2U, ("cbAligned=%#zx cb=%#zx", cbAligned, cb),
+                    VERR_INVALID_PARAMETER);
+
+    /*
+     * Allocate the requested memory.
+     */
+    void *pv;
+    if (fFlags & RTMEMALLOCEX_FLAGS_EXEC)
+    {
+        pv = RTMemExecAlloc(cbAligned + sizeof(RTMEMHDRR3));
+        if ((fFlags & RTMEMALLOCEX_FLAGS_ZEROED) && pv)
+            RT_BZERO(pv, cbAligned + sizeof(RTMEMHDRR3));
+    }
+    else if (fFlags & RTMEMALLOCEX_FLAGS_ZEROED)
+        pv = RTMemAllocZ(cbAligned + sizeof(RTMEMHDRR3));
+    else
+        pv = RTMemAlloc(cbAligned + sizeof(RTMEMHDRR3));
+    if (!pv)
+        return VERR_NO_MEMORY;
+
+    /*
+     * Fill in the header and return.
+     */
+    PRTMEMHDRR3 pHdr = (PRTMEMHDRR3)pv;
+    pHdr->u32Magic  = RTMEMHDR_MAGIC;
+    pHdr->fFlags    = fFlags;
+    pHdr->cb        = cbAligned;
+    pHdr->cbReq     = cb;
+
+    *ppv = pHdr + 1;
+    return VINF_SUCCESS;
+}
+RT_EXPORT_SYMBOL(RTMemAllocExTag);
+
+
+RTDECL(void) RTMemFreeEx(void *pv, size_t cb) RT_NO_THROW
+{
+    if (!pv)
+        return;
+    AssertPtr(pv);
+
+    PRTMEMHDRR3 pHdr = (PRTMEMHDRR3)pv - 1;
+    AssertMsg(pHdr->u32Magic == RTMEMHDR_MAGIC, ("pHdr->u32Magic=%RX32 pv=%p cb=%#x\n", pHdr->u32Magic, pv, cb));
+    pHdr->u32Magic = RTMEMHDR_MAGIC_DEAD;
+    Assert(pHdr->cbReq == cb);
+
+    if (pHdr->fFlags & RTMEMALLOCEX_FLAGS_EXEC)
+        RTMemExecFree(pHdr, pHdr->cb + sizeof(*pHdr));
+    else
+        RTMemFree(pHdr);
+}
+RT_EXPORT_SYMBOL(RTMemFreeEx);
+
