LLVM and dynamic linking

Ben Gamari bgamari.foss at gmail.com
Sat Dec 14 22:13:25 UTC 2013


# 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

-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 489 bytes
Desc: not available
URL: <http://www.haskell.org/pipermail/ghc-devs/attachments/20131214/ee79f859/attachment.sig>


More information about the ghc-devs mailing list