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 [[email protected]] -- To UNSUBSCRIBE, email to [email protected] with a subject of "unsubscribe". Trouble? Contact [email protected] Archive: http://lists.debian.org/[email protected]
