
This sounds right to me. Did you submit a patch? Note that dynamic linking with LLVM is likely to produce significantly worse code that with the NCG right now, because the LLVM back end uses dynamic references even for symbols in the same package, whereas the NCG back-end uses direct static references for these. Cheers, Simon On 14/12/2013 22:13, Ben Gamari wrote:
# The Problem
Dynamic linking is currently broken with the LLVM code generator. This can be easily seen by attempting to compile GHC with,
GhcDynamic = YES DYNAMIC_BY_DEFAULT = YES DYNAMIC_GHC_PROGRAMS = YES BuildFlavour = quick-llvm
This build will fail with a error along the lines of,
dll-split: internal error: invalid closure, info=0x402ec0 (GHC version 7.7.20131212 for x86_64_unknown_linux) Please report this as a GHC bug: http://www.haskell.org/ghc/reportabug
After some poking around with the help of Peter Wortmann, it seems clear that this is due to a subtle difference in how LLVM emits function symbols. While the NCG emits these symbols with `.type @object`, LLVM emits `.type @function`.
It appears that the `.type` annotation guides the linker in choosing the relocation mechanism to use for the symbol. While `@object` symbols use the Global Offset Table, `@function` symbols are relocated through the Procedure Linking Table, a table of trampoline calls which are fixed up at runtime. This means that static references to functions end up pointing not to the object itself (and its info table) but instead to some linker-generated assembly. When the garbage collector attempts to examine the info table of one of these references, it finds nonsense and fails.
# A solution
Peter demonstrated that manually modifying the assembler produced by llc, passing this through GHC's mangler, and assembling the result yields a functional binary.
As far as I can tell, LLVM's intermediate language doesn't expose any way to force a function to `.type @object`. Unfortunately this means that, at least for now, the only fix is to augment the mangler with logic to perform this transform. I've done this in my `llvm-dynamic` branch[1] (in addition to finding a bug in the `rewriteInstructions` function used by AVX rewriting).
This branch compiles on my x86_64 machine to produce what appears to be a functional compiler. Unfortunately installation issues (which I'll describe shortly in a new thread) prevent me from verifying this. I'm currently waiting for a build on my ARM box but assuming this fix works this means that GHC could (finally) have first-class, stable ARM support.
Comments?
Cheers,
- Ben
[1] https://github.com/bgamari/ghc/tree/llvm-dynamic
_______________________________________________ ghc-devs mailing list ghc-devs@haskell.org http://www.haskell.org/mailman/listinfo/ghc-devs