From 3087e48ab74ddd434fe90d4579b17884b98e3974 Mon Sep 17 00:00:00 2001 From: Ivan K Date: Thu, 13 Feb 2025 17:14:44 +0300 Subject: [PATCH 1/2] configure: check for VirtualAlloc() Windows API Since the Microsoft documentation is not 100% clear on this, check for VirtualAlloc() and VirtualFree() in either or + , even though the documentation may have meant "use either header file". Do not regenerate ./configure yet. --- conf.h.in | 10 ++++++++++ configure.ac | 26 +++++++++++++++++++++++++- 2 files changed, 35 insertions(+), 1 deletion(-) diff --git a/conf.h.in b/conf.h.in index ecd1811..48de4cb 100644 --- a/conf.h.in +++ b/conf.h.in @@ -60,6 +60,16 @@ #define USE_MMAP 0 #define HAVE_MUNMAP 0 +/* + * On Windows, use VirtualAlloc() to allocate memory and use VirtualFree + * to deallocate it. To be absolutely sure, try to find it in one of the + * two sets of header files. + */ +#define HAVE_DECL_VIRTUALALLOC 0 +#define HAVE_DECL_VIRTUALFREE 0 +#define HAVE_VIRTUALALLOC_MEMORYAPI_H 0 +#define HAVE_VIRTUALALLOC_WINDOWS_H 0 + /* * This is the basic block size in bits. If possible, the configure * script will set this to be the value returned by the getpagesize() diff --git a/configure.ac b/configure.ac index a5295f1..7d84310 100644 --- a/configure.ac +++ b/configure.ac @@ -345,7 +345,31 @@ AC_MSG_NOTICE([important functionality]) AC_CHECK_FUNCS(mmap munmap sbrk) -if test "x$ac_cv_func_mmap" != "xyes" && test "x$ac_cv_func_sbrk" != "xyes"; then +ac_cv_target_win32=no +AC_MSG_CHECKING([for VirtualAlloc in (Windows)]) +AC_CHECK_DECLS( + [[VirtualAlloc(LPVOID, SIZE_T, DWORD, DWORD)], + [VirtualFree(LPVOID, SIZE_T, DWORD)]], + [ ac_cv_target_win32=yes; AC_DEFINE(HAVE_VIRTUALALLOC_WINDOWS_H) ], + [ + AC_MSG_CHECKING([for VirtualAlloc in , (Windows)]) + AC_CHECK_DECLS( + [[VirtualAlloc(LPVOID, SIZE_T, DWORD, DWORD)], + [VirtualFree(LPVOID, SIZE_T, DWORD)]], + [ ac_cv_target_win32=yes; AC_DEFINE(HAVE_VIRTUALALLOC_MEMORYAPI_H) ], + [ ac_cv_target_win32=no ], + [[#define WIN32_LEAN_AND_MEAN + #include + #include ]] + ) + ], + [[#define WIN32_LEAN_AND_MEAN + #include ]] +) + +if test "x$ac_cv_func_mmap" != "xyes" && test "x$ac_cv_func_sbrk" != "xyes" && \ + test "x$ac_cv_target_win32" != "xyes"; +then AC_MSG_WARN() AC_MSG_WARN(no mmap nor sbrk function. See INTERNAL_MEMORY_SPACE in settings.dist.) AC_MSG_WARN() From 4e25a14291db72caf5eed4c7c0fbe62242cc3730 Mon Sep 17 00:00:00 2001 From: Ivan K Date: Wed, 16 Dec 2020 18:58:21 +0300 Subject: [PATCH 2/2] use VirtualAlloc/Free if available on Windows Pass both dmalloc_fc_t and dmalloc_t tests. --- dmalloc_t.c | 2 +- heap.c | 19 +++++++++++++++++++ settings.dist | 2 +- 3 files changed, 21 insertions(+), 2 deletions(-) diff --git a/dmalloc_t.c b/dmalloc_t.c index 13143b2..e9417db 100644 --- a/dmalloc_t.c +++ b/dmalloc_t.c @@ -61,7 +61,7 @@ #define INTER_CHAR 'i' #define DEFAULT_ITERATIONS 10000 #define MAX_POINTERS 1024 -#if HAVE_SBRK == 0 && HAVE_MMAP == 0 +#if HAVE_SBRK == 0 && HAVE_MMAP == 0 && (HAVE_DECL_VIRTUALALLOC == 0 || HAVE_DECL_VIRTUALFREE == 0) /* if we have a small memory area then just take 1/10 of the internal space */ #define MAX_ALLOC (INTERNAL_MEMORY_SPACE / 10) #else diff --git a/heap.c b/heap.c index 210c29e..8edcd3c 100644 --- a/heap.c +++ b/heap.c @@ -24,12 +24,22 @@ * heap as well as reporting the current position of the heap. */ +#include "conf.h" + #if HAVE_SYS_TYPES_H # include #endif #if HAVE_SYS_MMAN_H # include /* for mmap stuff */ #endif +#if HAVE_VIRTUALALLOC_WINDOWS_H +# define WIN32_LEAN_AND_MEAN +# include +#elif HAVE_VIRTUALALLOC_MEMORYAPI_H +# define WIN32_LEAN_AND_MEAN +# include +# include +#endif #define DMALLOC_DISABLE @@ -95,6 +105,9 @@ static void *heap_extend(const int incr) #else #if HAVE_SBRK ret = sbrk(incr); +#elif HAVE_DECL_VIRTUALALLOC && HAVE_DECL_VIRTUALFREE + ret = VirtualAlloc(NULL, incr, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE); + if (!ret) ret = SBRK_ERROR; #endif /* if HAVE_SBRK */ #endif /* if not HAVE_MMAP && USE_MMAP */ #endif /* if not INTERNAL_MEMORY_SPACE */ @@ -149,6 +162,12 @@ static void heap_release(void *addr, const int size) dmalloc_message("munmap failed to release heap memory %p, size %d", addr, size); } +#elif HAVE_DECL_VIRTUALALLOC && HAVE_DECL_VIRTUALFREE + /* NB: Assuming that heap_release is always called with the same size as + ** heap_extend. WinAPI requires the second parameter to VirtualFree + ** to be 0 to avoid reserving and then abandoning blocks of uncommitted + ** address space. */ + VirtualFree(addr, 0, MEM_RELEASE); #else /* no-op */ #endif /* if not HAVE_MMAP && USE_MMAP */ diff --git a/settings.dist b/settings.dist index eec24fc..3535ae9 100644 --- a/settings.dist +++ b/settings.dist @@ -387,7 +387,7 @@ * HAVE_MMAP are 0. Please send me email with any problems or * comments on this feature. */ -#if HAVE_SBRK == 0 && HAVE_MMAP == 0 +#if HAVE_SBRK == 0 && HAVE_MMAP == 0 && (HAVE_DECL_VIRTUALALLOC == 0 || HAVE_DECL_VIRTUALFREE == 0) #define INTERNAL_MEMORY_SPACE (1024 * 1024) #endif