[LLVMdev] Having JIT resolve extern "C" functions declared in executible

Albert Graef Dr.Graef at t-online.de
Sat Jul 4 09:19:35 PDT 2009

John McCall wrote:
> On Jul 2, 2009, at 1:05 AM, Carter Cheng wrote:
>> I am having some difficulties getting the LLVM JIT to resolve extern  
>> "C" functions which I have defined in source file and invoking them  
>> via EE::runFunction() after generating a Function prototype for it.  
>> Is this possible or do I need to generate a .so for my functions are  
>> link against it?
> If the JIT needs a pointer to a function, and that function has no  
> body, it'll ask the ModuleProvider to materialize the function.  If  
> the MP returns false, it'll just ask the dynamic linker for the  
> function with that name.  If no such function is linked into your  
> program, then the JIT will just give up.  So you have three options:
> (1)  You can circumvent this entire process by giving the JIT an  
> explicit pointer to the function using JIT::addGlobalMapping().   
> Obviously this requires the function to be compiled and linked into  
> your program.
> (2)  You can compile and link the function into your program in such a  
> way that the dynamic linker will find it.
> (3)  You can give the JIT a custom module provider which somehow  
> materializes IR for the given function.

Maybe I'm missing something, but this seems to be overkill. As John
mentioned, if the C function to be called is linked into your program
then the JIT should normally resolve it just fine. The Kaleidoscope
tutorial [1] illustrates how to do this.

[1] http://llvm.org/docs/tutorial/

There is one gotcha here, though: If the symbol is linked directly into
your main executable, as is in the Kaleidoscope example, then you *must*
use -rdynamic (or whatever flag your compiler provides to enable
backlinking) when linking the executable, in order to make this work.
This isn't necessary if the symbol is in a shared library linked into
your program.

Otherwise you just put the function into a shared library and load that
library through llvm::sys::DynamicLibrary::LoadLibraryPermanently() [2].
Then the JIT resolves it without the shared library being linked at
compile/link time.

[2] http://llvm.org/doxygen/classllvm_1_1sys_1_1DynamicLibrary.html

Only in unusual circumstances (i.e., you can't/don't want want to put
the stuff into a separate shared library *and* your C compiler doesn't
support backlinking a la -rdynamic), it's necessary to explicitly tell
the dynamic loader about your C function, by calling
sys::DynamicLibrary::AddSymbol() with a pointer to the function.

This is all I ever needed to interface to C functions using LLVM. It's
really easy. Of course you still need a prototype of the external
function (function definition without body) in your IR, but that's it.


Dr. Albert Gr"af
Dept. of Music-Informatics, University of Mainz, Germany
Email:  Dr.Graef at t-online.de, ag at muwiinfa.geschichte.uni-mainz.de
WWW:    http://www.musikinformatik.uni-mainz.de/ag

More information about the llvm-dev mailing list