[Pkg-haskell-commits] darcs: ghc: Add missing patch.

Erik de Castro Lopo erikd at mega-nerd.com
Mon Oct 8 12:00:35 UTC 2012


Mon Aug  6 20:28:33 UTC 2012  Erik de Castro Lopo <erikd at mega-nerd.com>
  * Add missing patch.
  Ignore-this: 5b2588e893004fd68909514cd22afe86

    A ./patches/Fix-GHCi-segfault-on-linux-powerpc

Mon Aug  6 20:28:33 UTC 2012  Erik de Castro Lopo <erikd at mega-nerd.com>
  * Add missing patch.
  Ignore-this: 5b2588e893004fd68909514cd22afe86
diff -rN -u old-ghc//patches/Fix-GHCi-segfault-on-linux-powerpc new-ghc//patches/Fix-GHCi-segfault-on-linux-powerpc
--- old-ghc//patches/Fix-GHCi-segfault-on-linux-powerpc	1970-01-01 00:00:00.000000000 +0000
+++ new-ghc//patches/Fix-GHCi-segfault-on-linux-powerpc	2012-10-08 12:00:34.602224905 +0000
@@ -0,0 +1,99 @@
+From 0f0312f02177b842431d2f4f2a4e9b99b146faff Mon Sep 17 00:00:00 2001
+From: Erik de Castro Lopo <erikd at mega-nerd.com>
+Date: Tue, 31 Jul 2012 05:53:49 +1000
+Subject: [PATCH 2/3] Fix GHCi segfault during startup on linux-powerpc
+ (#2972).
+
+Slightly modified version of a patch from Ben Collins <bcollins at ubuntu.com>
+who did the final debugging that showed the segfault was being caused the
+memory protection mechanism.
+
+Due to the requirement of "jump islands" to handle 24 bit relative jump
+offsets, GHCi on PowerPC did not use mmap to load object files like the
+other architectures. Instead, it allocated memory using malloc and fread
+to load the object code. However there is a quirk in the GNU libc malloc
+implementation. For memory regions over certain size (dynamic and
+configurable), malloc will use mmap to obtain the required memory instead
+of sbrk and malloc's call to mmap sets the memory readable and writable,
+but not executable. That means when GHCi loads code into a memory region
+that was mmapped instead of malloc-ed and tries to execute it we get a
+segfault.
+
+This solution drops the malloc/fread object loading in favour of using
+mmap and then puts the jump island for each object code module at the
+end of the mmaped region for that object.
+
+This patch may also be a solution on other ELF based powerpc systems
+but does not work on darwin-powerpc.
+---
+ rts/Linker.c |   37 +++++++++++++++++++++++++++++++++----
+ 1 file changed, 33 insertions(+), 4 deletions(-)
+
+diff --git a/rts/Linker.c b/rts/Linker.c
+index fd5550e..6beb534 100644
+--- a/rts/Linker.c
++++ b/rts/Linker.c
+@@ -70,11 +70,12 @@
+ #include <sys/wait.h>
+ #endif
+ 
+-#if !defined(powerpc_HOST_ARCH) && \
+-    (   defined(linux_HOST_OS    ) || defined(freebsd_HOST_OS) || \
++#if (defined(powerpc_HOST_ARCH) && defined(linux_HOST_OS)) \
++ || (!defined(powerpc_HOST_ARCH) && \
++    (   defined(linux_HOST_OS)     || defined(freebsd_HOST_OS) || \
+         defined(dragonfly_HOST_OS) || defined(netbsd_HOST_OS ) || \
+         defined(openbsd_HOST_OS  ) || defined(darwin_HOST_OS ) || \
+-        defined(kfreebsdgnu_HOST_OS) || defined(gnu_HOST_OS))
++        defined(kfreebsdgnu_HOST_OS) || defined(gnu_HOST_OS)))
+ /* Don't use mmap on powerpc_HOST_ARCH as mmap doesn't support
+  * reallocating but we need to allocate jump islands just after each
+  * object images. Otherwise relative branches to jump islands can fail
+@@ -90,6 +91,16 @@
+ 
+ #endif
+ 
++
++/* PowerPC has relative branch instructions with only 24 bit displacements
++ * and therefore needs jump islands contiguous with each object code module.
++ */
++#if (defined(USE_MMAP) && defined(powerpc_HOST_ARCH) && defined(linux_HOST_OS))
++#define USE_CONTIGUOUS_MMAP 1
++#else
++#define USE_CONTIGUOUS_MMAP 0
++#endif
++
+ #if defined(linux_HOST_OS) || defined(solaris2_HOST_OS) || defined(freebsd_HOST_OS) || defined(kfreebsdgnu_HOST_OS) || defined(dragonfly_HOST_OS) || defined(netbsd_HOST_OS) || defined(openbsd_HOST_OS) || defined(gnu_HOST_OS)
+ #  define OBJFORMAT_ELF
+ #  include <regex.h>    // regex is already used by dlopen() so this is OK
+@@ -2797,8 +2808,26 @@ static int ocAllocateSymbolExtras( ObjectCode* oc, int count, int first )
+      */
+     if( m > n ) // we need to allocate more pages
+     {
+-        oc->symbol_extras = mmapForLinker(sizeof(SymbolExtra) * count,
++        if (USE_CONTIGUOUS_MMAP)
++        {
++            /* Keep image and symbol_extras contiguous */
++            void *new = mmapForLinker(n + (sizeof(SymbolExtra) * count),
++                                  MAP_ANONYMOUS, -1);
++            if (new)
++            {
++                memcpy(new, oc->image, oc->fileSize);
++                munmap(oc->image, n);
++                oc->image = new;
++                oc->symbol_extras = (SymbolExtra *) (oc->image + n);
++            }
++            else
++                oc->symbol_extras = NULL;
++        }
++        else
++        {
++            oc->symbol_extras = mmapForLinker(sizeof(SymbolExtra) * count,
+                                           MAP_ANONYMOUS, -1);
++        }
+     }
+     else
+     {
+-- 
+1.7.10.4
+





More information about the Pkg-haskell-commits mailing list