[LLVMdev] Weird problems on calling an external function from MCJIT on Windows(mingw)

Anton Korobeynikov
Fri, 04 Apr 2014 08:10:34 -0000

Hello

While there is a symbol in the object file, there is nothing like this
in the final executable (well, you can try to export functions from
PE/COFF executable, but this is pretty non-standard technique). This
is the biggest difference wrt linux, where all the visible symbols are
exported by default from the binary.

Most probably, the best way here is to create an explicit mapping
between a GlobalValue which represents your external function and the
address of your function. ExecutionEngine::addGlobalMapping() is your
friend here.

On Fri, Apr 4, 2014 at 9:48 AM, waxiadao at gmail.com <waxiadao at
gmail.com> wrote:
> Hi,
> I have a IR file generated by Clang:
>
> ; ModuleID = 'test_load_lib.c'
> target datalayout >
"e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-f80:128:128-v64:64:64-v128:128:128-a0:0:64-f80:32:32-n8:16:32-S32"
> target triple = "i686-pc-mingw32"
>
> declare i32 @a_outside_func(i32)
>
> define i32 @test_func() {
> entry:
>   %call = call i32 @a_outside_func(i32 15)
>   ret i32 %call
> }
>
> where a_outside_func is a function defined on my code:
>
> extern "C" int a_outside_func(int a)
> {
>   return a + 50;
> }
>
> and following code is to get MCJIT work:
>
> #define prt(x) if(x) { cout << x << endl; }
> LLVMInitializeAllTargets();
>   LLVMInitializeAllTargetMCs();
>   LLVMInitializeAllTargetInfos();
>   LLVMInitializeAllAsmParsers();
>   LLVMInitializeAllAsmPrinters();
>   LLVMInitializeAllDisassemblers(); // just initialize them all....
>   prt(a_outside_func(50));               // afraid of linker optmize it out
>
>   char *err = 0;
>   LLVMMemoryBufferRef ll_f = 0;
>   LLVMModuleRef m = 0;
>
LLVMCreateMemoryBufferWithContentsOfFile("test_load_lib.ll",&ll_f,&err);
> //read .ll
>   prt(err);
>   LLVMParseIRInContext(LLVMGetGlobalContext(),ll_f,&m,&err); //
ll_f doesnt
> need freeing
>   prt(err);
>   LLVMDumpModule(m);
>
>   LLVMLinkInMCJIT();
>   LLVMExecutionEngineRef ee = 0;
>   LLVMCreateMCJITCompilerForModule(&ee,m,0,0,&err);
>   prt(err);
>   using tf_t = int ();
>   tf_t *f >
(tf_t*)LLVMGetPointerToGlobal(ee,LLVMGetNamedFunction(m,"test_func"));
>
> At first i got "LLVM ERROR: Incompatible object format! "
> But by reading some articles I append
LLVMSetTarget(m,"i686-pc-mingw32");
> and it's fixed.
> Then I got "LLVM ERROR: Program used external function
'a_outside_func'
> which could not be resolved!".
> I assumed my program didn't export the symbol properly.Thus,I use nm to
> check my program's export and I found "a_outside_func" was
renamed to
> "_a_outside_func"
> .
> For it I rename the function name in the IR to
"_a_outside_func".But it
> seemed to make no difference: "LLVM ERROR: Program used external
function
> '_a_outside_func' which could not be resolved!".
> .............
> After a day's wasting I unconsciously packed my external function
> "a_outside_func" into a shared object,called
> llvm::sys::DynamicLibrary::LoadLibraryPermanently("ext_func.so");
at the
> beginning of the program and named the function "_a_outside_func"
in the IR.
> OMG IT WORKS THEN?!
> So I'd like to ask why llvm cant resolve my external function from the
> program itself(in fact i dont get such problems on linux)?
>
> _______________________________________________
> LLVM Developers mailing list
> LLVMdev at cs.uiuc.edu         http://llvm.cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
>



--
With best regards, Anton Korobeynikov
Faculty of Mathematics and Mechanics, Saint Petersburg State University