diff options
author | Ben Gamari <ben@smart-cactus.org> | 2022-02-07 19:56:22 -0500 |
---|---|---|
committer | Marge Bot <ben+marge-bot@smart-cactus.org> | 2022-02-09 20:43:39 -0500 |
commit | 4d3a306dce59649b303ac7aba56758aff3dee077 (patch) | |
tree | d61824b92ccd6074978b8e439d2405a8f9de0187 /rts | |
parent | 30e205ca1e8d78a538e0217e3cb07f13396900df (diff) | |
download | haskell-4d3a306dce59649b303ac7aba56758aff3dee077.tar.gz |
rts/linker/MMap: Use MemoryAccess in mmapForLinker
Diffstat (limited to 'rts')
-rw-r--r-- | rts/Linker.c | 5 | ||||
-rw-r--r-- | rts/linker/Elf.c | 2 | ||||
-rw-r--r-- | rts/linker/MMap.c | 54 | ||||
-rw-r--r-- | rts/linker/MMap.h | 3 | ||||
-rw-r--r-- | rts/linker/MachO.c | 2 |
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. " |