[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Re: Haskell migration exp to unstable



On Mon, May 27, 2013 at 04:03:38PM +0200, Joachim Breitner wrote:
> Am Montag, den 27.05.2013, 14:39 +0100 schrieb Colin Watson:
> > I can indeed confirm that we're starting to see failures due to broken
> > GHCi, for example:
> > 
> >   https://buildd.debian.org/status/fetch.php?pkg=haskell-data-accessor-template&arch=armel&ver=0.2.1.10-3&stamp=1369656600
> >   https://buildd.debian.org/status/fetch.php?pkg=haskell-distributive&arch=armhf&ver=0.3-2&stamp=1369561716
> > 
> > Note that some of the affected packages would succeed if GHCi were
> > disabled (because doctest detects that condition and skips), so it's not
> > quite true that we'd just have to remove all the affected packages
> > anyway.
> 
> how bad is the breakage of GHCi on arm anyways? Just affecting some
> packages, or unusable?

Essentially unusable.

When certain Thumb relocations are involved it often fails to even start
up (http://hackage.haskell.org/trac/ghc/ticket/7823).

On armel the R_ARM_V4BX relocation is unimplemented.  This can just be
ignored, as follows, but I don't think I got round to sending this
upstream since I never managed to get the whole assemblage to work.

diff --git a/rts/Linker.c b/rts/Linker.c
index 40f5204..3a2cd03 100644
--- a/rts/Linker.c
+++ b/rts/Linker.c
@@ -4143,6 +4143,9 @@ ocResolve_PEi386 ( ObjectCode* oc )
 #ifndef R_ARM_MOVW_ABS_NC
 #  define R_ARM_MOVW_ABS_NC      43
 #endif
+#ifndef R_ARM_V4BX
+#  define R_ARM_V4BX      40
+#endif
 #ifndef R_ARM_MOVT_ABS
 #  define R_ARM_MOVT_ABS      44
 #endif
@@ -5018,6 +5021,13 @@ do_Elf_Rel_relocations ( ObjectCode* oc, char* ehdrC,
             break;
          }
 
+         case R_ARM_V4BX:
+            /* This records the location of an ARMv4t BX instruction so that
+             * a linker can transform it into MOV PC, r for ARMv4.  We have
+             * no need of this and can just ignore the relocation.
+             */
+            return 0;
+
 #        endif // arm_HOST_ARCH
 
          default:

You lose as soon as the interpreter tries to generate any new bytecode
(http://hackage.haskell.org/trac/ghc/ticket/7794).  My work-in-progress
for this looks like the following, but I still haven't managed to get
this to work.  I hear that 7.8 will completely rearrange this using
dynamic linking anyway, so my motivation to embark on further nine-hour
test builds and multi-hour debugging/head-scratching sessions for this
is pretty slim.

diff --git a/compiler/ghci/ByteCodeItbls.lhs b/compiler/ghci/ByteCodeItbls.lhs
index f152473..95be15f 100644
--- a/compiler/ghci/ByteCodeItbls.lhs
+++ b/compiler/ghci/ByteCodeItbls.lhs
@@ -241,6 +241,12 @@ mkJumpToAddr a
       , fromIntegral ((w64 `shiftR` 32) .&. 0x0000FFFF) ]
     where w64 = fromIntegral (ptrToInt a) :: Word64
 
+#elif arm_TARGET_ARCH
+type ItblCode = Word32
+mkJumpToAddr a
+    = [ 0xe51ff004      -- ldr pc, [pc, #-4]    # pc reads as <current insn>+8
+      , fromIntegral (ptrToInt a) ]
+
 #else
 type ItblCode = Word32
 mkJumpToAddr a
@@ -419,14 +425,23 @@ load = do addr <- advance
           lift (peek addr)
 
 
-newExecConItbl :: DynFlags -> StgConInfoTable -> IO (FunPtr ())
-newExecConItbl dflags obj
+newExecMem :: Int -> (Ptr a -> Ptr a -> IO ()) -> IO (FunPtr ())
+newExecMem len poke_fn
    = alloca $ \pcode -> do
-        wr_ptr <- _allocateExec (fromIntegral (sizeOfConItbl obj)) pcode
+        wr_ptr <- _allocateExec (fromIntegral len) pcode
         ex_ptr <- peek pcode
-        pokeConItbl dflags wr_ptr ex_ptr obj
+        poke_fn wr_ptr ex_ptr
+        _clearExecCache (fromIntegral len) wr_ptr
         return (castPtrToFunPtr ex_ptr)
 
+newExecConItbl :: DynFlags -> StgConInfoTable -> IO (FunPtr ())
+newExecConItbl dflags obj
+   = newExecMem (sizeOfConItbl obj) new_con_itbl where
+        new_con_itbl wr_ptr ex_ptr = pokeConItbl dflags wr_ptr ex_ptr obj
+
 foreign import ccall unsafe "allocateExec"
   _allocateExec :: CUInt -> Ptr (Ptr a) -> IO (Ptr a)  
+
+foreign import ccall unsafe "clearExecCache"
+  _clearExecCache :: CUInt -> Ptr a -> IO ()
 \end{code}
diff --git a/includes/rts/storage/GC.h b/includes/rts/storage/GC.h
index 80f11d3..8b3997a 100644
--- a/includes/rts/storage/GC.h
+++ b/includes/rts/storage/GC.h
@@ -156,6 +156,7 @@ StgPtr  allocatePinned  ( Capability *cap, W_ n );
 /* memory allocator for executable memory */
 void * allocateExec(W_ len, void **exec_addr);
 void   freeExec (void *p);
+void   clearExecCache (W_ bytes, void *addr);
 
 // Used by GC checks in external .cmm code:
 extern W_ large_alloc_lim;
diff --git a/rts/Linker.c b/rts/Linker.c
index 40f5204..3a2cd03 100644
--- a/rts/Linker.c
+++ b/rts/Linker.c
@@ -1315,6 +1315,7 @@ typedef struct _RtsSymbolVal {
       SymI_HasProto(allocate)                                           \
       SymI_HasProto(allocateExec)                                       \
       SymI_HasProto(freeExec)                                           \
+      SymI_HasProto(clearExecCache)                                     \
       SymI_HasProto(getAllocations)                                     \
       SymI_HasProto(revertCAFs)                                         \
       SymI_HasProto(RtsFlags)                                           \
diff --git a/rts/sm/Storage.c b/rts/sm/Storage.c
index 5c4e54f..f2c71b8 100644
--- a/rts/sm/Storage.c
+++ b/rts/sm/Storage.c
@@ -1194,6 +1194,14 @@ void freeExec (void *addr)
 
 #endif /* mingw32_HOST_OS */
 
+void clearExecCache (W_ bytes, void *addr)
+{
+#if defined(__GNUC__) && \
+    (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3))
+    __clear_cache((char *)addr, (char *)addr + bytes);
+#endif
+}
+
 #ifdef DEBUG
 
 // handy function for use in gdb, because Bdescr() is inlined.

There may be further problems; this is as far as I got.  In practice, I
don't think I've seen any non-trivial GHCi code working on ARM.

-- 
Colin Watson                                       [cjwatson@debian.org]


Reply to: