<div dir="ltr"><div class="gmail_extra">oh,I'm sorry to make such a stupid mistake...But I still have to tell the correct one still didnt make difference...so weird<br><br><div class="gmail_quote">2014-04-04 16:30 GMT+08:00 Anton Korobeynikov <span dir="ltr"><<a href="mailto:anton@korobeynikov.info" target="_blank">anton@korobeynikov.info</a>></span>:<br>

<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Are you sure, that LLVMGetNamedFunction(m,"_a_outside_func") does not<br>
return NULL? I believe it should be<br>
LLVMGetNamedFunction(m,"a_outside_func")<br>
<div class="HOEnZb"><div class="h5"><br>
On Fri, Apr 4, 2014 at 12:25 PM, <a href="mailto:waxiadao@gmail.com">waxiadao@gmail.com</a> <<a href="mailto:waxiadao@gmail.com">waxiadao@gmail.com</a>> wrote:<br>
> Hello<br>
> I quite thank you for your advice,but I have to tell that it made no<br>
> difference too calling<br>
> "LLVMAddGlobalMapping(ee,LLVMGetNamedFunction(m,"_a_outside_func"),(void*)(&a_outside_func));".<br>
><br>
><br>
> 2014-04-04 16:10 GMT+08:00 Anton Korobeynikov <<a href="mailto:anton@korobeynikov.info">anton@korobeynikov.info</a>>:<br>
><br>
>> Hello<br>
>><br>
>> While there is a symbol in the object file, there is nothing like this<br>
>> in the final executable (well, you can try to export functions from<br>
>> PE/COFF executable, but this is pretty non-standard technique). This<br>
>> is the biggest difference wrt linux, where all the visible symbols are<br>
>> exported by default from the binary.<br>
>><br>
>> Most probably, the best way here is to create an explicit mapping<br>
>> between a GlobalValue which represents your external function and the<br>
>> address of your function. ExecutionEngine::addGlobalMapping() is your<br>
>> friend here.<br>
>><br>
>> On Fri, Apr 4, 2014 at 9:48 AM, <a href="mailto:waxiadao@gmail.com">waxiadao@gmail.com</a> <<a href="mailto:waxiadao@gmail.com">waxiadao@gmail.com</a>><br>
>> wrote:<br>
>> > Hi,<br>
>> > I have a IR file generated by Clang:<br>
>> ><br>
>> > ; ModuleID = 'test_load_lib.c'<br>
>> > target datalayout =<br>
>> ><br>
>> > "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"<br>
>> > target triple = "i686-pc-mingw32"<br>
>> ><br>
>> > declare i32 @a_outside_func(i32)<br>
>> ><br>
>> > define i32 @test_func() {<br>
>> > entry:<br>
>> >   %call = call i32 @a_outside_func(i32 15)<br>
>> >   ret i32 %call<br>
>> > }<br>
>> ><br>
>> > where a_outside_func is a function defined on my code:<br>
>> ><br>
>> > extern "C" int a_outside_func(int a)<br>
>> > {<br>
>> >   return a + 50;<br>
>> > }<br>
>> ><br>
>> > and following code is to get MCJIT work:<br>
>> ><br>
>> > #define prt(x) if(x) { cout << x << endl; }<br>
>> > LLVMInitializeAllTargets();<br>
>> >   LLVMInitializeAllTargetMCs();<br>
>> >   LLVMInitializeAllTargetInfos();<br>
>> >   LLVMInitializeAllAsmParsers();<br>
>> >   LLVMInitializeAllAsmPrinters();<br>
>> >   LLVMInitializeAllDisassemblers(); // just initialize them all....<br>
>> >   prt(a_outside_func(50));               // afraid of linker optmize it<br>
>> > out<br>
>> ><br>
>> >   char *err = 0;<br>
>> >   LLVMMemoryBufferRef ll_f = 0;<br>
>> >   LLVMModuleRef m = 0;<br>
>> ><br>
>> > LLVMCreateMemoryBufferWithContentsOfFile("test_load_lib.ll",&ll_f,&err);<br>
>> > //read .ll<br>
>> >   prt(err);<br>
>> >   LLVMParseIRInContext(LLVMGetGlobalContext(),ll_f,&m,&err); // ll_f<br>
>> > doesnt<br>
>> > need freeing<br>
>> >   prt(err);<br>
>> >   LLVMDumpModule(m);<br>
>> ><br>
>> >   LLVMLinkInMCJIT();<br>
>> >   LLVMExecutionEngineRef ee = 0;<br>
>> >   LLVMCreateMCJITCompilerForModule(&ee,m,0,0,&err);<br>
>> >   prt(err);<br>
>> >   using tf_t = int ();<br>
>> >   tf_t *f =<br>
>> > (tf_t*)LLVMGetPointerToGlobal(ee,LLVMGetNamedFunction(m,"test_func"));<br>
>> ><br>
>> > At first i got "LLVM ERROR: Incompatible object format! "<br>
>> > But by reading some articles I append<br>
>> > LLVMSetTarget(m,"i686-pc-mingw32");<br>
>> > and it's fixed.<br>
>> > Then I got "LLVM ERROR: Program used external function 'a_outside_func'<br>
>> > which could not be resolved!".<br>
>> > I assumed my program didn't export the symbol properly.Thus,I use nm to<br>
>> > check my program's export and I found "a_outside_func" was renamed to<br>
>> > "_a_outside_func"<br>
>> > .<br>
>> > For it I rename the function name in the IR to "_a_outside_func".But it<br>
>> > seemed to make no difference: "LLVM ERROR: Program used external<br>
>> > function<br>
>> > '_a_outside_func' which could not be resolved!".<br>
>> > .............<br>
>> > After a day's wasting I unconsciously packed my external function<br>
>> > "a_outside_func" into a shared object,called<br>
>> > llvm::sys::DynamicLibrary::LoadLibraryPermanently("ext_func.so"); at the<br>
>> > beginning of the program and named the function "_a_outside_func" in the<br>
>> > IR.<br>
>> > OMG IT WORKS THEN?!<br>
>> > So I'd like to ask why llvm cant resolve my external function from the<br>
>> > program itself(in fact i dont get such problems on linux)?<br>
>> ><br>
>> > _______________________________________________<br>
>> > LLVM Developers mailing list<br>
>> > <a href="mailto:LLVMdev@cs.uiuc.edu">LLVMdev@cs.uiuc.edu</a>         <a href="http://llvm.cs.uiuc.edu" target="_blank">http://llvm.cs.uiuc.edu</a><br>
>> > <a href="http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev</a><br>
>> ><br>
>><br>
>><br>
>><br>
>> --<br>
>> With best regards, Anton Korobeynikov<br>
>> Faculty of Mathematics and Mechanics, Saint Petersburg State University<br>
><br>
><br>
<br>
<br>
<br>
--<br>
With best regards, Anton Korobeynikov<br>
Faculty of Mathematics and Mechanics, Saint Petersburg State University<br>
</div></div></blockquote></div><br></div></div>