xref: /reactos/sdk/include/ucrt/malloc.h (revision e3e520d1)
1 //
2 // malloc.h
3 //
4 //      Copyright (c) Microsoft Corporation. All rights reserved.
5 //
6 // The memory allocation library.
7 //
8 #pragma once
9 #ifndef _INC_MALLOC // include guard for 3rd party interop
10 #define _INC_MALLOC
11 
12 #include <corecrt.h>
13 #include <corecrt_malloc.h>
14 
15 #pragma warning(push)
16 #pragma warning(disable: _UCRT_DISABLED_WARNINGS)
17 _UCRT_DISABLE_CLANG_WARNINGS
18 
19 _CRT_BEGIN_C_HEADER
20 
21 
22 
23 // Maximum heap request the heap manager will attempt
24 #ifdef _WIN64
25     #define _HEAP_MAXREQ 0xFFFFFFFFFFFFFFE0
26 #else
27     #define _HEAP_MAXREQ 0xFFFFFFE0
28 #endif
29 
30 
31 
32 // Constants for _heapchk and _heapwalk routines
33 #define _HEAPEMPTY    (-1)
34 #define _HEAPOK       (-2)
35 #define _HEAPBADBEGIN (-3)
36 #define _HEAPBADNODE  (-4)
37 #define _HEAPEND      (-5)
38 #define _HEAPBADPTR   (-6)
39 #define _FREEENTRY      0
40 #define _USEDENTRY      1
41 
42 typedef struct _heapinfo
43 {
44     int* _pentry;
45     size_t _size;
46     int _useflag;
47 } _HEAPINFO;
48 
49 #define _mm_free(a)      _aligned_free(a)
50 #define _mm_malloc(a, b) _aligned_malloc(a, b)
51 
52 
53 
54 _Ret_notnull_ _Post_writable_byte_size_(_Size)
55 void* __cdecl _alloca(_In_ size_t _Size);
56 
57 
58 
59 #if !defined __midl && !defined RC_INVOKED
60 
61     _ACRTIMP intptr_t __cdecl _get_heap_handle(void);
62 
63     _Check_return_
64     _DCRTIMP int __cdecl _heapmin(void);
65 
66     #if defined _DEBUG || defined _CRT_USE_WINAPI_FAMILY_DESKTOP_APP || defined _CORECRT_BUILD
67         _ACRTIMP int __cdecl _heapwalk(_Inout_ _HEAPINFO* _EntryInfo);
68     #endif
69 
70     #if defined _CRT_USE_WINAPI_FAMILY_DESKTOP_APP || defined _CRT_USE_WINAPI_FAMILY_GAMES
71         _Check_return_ _DCRTIMP int __cdecl _heapchk(void);
72     #endif
73 
74     _DCRTIMP int __cdecl _resetstkoflw(void);
75 
76     #define _ALLOCA_S_THRESHOLD     1024
77     #define _ALLOCA_S_STACK_MARKER  0xCCCC
78     #define _ALLOCA_S_HEAP_MARKER   0xDDDD
79 
80     #ifdef _WIN64
81         #define _ALLOCA_S_MARKER_SIZE 16
82     #else
83         #define _ALLOCA_S_MARKER_SIZE 8
84     #endif
85 
86     _STATIC_ASSERT(sizeof(unsigned int) <= _ALLOCA_S_MARKER_SIZE);
87 
88 
89     #pragma warning(push)
90     #pragma warning(disable: 6540) // C6540: attribute annotations on this function will invalidate all
91                                    // of its existing __declspec annotations
92 
93     __inline void* _MarkAllocaS(_Out_opt_ __crt_typefix(unsigned int*) void* _Ptr, unsigned int _Marker)
94     {
95         if (_Ptr)
96         {
97             *((unsigned int*)_Ptr) = _Marker;
98             _Ptr = (char*)_Ptr + _ALLOCA_S_MARKER_SIZE;
99         }
100         return _Ptr;
101     }
102 
103     __inline size_t _MallocaComputeSize(size_t _Size)
104     {
105         size_t _MarkedSize = _Size + _ALLOCA_S_MARKER_SIZE;
106         return _MarkedSize > _Size ? _MarkedSize : 0;
107     }
108 
109     #pragma warning(pop)
110 
111 #endif
112 
113 
114 
115 #ifdef _DEBUG
116 // C6255: _alloca indicates failure by raising a stack overflow exception
117 // C6386: buffer overrun
118     #ifndef _CRTDBG_MAP_ALLOC
119         #undef _malloca
120         #define _malloca(size)                                                           \
121             __pragma(warning(suppress: 6255 6386))                                       \
122             (_MallocaComputeSize(size) != 0                                              \
123                 ? _MarkAllocaS(malloc(_MallocaComputeSize(size)), _ALLOCA_S_HEAP_MARKER) \
124                 : NULL)
125     #endif
126 
127 #else
128 
129     #undef _malloca
130     #define _malloca(size)                                                                 \
131         __pragma(warning(suppress: 6255 6386))                                             \
132         (_MallocaComputeSize(size) != 0                                                    \
133             ? (((_MallocaComputeSize(size) <= _ALLOCA_S_THRESHOLD)                         \
134                 ? _MarkAllocaS(_alloca(_MallocaComputeSize(size)), _ALLOCA_S_STACK_MARKER) \
135                 : _MarkAllocaS(malloc(_MallocaComputeSize(size)), _ALLOCA_S_HEAP_MARKER))) \
136             : NULL)
137 
138 #endif
139 
140 
141 
142 #if defined __midl && !defined RC_INVOKED
143 #elif defined _DEBUG && defined _CRTDBG_MAP_ALLOC
144 #else
145 
146     #undef _freea
147 
148     #pragma warning(push)
149     #pragma warning(disable: 6014) // leaking memory
150     __inline void __CRTDECL _freea(_Pre_maybenull_ _Post_invalid_ void* _Memory)
151     {
152         unsigned int _Marker;
153         if (_Memory)
154         {
155             _Memory = (char*)_Memory - _ALLOCA_S_MARKER_SIZE;
156             _Marker = *(unsigned int*)_Memory;
157             if (_Marker == _ALLOCA_S_HEAP_MARKER)
158             {
159                 free(_Memory);
160             }
161             #ifdef _ASSERTE
162             else if (_Marker != _ALLOCA_S_STACK_MARKER)
163             {
164                 _ASSERTE(("Corrupted pointer passed to _freea" && 0));
165             }
166             #endif
167         }
168     }
169     #pragma warning(pop)
170 
171 #endif
172 
173 
174 
175 #if defined(_CRT_INTERNAL_NONSTDC_NAMES) && _CRT_INTERNAL_NONSTDC_NAMES
176     #define alloca _alloca
177 #endif
178 
179 
180 
181 _CRT_END_C_HEADER
182 _UCRT_RESTORE_CLANG_WARNINGS
183 #pragma warning(pop) // _UCRT_DISABLED_WARNINGS
184 #endif // _INC_MALLOC
185