typedef LONG NTSTATUS;
-typedef NTSTATUS
-(NTAPI * PRTL_HEAP_COMMIT_ROUTINE)(
- IN PVOID Base,
- IN OUT PVOID *CommitAddress,
- IN OUT PSIZE_T CommitSize
- );
+typedef NTSTATUS (NTAPI *PRTL_HEAP_COMMIT_ROUTINE) (
+ IN PVOID Base,
+ IN OUT PVOID *CommitAddress,
+ IN OUT PSIZE_T CommitSize
+ );
typedef struct _RTL_HEAP_PARAMETERS {
ULONG Length;
special segment to the executable. In order to be able to do this
without losing too much space, we need to create a Windows heap at
the specific address of the static array. The RtlCreateHeap
- available inside the NT kernel since XP will do this. It allows to
- create a non-growable heap at a specific address. So before
+ available inside the NT kernel since XP will do this. It allows the
+ creation of a non-growable heap at a specific address. So before
dumping, we create a non-growable heap at the address of the
dumped_data[] array. After dumping, we reuse memory allocated
there without being able to free it (but most of it is not meant to
claims for new memory. Before dumping, we allocate space
from the fixed size dumped_data[] array.
*/
-NTSTATUS NTAPI
+static NTSTATUS NTAPI
dumped_data_commit (PVOID Base, PVOID *CommitAddress, PSIZE_T CommitSize)
{
/* This is used before dumping.
/* FREEABLE_P checks if the block can be safely freed. */
#define FREEABLE_P(addr) \
- ((unsigned char *)(addr) > 0 \
- && ((unsigned char *)(addr) < dumped_data \
- || (unsigned char *)(addr) >= dumped_data + DUMPED_HEAP_SIZE))
+ ((DWORD_PTR)(unsigned char *)(addr) > 0 \
+ && ((unsigned char *)(addr) < dumped_data \
+ || (unsigned char *)(addr) >= dumped_data + DUMPED_HEAP_SIZE))
void *
malloc_after_dump (size_t size)
advance, and the buffer is enlarged several times as the data is
decompressed on the fly. */
if (nbytes < MAX_BUFFER_SIZE)
- p = VirtualAlloc (NULL, (nbytes * 2), MEM_RESERVE, PAGE_READWRITE);
+ p = VirtualAlloc (NULL, ROUND_UP (nbytes * 2, get_allocation_unit ()),
+ MEM_RESERVE, PAGE_READWRITE);
/* If it fails, or if the request is above 512MB, try with the
requested size. */
if (p == NULL)
- p = VirtualAlloc (NULL, nbytes, MEM_RESERVE, PAGE_READWRITE);
+ p = VirtualAlloc (NULL, ROUND_UP (nbytes, get_allocation_unit ()),
+ MEM_RESERVE, PAGE_READWRITE);
if (p != NULL)
{
/* Now, commit pages for NBYTES. */
*var = VirtualAlloc (p, nbytes, MEM_COMMIT, PAGE_READWRITE);
+ if (*var == NULL)
+ p = *var;
}
if (!p)
{
- if (GetLastError () == ERROR_NOT_ENOUGH_MEMORY)
+ DWORD e = GetLastError ();
+
+ if (e == ERROR_NOT_ENOUGH_MEMORY)
errno = ENOMEM;
else
{
- DebPrint (("mmap_alloc: error %ld\n", GetLastError ()));
+ DebPrint (("mmap_alloc: error %ld\n", e));
errno = EINVAL;
}
}
mmap_realloc (void **var, size_t nbytes)
{
MEMORY_BASIC_INFORMATION memInfo, m2;
+ void *old_ptr;
if (*var == NULL)
return mmap_alloc (var, nbytes);
return mmap_alloc (var, nbytes);
}
+ memset (&memInfo, 0, sizeof (memInfo));
if (VirtualQuery (*var, &memInfo, sizeof (memInfo)) == 0)
DebPrint (("mmap_realloc: VirtualQuery error = %ld\n", GetLastError ()));
/* We need to enlarge the block. */
if (memInfo.RegionSize < nbytes)
{
- if (VirtualQuery (*var + memInfo.RegionSize, &m2, sizeof(m2)) == 0)
+ memset (&m2, 0, sizeof (m2));
+ if (VirtualQuery ((char *)*var + memInfo.RegionSize, &m2, sizeof(m2)) == 0)
DebPrint (("mmap_realloc: VirtualQuery error = %ld\n",
GetLastError ()));
/* If there is enough room in the current reserved area, then
commit more pages as needed. */
if (m2.State == MEM_RESERVE
+ && m2.AllocationBase == memInfo.AllocationBase
&& nbytes <= memInfo.RegionSize + m2.RegionSize)
{
void *p;
- p = VirtualAlloc (*var + memInfo.RegionSize,
- nbytes - memInfo.RegionSize,
- MEM_COMMIT, PAGE_READWRITE);
+ p = VirtualAlloc (*var, nbytes, MEM_COMMIT, PAGE_READWRITE);
if (!p /* && GetLastError() != ERROR_NOT_ENOUGH_MEMORY */)
{
- DebPrint (("realloc enlarge: VirtualAlloc error %ld\n",
+ DebPrint (("realloc enlarge: VirtualAlloc (%p + %I64x, %I64x) error %ld\n",
+ *var, (uint64_t)memInfo.RegionSize,
+ (uint64_t)(nbytes - memInfo.RegionSize),
GetLastError ()));
- errno = ENOMEM;
+ DebPrint (("next region: %p %p %I64x %x\n", m2.BaseAddress,
+ m2.AllocationBase, (uint64_t)m2.RegionSize,
+ m2.AllocationProtect));
}
+ else
+ return *var;
+ }
+ /* Else we must actually enlarge the block by allocating a new
+ one and copying previous contents from the old to the new one. */
+ old_ptr = *var;
+
+ if (mmap_alloc (var, nbytes))
+ {
+ CopyMemory (*var, old_ptr, memInfo.RegionSize);
+ mmap_free (&old_ptr);
return *var;
}
else
{
- /* Else we must actually enlarge the block by allocating a
- new one and copying previous contents from the old to the
- new one. */
- void *old_ptr = *var;
-
- if (mmap_alloc (var, nbytes))
- {
- CopyMemory (*var, old_ptr, memInfo.RegionSize);
- mmap_free (&old_ptr);
- return *var;
- }
- else
- {
- /* We failed to enlarge the buffer. */
- *var = old_ptr;
- return NULL;
- }
+ /* We failed to reallocate the buffer. */
+ *var = old_ptr;
+ return NULL;
}
}
{
/* Let's give some memory back to the system and release
some pages. */
- void *old_ptr = *var;
+ old_ptr = *var;
if (mmap_alloc (var, nbytes))
{
}
/* We still can decommit pages. */
- if (VirtualFree (*var + nbytes + get_page_size(),
+ if (VirtualFree ((char *)*var + nbytes + get_page_size(),
memInfo.RegionSize - nbytes - get_page_size(),
MEM_DECOMMIT) == 0)
DebPrint (("mmap_realloc: VirtualFree error %ld\n", GetLastError ()));