[Git][ghc/ghc][wip/angerman/aarch64-always-pic] [AArch64] Aarch64 Always PIC

Moritz Angermann gitlab at gitlab.haskell.org
Tue Nov 3 13:28:34 UTC 2020



Moritz Angermann pushed to branch wip/angerman/aarch64-always-pic at Glasgow Haskell Compiler / GHC


Commits:
c788de1a by Moritz Angermann at 2020-11-03T13:27:27+00:00
[AArch64] Aarch64 Always PIC

- - - - -


6 changed files:

- compiler/GHC/Driver/Session.hs
- docs/users_guide/runtime_control.rst
- includes/rts/Flags.h
- rts/Libdw.c
- rts/Linker.c
- rts/LinkerInternals.h


Changes:

=====================================
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


=====================================
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⟩
 


=====================================
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


=====================================
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);


=====================================
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);


=====================================
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);



View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/c788de1a35c525f0efc26d90912581f89971501c

-- 
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/c788de1a35c525f0efc26d90912581f89971501c
You're receiving this email because of your account on gitlab.haskell.org.


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.haskell.org/pipermail/ghc-commits/attachments/20201103/66edbb38/attachment-0001.html>


More information about the ghc-commits mailing list