[GHC] #7722: iOS patch no 11: Fix quirk with runtime loader

#7722: iOS patch no 11: Fix quirk with runtime loader ------------------------------+--------------------------------------------- Reporter: StephenBlackheath | Owner: Type: feature request | Status: new Priority: normal | Component: Compiler Version: 7.7 | Keywords: Os: Other | Architecture: arm Failure: None/Unknown | Blockedby: Blocking: | Related: ------------------------------+--------------------------------------------- On iOS, due to a quirk, we must put references to external symbols into the data segment. If, for example, we have a declaration like this: {{{ foreign import ccall unsafe "static stdlib.h &free" c_free_finalizer :: FunPtr (Ptr Word8 -> IO ()) }}} ...then it tries to resolve the address of 'free' at runtime. The loader then attempts to write that address into the text segment. On iOS, modifying the text segment is not allowed, and so a runtime exception is thrown. We work around this issue by fetching the reference to the external symbol from the data segment. -- Ticket URL: http://hackage.haskell.org/trac/ghc/ticket/7722 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#7722: iOS patch no 11: Fix quirk with runtime loader ------------------------------+--------------------------------------------- Reporter: StephenBlackheath | Owner: Type: feature request | Status: patch Priority: normal | Component: Compiler Version: 7.7 | Keywords: Os: Other | Architecture: arm Failure: None/Unknown | Blockedby: Blocking: | Related: ------------------------------+--------------------------------------------- Changes (by StephenBlackheath): * status: new => patch -- Ticket URL: http://hackage.haskell.org/trac/ghc/ticket/7722#comment:1 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#7722: iOS patch no 11: Fix quirk with runtime loader ------------------------------+--------------------------------------------- Reporter: StephenBlackheath | Owner: StephenBlackheath Type: feature request | Status: patch Priority: normal | Component: Compiler Version: 7.7 | Keywords: Os: Other | Architecture: arm Failure: None/Unknown | Blockedby: Blocking: 7724 | Related: ------------------------------+--------------------------------------------- Changes (by StephenBlackheath): * owner: => StephenBlackheath Comment: Sadly this patch does not fix this issue, so more work is needed. The regression test is this: {{{ main = do putStrLn $ "ByteString regression test: "++show (B.empty) }}} The program dies with this appearing in the runtime console: {{{ dyld: vm_protect(0x00001000, 0x0042D000, false, 0x07) failed, result=2 for segment __TEXT in /var/mobile/Applications/38E8C4C6-DA4E- 4FBA-8183-6473AAA58A66F/Pear.app/Pear }}} -- Ticket URL: http://hackage.haskell.org/trac/ghc/ticket/7722#comment:3 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#7722: iOS patch no 11: Fix quirk with runtime loader ------------------------------+--------------------------------------------- Reporter: StephenBlackheath | Owner: Type: feature request | Status: patch Priority: normal | Component: Compiler Version: 7.7 | Keywords: Os: Other | Architecture: arm Failure: None/Unknown | Blockedby: Blocking: 7724 | Related: ------------------------------+--------------------------------------------- Changes (by StephenBlackheath): * owner: StephenBlackheath => -- Ticket URL: http://hackage.haskell.org/trac/ghc/ticket/7722#comment:4 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#7722: iOS patch no 11: Fix quirk with runtime loader ----------------------------------+----------------------------------------- Reporter: StephenBlackheath | Owner: Type: feature request | Status: patch Priority: normal | Milestone: Component: Compiler | Version: 7.7 Keywords: | Os: Other Architecture: arm | Failure: None/Unknown Difficulty: Unknown | Testcase: Blockedby: | Blocking: 7724 Related: | ----------------------------------+----------------------------------------- Changes (by simonmar): * difficulty: => Unknown Comment: I don't fully understand the problem here. How is the `free` symbol different from other symbols that we refer to? What happens if you write a C program that refers to `free`? (that would give us a clue about how the C compiler works around the issue, and hence how we should do it). -- Ticket URL: http://hackage.haskell.org/trac/ghc/ticket/7722#comment:5 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#7722: iOS patch no 11: Fix quirk with runtime loader ----------------------------------+----------------------------------------- Reporter: StephenBlackheath | Owner: Type: feature request | Status: patch Priority: normal | Milestone: Component: Compiler | Version: 7.7 Keywords: | Os: Other Architecture: arm | Failure: None/Unknown Difficulty: Unknown | Testcase: Blockedby: | Blocking: 7724 Related: | ----------------------------------+----------------------------------------- Comment(by StephenBlackheath): I don't fully understand it either. I don't think there's anything special about free apart from - I assume - getting resolved at runtime. Here's what the darwin -> iOS C compiler produces for {{{printf("%p\n", free);}}} {{{ movw r0, :lower16:(L_free$non_lazy_ptr-(LPC0_0+4)) movt r0, :upper16:(L_free$non_lazy_ptr-(LPC0_0+4)) LPC0_0: add r0, pc ldr r1, [r0] <-- r1 being the second argument of printf ... .section __DATA,__nl_symbol_ptr,non_lazy_symbol_pointers .align 2 L_free$non_lazy_ptr: .indirect_symbol _free .long 0 }}} Here's what GHC produces WITHOUT my patch, and this is the code that dies at runtime if you say 'print Data.ByteString.empty'. The source file is libraries/bytestring/Data/ByteString/Unsafe.hs {{{ .text .align 2 _s2jH_info: @ @s2jH_info ... ldr r9, LCPI29_2 ... .align 2 LCPI29_2: .long _free <-- still under the .text above, i.e. in text segment }}} Here's what GHC produces WITH my patch: {{{ .text .align 2 _s2jH_info: @ @s2jH_info ... ldr r8, LCPI29_1 ... ldr r9, [r8] ... .align 2 LCPI29_1: .long _free_ref_n3dd ... .section __DATA,__data ... .align 3 @ @free_ref_n3dd _free_ref_n3dd: .long _free }}} I don't know what .indirect_symbol does (and my assumption would be that llvm can't output it), but it certainly looks like the C compiler has also made sure the reference to _free is in the DATA segment. And my code has (surprisingly) fewer instructions than the C output. My priority has been to get things working, and not so much on proving the necessity or showing that it's the best way. Do you think this satisfies your questions about whether the changes are justified? If not, I'll investigate further. -- Ticket URL: http://hackage.haskell.org/trac/ghc/ticket/7722#comment:6 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#7722: iOS patch no 11: Fix quirk with runtime loader ----------------------------------+----------------------------------------- Reporter: StephenBlackheath | Owner: Type: feature request | Status: patch Priority: normal | Milestone: Component: Compiler | Version: 7.7 Keywords: | Os: Other Architecture: arm | Failure: None/Unknown Difficulty: Unknown | Testcase: Blockedby: | Blocking: 7724 Related: | ----------------------------------+----------------------------------------- Changes (by simonmar): * cc: dterei (added) Comment: So it looks like the C compiler is generating an indirect reference, as you would do when compiling a shared library (e.g. with `-fPIC`). On ELF platforms it isn't necessary to do this for static object files, because the linker relocates the data (rather than the symbol) at runtime. It looks like the iOS linker is using a different strategy. I expect you can fix this by telling LLVM to use a dynamic reference for the symbols in question (it would be any symbol which might be dynamically linked). If there's no way to get LLVM to generate the right kind of symbol reference, then at the least you can re-use the code in GHC that does this: `nativeGen/PIC.hs`. I'm not familiar with LLVM or with GHC's LLVM backend, so I've CC'd David Terei who might be able to help. -- Ticket URL: http://hackage.haskell.org/trac/ghc/ticket/7722#comment:7 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#7722: iOS patch no 11: Fix quirk with runtime loader ----------------------------------+----------------------------------------- Reporter: StephenBlackheath | Owner: Type: feature request | Status: patch Priority: normal | Milestone: Component: Compiler | Version: 7.7 Keywords: | Os: Other Architecture: arm | Failure: None/Unknown Difficulty: Unknown | Testcase: Blockedby: | Blocking: 7724 Related: | ----------------------------------+----------------------------------------- Comment(by simonmar): Also see #4210; from a quick look at that it seems that you might be able to just use "dynamic-no-pic" as the relocation mode for LLVM. -- Ticket URL: http://hackage.haskell.org/trac/ghc/ticket/7722#comment:8 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#7722: iOS patch no 11: Fix quirk with runtime loader ----------------------------------+----------------------------------------- Reporter: StephenBlackheath | Owner: Type: feature request | Status: patch Priority: normal | Milestone: Component: Compiler | Version: 7.7 Keywords: | Os: Other Architecture: arm | Failure: None/Unknown Difficulty: Unknown | Testcase: Blockedby: | Blocking: 7724 Related: | ----------------------------------+----------------------------------------- Comment(by StephenBlackheath): Simon, you were quite right and it works beautifully. A new very short patch attached to force that option for iOS targets. -- Ticket URL: http://hackage.haskell.org/trac/ghc/ticket/7722#comment:9 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#7722: iOS patch no 11: Fix quirk with runtime loader
----------------------------------+-----------------------------------------
Reporter: StephenBlackheath | Owner:
Type: feature request | Status: patch
Priority: normal | Milestone:
Component: Compiler | Version: 7.7
Keywords: | Os: Other
Architecture: arm | Failure: None/Unknown
Difficulty: Unknown | Testcase:
Blockedby: | Blocking: 7724
Related: |
----------------------------------+-----------------------------------------
Comment(by davidterei@…):
commit d6a6974f3b88417fcc0d780d164251331bcf9309
{{{
Author: David Terei

#7722: iOS patch no 11: Fix quirk with runtime loader --------------------------------+------------------------------------------- Reporter: StephenBlackheath | Owner: Type: feature request | Status: closed Priority: normal | Milestone: Component: Compiler | Version: 7.7 Resolution: fixed | Keywords: Os: Other | Architecture: arm Failure: None/Unknown | Difficulty: Unknown Testcase: | Blockedby: Blocking: 7724 | Related: --------------------------------+------------------------------------------- Changes (by dterei): * status: patch => closed * resolution: => fixed Comment: Thanks Stephen and Simon! I love it when LLVM issues are so nicely solved by others :). -- Ticket URL: http://hackage.haskell.org/trac/ghc/ticket/7722#comment:11 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#7722: iOS patch no 11: Fix quirk with runtime loader --------------------------------+------------------------------------------- Reporter: StephenBlackheath | Owner: Type: feature request | Status: closed Priority: normal | Milestone: Component: Compiler | Version: 7.7 Resolution: fixed | Keywords: Os: Other | Architecture: arm Failure: None/Unknown | Difficulty: Unknown Testcase: | Blockedby: Blocking: 7724 | Related: --------------------------------+------------------------------------------- Comment(by simonmar): Ok, but you might want to check that it isn't generating dynamic references for everything, which could add a lot of overhead. A quick check of the code size and performance before/after on a benchmark or two should be enough. -- Ticket URL: http://hackage.haskell.org/trac/ghc/ticket/7722#comment:12 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler
participants (1)
-
GHC