1
0
mirror of https://git.code.sf.net/p/mingw-w64/mingw-w64 synced 2025-04-18 17:44:18 +03:00

crt: Provide *_recalloc functions

They are natively available since msvcr80.dll, they are not available in
msvcrt.dll. Provide compatibility emulation into all import libraries where
they are not available.

Compatibility emulation needs to use _msize() or _aligned_msize() functions
to figure out the previous size and properly clear the expanded memory as
*calloc functions require.

Memory allocated by these mingw-w64 emulation functions can be normally
released by the appropriate CRT free() or _aligned_free() function.

Signed-off-by: Martin Storsjö <martin@martin.st>
This commit is contained in:
Pali Rohár 2025-04-08 00:20:47 +02:00 committed by Martin Storsjö
parent b40e24afb1
commit e1ff62d7f9
7 changed files with 81 additions and 6 deletions

View File

@ -324,7 +324,10 @@ src_msvcrt=\
misc/__sys_errlist.c \
misc/__sys_nerr.c \
misc/_aligned_msize.c \
misc/_aligned_offset_recalloc.c \
misc/_aligned_recalloc.c \
misc/_configthreadlocale.c \
misc/_recalloc.c \
misc/_set_purecall_handler.c \
misc/imaxdiv.c \
misc/invalid_parameter_handler.c \
@ -813,9 +816,12 @@ src_pre_msvcr80=\
misc/__sys_errlist.c \
misc/__sys_nerr.c \
misc/_aligned_msize.c \
misc/_aligned_offset_recalloc.c \
misc/_aligned_recalloc.c \
misc/_configthreadlocale.c \
misc/_get_errno.c \
misc/_initterm_e.c \
misc/_recalloc.c \
misc/_set_errno.c \
misc/btowc.c \
misc/imaxabs.c \

View File

@ -0,0 +1,25 @@
/**
* This file has no copyright assigned and is placed in the Public Domain.
* This file is part of the mingw-w64 runtime package.
* No warranty is given; refer to the file DISCLAIMER.PD within this package.
*/
#include <malloc.h>
#include <string.h>
void * __cdecl _aligned_offset_recalloc(void *memory, size_t count, size_t size, size_t alignment, size_t offset)
{
void *new_memory;
size_t previous_size;
size_t total_size;
if (__builtin_mul_overflow(count, size, &total_size))
return NULL;
previous_size = memory ? _aligned_msize(memory, alignment, offset) : 0;
if (previous_size == (size_t)-1)
return NULL;
new_memory = _aligned_offset_realloc(memory, total_size, alignment, offset);
if (new_memory && previous_size < total_size)
memset(new_memory + previous_size, 0, total_size - previous_size);
return new_memory;
}
void * (__cdecl *__MINGW_IMP_SYMBOL(_aligned_offset_recalloc))(void *, size_t, size_t, size_t, size_t) = _aligned_offset_recalloc;

View File

@ -0,0 +1,25 @@
/**
* This file has no copyright assigned and is placed in the Public Domain.
* This file is part of the mingw-w64 runtime package.
* No warranty is given; refer to the file DISCLAIMER.PD within this package.
*/
#include <malloc.h>
#include <string.h>
void * __cdecl _aligned_recalloc(void *memory, size_t count, size_t size, size_t alignment)
{
void *new_memory;
size_t previous_size;
size_t total_size;
if (__builtin_mul_overflow(count, size, &total_size))
return NULL;
previous_size = memory ? _aligned_msize(memory, alignment, 0) : 0;
if (previous_size == (size_t)-1)
return NULL;
new_memory = _aligned_realloc(memory, total_size, alignment);
if (new_memory && previous_size < total_size)
memset(new_memory + previous_size, 0, total_size - previous_size);
return new_memory;
}
void * (__cdecl *__MINGW_IMP_SYMBOL(_aligned_recalloc))(void *, size_t, size_t, size_t) = _aligned_recalloc;

View File

