diff options
author | Moritz Angermann <moritz.angermann@gmail.com> | 2020-10-27 10:52:25 +0800 |
---|---|---|
committer | Marge Bot <ben+marge-bot@smart-cactus.org> | 2020-11-06 03:46:44 -0500 |
commit | 2cb879092c0c946f5313216fc9ce4b93954c2f74 (patch) | |
tree | dfe782a367219dbf96172b451fa3cfa7c7c1388c | |
parent | c85f4928d4dbb2eb2cf906d08bfe7620d6f04ca5 (diff) | |
download | haskell-2cb879092c0c946f5313216fc9ce4b93954c2f74.tar.gz |
[AArch64] Aarch64 Always PIC
-rw-r--r-- | compiler/GHC/Driver/Session.hs | 17 | ||||
-rw-r--r-- | docs/users_guide/runtime_control.rst | 6 | ||||
-rw-r--r-- | includes/rts/Flags.h | 2 | ||||
-rw-r--r-- | rts/Libdw.c | 3 | ||||
-rw-r--r-- | rts/Linker.c | 40 | ||||
-rw-r--r-- | rts/LinkerInternals.h | 1 |
6 files changed, 24 insertions, 45 deletions
diff --git a/compiler/GHC/Driver/Session.hs b/compiler/GHC/Driver/Session.hs index 9529b0dea8..7db08595d7 100644 --- a/compiler/GHC/Driver/Session.hs +++ b/compiler/GHC/Driver/Session.hs @@ -3830,8 +3830,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); |