21#include <winpr/config.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")
42struct winpr_aligned_mem
48typedef struct winpr_aligned_mem WINPR_ALIGNED_MEM;
50void* winpr_aligned_malloc(
size_t size,
size_t alignment)
52 return winpr_aligned_offset_malloc(size, alignment, 0);
55void* winpr_aligned_calloc(
size_t count,
size_t size,
size_t alignment)
57 return winpr_aligned_recalloc(NULL, count, size, alignment);
60void* winpr_aligned_realloc(
void* memblock,
size_t size,
size_t alignment)
62 return winpr_aligned_offset_realloc(memblock, size, alignment, 0);
65void* 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);
70void* 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;
129void* 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);
166static INLINE
size_t cMIN(
size_t a,
size_t b)
173void* 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);
224size_t winpr_aligned_msize(
void* memblock, WINPR_ATTR_UNUSED
size_t alignment,
225 WINPR_ATTR_UNUSED
size_t offset)
227 WINPR_ALIGNED_MEM* pMem = NULL;
232 pMem = WINPR_ALIGNED_MEM_STRUCT_FROM_PTR(memblock);
234 if (pMem->sig != WINPR_ALIGNED_MEM_SIGNATURE)
236 WLog_ERR(TAG,
"_aligned_msize: memory block was not allocated by _aligned_malloc!");
243void winpr_aligned_free(
void* memblock)
245 WINPR_ALIGNED_MEM* pMem = NULL;
250 pMem = WINPR_ALIGNED_MEM_STRUCT_FROM_PTR(memblock);
252 if (pMem->sig != WINPR_ALIGNED_MEM_SIGNATURE)
254 WLog_ERR(TAG,
"_aligned_free: memory block was not allocated by _aligned_malloc!");
258 free(pMem->base_addr);