summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--compiler/GHC/Driver/Session.hs17
-rw-r--r--docs/users_guide/runtime_control.rst6
-rw-r--r--includes/rts/Flags.h2
-rw-r--r--rts/Libdw.c3
-rw-r--r--rts/Linker.c40
-rw-r--r--rts/LinkerInternals.h1
6 files changed, 24 insertions, 45 deletions
diff --git a/compiler/GHC/Driver/Session.hs b/compiler/GHC/Driver/Session.hs
index 2000b9760b..ab11b0ddb1 100644
--- a/compiler/GHC/Driver/Session.hs
+++ b/compiler/GHC/Driver/Session.hs
@@ -3796,8 +3796,21 @@ validHoleFitsImpliedGFlags
default_PIC :: Platform -> [GeneralFlag]
default_PIC platform =
case (platformOS platform, platformArch platform) of
- (OSDarwin, ArchX86_64) -> [Opt_PIC]
- (OSOpenBSD, ArchX86_64) -> [Opt_PIC] -- Due to PIE support in
+ -- Darwin always requires PIC. Especially on more recent macOS releases
+ -- there will be a 4GB __ZEROPAGE that prevents us from using 32bit addresses
+ -- while we could work around this on x86_64 (like WINE does), we won't be
+ -- able on aarch64, where this is enforced.
+ (OSDarwin, ArchX86_64) -> [Opt_PIC]
+ -- For AArch64, we need to always have PIC enabled. The relocation model
+ -- on AArch64 does not permit arbitrary relocations. Under ASLR, we can't
+ -- control much how far apart symbols are in memory for our in-memory static
+ -- linker; and thus need to ensure we get sufficiently capable relocations.
+ -- This requires PIC on AArch64, and ExternalDynamicRefs on Linux as on top
+ -- of that. Subsequently we expect all code on aarch64/linux (and macOS) to
+ -- be built with -fPIC.
+ (OSDarwin, ArchARM64) -> [Opt_PIC]
+ (OSLinux, ArchARM64) -> [Opt_PIC, Opt_ExternalDynamicRefs]
+ (OSOpenBSD, ArchX86_64) -> [Opt_PIC] -- Due to PIE support in
-- OpenBSD since 5.3 release
-- (1 May 2013) we need to
-- always generate PIC. See
diff --git a/docs/users_guide/runtime_control.rst b/docs/users_guide/runtime_control.rst
index d19f3d07fc..45bb9f7266 100644
--- a/docs/users_guide/runtime_control.rst
+++ b/docs/users_guide/runtime_control.rst
@@ -327,8 +327,10 @@ Miscellaneous RTS options
an object, the linker will probably fail with an error message when the
problem is detected.
- On some platforms where PIC is always the case, e.g. x86_64 MacOS X, this
- flag is enabled by default.
+ On some platforms where PIC is always the case, e.g. macOS and OpenBSD on
+ x86_64, and macOS and Linux on aarch64 this flag is enabled by default.
+ One repercussion of this is that referenced system libraries also need to be
+ compiled with ``-fPIC`` if we need to load them in the runtime linker.
.. rts-flag:: -xm ⟨address⟩
diff --git a/includes/rts/Flags.h b/includes/rts/Flags.h
index bf84c5dc96..dcaf0d8bd2 100644
--- a/includes/rts/Flags.h
+++ b/includes/rts/Flags.h
@@ -200,7 +200,7 @@ typedef struct _CONCURRENT_FLAGS {
* files were compiled with -fPIC -fexternal-dynamic-refs and load them
* anywhere in the address space.
*/
-#if defined(x86_64_HOST_ARCH) && defined(darwin_HOST_OS)
+#if defined(darwin_HOST_OS) || defined(aarch64_HOST_ARCH)
#define DEFAULT_LINKER_ALWAYS_PIC true
#else
#define DEFAULT_LINKER_ALWAYS_PIC false
diff --git a/rts/Libdw.c b/rts/Libdw.c
index d45d9d0e5d..9619479313 100644
--- a/rts/Libdw.c
+++ b/rts/Libdw.c
@@ -133,8 +133,9 @@ int libdwLookupLocation(LibdwSession *session, Location *frame,
Dwfl_Module *mod = dwfl_addrmodule(session->dwfl, addr);
if (mod == NULL)
return 1;
+ void *object_file = &frame->object_file;
dwfl_module_info(mod, NULL, NULL, NULL, NULL, NULL,
- &frame->object_file, NULL);
+ object_file, NULL);
// Find function name
frame->function = dwfl_module_addrname(mod, addr);
diff --git a/rts/Linker.c b/rts/Linker.c
index 2d54c29196..036c7937a4 100644
--- a/rts/Linker.c
+++ b/rts/Linker.c
@@ -1022,42 +1022,6 @@ resolveSymbolAddr (pathchar* buffer, int size,
}
#if RTS_LINKER_USE_MMAP
-
-/* -----------------------------------------------------------------------------
- Occationally we depend on mmap'd region being close to already mmap'd regions.
-
- Our static in-memory linker may be restricted by the architectures relocation
- range. E.g. aarch64 has a +-4GB range for PIC code, thus we'd preferrably
- get memory for the linker close to existing mappings. mmap on it's own is
- free to return any memory location, independent of what the preferred
- location argument indicates.
-
- For example mmap (via qemu) might give you addresses all over the available
- memory range if the requested location is already occupied.
-
- mmap_next will do a linear search from the start page upwards to find a
- suitable location that is as close as possible to the locations (proivded
- via the first argument).
- -------------------------------------------------------------------------- */
-
-void*
-mmap_next(void *addr, size_t length, int prot, int flags, int fd, off_t offset) {
- if(addr == NULL) return mmap(addr, length, prot, flags, fd, offset);
- // we are going to look for up to pageSize * 1024 * 1024 (4GB) from the
- // address.
- size_t pageSize = getPageSize();
- for(int i = (uintptr_t)addr & (pageSize-1) ? 1 : 0; i < 1024*1024; i++) {
- void *target = (void*)(((uintptr_t)addr & ~(pageSize-1))+(i*pageSize));
- void *mem = mmap(target, length, prot, flags, fd, offset);
- if(mem == NULL) return mem;
- if(mem == target) return mem;
- munmap(mem, length);
- IF_DEBUG(linker && (i % 1024 == 0),
- debugBelch("mmap_next failed to find suitable space in %p - %p\n", addr, target));
- }
- return NULL;
-}
-
//
// Returns NULL on failure.
//
@@ -1089,8 +1053,8 @@ mmap_again:
debugBelch("mmapForLinker: \tflags %#0x\n",
MAP_PRIVATE | tryMap32Bit | fixed | flags));
- result = mmap_next(map_addr, size, prot,
- MAP_PRIVATE|tryMap32Bit|fixed|flags, fd, offset);
+ result = mmap(map_addr, size, prot,
+ MAP_PRIVATE|tryMap32Bit|fixed|flags, fd, offset);
if (result == MAP_FAILED) {
sysErrorBelch("mmap %" FMT_Word " bytes at %p",(W_)size,map_addr);
diff --git a/rts/LinkerInternals.h b/rts/LinkerInternals.h
index 2e76a888e4..e8923fb7eb 100644
--- a/rts/LinkerInternals.h
+++ b/rts/LinkerInternals.h
@@ -14,7 +14,6 @@
#if RTS_LINKER_USE_MMAP
#include <sys/mman.h>
-void* mmap_next(void *addr, size_t length, int prot, int flags, int fd, off_t offset);
#endif
void printLoadedObjects(void);