[FTFD] Fix malloc/realloc/free wrappers

On x64 malloc needs to return a 16 byte aligned buffer, the previous code used an 8 byte header, making the allocations unaligned. This is now fixed with an improved header structure.
Also simplify realloc a bit and make it handle Object == NULL.
This commit is contained in:
Timo Kreuzer 2025-03-31 15:26:06 +03:00
parent 91fadeb6c3
commit dca5194279

View file

@ -36,43 +36,54 @@ DbgPrint(IN PCCH Format, IN ...)
* buffer (need to copy the old contents to the new buffer). So, allocate * buffer (need to copy the old contents to the new buffer). So, allocate
* extra space for a size_t, store the allocated size in there and return * extra space for a size_t, store the allocated size in there and return
* the address just past it as the allocated buffer. * the address just past it as the allocated buffer.
* On win64 we need to align the allocation to 16 bytes, otherwise 8 bytes.
*/ */
typedef struct _MALLOC_HEADER
{
SIZE_T Size;
SIZE_T Alignment;
} MALLOC_HEADER, * PMALLOC_HEADER;
void * void *
malloc(size_t Size) malloc(size_t Size)
{ {
void *Object; PMALLOC_HEADER Header;
Object = EngAllocMem(0, sizeof(size_t) + Size, TAG_FREETYPE); Header = EngAllocMem(0, sizeof(MALLOC_HEADER) + Size, TAG_FREETYPE);
if (Object != NULL) if (Header == NULL)
{ {
*((size_t *)Object) = Size; return NULL;
Object = (void *)((size_t *)Object + 1);
} }
return Object; Header->Size = Size;
Header->Alignment = -1;
return (Header + 1);
} }
void * void *
realloc(void *Object, size_t Size) realloc(void *Object, size_t Size)
{ {
void *NewObject; PVOID NewObject;
PMALLOC_HEADER OldHeader;
size_t CopySize; size_t CopySize;
NewObject = EngAllocMem(0, sizeof(size_t) + Size, TAG_FREETYPE); NewObject = malloc(Size);
if (NewObject != NULL) if (NewObject == NULL)
{ {
*((size_t *)NewObject) = Size; return NULL;
NewObject = (void *)((size_t *)NewObject + 1);
CopySize = *((size_t *)Object - 1);
if (Size < CopySize)
{
CopySize = Size;
}
memcpy(NewObject, Object, CopySize);
EngFreeMem((size_t *)Object - 1);
} }
if (Object == NULL)
{
return NewObject;
}
OldHeader = (PMALLOC_HEADER)Object - 1;
CopySize = min(OldHeader->Size, Size);
memcpy(NewObject, Object, CopySize);
free(Object);
return NewObject; return NewObject;
} }
@ -81,7 +92,7 @@ free(void *Object)
{ {
if (Object != NULL) if (Object != NULL)
{ {
EngFreeMem((size_t *)Object - 1); EngFreeMem((PMALLOC_HEADER)Object - 1);
} }
} }