[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.
HTH,
Albert
--
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