LLVM C API OrcJIT

Hello, I’ve been trying to use LLVM’s Orc JIT from C API for a few days and i can’t get it to work, I’m kind of annoyed for the lack of documentation examples for the C API.

Here’s my code: https://hasteb.in/ohexiweb.cpp

I compile it using

clang llvm-config --cflags --ldflags --libs all main.c -o main -g -rdynamic

And it ends up segfaulting at the line where it calls LLVMOrcAddLazilyCompiledIR

I can do a similar example with MCJIT just fine but i need to use lazy compiling here.

Could anyone point out the mistakes in my code or give me a full example of properly using Orc JIT from the C API, Thanks.

Hi Ladybug,

Is this on Linux? With LLVM top-of-tree, or a release branch? Are you able to get a backtrace of the crash?

There are a couple of issues that I can see by inspection:

(1) You will want to remove the call to LLVMOrcGetSymbolAddress from your sym_resolver function: In the ORC C API resolvers are only used to resolve external symbols (i.e. ones not defined in the JIT’d code). So in your case, given that you only searched the JIT, I think you can define this function to just return zero, meaning JIT’d code can’t call external functions.

(2) You should remove the call to LLVMDisposeModule at the end of main. LLVMOrcAddLazilyCompiledIR takes ownership of the module (my bad: this should be documented in the comments.) and will manage its lifetime for you.

(3) You should not need to mangle the symbol you pass to LLVMOrcGetMangledSymbol. That function will mangle it for you.

None of these explain your crash in LLVMOrcAddLazilyCompiledIR though, so I will need enough information to reproduce the crash before I can explain that.

A heads up too: the current C API is not well maintained (as you’ve discovered). The reason is that the underlying C++ APIs have undergone a big redesign to support concurrent compilation, but the C API has not caught up yet. We definitely want to update the C API, but I don’t have a timeline for it yet. Patches very welcome if you are interested in getting involved!

Cheers,
Lang.

In my experience with LLVM 4, LLVM can generate calls to external functions such as memcpy, so, assuming LLVM doesn’t resolve those functions by itself, you still need to resolve them in the symbol resolver function.

You can add a breakpoint or printf to the symbol resolver to see which names it tries to resolve and add those manually.

Jacob Lifshay