21 #include <winpr/config.h>
23 #include <winpr/crt.h>
27 #if !defined(_WIN32) || (defined(__MINGW32__) && !defined(_UCRT))
32 #define WINPR_ALIGNED_MEM_SIGNATURE 0x0BA0BAB
34 #define WINPR_ALIGNED_MEM_STRUCT_FROM_PTR(_memptr) \
35 (WINPR_ALIGNED_MEM*)(((size_t)(((BYTE*)(_memptr)) - sizeof(WINPR_ALIGNED_MEM))))
40 #define TAG WINPR_TAG("crt")
42 struct winpr_aligned_mem
48 typedef struct winpr_aligned_mem WINPR_ALIGNED_MEM;
50 void* winpr_aligned_malloc(
size_t size,
size_t alignment)
52 return winpr_aligned_offset_malloc(size, alignment, 0);
55 void* winpr_aligned_calloc(
size_t count,
size_t size,
size_t alignment)
57 return winpr_aligned_recalloc(NULL, count, size, alignment);
60 void* winpr_aligned_realloc(
void* memblock,
size_t size,
size_t alignment)
62 return winpr_aligned_offset_realloc(memblock, size, alignment, 0);
65 void* winpr_aligned_recalloc(
void* memblock,
size_t num,
size_t size,
size_t alignment)
67 return winpr_aligned_offset_recalloc(memblock, num, size, alignment, 0);
70 void* winpr_aligned_offset_malloc(
size_t size,
size_t alignment,
size_t offset)
74 uintptr_t basesize = 0;
76 void* memblock = NULL;
77 WINPR_ALIGNED_MEM* pMem = NULL;
80 if (alignment % 2 == 1)
88 if (alignment <
sizeof(
void*))
89 alignment =
sizeof(
void*);
91 if (alignment > SIZE_MAX -
sizeof(WINPR_ALIGNED_MEM))
94 header =
sizeof(WINPR_ALIGNED_MEM) + alignment;
96 if (size > SIZE_MAX - header)
99 alignsize = size + header;
101 #if defined(_ISOC11_SOURCE)
102 base = aligned_alloc(alignment, alignsize);
103 #elif defined(_POSIX_C_SOURCE) && (_POSIX_C_SOURCE >= 200112L) || (_XOPEN_SOURCE >= 600)
104 if (posix_memalign(&base, alignment, alignsize) != 0)
107 base = malloc(alignsize);
112 basesize = (uintptr_t)base;
114 if ((offset > UINTPTR_MAX) || (header > UINTPTR_MAX - offset) ||
115 (basesize > UINTPTR_MAX - header - offset))
121 memblock = (
void*)(((basesize + header + offset) & ~(alignment - 1)) - offset);
122 pMem = WINPR_ALIGNED_MEM_STRUCT_FROM_PTR(memblock);
123 pMem->sig = WINPR_ALIGNED_MEM_SIGNATURE;
124 pMem->base_addr = base;
129 void* winpr_aligned_offset_realloc(
void* memblock,
size_t size,
size_t alignment,
size_t offset)
132 void* newMemblock = NULL;
133 WINPR_ALIGNED_MEM* pMem = NULL;
134 WINPR_ALIGNED_MEM* pNewMem = NULL;
137 return winpr_aligned_offset_malloc(size, alignment, offset);
139 pMem = WINPR_ALIGNED_MEM_STRUCT_FROM_PTR(memblock);
141 if (pMem->sig != WINPR_ALIGNED_MEM_SIGNATURE)
144 "_aligned_offset_realloc: memory block was not allocated by _aligned_malloc!");
150 winpr_aligned_free(memblock);
154 newMemblock = winpr_aligned_offset_malloc(size, alignment, offset);
159 pNewMem = WINPR_ALIGNED_MEM_STRUCT_FROM_PTR(newMemblock);
160 copySize = (pNewMem->size < pMem->size) ? pNewMem->size : pMem->size;
161 CopyMemory(newMemblock, memblock, copySize);
162 winpr_aligned_free(memblock);
166 static INLINE
size_t cMIN(
size_t a,
size_t b)
173 void* winpr_aligned_offset_recalloc(
void* memblock,
size_t num,
size_t size,
size_t alignment,
176 char* newMemblock = NULL;
177 WINPR_ALIGNED_MEM* pMem = NULL;
178 WINPR_ALIGNED_MEM* pNewMem = NULL;
182 newMemblock = winpr_aligned_offset_malloc(size * num, alignment, offset);
186 pNewMem = WINPR_ALIGNED_MEM_STRUCT_FROM_PTR(newMemblock);
187 ZeroMemory(newMemblock, pNewMem->size);
193 pMem = WINPR_ALIGNED_MEM_STRUCT_FROM_PTR(memblock);
195 if (pMem->sig != WINPR_ALIGNED_MEM_SIGNATURE)
198 "_aligned_offset_recalloc: memory block was not allocated by _aligned_malloc!");
202 if ((num == 0) || (size == 0))
205 if (pMem->size > (1ull * num * size) + alignment)
208 newMemblock = winpr_aligned_offset_malloc(size * num, alignment, offset);
213 pNewMem = WINPR_ALIGNED_MEM_STRUCT_FROM_PTR(newMemblock);
215 const size_t csize = cMIN(pMem->size, pNewMem->size);
216 memcpy(newMemblock, memblock, csize);
217 ZeroMemory(newMemblock + csize, pNewMem->size - csize);
220 winpr_aligned_free(memblock);
224 size_t winpr_aligned_msize(
void* memblock,
size_t alignment,
size_t offset)
226 WINPR_ALIGNED_MEM* pMem = NULL;
231 pMem = WINPR_ALIGNED_MEM_STRUCT_FROM_PTR(memblock);
233 if (pMem->sig != WINPR_ALIGNED_MEM_SIGNATURE)
235 WLog_ERR(TAG,
"_aligned_msize: memory block was not allocated by _aligned_malloc!");
242 void winpr_aligned_free(
void* memblock)
244 WINPR_ALIGNED_MEM* pMem = NULL;
249 pMem = WINPR_ALIGNED_MEM_STRUCT_FROM_PTR(memblock);
251 if (pMem->sig != WINPR_ALIGNED_MEM_SIGNATURE)
253 WLog_ERR(TAG,
"_aligned_free: memory block was not allocated by _aligned_malloc!");
257 free(pMem->base_addr);