summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBen Gamari <ben@smart-cactus.org>2022-02-07 19:56:22 -0500
committerMarge Bot <ben+marge-bot@smart-cactus.org>2022-02-09 20:43:39 -0500
commit4d3a306dce59649b303ac7aba56758aff3dee077 (patch)
treed61824b92ccd6074978b8e439d2405a8f9de0187
parent30e205ca1e8d78a538e0217e3cb07f13396900df (diff)
downloadhaskell-4d3a306dce59649b303ac7aba56758aff3dee077.tar.gz
rts/linker/MMap: Use MemoryAccess in mmapForLinker
-rw-r--r--rts/Linker.c5
-rw-r--r--rts/linker/Elf.c2
-rw-r--r--rts/linker/MMap.c54
-rw-r--r--rts/linker/MMap.h3
-rw-r--r--rts/linker/MachO.c2
5 files changed, 42 insertions, 24 deletions
diff --git a/rts/Linker.c b/rts/Linker.c
index fcba191249..a98f0bd2cb 100644
--- a/rts/Linker.c
+++ b/rts/Linker.c
@@ -1315,10 +1315,9 @@ preloadObjectFile (pathchar *path)
* See also the misalignment logic for darwin below.
*/
#if defined(darwin_HOST_OS) || defined(openbsd_HOST_OS)
- image = mmapForLinker(fileSize, PROT_READ|PROT_WRITE, MAP_PRIVATE, fd, 0);
+ image = mmapForLinker(fileSize, MEM_READ_WRITE, MAP_PRIVATE, fd, 0);
#else
- image = mmapForLinker(fileSize, PROT_READ|PROT_WRITE|PROT_EXEC,
- MAP_PRIVATE, fd, 0);
+ image = mmapForLinker(fileSize, MEM_READ_WRITE_EXECUTE, MAP_PRIVATE, fd, 0);
#endif
if (image == MAP_FAILED) {
diff --git a/rts/linker/Elf.c b/rts/linker/Elf.c
index f84d6bb495..70f3c8870b 100644
--- a/rts/linker/Elf.c
+++ b/rts/linker/Elf.c
@@ -650,7 +650,7 @@ mapObjectFileSection (int fd, Elf_Word offset, Elf_Word size,
pageOffset = roundDownToPage(offset);
pageSize = roundUpToPage(offset-pageOffset+size);
- p = mmapForLinker(pageSize, PROT_READ | PROT_WRITE, 0, fd, pageOffset);
+ p = mmapForLinker(pageSize, MEM_READ_WRITE, 0, fd, pageOffset);
if (p == NULL) return NULL;
*mapped_size = pageSize;
*mapped_offset = pageOffset;
diff --git a/rts/linker/MMap.c b/rts/linker/MMap.c
index f4eaf3d686..0fd12dcf5c 100644
--- a/rts/linker/MMap.c
+++ b/rts/linker/MMap.c
@@ -47,12 +47,28 @@ static const char *memoryAccessDescription(MemoryAccess mode)
case MEM_READ_ONLY: return "read-only";
case MEM_READ_WRITE: return "read-write";
case MEM_READ_EXECUTE: return "read-execute";
+ case MEM_READ_WRITE_EXECUTE:
+ return "read-write-execute";
default: barf("invalid MemoryAccess");
}
}
#if defined(mingw32_HOST_OS)
+static DWORD
+memoryAccessToProt(MemoryAccess access)
+{
+ switch (access) {
+ case MEM_NO_ACCESS: return PAGE_NOACCESS;
+ case MEM_READ_ONLY: return PAGE_READONLY;
+ case MEM_READ_WRITE: return PAGE_READWRITE;
+ case MEM_READ_EXECUTE: return PAGE_EXECUTE_READ;
+ case MEM_READ_WRITE_EXECUTE:
+ return PAGE_EXECUTE_READWRITE;
+ default: barf("invalid MemoryAccess");
+ }
+}
+
//
// Returns NULL on failure.
//
@@ -82,14 +98,7 @@ mprotectForLinker(void *start, size_t len, MemoryAccess mode)
if (len == 0) {
return;
}
- DWORD prot;
- switch (mode) {
- case MEM_NO_ACCESS: prot = PAGE_NOACCESS; break;
- case MEM_READ_ONLY: prot = PAGE_READONLY; break;
- case MEM_READ_WRITE: prot = PAGE_READWRITE; break;
- case MEM_READ_EXECUTE: prot = PAGE_EXECUTE_READ; break;
- default: barf("invalid MemoryAccess");
- }
+ DWORD prot = memoryAccessToProt(mode);
if (VirtualProtect(start, len, prot, &old) == 0) {
sysErrorBelch("mprotectForLinker: failed to protect %zd bytes at %p as %s",
@@ -99,11 +108,26 @@ mprotectForLinker(void *start, size_t len, MemoryAccess mode)
}
#elif RTS_LINKER_USE_MMAP
+
+static int
+memoryAccessToProt(MemoryAccess access)
+{
+ switch (access) {
+ case MEM_NO_ACCESS: return 0;
+ case MEM_READ_ONLY: return PROT_READ;
+ case MEM_READ_WRITE: return PROT_READ | PROT_WRITE;
+ case MEM_READ_EXECUTE: return PROT_READ | PROT_EXEC;
+ case MEM_READ_WRITE_EXECUTE:
+ return PROT_READ | PROT_WRITE | PROT_EXEC;
+ default: barf("invalid MemoryAccess");
+ }
+}
+
//
// Returns NULL on failure.
//
void *
-mmapForLinker (size_t bytes, uint32_t prot, uint32_t flags, int fd, int offset)
+mmapForLinker (size_t bytes, MemoryAccess access, uint32_t flags, int fd, int offset)
{
void *map_addr = NULL;
void *result;
@@ -112,6 +136,7 @@ mmapForLinker (size_t bytes, uint32_t prot, uint32_t flags, int fd, int offset)
? 0
: TRY_MAP_32BIT;
static uint32_t fixed = 0;
+ int prot = memoryAccessToProt(access);
IF_DEBUG(linker_verbose, debugBelch("mmapForLinker: start\n"));
size = roundUpToPage(bytes);
@@ -226,7 +251,7 @@ mmap_again:
void *
mmapAnonForLinker (size_t bytes)
{
- return mmapForLinker (bytes, PROT_READ|PROT_WRITE, MAP_ANONYMOUS, -1, 0);
+ return mmapForLinker (bytes, MEM_READ_WRITE, MAP_ANONYMOUS, -1, 0);
}
void munmapForLinker (void *addr, size_t bytes, const char *caller)
@@ -273,14 +298,7 @@ void mprotectForLinker(void *start, size_t len, MemoryAccess mode)
" bytes starting at %p as %s\n",
(W_)len, start, memoryAccessDescription(mode)));
- int prot;
- switch (mode) {
- case MEM_NO_ACCESS: prot = 0; break;
- case MEM_READ_ONLY: prot = PROT_READ; break;
- case MEM_READ_WRITE: prot = PROT_READ | PROT_WRITE; break;
- case MEM_READ_EXECUTE: prot = PROT_READ | PROT_EXEC; break;
- default: barf("invalid MemoryAccess");
- }
+ int prot = memoryAccessToProt(mode);
if (mprotect(start, len, prot) == -1) {
sysErrorBelch("mprotectForLinker: failed to protect %zd bytes at %p as %s",
diff --git a/rts/linker/MMap.h b/rts/linker/MMap.h
index ed0baa6899..9eebc3c4b2 100644
--- a/rts/linker/MMap.h
+++ b/rts/linker/MMap.h
@@ -55,6 +55,7 @@ typedef enum {
MEM_READ_ONLY,
MEM_READ_WRITE,
MEM_READ_EXECUTE,
+ MEM_READ_WRITE_EXECUTE,
} MemoryAccess;
extern void *mmap_32bit_base;
@@ -73,7 +74,7 @@ void munmapForLinker (void *addr, size_t bytes, const char *caller);
//
// Note that this not available on Windows since file mapping on Windows is
// sufficiently different to warrant its own interface.
-void *mmapForLinker (size_t bytes, uint32_t prot, uint32_t flags, int fd, int offset);
+void *mmapForLinker (size_t bytes, MemoryAccess prot, uint32_t flags, int fd, int offset);
#endif
#include "EndPrivate.h"
diff --git a/rts/linker/MachO.c b/rts/linker/MachO.c
index 79d14a2d55..ab00c8e06f 100644
--- a/rts/linker/MachO.c
+++ b/rts/linker/MachO.c
@@ -1218,7 +1218,7 @@ ocGetNames_MachO(ObjectCode* oc)
unsigned nstubs = numberOfStubsForSection(oc, sec_idx);
unsigned stub_space = STUB_SIZE * nstubs;
- void * mem = mmapForLinker(section->size+stub_space, PROT_READ | PROT_WRITE, MAP_ANON, -1, 0);
+ void * mem = mmapForLinker(section->size+stub_space, MEM_READ_WRITE, MAP_ANON, -1, 0);
if( mem == MAP_FAILED ) {
sysErrorBelch("failed to mmap allocated memory to load section %d. "