|
|
@@ -6330,7 +6330,125 @@ History:
|
|
|
|
|
|
#endif /* !HAVE_MALLOC */
|
|
|
|
|
|
-#ifdef HAVE_MALLOC
|
|
|
+
|
|
|
+// Define WIN32_DETECT_OVERWRITE if you'd like guard pages around memory allocations on Windows
|
|
|
+#if 0
|
|
|
+#define WIN32_DETECT_OVERWRITE
|
|
|
+#endif
|
|
|
+#ifdef WIN32_DETECT_OVERWRITE
|
|
|
+
|
|
|
+#include <windows.h>
|
|
|
+
|
|
|
+typedef struct
|
|
|
+{
|
|
|
+ PBYTE pAddr;
|
|
|
+ ULONG ulSize;
|
|
|
+} SAFE_HEAP_POINTER;
|
|
|
+
|
|
|
+static DWORD GetPageSize()
|
|
|
+{
|
|
|
+ static DWORD page_size;
|
|
|
+
|
|
|
+ if (!page_size) {
|
|
|
+ SYSTEM_INFO si = { 0 };
|
|
|
+ GetSystemInfo(&si);
|
|
|
+ page_size = si.dwPageSize;
|
|
|
+ }
|
|
|
+ return page_size;
|
|
|
+}
|
|
|
+
|
|
|
+static ULONG SDLCALL real_msize(IN void *pPtr)
|
|
|
+{
|
|
|
+ PBYTE pVirtualAddr = (PBYTE)pPtr;
|
|
|
+ SAFE_HEAP_POINTER *pSafePtr = (SAFE_HEAP_POINTER *)(pVirtualAddr - sizeof(SAFE_HEAP_POINTER));
|
|
|
+ ULONG_PTR rvaOld = (ULONG_PTR)(pSafePtr + 1) - (ULONG_PTR)pSafePtr->pAddr;
|
|
|
+ return (ULONG)(pSafePtr->ulSize - GetPageSize() - rvaOld);
|
|
|
+}
|
|
|
+
|
|
|
+static void SDLCALL real_free(IN void *pPtr)
|
|
|
+{
|
|
|
+ if (!pPtr) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ PBYTE pVirtualAddr = (PBYTE)pPtr;
|
|
|
+ SAFE_HEAP_POINTER *pSafePtr = (SAFE_HEAP_POINTER *)(pVirtualAddr - sizeof(SAFE_HEAP_POINTER));
|
|
|
+ ULONG ulOldProtect;
|
|
|
+ VirtualProtect(pSafePtr->pAddr + pSafePtr->ulSize - GetPageSize(), GetPageSize(), PAGE_READWRITE, &ulOldProtect);
|
|
|
+ _aligned_free(pSafePtr->pAddr);
|
|
|
+}
|
|
|
+
|
|
|
+static void *SDLCALL real_malloc(IN size_t dwBytes)
|
|
|
+{
|
|
|
+ DWORD dwTotalBytes = (DWORD)dwBytes + sizeof(SAFE_HEAP_POINTER);
|
|
|
+ DWORD dwPages = (dwTotalBytes / GetPageSize()) + 1;
|
|
|
+ DWORD dwAlignedBytesCount = (dwPages + 1) * GetPageSize();
|
|
|
+ PBYTE pPtr = (PBYTE)_aligned_malloc(dwAlignedBytesCount, GetPageSize());
|
|
|
+ if (!pPtr) {
|
|
|
+ return NULL;
|
|
|
+ }
|
|
|
+
|
|
|
+ ZeroMemory(pPtr, dwAlignedBytesCount);
|
|
|
+ PBYTE pLastPageStart = pPtr + dwPages * GetPageSize();
|
|
|
+ ULONG ulOldProtect;
|
|
|
+ PBYTE pBlock = (PBYTE)(pLastPageStart - dwBytes);
|
|
|
+ if (!VirtualProtect(pLastPageStart, GetPageSize(), PAGE_READWRITE | PAGE_GUARD, &ulOldProtect)) {
|
|
|
+ _aligned_free(pPtr);
|
|
|
+ return NULL;
|
|
|
+ }
|
|
|
+ SAFE_HEAP_POINTER *pSafePtr = (SAFE_HEAP_POINTER *)(pBlock - sizeof(SAFE_HEAP_POINTER));
|
|
|
+ pSafePtr->pAddr = pPtr;
|
|
|
+ pSafePtr->ulSize = dwAlignedBytesCount;
|
|
|
+ return pBlock;
|
|
|
+}
|
|
|
+
|
|
|
+static void *SDLCALL real_calloc(IN size_t dwElements, IN size_t dwElementSize)
|
|
|
+{
|
|
|
+ PVOID pPtr = real_malloc(dwElements * dwElementSize);
|
|
|
+ if (pPtr) {
|
|
|
+ ZeroMemory(pPtr, dwElements * dwElementSize);
|
|
|
+ }
|
|
|
+ return pPtr;
|
|
|
+}
|
|
|
+
|
|
|
+static void *SDLCALL real_realloc(IN void *pPtr, IN size_t dwBytes)
|
|
|
+{
|
|
|
+ if (!pPtr) {
|
|
|
+ return real_malloc(dwBytes);
|
|
|
+ }
|
|
|
+
|
|
|
+ PBYTE pVirtualAddr = (PBYTE)pPtr;
|
|
|
+ SAFE_HEAP_POINTER *pSafePtr = (SAFE_HEAP_POINTER *)(pVirtualAddr - sizeof(SAFE_HEAP_POINTER));
|
|
|
+ SAFE_HEAP_POINTER oldPtr = *pSafePtr;
|
|
|
+ ULONG ulPrevSize = real_msize(pPtr);
|
|
|
+ if (ulPrevSize == dwBytes) {
|
|
|
+ return pPtr;
|
|
|
+ }
|
|
|
+
|
|
|
+ // Start working on the addresses
|
|
|
+ DWORD dwTotalBytes = (DWORD)dwBytes + sizeof(SAFE_HEAP_POINTER);
|
|
|
+ DWORD dwNewPages = (dwTotalBytes / GetPageSize()) + 1;
|
|
|
+ DWORD dwAlignedBytesCount = (dwNewPages + 1) * GetPageSize();
|
|
|
+ PBYTE pBlock = 0;
|
|
|
+ PBYTE pLastPageStart = 0;
|
|
|
+ if ((dwAlignedBytesCount <= oldPtr.ulSize) && (dwAlignedBytesCount + GetPageSize() >= oldPtr.ulSize)) {
|
|
|
+ // No need to reallocate memory, the allocated pages R enough
|
|
|
+ pLastPageStart = pSafePtr->pAddr + dwNewPages * GetPageSize();
|
|
|
+ pBlock = (pLastPageStart - dwBytes);
|
|
|
+ MoveMemory(pBlock, pPtr, min(ulPrevSize, dwBytes));
|
|
|
+ pSafePtr = (SAFE_HEAP_POINTER *)(pBlock - sizeof(SAFE_HEAP_POINTER));
|
|
|
+ *pSafePtr = oldPtr;
|
|
|
+ return pBlock;
|
|
|
+ }
|
|
|
+
|
|
|
+ // Buffer was enlarged or reduced by more than PAGE_SIZE
|
|
|
+ PBYTE pNew = (PBYTE)real_malloc(dwBytes);
|
|
|
+ CopyMemory(pNew, pPtr, min(ulPrevSize, dwBytes));
|
|
|
+ real_free(pPtr);
|
|
|
+ return pNew;
|
|
|
+}
|
|
|
+
|
|
|
+#elif defined(HAVE_MALLOC)
|
|
|
static void * SDLCALL real_malloc(size_t s) { return malloc(s); }
|
|
|
static void * SDLCALL real_calloc(size_t n, size_t s) { return calloc(n, s); }
|
|
|
static void * SDLCALL real_realloc(void *p, size_t s) { return realloc(p,s); }
|