diff --git a/inc/malloc_km.h b/kext/kmalloc.h
similarity index 100%
rename from inc/malloc_km.h
rename to kext/kmalloc.h
diff --git a/inc/new_km.h b/kext/knew.h
similarity index 100%
rename from inc/new_km.h
rename to kext/knew.h
diff --git a/msvc/ucxxrt.vcxproj b/msvc/ucxxrt.vcxproj
index d9fad6a..f611493 100644
--- a/msvc/ucxxrt.vcxproj
+++ b/msvc/ucxxrt.vcxproj
@@ -270,7 +270,6 @@
-
@@ -299,7 +298,6 @@
-
@@ -343,26 +341,16 @@
-
-
-
- true
- true
- true
- true
-
+
-
-
+
-
-
+
-
diff --git a/msvc/ucxxrt.vcxproj.filters b/msvc/ucxxrt.vcxproj.filters
index 084f3ee..79dfd79 100644
--- a/msvc/ucxxrt.vcxproj.filters
+++ b/msvc/ucxxrt.vcxproj.filters
@@ -254,9 +254,6 @@
ucxxrt\crt\vcruntime
-
- ucxxrt\crt\vcruntime
-
ucxxrt\crt\vcruntime
@@ -338,9 +335,6 @@
ucxxrt\crt\vcruntime
-
- ucxxrt\crt\vcruntime
-
ucxxrt\crt\vcruntime
@@ -647,33 +641,18 @@
ucxxrt\ucrt\heap
-
- ucxxrt\ucrt\heap
-
-
- ucxxrt\ucrt\heap
-
ucxxrt\ucrt\heap
ucxxrt\ucrt\heap
-
- ucxxrt\ucrt\heap
-
-
- ucxxrt\ucrt\heap
-
ucxxrt\ucrt\heap
ucxxrt\ucrt\heap
-
- ucxxrt\ucrt\heap
-
ucxxrt\ucrt\heap
@@ -686,13 +665,13 @@
ucxxrt\crt\vcruntime
-
+
ucxxrt\ucrt\heap
-
+
ucxxrt\ucrt\heap
-
+
ucxxrt\ucrt\heap
diff --git a/src/crt/vcruntime/delete_debug.cpp b/src/crt/vcruntime/delete_debug.cpp
deleted file mode 100644
index 8a2326f..0000000
--- a/src/crt/vcruntime/delete_debug.cpp
+++ /dev/null
@@ -1,72 +0,0 @@
-//
-// delete_debug.cpp
-//
-// Copyright (c) Microsoft Corporation. All rights reserved.
-//
-// Defines the debug operator delete (both scalar and array forms).
-//
-#include
-#include
-
-
-
-#ifdef _DEBUG
-
- _CRT_SECURITYCRITICAL_ATTRIBUTE
- void __CRTDECL operator delete(
- void* block,
- int const block_use,
- char const* file_name,
- int const line_number
- ) noexcept
- {
- UNREFERENCED_PARAMETER(file_name);
- UNREFERENCED_PARAMETER(line_number);
-
- _free_dbg(block, block_use);
- }
-
- _CRT_SECURITYCRITICAL_ATTRIBUTE
- void __CRTDECL operator delete[](
- void* block,
- int const block_use,
- char const* file_name,
- int const line_number
- ) noexcept
- {
- return operator delete(block, block_use, file_name, line_number);
- }
-
-#else // ^^^ _DEBUG ^^^ // vvv !_DEBUG vvv //
-
- _CRT_SECURITYCRITICAL_ATTRIBUTE
- void __CRTDECL operator delete(
- void* block,
- int const block_use,
- char const* file_name,
- int const line_number
- ) noexcept
- {
- UNREFERENCED_PARAMETER(block_use);
- UNREFERENCED_PARAMETER(file_name);
- UNREFERENCED_PARAMETER(line_number);
-
- return operator delete(block);
- }
-
- _CRT_SECURITYCRITICAL_ATTRIBUTE
- void __CRTDECL operator delete[](
- void* block,
- int const block_use,
- char const* file_name,
- int const line_number
- ) noexcept
- {
- UNREFERENCED_PARAMETER(block_use);
- UNREFERENCED_PARAMETER(file_name);
- UNREFERENCED_PARAMETER(line_number);
-
- return operator delete[](block);
- }
-
-#endif
diff --git a/src/crt/vcruntime/delete_km.cpp b/src/crt/vcruntime/delete_km.cpp
index 8bf344b..4bf2f9d 100644
--- a/src/crt/vcruntime/delete_km.cpp
+++ b/src/crt/vcruntime/delete_km.cpp
@@ -14,6 +14,7 @@
#include
#include
#include
+#include
////////////////////////////////////////////////////////////////
// delete() Fallback Ordering
diff --git a/src/crt/vcruntime/delete_scalar.cpp b/src/crt/vcruntime/delete_scalar.cpp
index 85e7cf3..3ba19e0 100644
--- a/src/crt/vcruntime/delete_scalar.cpp
+++ b/src/crt/vcruntime/delete_scalar.cpp
@@ -30,9 +30,5 @@
_CRT_SECURITYCRITICAL_ATTRIBUTE
void __CRTDECL operator delete(void* const block) noexcept
{
- #ifdef _DEBUG
- _free_dbg(block, _UNKNOWN_BLOCK);
- #else
free(block);
- #endif
}
diff --git a/src/crt/vcruntime/internal_shared.h b/src/crt/vcruntime/internal_shared.h
index c06de47..6bb07e4 100644
--- a/src/crt/vcruntime/internal_shared.h
+++ b/src/crt/vcruntime/internal_shared.h
@@ -248,53 +248,17 @@ extern "C++"
// CRT Memory Allocation and Management
//
//-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-#ifdef _DEBUG
- // These must match the definitions in the CoreCRT's debug header. They
- // are defined separately here to avoid unwanted CRT header dependencies.
- #define _NORMAL_BLOCK 1
- #define _CRT_BLOCK 2
-
- #define _calloc_crt(c, s) (_calloc_dbg ( c, s, _CRT_BLOCK, __FILE__, __LINE__))
- #define _free_crt(p) (_free_dbg (p, _CRT_BLOCK ))
- #define _malloc_crt(s) (_malloc_dbg ( s, _CRT_BLOCK, __FILE__, __LINE__))
- #define _msize_crt(p) (_msize_dbg (p, _CRT_BLOCK ))
- #define _recalloc_crt(p, c, s) (_recalloc_dbg(p, c, s, _CRT_BLOCK, __FILE__, __LINE__))
- #define _realloc_crt(p, s) (_realloc_dbg (p, s, _CRT_BLOCK, __FILE__, __LINE__))
-
- #define _malloca_crt(size) \
- __pragma(warning(suppress: 6255)) \
- (_MallocaComputeSize(size) != 0 \
- ? _MarkAllocaS(_malloc_crt(_MallocaComputeSize(size)), _ALLOCA_S_HEAP_MARKER) \
- : NULL)
+// When building for vcruntime*.dll, we are not a part of the UCRT or OS so we
+// should use the public allocation functions exported by the UCRT.
+#define _calloc_crt calloc
+#define _free_crt free
+#define _malloc_crt malloc
+#define _realloc_crt realloc
+#define _msize_crt _msize
+#define _recalloc_crt _recalloc
-#else // ^^^ _DEBUG ^^^ // vvv !_DEBUG vvv
-
- // The *_crt macros call the allocation function that vcruntime should use for
- // internal allocations. It changes based off of where it is being built.
-
- #ifdef _CRT_WINDOWS
- // When building for the UCRT, we want to use the internal allocation functions.
- // We need to ensure that users hooking the public allocation functions do not
- // interfere with the UCRT's allocations.
- #define _calloc_crt _calloc_base
- #define _free_crt _free_base
- #define _malloc_crt _malloc_base
- #define _realloc_crt _realloc_base
- #define _msize_crt _msize_base
- #define _recalloc_crt _recalloc_base
- #else
- // When building for vcruntime*.dll, we are not a part of the UCRT or OS so we
- // should use the public allocation functions exported by the UCRT.
- #define _calloc_crt calloc
- #define _free_crt free
- #define _malloc_crt malloc
- #define _realloc_crt realloc
- #define _msize_crt _msize
- #define _recalloc_crt _recalloc
- #endif
-
- #define _malloca_crt(size) \
+#define _malloca_crt(size) \
__pragma(warning(suppress: 6255)) \
(_MallocaComputeSize(size) != 0 \
? ((_MallocaComputeSize(size) <= _ALLOCA_S_THRESHOLD) \
@@ -302,8 +266,6 @@ extern "C++"
: _MarkAllocaS(_malloc_crt(_MallocaComputeSize(size)), _ALLOCA_S_HEAP_MARKER)) \
: NULL)
-#endif // !_DEBUG
-
#pragma warning(push)
#pragma warning(disable: 6014)
__inline void __CRTDECL _freea_crt(_Pre_maybenull_ _Post_invalid_ void* memory)
@@ -482,7 +444,6 @@ extern "C++" {
#define _malloca_crt_t(t, n) (__crt_scoped_stack_ptr_tag(static_cast(_malloca_crt ( (n) * sizeof(t)))))
-
enum : int
{
__crt_maximum_pointer_shift = sizeof(uintptr_t) * 8
@@ -650,22 +611,6 @@ extern "C++" {
-#define _CRT_DEBUGGER_IGNORE -1
-#define _CRT_DEBUGGER_GSFAILURE 1
-#define _CRT_DEBUGGER_INVALIDPARAMETER 2
-#define _CRT_DEBUGGER_ABORT 3
-
-// Note: These names are well-known to the debugger
-#ifdef _M_IX86
- void __cdecl _crt_debugger_hook(int);
- #define _CRT_DEBUGGER_HOOK _crt_debugger_hook
-#else
- void __cdecl __crt_debugger_hook(int);
- #define _CRT_DEBUGGER_HOOK __crt_debugger_hook
-#endif
-
-
-
//-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
//
// Precondition Validation Macros
diff --git a/src/crt/vcruntime/new_debug.cpp b/src/crt/vcruntime/new_debug.cpp
deleted file mode 100644
index 42576c5..0000000
--- a/src/crt/vcruntime/new_debug.cpp
+++ /dev/null
@@ -1,96 +0,0 @@
-//
-// new_debug.cpp
-//
-// Copyright (c) Microsoft Corporation. All rights reserved.
-//
-// Defines the debug operator new (both scalar and array forms).
-//
-// The debug operator new and operator new[] are implemented in both the debug
-// and retail CRT libraries. In the retail CRT, they simply call the ordinary
-// operator new. These operators are only declared in the public header files
-// when building with the debug CRT. Implementing these operators in the CRT
-// libraries makes it easier to override them by linking to nothrownew.obj.
-//
-#include
-#include
-#include
-#include
-#include
-
-
-
-#ifdef _DEBUG
-
- _CRT_SECURITYCRITICAL_ATTRIBUTE
- void* __CRTDECL operator new(
- size_t const size,
- int const block_use,
- char const* file_name,
- int const line_number
- )
- {
- for (;;)
- {
- if (void* const block = _malloc_dbg(size, block_use, file_name, line_number))
- {
- return block;
- }
-
- if (_callnewh(size) == 0)
- {
- if (size == SIZE_MAX)
- {
- __scrt_throw_std_bad_array_new_length();
- }
- else
- {
- __scrt_throw_std_bad_alloc();
- }
- }
- }
- }
-
- _CRT_SECURITYCRITICAL_ATTRIBUTE
- void* __CRTDECL operator new[](
- size_t const size,
- int const block_use,
- char const* file_name,
- int const line_number
- )
- {
- return operator new(size, block_use, file_name, line_number);
- }
-
-#else // ^^^ _DEBUG ^^^ // vvv !_DEBUG vvv //
-
- _CRT_SECURITYCRITICAL_ATTRIBUTE
- void* __CRTDECL operator new(
- size_t const size,
- int const block_use,
- char const* file_name,
- int const line_number
- )
- {
- UNREFERENCED_PARAMETER(block_use);
- UNREFERENCED_PARAMETER(file_name);
- UNREFERENCED_PARAMETER(line_number);
-
- return operator new(size);
- }
-
- _CRT_SECURITYCRITICAL_ATTRIBUTE
- void* __CRTDECL operator new[](
- size_t const size,
- int const block_use,
- char const* file_name,
- int const line_number
- )
- {
- UNREFERENCED_PARAMETER(block_use);
- UNREFERENCED_PARAMETER(file_name);
- UNREFERENCED_PARAMETER(line_number);
-
- return operator new[](size);
- }
-
-#endif // !_DEBUG
diff --git a/src/crt/vcruntime/new_km.cpp b/src/crt/vcruntime/new_km.cpp
index 50b0423..6849844 100644
--- a/src/crt/vcruntime/new_km.cpp
+++ b/src/crt/vcruntime/new_km.cpp
@@ -13,6 +13,7 @@
#include
#include
#include
+#include
// Enable the compiler to elide null checks during LTCG
#pragma comment(linker, "/ThrowingNew")
diff --git a/src/crt/vcruntime/std_type_info.cpp b/src/crt/vcruntime/std_type_info.cpp
index 724ec97..2051fa7 100644
--- a/src/crt/vcruntime/std_type_info.cpp
+++ b/src/crt/vcruntime/std_type_info.cpp
@@ -81,8 +81,8 @@ extern "C" char const* __cdecl __std_type_info_name(
nullptr,
data->_DecoratedName + 1,
0,
- [](size_t const n) { return _malloc_crt(n); },
- [](void* const p) { return _free_crt(p); },
+ [](size_t const n) { return malloc(n); },
+ [](void* const p) { return free(p); },
UNDNAME_32_BIT_DECODE | UNDNAME_TYPE_ONLY));
if (!undecorated_name)
@@ -100,7 +100,7 @@ extern "C" char const* __cdecl __std_type_info_name(
size_t const undecorated_name_count = undecorated_name_length + 1;
size_t const node_size = sizeof(SLIST_ENTRY) + undecorated_name_count;
- __crt_unique_heap_ptr node_block(_malloc_crt(node_size));
+ __crt_unique_heap_ptr node_block(malloc(node_size));
if (!node_block)
{
return nullptr; // CRT_REFACTOR TODO This is nonconforming
@@ -143,7 +143,7 @@ extern "C" void __cdecl __std_type_info_destroy_list(
while (current_node)
{
PSLIST_ENTRY const next_node = current_node->Next;
- _free_crt(current_node);
+ free(current_node);
current_node = next_node;
}
}
diff --git a/src/ucrt/heap/align.cpp b/src/ucrt/heap/align.cpp
index 5f71c49..121f7fa 100644
--- a/src/ucrt/heap/align.cpp
+++ b/src/ucrt/heap/align.cpp
@@ -37,121 +37,88 @@
*
*******************************************************************************/
-extern "C" void __cdecl _aligned_free_base(
- _Pre_maybenull_ _Post_invalid_ void* block
- );
-
-_Check_return_ _Ret_maybenull_ _Post_writable_byte_size_(size)
-extern "C" void* __cdecl _aligned_malloc_base(
- _In_ size_t size,
- _In_ size_t alignment
- );
-
-_Check_return_
-extern "C" size_t __cdecl _aligned_msize_base(
- _Pre_notnull_ void* block,
- _In_ size_t alignment,
- _In_ size_t offset
- );
-
-_Check_return_ _Ret_maybenull_ _Post_writable_byte_size_(size)
-extern "C" void* __cdecl _aligned_offset_malloc_base(
- _In_ size_t size,
- _In_ size_t alignment,
- _In_ size_t offset
- );
-
-_Success_(return != 0) _Check_return_ _Ret_maybenull_ _Post_writable_byte_size_(size)
-extern "C" void* __cdecl _aligned_offset_realloc_base(
- _Pre_maybenull_ _Post_invalid_ void* block,
- _In_ size_t size,
- _In_ size_t alignment,
- _In_ size_t offset
- );
-
-_Success_(return != 0) _Check_return_ _Ret_maybenull_ _Post_writable_byte_size_(size * count)
-extern "C" void* __cdecl _aligned_offset_recalloc_base(
- _Pre_maybenull_ _Post_invalid_ void* block,
- _In_ size_t count,
- _In_ size_t size,
- _In_ size_t alignment,
- _In_ size_t offset
- );
-
-_Success_(return != 0) _Check_return_ _Ret_maybenull_ _Post_writable_byte_size_(size)
-extern "C" void* __cdecl _aligned_realloc_base(
- _Pre_maybenull_ _Post_invalid_ void* block,
- _In_ size_t size,
- _In_ size_t alignment
- );
-
-_Success_(return != 0) _Check_return_ _Ret_maybenull_ _Post_writable_byte_size_(size * count)
-extern "C" void* __cdecl _aligned_recalloc_base(
- _Pre_maybenull_ _Post_invalid_ void* block,
- _In_ size_t count,
- _In_ size_t size,
- _In_ size_t alignment
- );
+extern "C" __declspec(noinline) _CRTRESTRICT void* __cdecl _aligned_offset_malloc(
+ size_t const size,
+ size_t const alignment,
+ size_t const offset
+);
-/***
-* void *_aligned_malloc_base(size_t size, size_t alignment)
-* - Get a block of aligned memory from the heap.
-*
-* Purpose:
-* Allocate of block of aligned memory aligned on the alignment of at least
-* size bytes from the heap and return a pointer to it.
-*
-* Entry:
-* size_t size - size of block requested
-* size_t alignment - alignment of memory (needs to be a power of 2)
-*
-* Exit:
-* Success: Pointer to memory block
-* Failure: Null, errno is set
-*
-* Exceptions:
-* Input parameters are validated. Refer to the validation section of the function.
-*
-*******************************************************************************/
+// These functions are patchable and therefore must be marked noinline.
+// Their *_base implementations are marked __forceinline in order to
+// ensure each export is separated from each other and that there is
+// enough space in each export to host a patch.
-extern "C" void* __cdecl _aligned_malloc_base(
+extern "C" __declspec(noinline) void __cdecl _aligned_free(void* const block)
+{
+ uintptr_t ptr;
+
+ if (block == nullptr)
+ return;
+
+ ptr = (uintptr_t)block;
+
+ /* ptr points to the pointer to starting of the memory block */
+ ptr = (ptr & ~(PTR_SZ - 1)) - PTR_SZ;
+
+ /* ptr is the pointer to the start of memory block*/
+ ptr = *((uintptr_t*)ptr);
+ free((void*)ptr);
+}
+
+extern "C" __declspec(noinline) _CRTRESTRICT void* __cdecl _aligned_malloc(
size_t const size,
size_t const alignment
)
{
- return _aligned_offset_malloc_base(size, alignment, 0);
+ return _aligned_offset_malloc(size, alignment, 0);
}
-/***
-* void *_aligned_offset_malloc_base(size_t size, size_t alignment, int offset)
-* - Get a block of memory from the heap.
-*
-* Purpose:
-* Allocate a block of memory which is shifted by offset from alignment of
-* at least size bytes from the heap and return a pointer to it.
-*
-* Entry:
-* size_t size - size of block of memory
-* size_t alignment - alignment of memory (needs to be a power of 2)
-* size_t offset - offset of memory from the alignment
-*
-* Exit:
-* Success: Pointer to memory block
-* Failure: Null, errno is set
-*
-* Exceptions:
-* Input parameters are validated. Refer to the validation section of the function.
-*
-*******************************************************************************/
+extern "C" __declspec(noinline) size_t __cdecl _aligned_msize(
+ void* const block,
+ size_t const alignment,
+ size_t const offset)
+{
+ size_t align = alignment;
+ size_t header_size = 0; /* Size of the header block */
+ size_t footer_size = 0; /* Size of the footer block */
+ size_t total_size = 0; /* total size of the allocated block */
+ size_t user_size = 0; /* size of the user block*/
+ uintptr_t gap = 0; /* keep the alignment of the data block */
+ /* after the sizeof(void*) aligned pointer */
+ /* to the beginning of the allocated block */
+ uintptr_t ptr = 0; /* computes the beginning of the allocated block */
+
+ _VALIDATE_RETURN(block != nullptr, EINVAL, static_cast(-1));
+
+ /* HEADER SIZE + FOOTER SIZE = GAP + ALIGN + SIZE OF A POINTER*/
+ /* HEADER SIZE + USER SIZE + FOOTER SIZE = TOTAL SIZE */
+
+ ptr = (uintptr_t)block; /* ptr points to the start of the aligned memory block */
+ ptr = (ptr & ~(PTR_SZ - 1)) - PTR_SZ; /* ptr is one position behind memblock */
+ /* the value in ptr is the start of the real allocated block */
+ ptr = *((uintptr_t *)ptr); /* after dereference ptr points to the beginning of the allocated block */
-extern "C" void* __cdecl _aligned_offset_malloc_base(
- size_t size,
- size_t align,
- size_t offset
+ total_size = _msize((void*)ptr);
+ header_size = (uintptr_t) block - ptr;
+ gap = (0 - offset) & (PTR_SZ - 1);
+
+ /* Alignment cannot be less than sizeof(void*) */
+ align = (align > PTR_SZ ? align : PTR_SZ) -1;
+ footer_size = gap + align + PTR_SZ - header_size;
+ user_size = total_size - header_size - footer_size;
+
+ return user_size;
+}
+
+extern "C" __declspec(noinline) _CRTRESTRICT void* __cdecl _aligned_offset_malloc(
+ size_t const size,
+ size_t const alignment,
+ size_t const offset
)
{
uintptr_t ptr, retptr, gap;
size_t nonuser_size,block_size;
+ size_t align = alignment;
/* validation section */
_VALIDATE_RETURN(IS_2_POW_N(align), EINVAL, nullptr);
@@ -175,130 +142,26 @@ extern "C" void* __cdecl _aligned_offset_malloc_base(
return (void *)retptr;
}
-/***
-*
-* void *_aligned_realloc_base(void * memblock, size_t size, size_t alignment)
-* - Reallocate a block of aligned memory from the heap.
-*
-* Purpose:
-* Reallocates of block of aligned memory aligned on the alignment of at
-* least size bytes from the heap and return a pointer to it. Size can be
-* either greater or less than the original size of the block.
-* The reallocation may result in moving the block as well as changing the
-* size.
-*
-* Entry:
-* void *memblock - pointer to block in the heap previously allocated by
-* call to _aligned_malloc(), _aligned_offset_malloc(),
-* _aligned_realloc() or _aligned_offset_realloc().
-* size_t size - size of block requested
-* size_t alignment - alignment of memory
-*
-* Exit:
-* Success: Pointer to re-allocated memory block
-* Failure: Null, errno is set
-*
-* Exceptions:
-* Input parameters are validated. Refer to the validation section of the function.
-*
-*******************************************************************************/
-
-extern "C" void* __cdecl _aligned_realloc_base(
- void* const block,
- size_t const size,
- size_t const alignment
- )
-{
- return _aligned_offset_realloc_base(block, size, alignment, 0);
-}
-
-/***
-*
-* void *_aligned_recalloc_base(void * memblock, size_t count, size_t size, size_t alignment)
-* - Reallocate a block of aligned memory from the heap.
-*
-* Purpose:
-* Reallocates of block of aligned memory aligned on the alignment of at
-* least size bytes from the heap and return a pointer to it. Size can be
-* either greater or less than the original size of the block.
-* The reallocation may result in moving the block as well as changing the
-* size.
-*
-* Entry:
-* void *memblock - pointer to block in the heap previously allocated by
-* call to _aligned_malloc(), _aligned_offset_malloc(),
-* _aligned_realloc() or _aligned_offset_realloc().
-* size_t count - count of items
-* size_t size - size of item
-* size_t alignment - alignment of memory
-*
-* Exit:
-* Success: Pointer to re-allocated memory block
-* Failure: Null, errno is set
-*
-* Exceptions:
-* Input parameters are validated. Refer to the validation section of the function.
-*
-*******************************************************************************/
-
-extern "C" void* __cdecl _aligned_recalloc_base(
+extern "C" __declspec(noinline) _CRTRESTRICT void* __cdecl _aligned_offset_realloc(
void* const block,
- size_t const count,
size_t const size,
- size_t const alignment
- )
-{
- return _aligned_offset_recalloc_base(block, count, size, alignment, 0);
-}
-
-/***
-*
-* void *_aligned_offset_realloc_base (void * memblock, size_t size,
-* size_t alignment, int offset)
-* - Reallocate a block of memory from the heap.
-*
-* Purpose:
-* Reallocates a block of memory which is shifted by offset from
-* alignment of at least size bytes from the heap and return a pointer
-* to it. Size can be either greater or less than the original size of the
-* block.
-*
-* Entry:
-* void *memblock - pointer to block in the heap previously allocated by
-* call to _aligned_malloc(), _aligned_offset_malloc(),
-* _aligned_realloc() or _aligned_offset_realloc().
-* size_t size - size of block of memory
-* size_t alignment - alignment of memory
-* size_t offset - offset of memory from the alignment
-*
-* Exit:
-* Success: Pointer to re-allocated memory block
-* Failure: Null, errno is set
-*
-* Exceptions:
-* Input parameters are validated. Refer to the validation section of the function.
-*
-*******************************************************************************/
-
-extern "C" void* __cdecl _aligned_offset_realloc_base(
- void* block,
- size_t size,
- size_t align,
- size_t offset
+ size_t const alignment,
+ size_t const offset
)
{
uintptr_t ptr, retptr, gap, stptr, diff;
uintptr_t movsz, reqsz;
+ size_t align = alignment;
int bFree = 0;
/* special cases */
if (block == nullptr)
{
- return _aligned_offset_malloc_base(size, align, offset);
+ return _aligned_offset_malloc(size, align, offset);
}
if (size == 0)
{
- _aligned_free_base(block);
+ _aligned_free(block);
return nullptr;
}
@@ -323,7 +186,7 @@ extern "C" void* __cdecl _aligned_offset_realloc_base(
*/
#pragma warning(push)
#pragma warning(disable: 22018) // Silence prefast about overflow/underflow
- movsz = _msize_base((void *)stptr) - ((uintptr_t)block - stptr);
+ movsz = _msize((void *)stptr) - ((uintptr_t)block - stptr);
#pragma warning(pop)
movsz = movsz > size ? size : movsz;
@@ -377,99 +240,19 @@ extern "C" void* __cdecl _aligned_offset_realloc_base(
return (void *)retptr;
}
-
-/***
-*
-* size_t _aligned_msize_base(void *memblock, size_t align, size_t offset)
-*
-* Purpose:
-* Computes the size of an aligned block.
-*
-* Entry:
-* void * memblock - pointer to the aligned block of memory
-*
-* Exceptions:
-* None. If memblock == nullptr 0 is returned.
-*
-*******************************************************************************/
-
-extern "C" size_t __cdecl _aligned_msize_base(
- void* block,
- size_t align,
- size_t offset
- )
-{
- size_t header_size = 0; /* Size of the header block */
- size_t footer_size = 0; /* Size of the footer block */
- size_t total_size = 0; /* total size of the allocated block */
- size_t user_size = 0; /* size of the user block*/
- uintptr_t gap = 0; /* keep the alignment of the data block */
- /* after the sizeof(void*) aligned pointer */
- /* to the beginning of the allocated block */
- uintptr_t ptr = 0; /* computes the beginning of the allocated block */
-
- _VALIDATE_RETURN(block != nullptr, EINVAL, static_cast(-1));
-
- /* HEADER SIZE + FOOTER SIZE = GAP + ALIGN + SIZE OF A POINTER*/
- /* HEADER SIZE + USER SIZE + FOOTER SIZE = TOTAL SIZE */
-
- ptr = (uintptr_t)block; /* ptr points to the start of the aligned memory block */
- ptr = (ptr & ~(PTR_SZ - 1)) - PTR_SZ; /* ptr is one position behind memblock */
- /* the value in ptr is the start of the real allocated block */
- ptr = *((uintptr_t *)ptr); /* after dereference ptr points to the beginning of the allocated block */
-
- total_size = _msize_base((void*)ptr);
- header_size = (uintptr_t) block - ptr;
- gap = (0 - offset) & (PTR_SZ - 1);
- /* Alignment cannot be less than sizeof(void*) */
- align = (align > PTR_SZ ? align : PTR_SZ) -1;
- footer_size = gap + align + PTR_SZ - header_size;
- user_size = total_size - header_size - footer_size;
-
- return user_size;
-}
-
-/***
-*
-* void *_aligned_offset_recalloc_base (void * memblock, size_t size, size_t count, size_t alignment, int offset)
-* - Reallocate a block of memory from the heap.
-*
-* Purpose:
-* Reallocates a block of memory which is shifted by offset from
-* alignment of at least size bytes from the heap and return a pointer
-* to it. Size can be either greater or less than the original size of the
-* block.
-*
-* Entry:
-* void *memblock - pointer to block in the heap previously allocated by
-* call to _aligned_malloc(), _aligned_offset_malloc(),
-* _aligned_realloc() or _aligned_offset_realloc().
-* size_t count - count of items
-* size_t size - size of items
-* size_t alignment - alignment of memory
-* size_t offset - offset of memory from the alignment
-*
-* Exit:
-* Success: Pointer to re-allocated memory block
-* Failure: Null, errno is set
-*
-* Exceptions:
-* Input parameters are validated. Refer to the validation section of the function.
-*
-*******************************************************************************/
-
-extern "C" void* __cdecl _aligned_offset_recalloc_base(
- void* block,
- size_t count,
- size_t size,
- size_t align,
- size_t offset
+extern "C" __declspec(noinline) _CRTRESTRICT void* __cdecl _aligned_offset_recalloc(
+ void* const block,
+ size_t const count,
+ size_t const size,
+ size_t const alignment,
+ size_t const offset
)
{
- size_t user_size = 0; /* wanted size, passed to aligned realoc */
- size_t start_fill = 0; /* location where aligned recalloc starts to fill with 0 */
- /* filling must start from the end of the previous user block */
- void * retptr = nullptr; /* result of aligned recalloc*/
+ size_t align = alignment;
+ size_t user_size = 0; /* wanted size, passed to aligned realoc */
+ size_t start_fill = 0; /* location where aligned recalloc starts to fill with 0 */
+ /* filling must start from the end of the previous user block */
+ void* retptr = nullptr; /* result of aligned recalloc*/
/* ensure that (size * num) does not overflow */
if (count > 0)
@@ -481,146 +264,28 @@ extern "C" void* __cdecl _aligned_offset_recalloc_base(
if (block != nullptr)
{
- start_fill = _aligned_msize_base(block, align, offset);
+ start_fill = _aligned_msize(block, align, offset);
}
- retptr = _aligned_offset_realloc_base(block, user_size, align, offset);
+ retptr = _aligned_offset_realloc(block, user_size, align, offset);
if (retptr != nullptr)
{
if (start_fill < user_size)
{
- memset ((char*)retptr + start_fill, 0, user_size - start_fill);
+ memset((char*)retptr + start_fill, 0, user_size - start_fill);
}
}
return retptr;
}
-/***
-*
-* void *_aligned_free_base(void *memblock)
-* - Free the memory which was allocated using _aligned_malloc or
-* _aligned_offset_memory
-*
-* Purpose:
-* Frees the aligned memory block which was allocated using _aligned_malloc.
-*
-* Entry:
-* void * memblock - pointer to the block of memory
-*
-* Exceptions:
-* None. If memblock == nullptr we simply return without doing anything.
-*
-*******************************************************************************/
-
-extern "C" void __cdecl _aligned_free_base(void* const block)
-{
- uintptr_t ptr;
-
- if (block == nullptr)
- return;
-
- ptr = (uintptr_t)block;
-
- /* ptr points to the pointer to starting of the memory block */
- ptr = (ptr & ~(PTR_SZ -1)) - PTR_SZ;
-
- /* ptr is the pointer to the start of memory block*/
- ptr = *((uintptr_t*)ptr);
- free((void *)ptr);
-}
-
-// These functions are patchable and therefore must be marked noinline.
-// Their *_base implementations are marked __forceinline in order to
-// ensure each export is separated from each other and that there is
-// enough space in each export to host a patch.
-
-extern "C" __declspec(noinline) void __cdecl _aligned_free(void* const block)
-{
- #ifdef _DEBUG
- _aligned_free_dbg(block);
- #else
- _aligned_free_base(block);
- #endif
-}
-
-extern "C" __declspec(noinline) _CRTRESTRICT void* __cdecl _aligned_malloc(
- size_t const size,
- size_t const alignment
- )
-{
- #ifdef _DEBUG
- return _aligned_offset_malloc_dbg(size, alignment, 0, nullptr, 0);
- #else
- return _aligned_malloc_base(size, alignment);
- #endif
-}
-
-extern "C" __declspec(noinline) size_t __cdecl _aligned_msize(
- void* const block,
- size_t const alignment,
- size_t const offset)
-{
- #ifdef _DEBUG
- return _aligned_msize_dbg(block, alignment, offset);
- #else
- return _aligned_msize_base(block, alignment, offset);
- #endif
-}
-
-extern "C" __declspec(noinline) _CRTRESTRICT void* __cdecl _aligned_offset_malloc(
- size_t const size,
- size_t const alignment,
- size_t const offset
- )
-{
- #ifdef _DEBUG
- return _aligned_offset_malloc_dbg(size, alignment, offset, nullptr, 0);
- #else
- return _aligned_offset_malloc_base(size, alignment, offset);
- #endif
-}
-
-extern "C" __declspec(noinline) _CRTRESTRICT void* __cdecl _aligned_offset_realloc(
- void* const block,
- size_t const size,
- size_t const alignment,
- size_t const offset
- )
-{
- #ifdef _DEBUG
- return _aligned_offset_realloc_dbg(block, size, alignment, offset, nullptr, 0);
- #else
- return _aligned_offset_realloc_base(block, size, alignment, offset);
- #endif
-}
-
-extern "C" __declspec(noinline) _CRTRESTRICT void* __cdecl _aligned_offset_recalloc(
- void* const block,
- size_t const count,
- size_t const size,
- size_t const alignment,
- size_t const offset
- )
-{
- #ifdef _DEBUG
- return _aligned_offset_recalloc_dbg(block, count, size, alignment, offset, nullptr, 0);
- #else
- return _aligned_offset_recalloc_base(block, count, size, alignment, offset);
- #endif
-}
-
extern "C" __declspec(noinline) _CRTRESTRICT void* __cdecl _aligned_realloc(
void* const block,
size_t const size,
size_t const alignment
)
{
- #ifdef _DEBUG
- return _aligned_offset_realloc_dbg(block, size, alignment, 0, nullptr, 0);
- #else
- return _aligned_realloc_base(block, size, alignment);
- #endif
+ return _aligned_offset_realloc(block, size, alignment, 0);
}
extern "C" __declspec(noinline) _CRTRESTRICT void* __cdecl _aligned_recalloc(
@@ -630,9 +295,5 @@ extern "C" __declspec(noinline) _CRTRESTRICT void* __cdecl _aligned_recalloc(
size_t const alignment
)
{
- #ifdef _DEBUG
- return _aligned_offset_recalloc_dbg(block, count, size, alignment, 0, nullptr, 0);
- #else
- return _aligned_recalloc_base(block, count, size, alignment);
- #endif
+ return _aligned_offset_recalloc(block, count, size, alignment, 0);
}
diff --git a/src/ucrt/heap/calloc.cpp b/src/ucrt/heap/calloc.cpp
index a4e9db7..66c1aa6 100644
--- a/src/ucrt/heap/calloc.cpp
+++ b/src/ucrt/heap/calloc.cpp
@@ -8,6 +8,7 @@
//
#include
#include
+#include
// Allocates a block of memory of size 'count * size' in the heap. The newly
// allocated block is zero-initialized. If allocation fails, nullptr is
@@ -22,9 +23,34 @@ extern "C" _CRT_HYBRIDPATCHABLE __declspec(noinline) _CRTRESTRICT void* __cdecl
size_t const size
)
{
-#ifdef _DEBUG
- return _calloc_dbg(count, size, _NORMAL_BLOCK, nullptr, 0);
-#else
- return _calloc_base(count, size);
-#endif
+ // Ensure that (count * size) does not overflow
+ _VALIDATE_RETURN_NOEXC(count == 0 || (_HEAP_MAXREQ / count) >= size, ENOMEM, nullptr);
+
+ // Ensure that we allocate a nonzero block size:
+ size_t const requested_block_size = count * size;
+ size_t const actual_block_size = requested_block_size == 0
+ ? 1
+ : requested_block_size;
+
+ for (;;)
+ {
+ void* const block = malloc(actual_block_size);
+
+ // If allocation succeeded, return the pointer to the new block:
+ if (block)
+ {
+ memset(block, 0, actual_block_size);
+ return block;
+ }
+
+ // Otherwise, see if we need to call the new handler, and if so call it.
+ // If the new handler fails, just return nullptr:
+ if (_query_new_mode() == 0 || !_callnewh(actual_block_size))
+ {
+ errno = ENOMEM;
+ return nullptr;
+ }
+
+ // The new handler was successful; try to allocate aagain...
+ }
}
diff --git a/src/ucrt/heap/calloc_base.cpp b/src/ucrt/heap/calloc_base.cpp
deleted file mode 100644
index 2d2f71b..0000000
--- a/src/ucrt/heap/calloc_base.cpp
+++ /dev/null
@@ -1,54 +0,0 @@
-//
-// calloc_base.cpp
-//
-// Copyright (c) Microsoft Corporation. All rights reserved.
-//
-// Implementation of _calloc_base(). This is defined in a different source file
-// from the calloc() function to allow calloc() to be replaced by the user.
-//
-#include
-#include
-#include
-
-// This function implements the logic of calloc().
-//
-// This function must be marked noinline, otherwise calloc and
-// _calloc_base will have identical COMDATs, and the linker will fold
-// them when calling one from the CRT. This is necessary because calloc
-// needs to support users patching in custom implementations.
-extern "C" __declspec(noinline) _CRTRESTRICT void* __cdecl _calloc_base(
- size_t const count,
- size_t const size
- )
-{
- // Ensure that (count * size) does not overflow
- _VALIDATE_RETURN_NOEXC(count == 0 || (_HEAP_MAXREQ / count) >= size, ENOMEM, nullptr);
-
- // Ensure that we allocate a nonzero block size:
- size_t const requested_block_size = count * size;
- size_t const actual_block_size = requested_block_size == 0
- ? 1
- : requested_block_size;
-
- for (;;)
- {
- void* const block = malloc(actual_block_size);
-
- // If allocation succeeded, return the pointer to the new block:
- if (block)
- {
- memset(block, 0, actual_block_size);
- return block;
- }
-
- // Otherwise, see if we need to call the new handler, and if so call it.
- // If the new handler fails, just return nullptr:
- if (_query_new_mode() == 0 || !_callnewh(actual_block_size))
- {
- errno = ENOMEM;
- return nullptr;
- }
-
- // The new handler was successful; try to allocate aagain...
- }
-}
diff --git a/src/ucrt/heap/debug_heap.cpp b/src/ucrt/heap/debug_heap.cpp
deleted file mode 100644
index 3853d0e..0000000
--- a/src/ucrt/heap/debug_heap.cpp
+++ /dev/null
@@ -1,339 +0,0 @@
-//
-// debug_heap.cpp
-//
-// Copyright (c) Microsoft Corporation. All rights reserved.
-//
-// The implementation of the CRT Debug Heap.
-//
-#ifndef _DEBUG
- #error This file is supported only in debug builds
- #define _DEBUG // For design-time support, when editing/viewing CRT sources
-#endif
-
-#include
-#include
-#include
-#include
-#include
-#include
-
-
-
-//-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-//
-// Constant Data
-//
-//-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-#define _ALLOCATION_FILE_LINENUM "\nMemory allocated at %hs(%d).\n"
-
-#if _FREE_BLOCK != 0 || _NORMAL_BLOCK != 1 || _CRT_BLOCK != 2 || _IGNORE_BLOCK != 3 || _CLIENT_BLOCK != 4
- #error Block numbers have changed!
-#endif
-
-//-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-//
-// Public Debug Heap Allocation APIs
-//
-//-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-
-_Check_return_ _Ret_maybenull_ _Post_writable_byte_size_(_Size)
-_ACRTIMP _CRTALLOCATOR _CRT_HYBRIDPATCHABLE
-extern "C" void* __cdecl _expand_base(
- _Pre_notnull_ void* _Block,
- _In_ size_t _Size
-);
-
-// These are the allocation functions that allocate, manipulate, and free blocks
-// from the debug heap. They are equivalent to the main allocation functions,
-// which deal with blocks from the process heap. Most of the debug allocation
-// functions accept a block use, file name, and/or line number which are used to
-// track where allocations originated.
-//
-// Documentation comments for these functions describe only the material
-// differences between them and the corresponding main allocation functions.
-
-// This function must be marked noinline, otherwise malloc and
-// _malloc_dbg will have identical COMDATs, and the linker will fold
-// them when calling one from the CRT. This is necessary because malloc
-// needs to support users patching in custom implementations.
-extern "C" __declspec(noinline) void* __cdecl _malloc_dbg(
- size_t const size,
- int const block_use,
- char const* const file_name,
- int const line_number
- )
-{
- UNREFERENCED_PARAMETER(block_use);
- UNREFERENCED_PARAMETER(file_name);
- UNREFERENCED_PARAMETER(line_number);
-
- return _malloc_base(size);
-}
-
-
-// This function must be marked noinline, otherwise calloc and
-// _calloc_dbg will have identical COMDATs, and the linker will fold
-// them when calling one from the CRT. This is necessary because calloc
-// needs to support users patching in custom implementations.
-extern "C" __declspec(noinline) void* __cdecl _calloc_dbg(
- size_t const count,
- size_t const element_size,
- int const block_use,
- char const* const file_name,
- int const line_number
- )
-{
- UNREFERENCED_PARAMETER(block_use);
- UNREFERENCED_PARAMETER(file_name);
- UNREFERENCED_PARAMETER(line_number);
-
- return _calloc_base(count, element_size);
-}
-
-
-// This function must be marked noinline, otherwise realloc and
-// _realloc_dbg will have identical COMDATs, and the linker will fold
-// them when calling one from the CRT. This is necessary because realloc
-// needs to support users patching in custom implementations.
-extern "C" __declspec(noinline) void* __cdecl _realloc_dbg(
- void* const block,
- size_t const requested_size,
- int const block_use,
- char const* const file_name,
- int const line_number
- )
-{
- UNREFERENCED_PARAMETER(block_use);
- UNREFERENCED_PARAMETER(file_name);
- UNREFERENCED_PARAMETER(line_number);
-
- return _realloc_base(block, requested_size);
-}
-
-
-// This function must be marked noinline, otherwise recalloc and
-// _recalloc_dbg will have identical COMDATs, and the linker will fold
-// them when calling one from the CRT. This is necessary because recalloc
-// needs to support users patching in custom implementations.
-extern "C" __declspec(noinline) void* __cdecl _recalloc_dbg(
- void* const block,
- size_t const count,
- size_t const element_size,
- int const block_use,
- char const* const file_name,
- int const line_number
- )
-{
- UNREFERENCED_PARAMETER(block_use);
- UNREFERENCED_PARAMETER(file_name);
- UNREFERENCED_PARAMETER(line_number);
-
- return _recalloc_base(block, count, element_size);
-}
-
-// This function must be marked noinline, otherwise _expand and
-// _expand_dbg will have identical COMDATs, and the linker will fold
-// them when calling one from the CRT. This is necessary because _expand
-// needs to support users patching in custom implementations.
-extern "C" __declspec(noinline) void* __cdecl _expand_dbg(
- void* const block,
- size_t const requested_size,
- int const block_use,
- char const* const file_name,
- int const line_number
- )
-{
- UNREFERENCED_PARAMETER(block_use);
- UNREFERENCED_PARAMETER(file_name);
- UNREFERENCED_PARAMETER(line_number);
-
- return _expand_base(block, requested_size);
-}
-
-
-
-// This function must be marked noinline, otherwise free and
-// _free_dbg will have identical COMDATs, and the linker will fold
-// them when calling one from the CRT. This is necessary because free
-// needs to support users patching in custom implementations.
-extern "C" __declspec(noinline) void __cdecl _free_dbg(void* const block, int const block_use)
-{
- UNREFERENCED_PARAMETER(block_use);
-
- return _free_base(block);
-}
-
-
-// This function must be marked noinline, otherwise _msize and
-// _msize_dbg will have identical COMDATs, and the linker will fold
-// them when calling one from the CRT. This is necessary because _msize
-// needs to support users patching in custom implementations.
-extern "C" __declspec(noinline) size_t __cdecl _msize_dbg(void* const block, int const block_use)
-{
- UNREFERENCED_PARAMETER(block_use);
-
- return _msize_base(block);
-}
-
-
-
-//-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-//
-// Aligned Allocation
-//
-//-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-
-extern "C" void __cdecl _aligned_free_base(
- _Pre_maybenull_ _Post_invalid_ void* block
-);
-
-_Check_return_ _Ret_maybenull_ _Post_writable_byte_size_(size)
-extern "C" void* __cdecl _aligned_malloc_base(
- _In_ size_t size,
- _In_ size_t alignment
-);
-
-_Check_return_
-extern "C" size_t __cdecl _aligned_msize_base(
- _Pre_notnull_ void* block,
- _In_ size_t alignment,
- _In_ size_t offset
-);
-
-_Check_return_ _Ret_maybenull_ _Post_writable_byte_size_(size)
-extern "C" void* __cdecl _aligned_offset_malloc_base(
- _In_ size_t size,
- _In_ size_t alignment,
- _In_ size_t offset
-);
-
-_Success_(return != 0) _Check_return_ _Ret_maybenull_ _Post_writable_byte_size_(size)
-extern "C" void* __cdecl _aligned_offset_realloc_base(
- _Pre_maybenull_ _Post_invalid_ void* block,
- _In_ size_t size,
- _In_ size_t alignment,
- _In_ size_t offset
-);
-
-_Success_(return != 0) _Check_return_ _Ret_maybenull_ _Post_writable_byte_size_(size * count)
-extern "C" void* __cdecl _aligned_offset_recalloc_base(
- _Pre_maybenull_ _Post_invalid_ void* block,
- _In_ size_t count,
- _In_ size_t size,
- _In_ size_t alignment,
- _In_ size_t offset
-);
-
-_Success_(return != 0) _Check_return_ _Ret_maybenull_ _Post_writable_byte_size_(size)
-extern "C" void* __cdecl _aligned_realloc_base(
- _Pre_maybenull_ _Post_invalid_ void* block,
- _In_ size_t size,
- _In_ size_t alignment
-);
-
-_Success_(return != 0) _Check_return_ _Ret_maybenull_ _Post_writable_byte_size_(size * count)
-extern "C" void* __cdecl _aligned_recalloc_base(
- _Pre_maybenull_ _Post_invalid_ void* block,
- _In_ size_t count,
- _In_ size_t size,
- _In_ size_t alignment
-);
-
-
-#define IS_2_POW_N(X) ((X) != 0 && ((X) & ((X) - 1)) == 0)
-
-
-extern "C" void* __cdecl _aligned_malloc_dbg(
- size_t const size,
- size_t const alignment,
- char const* const file_name,
- int const line_number
- )
-{
- return _aligned_offset_malloc_dbg(size, alignment, 0, file_name, line_number);
-}
-
-extern "C" void* __cdecl _aligned_offset_malloc_dbg(
- size_t const size,
- size_t alignment,
- size_t const offset,
- char const* const file_name,
- int const line_number
- )
-{
- UNREFERENCED_PARAMETER(file_name);
- UNREFERENCED_PARAMETER(line_number);
-
- return _aligned_offset_malloc_base(size, alignment, offset);
-}
-
-extern "C" void* __cdecl _aligned_realloc_dbg(
- void* const block,
- size_t const size,
- size_t const alignment,
- char const* const file_name,
- int const line_number
- )
-{
- return _aligned_offset_realloc_dbg(block, size, alignment, 0, file_name, line_number);
-}
-
-extern "C" void* __cdecl _aligned_recalloc_dbg(
- void* const block,
- size_t const count,
- size_t const size,
- size_t const alignment,
- char const* const file_name,
- int const line_number
- )
-{
- UNREFERENCED_PARAMETER(file_name);
- UNREFERENCED_PARAMETER(line_number);
-
- return _aligned_offset_recalloc_dbg(block, count, size, alignment, 0, file_name, line_number);
-}
-
-extern "C" void* __cdecl _aligned_offset_realloc_dbg(
- void * block,
- size_t size,
- size_t alignment,
- size_t offset,
- const char * file_name,
- int line_number
- )
-{
- UNREFERENCED_PARAMETER(file_name);
- UNREFERENCED_PARAMETER(line_number);
-
- return _aligned_offset_realloc_base(block, size, alignment, offset);
-}
-
-extern "C" size_t __cdecl _aligned_msize_dbg(
- void* const block,
- size_t alignment,
- size_t const offset
- )
-{
- return _aligned_msize_base(block, alignment, offset);
-}
-
-extern "C" void* __cdecl _aligned_offset_recalloc_dbg(
- void* const block,
- size_t const count,
- size_t const element_size,
- size_t const alignment,
- size_t const offset,
- char const* const file_name,
- int const line_number
- )
-{
- UNREFERENCED_PARAMETER(file_name);
- UNREFERENCED_PARAMETER(line_number);
-
- return _aligned_offset_recalloc_base(block, count, element_size, alignment, offset);
-}
-
-extern "C" void __cdecl _aligned_free_dbg(void* const block)
-{
- return _aligned_free_base(block);
-}
diff --git a/src/ucrt/heap/expand.cpp b/src/ucrt/heap/expand.cpp
index 9d651fc..7d0bcfe 100644
--- a/src/ucrt/heap/expand.cpp
+++ b/src/ucrt/heap/expand.cpp
@@ -9,31 +9,6 @@
#include
-
-// This function implements the logic of expand(). It is called directly by the
-// _expand() function in the Release CRT, and called by the debug heap in the
-// Debug CRT.
-//
-// This function must be marked noinline, otherwise _expand and
-// _expand_base will have identical COMDATs, and the linker will fold
-// them when calling one from the CRT. This is necessary because _expand
-// needs to support users patching in custom implementations.
-extern "C" __declspec(noinline) void* __cdecl _expand_base(void* const block, size_t const size)
-{
- // Validation section
- _VALIDATE_RETURN (block != nullptr, EINVAL, nullptr);
- _VALIDATE_RETURN_NOEXC(size <= _HEAP_MAXREQ, ENOMEM, nullptr);
-
- size_t const new_size = size == 0 ? 1 : size;
-
- void* new_block = _realloc_base(block, new_size);
- if (new_block != nullptr)
- return new_block;
-
- errno = __acrt_errno_from_os_error(STATUS_INSUFFICIENT_RESOURCES);
- return nullptr;
-}
-
// Expands or contracts a block of memory in the heap.
//
// This function resizes a block of memory in the heap to 'size' bytes. The
@@ -48,9 +23,16 @@ extern "C" __declspec(noinline) void* __cdecl _expand_base(void* const block, si
// with either other function or vice versa.
extern "C" _CRT_HYBRIDPATCHABLE __declspec(noinline) void* __cdecl _expand(void* const block, size_t const size)
{
-#ifdef _DEBUG
- return _expand_dbg(block, size, _NORMAL_BLOCK, nullptr, 0);
-#else
- return _expand_base(block, size);
-#endif
+ // Validation section
+ _VALIDATE_RETURN(block != nullptr, EINVAL, nullptr);
+ _VALIDATE_RETURN_NOEXC(size <= _HEAP_MAXREQ, ENOMEM, nullptr);
+
+ size_t const new_size = size == 0 ? 1 : size;
+
+ void* new_block = realloc(block, new_size);
+ if (new_block != nullptr)
+ return new_block;
+
+ errno = __acrt_errno_from_os_error(STATUS_INSUFFICIENT_RESOURCES);
+ return nullptr;
}
diff --git a/src/ucrt/heap/free.cpp b/src/ucrt/heap/free.cpp
index b99c653..cc62e8d 100644
--- a/src/ucrt/heap/free.cpp
+++ b/src/ucrt/heap/free.cpp
@@ -17,9 +17,8 @@
// with either other function or vice versa.
extern "C" _CRT_HYBRIDPATCHABLE __declspec(noinline) void __cdecl free(void* const block)
{
-#ifdef _DEBUG
- _free_dbg(block, _NORMAL_BLOCK);
-#else
- _free_base(block);
-#endif
+ if (block)
+ {
+ ExFreePoolWithTag(block, __ucxxrt_tag);
+ }
}
diff --git a/src/ucrt/heap/free_base.cpp b/src/ucrt/heap/free_base.cpp
deleted file mode 100644
index b96c108..0000000
--- a/src/ucrt/heap/free_base.cpp
+++ /dev/null
@@ -1,29 +0,0 @@
-//
-// free_base.cpp
-//
-// Copyright (c) Microsoft Corporation. All rights reserved.
-//
-// Implementation of _free_base(). This is defined in a different source file
-// from the free() function to allow free() to be replaced by the user.
-//
-#include
-#include
-
-
-
-// This function implements the logic of free(). It is called directly by the
-// free() function in the Release CRT, and it is called by the debug heap in the
-// Debug CRT.
-//
-// This function must be marked noinline, otherwise free and
-// _free_base will have identical COMDATs, and the linker will fold
-// them when calling one from the CRT. This is necessary because free
-// needs to support users patching in custom implementations.
-extern "C" void __declspec(noinline) __cdecl _free_base(void* const block)
-{
- if (block)
- {
- ExFreePoolWithTag(block, __ucxxrt_tag);
- }
-}
-
diff --git a/src/ucrt/heap/free_km.cpp b/src/ucrt/heap/free_km.cpp
deleted file mode 100644
index 6a66373..0000000
--- a/src/ucrt/heap/free_km.cpp
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * PROJECT: Universal C++ RunTime (UCXXRT)
- * FILE: free_km.cpp
- * DATA: 2022/06/17
- *
- * PURPOSE: Universal C++ RunTime
- *
- * LICENSE: Relicensed under The MIT License from The CC BY 4.0 License
- *
- * DEVELOPER: MiroKaku (miro.kaku AT Outlook.com)
- */
-
-#include
-#include
-
-
-// This function implements the logic of kfree(). It is called directly by the
-// kfree() function in the Release CRT, and it is called by the debug heap in the
-// Debug CRT.
-//
-// This function must be marked noinline, otherwise free and
-// _kfree_base will have identical COMDATs, and the linker will fold
-// them when calling one from the CRT. This is necessary because free
-// needs to support users patching in custom implementations.
-extern "C" void __declspec(noinline) __cdecl _kfree_base(void* const block, unsigned long tag)
-{
- if (block)
- {
- ExFreePoolWithTag(block, tag);
- }
-}
-
-
-#ifdef _DEBUG
-// This function must be marked noinline, otherwise kfree and
-// _kfree_dbg will have identical COMDATs, and the linker will fold
-// them when calling one from the CRT. This is necessary because free
-// needs to support users patching in custom implementations.
-extern "C" __declspec(noinline) void __cdecl _kfree_dbg(void* const block, unsigned long tag, int const block_use)
-{
- UNREFERENCED_PARAMETER(block_use);
-
- return _kfree_base(block, tag);
-}
-#endif
-
-
-// Frees a block in the heap. The 'block' pointer must either be a null pointer
-// or must point to a valid block in the heap.
-//
-// This function supports patching and therefore must be marked noinline.
-// Both _kfree_dbg and _kfree_base must also be marked noinline
-// to prevent identical COMDAT folding from substituting calls to free
-// with either other function or vice versa.
-extern "C" _CRT_HYBRIDPATCHABLE __declspec(noinline) void __cdecl kfree(void* const block, unsigned long tag)
-{
-#ifdef _DEBUG
- _kfree_dbg(block, tag, _NORMAL_BLOCK);
-#else
- _kfree_base(block, tag);
-#endif
-}
diff --git a/src/ucrt/heap/calloc_km.cpp b/src/ucrt/heap/kcalloc.cpp
similarity index 57%
rename from src/ucrt/heap/calloc_km.cpp
rename to src/ucrt/heap/kcalloc.cpp
index 1595811..d921543 100644
--- a/src/ucrt/heap/calloc_km.cpp
+++ b/src/ucrt/heap/kcalloc.cpp
@@ -11,22 +11,25 @@
*/
#include
-#include
+#include
#include
-// This function implements the logic of calloc().
+
+// Allocates a block of memory of size 'count * size' in the heap. The newly
+// allocated block is zero-initialized. If allocation fails, nullptr is
+// returned.
//
-// This function must be marked noinline, otherwise calloc and
-// _calloc_base will have identical COMDATs, and the linker will fold
-// them when calling one from the CRT. This is necessary because calloc
-// needs to support users patching in custom implementations.
-extern "C" __declspec(noinline) _CRTRESTRICT void* __cdecl _kcalloc_base(
+// This function supports patching and therefore must be marked noinline.
+// Both _calloc_dbg and _calloc_base must also be marked noinline
+// to prevent identical COMDAT folding from substituting calls to calloc
+// with either other function or vice versa.
+extern "C" _CRT_HYBRIDPATCHABLE __declspec(noinline) _CRTRESTRICT void* __cdecl kcalloc(
size_t const count,
size_t const size,
int pool_type,
unsigned long tag
-)
+ )
{
// Ensure that (count * size) does not overflow
_VALIDATE_RETURN_NOEXC(count == 0 || (_HEAP_MAXREQ / count) >= size, ENOMEM, nullptr);
@@ -59,48 +62,3 @@ extern "C" __declspec(noinline) _CRTRESTRICT void* __cdecl _kcalloc_base(
// The new handler was successful; try to allocate aagain...
}
}
-
-
-// This function must be marked noinline, otherwise calloc and
-// _calloc_dbg will have identical COMDATs, and the linker will fold
-// them when calling one from the CRT. This is necessary because calloc
-// needs to support users patching in custom implementations.
-extern "C" __declspec(noinline) void* __cdecl _kcalloc_dbg(
- size_t const count,
- size_t const element_size,
- int pool_type,
- unsigned long tag,
- int const block_use,
- char const* const file_name,
- int const line_number
-)
-{
- UNREFERENCED_PARAMETER(block_use);
- UNREFERENCED_PARAMETER(file_name);
- UNREFERENCED_PARAMETER(line_number);
-
- return _kcalloc_base(count, element_size, pool_type, tag);
-}
-
-
-// Allocates a block of memory of size 'count * size' in the heap. The newly
-// allocated block is zero-initialized. If allocation fails, nullptr is
-// returned.
-//
-// This function supports patching and therefore must be marked noinline.
-// Both _calloc_dbg and _calloc_base must also be marked noinline
-// to prevent identical COMDAT folding from substituting calls to calloc
-// with either other function or vice versa.
-extern "C" _CRT_HYBRIDPATCHABLE __declspec(noinline) _CRTRESTRICT void* __cdecl kcalloc(
- size_t const count,
- size_t const size,
- int pool_type,
- unsigned long tag
- )
-{
-#ifdef _DEBUG
- return _kcalloc_dbg(count, size, pool_type, tag, _NORMAL_BLOCK, nullptr, 0);
-#else
- return _kcalloc_base(count, size, pool_type, tag);
-#endif
-}
diff --git a/src/ucrt/heap/kfree.cpp b/src/ucrt/heap/kfree.cpp
new file mode 100644
index 0000000..cd37c01
--- /dev/null
+++ b/src/ucrt/heap/kfree.cpp
@@ -0,0 +1,30 @@
+/*
+ * PROJECT: Universal C++ RunTime (UCXXRT)
+ * FILE: free_km.cpp
+ * DATA: 2022/06/17
+ *
+ * PURPOSE: Universal C++ RunTime
+ *
+ * LICENSE: Relicensed under The MIT License from The CC BY 4.0 License
+ *
+ * DEVELOPER: MiroKaku (miro.kaku AT Outlook.com)
+ */
+
+#include
+#include
+
+
+// Frees a block in the heap. The 'block' pointer must either be a null pointer
+// or must point to a valid block in the heap.
+//
+// This function supports patching and therefore must be marked noinline.
+// Both _kfree_dbg and _kfree_base must also be marked noinline
+// to prevent identical COMDAT folding from substituting calls to free
+// with either other function or vice versa.
+extern "C" _CRT_HYBRIDPATCHABLE __declspec(noinline) void __cdecl kfree(void* const block, unsigned long tag)
+{
+ if (block)
+ {
+ ExFreePoolWithTag(block, tag);
+ }
+}
diff --git a/src/ucrt/heap/kmalloc.cpp b/src/ucrt/heap/kmalloc.cpp
new file mode 100644
index 0000000..b983591
--- /dev/null
+++ b/src/ucrt/heap/kmalloc.cpp
@@ -0,0 +1,55 @@
+/*
+ * PROJECT: Universal C++ RunTime (UCXXRT)
+ * FILE: malloc_km.cpp
+ * DATA: 2022/06/17
+ *
+ * PURPOSE: Universal C++ RunTime
+ *
+ * LICENSE: Relicensed under The MIT License from The CC BY 4.0 License
+ *
+ * DEVELOPER: MiroKaku (miro.kaku AT Outlook.com)
+ */
+
+#include
+#include
+#include
+
+
+
+// Allocates a block of memory of size 'size' bytes in the heap. If allocation
+// fails, nullptr is returned.
+//
+// This function supports patching and therefore must be marked noinline.
+// Both _kmalloc_dbg and _kmalloc_base must also be marked noinline
+// to prevent identical COMDAT folding from substituting calls to malloc
+// with either other function or vice versa.
+extern "C" _CRT_HYBRIDPATCHABLE __declspec(noinline) _CRTRESTRICT void* __cdecl kmalloc(
+ size_t const size,
+ int pool_type,
+ unsigned long tag
+)
+{
+ // Ensure that the requested size is not too large:
+ _VALIDATE_RETURN_NOEXC(_HEAP_MAXREQ >= size, ENOMEM, nullptr);
+
+ // Ensure we request an allocation of at least one byte:
+ size_t const actual_size = size == 0 ? 1 : size;
+
+ for (;;)
+ {
+ #pragma warning(suppress: 4996)
+ void* const block = ExAllocatePoolWithTag((POOL_TYPE)pool_type, actual_size, tag);
+ if (block)
+ return block;
+
+ // Otherwise, see if we need to call the new handler, and if so call it.
+ // If the new handler fails, just return nullptr:
+ if (_query_new_mode() == 0 || !_callnewh(actual_size))
+ {
+ errno = ENOMEM;
+ return nullptr;
+ }
+
+ // The new handler was successful; try to allocate again...
+ }
+}
diff --git a/src/ucrt/heap/malloc.cpp b/src/ucrt/heap/malloc.cpp
index e36fc4f..67be313 100644
--- a/src/ucrt/heap/malloc.cpp
+++ b/src/ucrt/heap/malloc.cpp
@@ -7,6 +7,7 @@
//
#include
#include
+#include
@@ -19,9 +20,27 @@
// with either other function or vice versa.
extern "C" _CRT_HYBRIDPATCHABLE __declspec(noinline) _CRTRESTRICT void* __cdecl malloc(size_t const size)
{
-#ifdef _DEBUG
- return _malloc_dbg(size, _NORMAL_BLOCK, nullptr, 0);
-#else
- return _malloc_base(size);
-#endif
+ // Ensure that the requested size is not too large:
+ _VALIDATE_RETURN_NOEXC(_HEAP_MAXREQ >= size, ENOMEM, nullptr);
+
+ // Ensure we request an allocation of at least one byte:
+ size_t const actual_size = size == 0 ? 1 : size;
+
+ for (;;)
+ {
+ #pragma warning(suppress: 4996)
+ void* const block = ExAllocatePoolWithTag(NonPagedPool, actual_size, __ucxxrt_tag);
+ if (block)
+ return block;
+
+ // Otherwise, see if we need to call the new handler, and if so call it.
+ // If the new handler fails, just return nullptr:
+ if (_query_new_mode() == 0 || !_callnewh(actual_size))
+ {
+ errno = ENOMEM;
+ return nullptr;
+ }
+
+ // The new handler was successful; try to allocate again...
+ }
}
diff --git a/src/ucrt/heap/malloc_base.cpp b/src/ucrt/heap/malloc_base.cpp
deleted file mode 100644
index b3e7433..0000000
--- a/src/ucrt/heap/malloc_base.cpp
+++ /dev/null
@@ -1,48 +0,0 @@
-//
-// malloc_base.cpp
-//
-// Copyright (c) Microsoft Corporation. All rights reserved.
-//
-// Implementation of _malloc_base(). This is defined in a different source file
-// from the malloc() function to allow malloc() to be replaced by the user.
-//
-#include
-#include
-#include
-
-
-
-// This function implements the logic of malloc(). It is called directly by the
-// malloc() function in the Release CRT and is called by the debug heap in the
-// Debug CRT.
-//
-// This function must be marked noinline, otherwise malloc and
-// _malloc_base will have identical COMDATs, and the linker will fold
-// them when calling one from the CRT. This is necessary because malloc
-// needs to support users patching in custom implementations.
-extern "C" __declspec(noinline) _CRTRESTRICT void* __cdecl _malloc_base(size_t const size)
-{
- // Ensure that the requested size is not too large:
- _VALIDATE_RETURN_NOEXC(_HEAP_MAXREQ >= size, ENOMEM, nullptr);
-
- // Ensure we request an allocation of at least one byte:
- size_t const actual_size = size == 0 ? 1 : size;
-
- for (;;)
- {
-#pragma warning(suppress: 4996)
- void* const block = ExAllocatePoolWithTag(NonPagedPool, actual_size, __ucxxrt_tag);
- if (block)
- return block;
-
- // Otherwise, see if we need to call the new handler, and if so call it.
- // If the new handler fails, just return nullptr:
- if (_query_new_mode() == 0 || !_callnewh(actual_size))
- {
- errno = ENOMEM;
- return nullptr;
- }
-
- // The new handler was successful; try to allocate again...
- }
-}
diff --git a/src/ucrt/heap/malloc_km.cpp b/src/ucrt/heap/malloc_km.cpp
deleted file mode 100644
index 645288e..0000000
--- a/src/ucrt/heap/malloc_km.cpp
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- * PROJECT: Universal C++ RunTime (UCXXRT)
- * FILE: malloc_km.cpp
- * DATA: 2022/06/17
- *
- * PURPOSE: Universal C++ RunTime
- *
- * LICENSE: Relicensed under The MIT License from The CC BY 4.0 License
- *
- * DEVELOPER: MiroKaku (miro.kaku AT Outlook.com)
- */
-
-#include
-#include
-#include
-
-
-// This function implements the logic of kmalloc(). It is called directly by the
-// kmalloc() function in the Release CRT and is called by the debug heap in the
-// Debug CRT.
-//
-// This function must be marked noinline, otherwise malloc and
-// _kmalloc_base will have identical COMDATs, and the linker will fold
-// them when calling one from the CRT. This is necessary because malloc
-// needs to support users patching in custom implementations.
-extern "C" __declspec(noinline) _CRTRESTRICT void* __cdecl _kmalloc_base(size_t const size, int pool_type, unsigned long tag)
-{
- // Ensure that the requested size is not too large:
- _VALIDATE_RETURN_NOEXC(_HEAP_MAXREQ >= size, ENOMEM, nullptr);
-
- // Ensure we request an allocation of at least one byte:
- size_t const actual_size = size == 0 ? 1 : size;
-
- for (;;)
- {
-#pragma warning(suppress: 4996)
- void* const block = ExAllocatePoolWithTag((POOL_TYPE)pool_type, actual_size, tag);
- if (block)
- return block;
-
- // Otherwise, see if we need to call the new handler, and if so call it.
- // If the new handler fails, just return nullptr:
- if (_query_new_mode() == 0 || !_callnewh(actual_size))
- {
- errno = ENOMEM;
- return nullptr;
- }
-
- // The new handler was successful; try to allocate again...
- }
-}
-
-#ifdef _DEBUG
-// These are the allocation functions that allocate, manipulate, and free blocks
-// from the debug heap. They are equivalent to the main allocation functions,
-// which deal with blocks from the process heap. Most of the debug allocation
-// functions accept a block use, file name, and/or line number which are used to
-// track where allocations originated.
-//
-// Documentation comments for these functions describe only the material
-// differences between them and the corresponding main allocation functions.
-
-// This function must be marked noinline, otherwise kmalloc and
-// _kmalloc_dbg will have identical COMDATs, and the linker will fold
-// them when calling one from the CRT. This is necessary because malloc
-// needs to support users patching in custom implementations.
-extern "C" __declspec(noinline) void* __cdecl _kmalloc_dbg(
- size_t const size,
- int pool_type,
- unsigned long tag,
- int const block_use,
- char const* const file_name,
- int const line_number
-)
-{
- UNREFERENCED_PARAMETER(block_use);
- UNREFERENCED_PARAMETER(file_name);
- UNREFERENCED_PARAMETER(line_number);
-
- return _kmalloc_base(size, pool_type, tag);
-}
-#endif
-
-// Allocates a block of memory of size 'size' bytes in the heap. If allocation
-// fails, nullptr is returned.
-//
-// This function supports patching and therefore must be marked noinline.
-// Both _kmalloc_dbg and _kmalloc_base must also be marked noinline
-// to prevent identical COMDAT folding from substituting calls to malloc
-// with either other function or vice versa.
-extern "C" _CRT_HYBRIDPATCHABLE __declspec(noinline) _CRTRESTRICT void* __cdecl kmalloc(
- size_t const size,
- int pool_type,
- unsigned long tag
-)
-{
-#ifdef _DEBUG
- return _kmalloc_dbg(size, pool_type, tag, _NORMAL_BLOCK, nullptr, 0);
-#else
- return _kmalloc_base(size, pool_type, tag);
-#endif
-}
diff --git a/src/ucrt/heap/msize.cpp b/src/ucrt/heap/msize.cpp
index 15f5723..6d75d2a 100644
--- a/src/ucrt/heap/msize.cpp
+++ b/src/ucrt/heap/msize.cpp
@@ -10,14 +10,14 @@
-// This function implements the logic of _msize(). It is called only in the
-// Release CRT. The Debug CRT has its own implementation of this function.
+// Calculates the size of the specified block in the heap. 'block' must be a
+// pointer to a valid block of heap-allocated memory (it must not be nullptr).
//
-// This function must be marked noinline, otherwise _msize and
-// _msize_base will have identical COMDATs, and the linker will fold
-// them when calling one from the CRT. This is necessary because _msize
-// needs to support users patching in custom implementations.
-extern "C" __declspec(noinline) size_t __cdecl _msize_base(void* const block) _CRT_NOEXCEPT
+// This function supports patching and therefore must be marked noinline.
+// Both _msize_dbg and _msize_base must also be marked noinline
+// to prevent identical COMDAT folding from substituting calls to _msize
+// with either other function or vice versa.
+extern "C" _CRT_HYBRIDPATCHABLE __declspec(noinline) size_t __cdecl _msize(void* const block)
{
size_t size = 0;
BOOLEAN quota_charged = FALSE;
@@ -32,25 +32,8 @@ extern "C" __declspec(noinline) size_t __cdecl _msize_base(void* const block) _C
// rather than the correct number of bytes.
size = 0;
-
KdBreakPoint();
}
return size;
}
-
-// Calculates the size of the specified block in the heap. 'block' must be a
-// pointer to a valid block of heap-allocated memory (it must not be nullptr).
-//
-// This function supports patching and therefore must be marked noinline.
-// Both _msize_dbg and _msize_base must also be marked noinline
-// to prevent identical COMDAT folding from substituting calls to _msize
-// with either other function or vice versa.
-extern "C" _CRT_HYBRIDPATCHABLE __declspec(noinline) size_t __cdecl _msize(void* const block)
-{
-#ifdef _DEBUG
- return _msize_dbg(block, _NORMAL_BLOCK);
-#else
- return _msize_base(block);
-#endif
-}
diff --git a/src/ucrt/heap/realloc.cpp b/src/ucrt/heap/realloc.cpp
index 5f70c56..0b21757 100644
--- a/src/ucrt/heap/realloc.cpp
+++ b/src/ucrt/heap/realloc.cpp
@@ -7,6 +7,36 @@
//
#include
#include
+#include
+
+
+
+extern"C" __declspec(noinline) void* __cdecl ExReallocatePoolWithTag(
+ _In_ SIZE_T OldSize,
+ _In_ SIZE_T NewSize,
+ _In_ PVOID OldBlock,
+ _In_ __drv_strictTypeMatch(__drv_typeExpr) POOL_TYPE PoolType,
+ _In_ ULONG Tag
+)
+{
+ if (OldSize == 0)
+ {
+ return nullptr;
+ }
+
+#pragma warning(suppress: 4996)
+ void* const NewBlock = ExAllocatePoolWithTag(PoolType, NewSize, Tag);
+ if (NewBlock)
+ {
+ memset(NewBlock, 0, NewSize);
+ memmove(NewBlock, OldBlock, OldSize);
+
+ ExFreePoolWithTag(OldBlock, Tag);
+ return NewBlock;
+ }
+
+ return nullptr;
+}
// Reallocates a block of memory in the heap.
//
@@ -33,9 +63,36 @@ extern "C" _CRT_HYBRIDPATCHABLE __declspec(noinline) _CRTRESTRICT void* __cdecl
size_t const size
)
{
-#ifdef _DEBUG
- return _realloc_dbg(block, size, _NORMAL_BLOCK, nullptr, 0);
-#else
- return _realloc_base(block, size);
-#endif
+ // If the block is a nullptr, just call malloc:
+ if (block == nullptr)
+ return malloc(size);
+
+ // If the new size is 0, just call free and return nullptr:
+ if (size == 0)
+ {
+ free(block);
+ return nullptr;
+ }
+
+ // Ensure that the requested size is not too large:
+ _VALIDATE_RETURN_NOEXC(_HEAP_MAXREQ >= size, ENOMEM, nullptr);
+
+ for (;;)
+ {
+ void* const new_block = ExReallocatePoolWithTag(_msize(block), size, block, NonPagedPool, __ucxxrt_tag);
+ if (new_block)
+ {
+ return new_block;
+ }
+
+ // Otherwise, see if we need to call the new handler, and if so call it.
+ // If the new handler fails, just return nullptr:
+ if (_query_new_mode() == 0 || !_callnewh(size))
+ {
+ errno = ENOMEM;
+ return nullptr;
+ }
+
+ // The new handler was successful; try to allocate again...
+ }
}
diff --git a/src/ucrt/heap/realloc_base.cpp b/src/ucrt/heap/realloc_base.cpp
deleted file mode 100644
index f4b0614..0000000
--- a/src/ucrt/heap/realloc_base.cpp
+++ /dev/null
@@ -1,89 +0,0 @@
-//
-// realloc_base.cpp
-//
-// Copyright (c) Microsoft Corporation. All rights reserved.
-//
-// Implementation of _realloc_base(). This is defined in a different source
-// file from the realloc() function to allow realloc() to be replaced by the
-// user.
-//
-#include
-#include
-#include
-
-
-extern"C" __declspec(noinline) void* __cdecl ExReallocatePoolWithTag(
- _In_ SIZE_T OldSize,
- _In_ SIZE_T NewSize,
- _In_ PVOID OldBlock,
- _In_ __drv_strictTypeMatch(__drv_typeExpr) POOL_TYPE PoolType,
- _In_ ULONG Tag
-)
-{
- if (OldSize == 0)
- {
- return nullptr;
- }
-
-#pragma warning(suppress: 4996)
- void* const NewBlock = ExAllocatePoolWithTag(PoolType, NewSize, Tag);
- if (NewBlock)
- {
- memset (NewBlock, 0, NewSize);
- memmove(NewBlock, OldBlock, OldSize);
-
- ExFreePoolWithTag(OldBlock, Tag);
- return NewBlock;
- }
-
- return nullptr;
-}
-
-
-// This function implements the logic of realloc(). It is called directly by
-// the realloc() and _recalloc() functions in the Release CRT and is called by
-// the debug heap in the Debug CRT.
-//
-// This function must be marked noinline, otherwise realloc and
-// _realloc_base will have identical COMDATs, and the linker will fold
-// them when calling one from the CRT. This is necessary because realloc
-// needs to support users patching in custom implementations.
-extern "C" __declspec(noinline) _CRTRESTRICT void* __cdecl _realloc_base(
- void* const block,
- size_t const size
- )
-{
- // If the block is a nullptr, just call malloc:
- if (block == nullptr)
- return _malloc_base(size);
-
- // If the new size is 0, just call free and return nullptr:
- if (size == 0)
- {
- _free_base(block);
- return nullptr;
- }
-
- // Ensure that the requested size is not too large:
- _VALIDATE_RETURN_NOEXC(_HEAP_MAXREQ >= size, ENOMEM, nullptr);
-
- for (;;)
- {
- void* const new_block = ExReallocatePoolWithTag(
- _msize_base(block), size, block, NonPagedPool, __ucxxrt_tag);
- if (new_block)
- {
- return new_block;
- }
-
- // Otherwise, see if we need to call the new handler, and if so call it.
- // If the new handler fails, just return nullptr:
- if (_query_new_mode() == 0 || !_callnewh(size))
- {
- errno = ENOMEM;
- return nullptr;
- }
-
- // The new handler was successful; try to allocate again...
- }
-}
diff --git a/src/ucrt/heap/recalloc.cpp b/src/ucrt/heap/recalloc.cpp
index d13d300..7f3d4ef 100644
--- a/src/ucrt/heap/recalloc.cpp
+++ b/src/ucrt/heap/recalloc.cpp
@@ -11,15 +11,20 @@
-// This function provides the logic for the _recalloc() function. It is called
-// only in the Release CRT (in the Debug CRT, the debug heap has its own
-// implementation of _recalloc()).
+// Reallocates a block of memory in the heap.
//
-// This function must be marked noinline, otherwise recalloc and
-// _recalloc_base will have identical COMDATs, and the linker will fold
-// them when calling one from the CRT. This is necessary because recalloc
-// needs to support users patching in custom implementations.
-extern "C" __declspec(noinline) _CRTRESTRICT void* __cdecl _recalloc_base(
+// This function reallocates the block pointed to by 'block' such that it is
+// 'count * size' bytes in size. The new size may be either greater or less
+// than the original size of the block. If the new size is greater than the
+// original size, the new bytes are zero-filled. This function shares its
+// implementation with the realloc() function; consult the comments of that
+// function for more information about the implementation.
+//
+// This function supports patching and therefore must be marked noinline.
+// Both _recalloc_dbg and _recalloc_base must also be marked noinline
+// to prevent identical COMDAT folding from substituting calls to _recalloc
+// with either other function or vice versa.
+extern "C" __declspec(noinline) _CRTRESTRICT void* __cdecl _recalloc(
void* const block,
size_t const count,
size_t const size
@@ -28,10 +33,10 @@ extern "C" __declspec(noinline) _CRTRESTRICT void* __cdecl _recalloc_base(
// Ensure that (count * size) does not overflow
_VALIDATE_RETURN_NOEXC(count == 0 || (_HEAP_MAXREQ / count) >= size, ENOMEM, nullptr);
- size_t const old_block_size = block != nullptr ? _msize_base(block) : 0;
+ size_t const old_block_size = block != nullptr ? _msize(block) : 0;
size_t const new_block_size = count * size;
- void* const new_block = _realloc_base(block, new_block_size);
+ void* const new_block = realloc(block, new_block_size);
// If the reallocation succeeded and the new block is larger, zero-fill the
// new bytes:
@@ -42,29 +47,3 @@ extern "C" __declspec(noinline) _CRTRESTRICT void* __cdecl _recalloc_base(
return new_block;
}
-
-// Reallocates a block of memory in the heap.
-//
-// This function reallocates the block pointed to by 'block' such that it is
-// 'count * size' bytes in size. The new size may be either greater or less
-// than the original size of the block. If the new size is greater than the
-// original size, the new bytes are zero-filled. This function shares its
-// implementation with the realloc() function; consult the comments of that
-// function for more information about the implementation.
-//
-// This function supports patching and therefore must be marked noinline.
-// Both _recalloc_dbg and _recalloc_base must also be marked noinline
-// to prevent identical COMDAT folding from substituting calls to _recalloc
-// with either other function or vice versa.
-extern "C" __declspec(noinline) _CRTRESTRICT void* __cdecl _recalloc(
- void* const block,
- size_t const count,
- size_t const size
- )
-{
-#ifdef _DEBUG
- return _recalloc_dbg(block, count, size, _NORMAL_BLOCK, nullptr, 0);
-#else
- return _recalloc_base(block, count, size);
-#endif
-}
diff --git a/src/ucrt/inc/corecrt_internal.h b/src/ucrt/inc/corecrt_internal.h
index 6268986..2ceb6be 100644
--- a/src/ucrt/inc/corecrt_internal.h
+++ b/src/ucrt/inc/corecrt_internal.h
@@ -194,9 +194,7 @@ extern "C++"
// CRT Allocation macros:
#define _expand_crt _expand
-
#define _strdup_crt _strdup
-
#define _dupenv_s_crt _dupenv_s
#define _wdupenv_s_crt _wdupenv_s
diff --git a/src/ucrt/internal/per_thread_data.cpp b/src/ucrt/internal/per_thread_data.cpp
index 0847249..4f08d24 100644
--- a/src/ucrt/internal/per_thread_data.cpp
+++ b/src/ucrt/internal/per_thread_data.cpp
@@ -57,8 +57,8 @@ VOID NTAPI __acrt_ptd_table_free(
auto ptd = static_cast<__acrt_ptd*>(buffer);
if (ptd)
{
- _free_crt(ptd->_strerror_buffer);
- _free_crt(ptd->_wcserror_buffer);
+ free(ptd->_strerror_buffer);
+ free(ptd->_wcserror_buffer);
}
return ExFreeToNPagedLookasideList(&__acrt_startup_ptd_pools, buffer);
diff --git a/src/ucrt/startup/onexit.cpp b/src/ucrt/startup/onexit.cpp
index 3b4b4ab..808a578 100644
--- a/src/ucrt/startup/onexit.cpp
+++ b/src/ucrt/startup/onexit.cpp
@@ -213,7 +213,7 @@ extern "C" int __cdecl _execute_onexit_table(_onexit_table_t* const table)
if (first != reinterpret_cast<_PVFV*>(-1))
{
- _free_crt(first);
+ free(first);
}
_PVFV* const encoded_nullptr = __crt_fast_encode_pointer(nullptr);
diff --git a/src/ucxxrt.h b/src/ucxxrt.h
index 794a251..1d3ba55 100644
--- a/src/ucxxrt.h
+++ b/src/ucxxrt.h
@@ -41,16 +41,8 @@
#define _VCRTIMP _CRTIMP
#endif
-#ifdef DBG
-# ifndef _DEBUG
-# define _DEBUG DBG
-# endif
-#endif
#include
-#include
-#include
-
#include
@@ -61,6 +53,7 @@ namespace ucxxrt
#endif
}
+
#ifndef _ByteSwap16
#define _ByteSwap16(x) ( \
((uint16_t(x) & uint16_t(0xFF << 8)) >> 8) | \
diff --git a/src/ucxxrt.inl b/src/ucxxrt.inl
index 9e58c87..a0c8b14 100644
--- a/src/ucxxrt.inl
+++ b/src/ucxxrt.inl
@@ -75,12 +75,6 @@
# define NTOS_KERNEL_RUNTIME __KERNEL_MODE
#endif
-#ifdef DBG
-# ifndef _DEBUG
-# define _DEBUG DBG
-# endif
-#endif
-
#include
#include
@@ -97,6 +91,10 @@
#include
#include
+#define _UCXXRT_ALLOCATOR_STDMALLOC 1
+#define _UCXXRT_ALLOCATOR_MINMALLOC 2
+#define _UCXXRT_ALLOCATOR _UCXXRT_ALLOCATOR_STDMALLOC
+
#include "ucxxrt.h"
#if _MSC_VER >= 1200
diff --git a/src/ucxxrtlib.props b/src/ucxxrtlib.props
index 377425a..2a3659c 100644
--- a/src/ucxxrtlib.props
+++ b/src/ucxxrtlib.props
@@ -32,7 +32,7 @@ copy /Y "$(SolutionDir)README.md" "$(SolutionDir)ucxxrt\"
copy /Y "$(SolutionDir)LICENSE" "$(SolutionDir)ucxxrt\"
copy /Y "$(SolutionDir)src\ucxxrt.props" "$(SolutionDir)ucxxrt\"
copy /Y "$(SolutionDir)src\ucxxrt.h" "$(SolutionDir)ucxxrt\"
-xcopy /D /S /Y /V /F "$(SolutionDir)inc" "$(SolutionDir)ucxxrt\inc\"
+xcopy /D /S /Y /V /F "$(SolutionDir)kext" "$(SolutionDir)ucxxrt\kext\"
xcopy /D /S /Y /V /F "$(SolutionDir)lib" "$(SolutionDir)ucxxrt\lib\" /EXCLUDE:$(SolutionDir)src\exclusion.txt