@ -0,0 +1,25 @@
/**
* This file has no copyright assigned and is placed in the Public Domain.
* This file is part of the mingw-w64 runtime package.
* No warranty is given; refer to the file DISCLAIMER.PD within this package.
*/
#include <malloc.h>
#include <string.h>
void * __cdecl _recalloc(void *memory, size_t count, size_t size)
{
void *new_memory;
size_t previous_size;
size_t total_size;
if (__builtin_mul_overflow(count, size, &total_size))
return NULL;
previous_size = memory ? _msize(memory) : 0;
if (previous_size == (size_t)-1)
return NULL;
new_memory = realloc(memory, total_size);
if (new_memory && previous_size < total_size)
memset(new_memory + previous_size, 0, total_size - previous_size);
return new_memory;
}
void * (__cdecl *__MINGW_IMP_SYMBOL(_recalloc))(void *, size_t, size_t) = _recalloc;

View File

@ -161,11 +161,9 @@ extern "C" {
#define _aligned_offset_malloc_dbg(s,a,o,f,l) _aligned_offset_malloc(s,a,o)
#define _aligned_offset_realloc_dbg(p,s,a,o,f,l) _aligned_offset_realloc(p,s,a,o)
#if __MSVCRT_VERSION__ >= 0x900
#define _recalloc_dbg(p,c,s,t,f,l) _recalloc(p,c,s)
#define _aligned_recalloc_dbg(p,c,s,a,f,l) _aligned_realloc(p,c,s,a)
#define _aligned_offset_recalloc_dbg(p,c,s,a,o,f,l) _aligned_offset_recalloc(p,c,s,a,o)
#endif
#define _aligned_msize_dbg(p,a,o) _aligned_msize(p,a,o)
#define _malloca_dbg(s,t,f,l) _malloca(s)

View File

@ -102,11 +102,9 @@ extern "C" {
_CRTIMP void *__cdecl _aligned_offset_malloc(size_t _Size,size_t _Alignment,size_t _Offset);
_CRTIMP void *__cdecl _aligned_realloc(void *_Memory,size_t _Size,size_t _Alignment);
_CRTIMP void *__cdecl _aligned_offset_realloc(void *_Memory,size_t _Size,size_t _Alignment,size_t _Offset);
# if __MSVCRT_VERSION__ >= 0x900
_CRTIMP void *__cdecl _recalloc(void *_Memory,size_t _Count,size_t _Size);
_CRTIMP void *__cdecl _aligned_recalloc(void *_Memory,size_t _Count,size_t _Size,size_t _Alignment);
_CRTIMP void *__cdecl _aligned_offset_recalloc(void *_Memory,size_t _Count,size_t _Size,size_t _Alignment,size_t _Offset);
# endif
_CRTIMP size_t __cdecl _aligned_msize(void *_Memory,size_t _Alignment,size_t _Offset);
#if defined(_DEBUG) && defined(_CRTDBG_MAP_ALLOC)

View File

@ -458,11 +458,9 @@ float __cdecl __MINGW_NOTHROW strtof(const char * __restrict__ _Str,char ** __re
_CRTIMP void *__cdecl _aligned_offset_malloc(size_t _Size,size_t _Alignment,size_t _Offset);
_CRTIMP void *__cdecl _aligned_realloc(void *_Memory,size_t _Size,size_t _Alignment);
_CRTIMP void *__cdecl _aligned_offset_realloc(void *_Memory,size_t _Size,size_t _Alignment,size_t _Offset);
# if __MSVCRT_VERSION__ >= 0x900
_CRTIMP void *__cdecl _recalloc(void *_Memory,size_t _Count,size_t _Size);
_CRTIMP void *__cdecl _aligned_recalloc(void *_Memory,size_t _Count,size_t _Size,size_t _Alignment);
_CRTIMP void *__cdecl _aligned_offset_recalloc(void *_Memory,size_t _Count,size_t _Size,size_t _Alignment,size_t _Offset);
# endif
_CRTIMP size_t __cdecl _aligned_msize(void *_Memory,size_t _Alignment,size_t _Offset);
#if defined(_DEBUG) && defined(_CRTDBG_MAP_ALLOC)