/* Emulate Unix sbrk. Note that ralloc.c expects the return value to be the address of the _start_ (not end) of the new block in case of success, and zero (not -1) in case of failure. */ void * sbrk (ptrdiff_t increment) { void *result; ptrdiff_t size = increment; result = data_region_end; /* If size is negative, shrink the heap by decommitting pages. */ if (size < 0) { ptrdiff_t new_size; unsigned char *new_data_region_end; size = -size; /* Sanity checks. */ if ((data_region_end - size) < data_region_base) return NULL; /* We can only decommit full pages, so allow for partial deallocation [cga]. */ new_data_region_end = (data_region_end - size); new_data_region_end = (unsigned char *) ((DWORD_PTR) (new_data_region_end + syspage_mask) & ~syspage_mask); new_size = real_data_region_end - new_data_region_end; real_data_region_end = new_data_region_end; if (new_size > 0) { /* Decommit size bytes from the end of the heap. */ if (using_dynamic_heap && !VirtualFree (real_data_region_end, new_size, MEM_DECOMMIT)) return NULL; } data_region_end -= size; } /* If size is positive, grow the heap by committing reserved pages. */ else if (size > 0) { /* Sanity checks. */ if ((data_region_end + size) > (data_region_base + get_reserved_heap_size ())) return NULL; /* Commit more of our heap. */ if (using_dynamic_heap && VirtualAlloc (data_region_end, size, MEM_COMMIT, PAGE_READWRITE) == NULL) return NULL; data_region_end += size; /* We really only commit full pages, so record where the real end of committed memory is [cga]. */ real_data_region_end = (unsigned char *) ((DWORD_PTR) (data_region_end + syspage_mask) & ~syspage_mask); } return result; }
static char * allocate_heap (void) { /* Try to get as much as possible of the address range from the end of the preload heap section up to the usable address limit. Since GNU malloc can handle gaps in the memory it gets from sbrk, we can simply set the sbrk pointer to the base of the new heap region. */ DWORD_PTR base = ROUND_UP ((RVA_TO_PTR (preload_heap_section->VirtualAddress) + preload_heap_section->Misc.VirtualSize), get_allocation_unit ()); DWORD_PTR end = ((unsigned __int64)1) << VALBITS; /* 256MB */ void *ptr = NULL; while (!ptr && (base < end)) { #ifdef _WIN64 reserved_heap_size = min(end - base, 0x4000000000i64); /* Limit to 256Gb */ #else reserved_heap_size = end - base; #endif ptr = VirtualAlloc ((void *) base, get_reserved_heap_size (), MEM_RESERVE, PAGE_NOACCESS); base += 0x00100000; /* 1MB increment */ } return ptr; }
/* Try to get as much as possible of the address range from the end of the preload heap section up to the usable address limit. Since GNU malloc can handle gaps in the memory it gets from sbrk, we can simply set the sbrk pointer to the base of the new heap region. */ unsigned long base = ROUND_UP ((RVA_TO_PTR (preload_heap_section->VirtualAddress) + preload_heap_section->Misc.VirtualSize), get_allocation_unit ()); unsigned long end = 1 << VALBITS; /* 256MB */ void *ptr = NULL; while (!ptr && (base < end)) { reserved_heap_size = end - base; ptr = VirtualAlloc ((void *) base, get_reserved_heap_size (), MEM_RESERVE, PAGE_NOACCESS); base += 0x00100000; /* 1MB increment */ } return ptr; } #else /* USE_LSB_TAG */ static char * allocate_heap (void) { unsigned long size = 0x80000000; /* start by asking for 2GB */ void *ptr = NULL; while (!ptr && size > 0x00100000) { reserved_heap_size = size; ptr = VirtualAlloc (NULL, get_reserved_heap_size (), MEM_RESERVE, PAGE_NOACCESS); size -= 0x00800000; /* if failed, decrease request by 8MB */ } return ptr; }
/* Try to get as much as possible of the address range from the end of the preload heap section up to the usable address limit. Since GNU malloc can handle gaps in the memory it gets from sbrk, we can simply set the sbrk pointer to the base of the new heap region. */ DWORD_PTR base = ROUND_UP ((RVA_TO_PTR (preload_heap_section->VirtualAddress) + preload_heap_section->Misc.VirtualSize), get_allocation_unit ()); DWORD_PTR end = ((unsigned __int64)1) << VALBITS; /* 256MB */ void *ptr = NULL; while (!ptr && (base < end)) { #ifdef _WIN64 reserved_heap_size = min(end - base, 0x4000000000i64); /* Limit to 256Gb */ #else reserved_heap_size = end - base; #endif ptr = VirtualAlloc ((void *) base, get_reserved_heap_size (), MEM_RESERVE, PAGE_NOACCESS); base += 0x00100000; /* 1MB increment */ } return ptr; } #else /* USE_LSB_TAG */ static char * allocate_heap (void) { #ifdef _WIN64 size_t size = 0x4000000000i64; /* start by asking for 32GB */ #else size_t size = 0x80000000; /* start by asking for 2GB */ #endif void *ptr = NULL; while (!ptr && size > 0x00100000) { reserved_heap_size = size; ptr = VirtualAlloc (NULL, get_reserved_heap_size (), MEM_RESERVE, PAGE_NOACCESS); size -= 0x00800000; /* if failed, decrease request by 8MB */ } return ptr; }