summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBen Gamari <ben@smart-cactus.org>2022-02-09 14:41:04 -0500
committerBen Gamari <ben@smart-cactus.org>2022-02-09 18:35:01 -0500
commit20d9dbbef58aecbf6db95beca8c8e1ce817c5214 (patch)
tree93024a8ae66606970e516c52a63bb617c88d6445
parentf4ff8aeea05e0a666107186384a1a9ce6a5a7259 (diff)
downloadhaskell-20d9dbbef58aecbf6db95beca8c8e1ce817c5214.tar.gz
rts/PEi386: Move allocateBytes to MMap.c
-rw-r--r--rts/linker/MMap.c93
-rw-r--r--rts/linker/PEi386.c101
-rw-r--r--rts/linker/PEi386.h8
3 files changed, 92 insertions, 110 deletions
diff --git a/rts/linker/MMap.c b/rts/linker/MMap.c
index 1ecfbc6c7f..c506100816 100644
--- a/rts/linker/MMap.c
+++ b/rts/linker/MMap.c
@@ -72,6 +72,97 @@ static struct MemoryRegion allMemory = {
#if defined(mingw32_HOST_OS)
+/* A wrapper for VirtualQuery() providing useful debug output */
+static int virtualQuery(void *baseAddr, PMEMORY_BASIC_INFORMATION info)
+{
+ int res = VirtualQuery (baseAddr, info, sizeof (*info));
+ IF_DEBUG(linker_verbose,
+ debugBelch("Probing region 0x%p (0x%p) - 0x%p (%" FMT_SizeT ") [%ld] with base 0x%p\n",
+ baseAddr,
+ info->BaseAddress,
+ (uint8_t *) info->BaseAddress + info->RegionSize,
+ info->RegionSize, info->State,
+ info->AllocationBase));
+ if (!res) {
+ IF_DEBUG(linker_verbose, debugBelch("Querying 0x%p failed. Aborting..\n", baseAddr));
+ return 1;
+ }
+ return 0;
+}
+
+static inline uintptr_t round_up(uintptr_t num, uint64_t factor)
+{
+ return num + factor - 1 - (num + factor - 1) % factor;
+}
+
+/*
+ * Try and find a location in the VMMAP to allocate SZ bytes starting at
+ * BASEADDR. If successful then location to use is returned and the amount of
+ * bytes you *must* allocate is returned in REQ. You are free to use less but
+ * you must allocate the amount given in REQ. If not successful NULL.
+ */
+static void *allocateBytes(void* baseAddr, size_t sz, size_t *req)
+{
+ SYSTEM_INFO sys;
+ GetSystemInfo(&sys);
+ const uint64_t max_range = 4294967296UL;
+ IF_DEBUG(linker_verbose, debugBelch("Base Address 0x%p\n", baseAddr));
+ IF_DEBUG(linker_verbose, debugBelch("Requesting mapping of %" FMT_SizeT " bytes within range %"
+ PRId64 " bytes\n", sz, max_range));
+
+ MEMORY_BASIC_INFORMATION info;
+ IF_DEBUG(linker_verbose, debugBelch("Initial query @ 0x%p...\n", baseAddr));
+ int res = virtualQuery(baseAddr, &info);
+ if (res) {
+ return NULL;
+ }
+
+ uint8_t *endAddr = (uint8_t *) baseAddr + max_range;
+ uint8_t *initialAddr = info.AllocationBase;
+ uint8_t *region = NULL;
+ while (!region
+ && (uint64_t) llabs(initialAddr - endAddr) <= max_range
+ && (void *) initialAddr < sys.lpMaximumApplicationAddress)
+ {
+ res = virtualQuery(initialAddr, &info);
+ if (res) {
+ return NULL;
+ }
+
+ if ((info.State & MEM_FREE) == MEM_FREE) {
+ IF_DEBUG(linker_verbose, debugBelch("Free range at 0x%p of %zu bytes\n",
+ info.BaseAddress, info.RegionSize));
+
+ MEMORY_BASIC_INFORMATION info2;
+ res = virtualQuery(endAddr+1, &info2);
+ if (info.RegionSize >= sz) {
+ if (info.AllocationBase == 0) {
+ size_t needed_sz = round_up (sz, sys.dwAllocationGranularity);
+ if (info.RegionSize >= needed_sz) {
+ IF_DEBUG(linker_verbose, debugBelch("Range is unmapped, Allocation "
+ "required by granule...\n"));
+ *req = needed_sz;
+ region
+ = (void*)(uintptr_t)round_up ((uintptr_t)initialAddr,
+ sys.dwAllocationGranularity);
+ IF_DEBUG(linker_verbose, debugBelch("Requested %" PRId64 ", rounded: %"
+ PRId64 ".\n", sz, *req));
+ IF_DEBUG(linker_verbose, debugBelch("Aligned region claimed 0x%p -> "
+ "0x%p.\n", initialAddr, region));
+ }
+ } else {
+ IF_DEBUG(linker_verbose, debugBelch("Range is usable for us, claiming...\n"));
+ *req = sz;
+ region = initialAddr;
+ }
+ }
+ }
+ initialAddr = (uint8_t *) info.BaseAddress + info.RegionSize;
+ }
+
+ return region;
+}
+
static DWORD
memoryAccessToProt(MemoryAccess access)
{
@@ -96,7 +187,7 @@ mmapAnonForLinker (size_t bytes)
/* For linking purposes we want to load code within a 4GB range from the
load address of the application. As such we need to find a location to
allocate at. */
- void* region = allocaLocalBytes (bytes, &size);
+ void* region = allocateBytes (GetModuleHandleW (NULL), bytes, &size);
if (region == NULL) {
return NULL;
}
diff --git a/rts/linker/PEi386.c b/rts/linker/PEi386.c
index ccda3800fe..453c223737 100644
--- a/rts/linker/PEi386.c
+++ b/rts/linker/PEi386.c
@@ -386,107 +386,6 @@ const int default_alignment = 8;
the pointer as a redirect. Essentially it's a DATA DLL reference. */
const void* __rts_iob_func = (void*)&__acrt_iob_func;
-/********************************************
- * Memory Management functions
- ********************************************/
-
-static inline uintptr_t round_up(uintptr_t num, uint64_t factor)
-{
- return num + factor - 1 - (num + factor - 1) % factor;
-}
-
-/* A wrapper for VirtualQuery() providing useful debug output */
-static int virtualQuery(void *baseAddr, PMEMORY_BASIC_INFORMATION info)
-{
- int res = VirtualQuery (baseAddr, info, sizeof (*info));
- IF_DEBUG(linker_verbose,
- debugBelch("Probing region 0x%p (0x%p) - 0x%p (%" FMT_SizeT ") [%ld] with base 0x%p\n",
- baseAddr,
- info->BaseAddress,
- (uint8_t *) info->BaseAddress + info->RegionSize,
- info->RegionSize, info->State,
- info->AllocationBase));
- if (!res) {
- IF_DEBUG(linker_verbose, debugBelch("Querying 0x%p failed. Aborting..\n", baseAddr));
- return 1;
- }
- return 0;
-}
-
-
-/*
- * Try and find a location in the VMMAP to allocate SZ bytes starting at
- * BASEADDR. If successful then location to use is returned and the amount of
- * bytes you *must* allocate is returned in REQ. You are free to use less but
- * you must allocate the amount given in REQ. If not successful NULL.
- */
-static void *allocateBytes(void* baseAddr, size_t sz, size_t *req)
-{
- SYSTEM_INFO sys;
- GetSystemInfo(&sys);
- const uint64_t max_range = 4294967296UL;
- IF_DEBUG(linker_verbose, debugBelch("Base Address 0x%p\n", baseAddr));
- IF_DEBUG(linker_verbose, debugBelch("Requesting mapping of %" FMT_SizeT " bytes within range %"
- PRId64 " bytes\n", sz, max_range));
-
- MEMORY_BASIC_INFORMATION info;
- IF_DEBUG(linker_verbose, debugBelch("Initial query @ 0x%p...\n", baseAddr));
- int res = virtualQuery(baseAddr, &info);
- if (res) {
- return NULL;
- }
-
- uint8_t *endAddr = (uint8_t *) baseAddr + max_range;
- uint8_t *initialAddr = info.AllocationBase;
- uint8_t *region = NULL;
- while (!region
- && (uint64_t) llabs(initialAddr - endAddr) <= max_range
- && (void *) initialAddr < sys.lpMaximumApplicationAddress)
- {
- res = virtualQuery(initialAddr, &info);
- if (res) {
- return NULL;
- }
-
- if ((info.State & MEM_FREE) == MEM_FREE) {
- IF_DEBUG(linker_verbose, debugBelch("Free range at 0x%p of %zu bytes\n",
- info.BaseAddress, info.RegionSize));
-
- MEMORY_BASIC_INFORMATION info2;
- res = virtualQuery(endAddr+1, &info2);
- if (info.RegionSize >= sz) {
- if (info.AllocationBase == 0) {
- size_t needed_sz = round_up (sz, sys.dwAllocationGranularity);
- if (info.RegionSize >= needed_sz) {
- IF_DEBUG(linker_verbose, debugBelch("Range is unmapped, Allocation "
- "required by granule...\n"));
- *req = needed_sz;
- region
- = (void*)(uintptr_t)round_up ((uintptr_t)initialAddr,
- sys.dwAllocationGranularity);
- IF_DEBUG(linker_verbose, debugBelch("Requested %" PRId64 ", rounded: %"
- PRId64 ".\n", sz, *req));
- IF_DEBUG(linker_verbose, debugBelch("Aligned region claimed 0x%p -> "
- "0x%p.\n", initialAddr, region));
- }
- } else {
- IF_DEBUG(linker_verbose, debugBelch("Range is usable for us, claiming...\n"));
- *req = sz;
- region = initialAddr;
- }
- }
- }
- initialAddr = (uint8_t *) info.BaseAddress + info.RegionSize;
- }
-
- return region;
-}
-
-void *allocaLocalBytes(size_t sz, size_t *req)
-{
- return allocateBytes (GetModuleHandleW (NULL), sz, req);
-}
-
void initLinker_PEi386()
{
if (!ghciInsertSymbolTable(WSTR("(GHCi/Ld special symbols)"),
diff --git a/rts/linker/PEi386.h b/rts/linker/PEi386.h
index 2624ff6832..c5c88459a6 100644
--- a/rts/linker/PEi386.h
+++ b/rts/linker/PEi386.h
@@ -166,12 +166,4 @@ because we have no stdcall convention on 64 bits.
See #9218
*/
-/********************************************
- * Memory Management functions
- ********************************************/
-
-/* Same as the above, but use the current process's load address as the starting
- point for memory allocations. */
-void *allocaLocalBytes(size_t sz, size_t *req);
-
#include "EndPrivate.h"