marwayusuf@feng.bu.edu.eg via llvm-dev
2015-Aug-19 22:42 UTC
[llvm-dev] creating a callinst to an external function
Dear All I'm making an instrumentation pass. The pass is supposed to modify the given IR in a specefic way. One of the required modifications is to insert a call to a function at a specific location. This is the signature of the called function: void myclass::foo(Function *f, BasicBlock* b) This function's prototype is in an foofile.h file in include/llvm And the function definition is in foofile.cpp file in the MCJIT folder. and running "make" at this folder works fine and the foofile.cpp is compiled with MCJIT.cpp and another function in the same file works just fine as expected. Not back to the instrumentation pass. How can I insert a callinst to the foo function in the given IR? Here is the snippet that inserts the call: Type* retTy = Type::getInt32Ty(C); FunctionType* FuncTy = FunctionType::get(retTy, false); PointerType* PtrToFuncTy = PointerType::get(FuncTy, 0); Constant *fun = M->getOrInsertFunction("foo", Type::getVoidTy(C), PtrToFuncTy, Type::getLabelTy(C), nullptr); Function *dofoo = cast<Function>(fun); Instruction* dofooCall = CallInst::Create(fun, Args2, "", bb); Note: Args2 is an arraylist containing 2 value pointers to a function and a basicblock, bb is the basicblock to insert the call in. When I run the pass using op on a given IR, it produces a declaration and a call correctly like this: declaration: declare void @foo(i32 ()*, label) call: call void @foo(i32 ()* @main, label %for.cond) But when I try to run the resulting .ll file using lli, everything explodes! This the first 2 lines before the stacktrace: Can't get register for value! UNREACHABLE executed at /home/marwayusuf/llvm-env/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp:1158! I concluded that the problem is it can't find the foo function. If this is the problem, how can I create the callinst correctly? Regards, Marwa Yusuf Teaching Assistant - Computer Engineering Department Faculty of Engineering - Benha University E-JUST PhD Student Computer Science & Engineering Dept. -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20150819/39bd273f/attachment.html>
marwayusuf@feng.bu.edu.eg via llvm-dev
2015-Sep-02 14:17 UTC
[llvm-dev] creating a callinst to an external function
I tried to remove parameters from the called function "foo". So I got a different error. LLVM ERROR: Program used external function 'foo' which could not be resolved! Any help? Regards, Marwa Yusuf Teaching Assistant - Computer Engineering Department Faculty of Engineering - Benha University E-JUST PhD Student Computer Science & Engineering Dept. ________________________________ From: llvm-dev <llvm-dev-bounces at lists.llvm.org> on behalf of marwayusuf at feng.bu.edu.eg via llvm-dev <llvm-dev at lists.llvm.org> Sent: Thursday, August 20, 2015 12:42 AM To: llvm-dev at lists.llvm.org Subject: [llvm-dev] creating a callinst to an external function Dear All I'm making an instrumentation pass. The pass is supposed to modify the given IR in a specefic way. One of the required modifications is to insert a call to a function at a specific location. This is the signature of the called function: void myclass::foo(Function *f, BasicBlock* b) This function's prototype is in an foofile.h file in include/llvm And the function definition is in foofile.cpp file in the MCJIT folder. and running "make" at this folder works fine and the foofile.cpp is compiled with MCJIT.cpp and another function in the same file works just fine as expected. Not back to the instrumentation pass. How can I insert a callinst to the foo function in the given IR? Here is the snippet that inserts the call: Type* retTy = Type::getInt32Ty(C); FunctionType* FuncTy = FunctionType::get(retTy, false); PointerType* PtrToFuncTy = PointerType::get(FuncTy, 0); Constant *fun = M->getOrInsertFunction("foo", Type::getVoidTy(C), PtrToFuncTy, Type::getLabelTy(C), nullptr); Function *dofoo = cast<Function>(fun); Instruction* dofooCall = CallInst::Create(fun, Args2, "", bb); Note: Args2 is an arraylist containing 2 value pointers to a function and a basicblock, bb is the basicblock to insert the call in. When I run the pass using op on a given IR, it produces a declaration and a call correctly like this: declaration: declare void @foo(i32 ()*, label) call: call void @foo(i32 ()* @main, label %for.cond) But when I try to run the resulting .ll file using lli, everything explodes! This the first 2 lines before the stacktrace: Can't get register for value! UNREACHABLE executed at /home/marwayusuf/llvm-env/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp:1158! I concluded that the problem is it can't find the foo function. If this is the problem, how can I create the callinst correctly? Regards, Marwa Yusuf Teaching Assistant - Computer Engineering Department Faculty of Engineering - Benha University E-JUST PhD Student Computer Science & Engineering Dept. -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20150902/304d7534/attachment-0001.html>
mats petersson via llvm-dev
2015-Sep-02 14:36 UTC
[llvm-dev] creating a callinst to an external function
If you look at the computer output of the file that provides the function `myclass::foo` (-S -emit-llvm if you use clang), you should see that the name of the function (probably) isn't `foo`. You need to precisely match the name between the caller and the actual function. -- Mats On 2 September 2015 at 15:17, marwayusuf at feng.bu.edu.eg via llvm-dev < llvm-dev at lists.llvm.org> wrote:> I tried to remove parameters from the called function "foo". So I got a > different error. > > LLVM ERROR: Program used external function 'foo' which could not be > resolved! > > Any help? > > > Regards, > Marwa Yusuf > Teaching Assistant - Computer Engineering Department > Faculty of Engineering - Benha University > E-JUST PhD Student > Computer Science & Engineering Dept. > > > ------------------------------ > *From:* llvm-dev <llvm-dev-bounces at lists.llvm.org> on behalf of > marwayusuf at feng.bu.edu.eg via llvm-dev <llvm-dev at lists.llvm.org> > *Sent:* Thursday, August 20, 2015 12:42 AM > *To:* llvm-dev at lists.llvm.org > *Subject:* [llvm-dev] creating a callinst to an external function > > > Dear All > > I'm making an instrumentation pass. The pass is supposed to modify the > given IR in a specefic way. One of the required modifications is to insert > a call to a function at a specific location. > > This is the signature of the called function: > > void myclass::foo(Function *f, BasicBlock* b) > > This function's prototype is in an foofile.h file in include/llvm > > And the function definition is in foofile.cpp file in the MCJIT folder. > > and running "make" at this folder works fine and the foofile.cpp is > compiled with MCJIT.cpp and another function in the same file works just > fine as expected. > > Not back to the instrumentation pass. How can I insert a callinst to the > foo function in the given IR? > > Here is the snippet that inserts the call: > > Type* retTy = Type::getInt32Ty(C); > > FunctionType* FuncTy = FunctionType::get(retTy, false); > > PointerType* PtrToFuncTy = PointerType::get(FuncTy, 0); > > Constant *fun = M->getOrInsertFunction("foo", > Type::getVoidTy(C), PtrToFuncTy, Type::getLabelTy(C), nullptr); > > Function *dofoo = cast<Function>(fun); > > Instruction* dofooCall = CallInst::Create(fun, Args2, "", bb); > > > Note: Args2 is an arraylist containing 2 value pointers to a function and > a basicblock, bb is the basicblock to insert the call in. > > > When I run the pass using op on a given IR, it produces a declaration and > a call correctly like this: > > declaration: declare void @foo(i32 ()*, label) > > call: call void @foo(i32 ()* @main, label %for.cond) > > But when I try to run the resulting .ll file using lli, everything > explodes! This the first 2 lines before the stacktrace: > > Can't get register for value! > > UNREACHABLE executed at > /home/marwayusuf/llvm-env/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp:1158! > > > > I concluded that the problem is it can't find the foo function. If this is > the problem, how can I create the callinst correctly? > > > > > Regards, > Marwa Yusuf > Teaching Assistant - Computer Engineering Department > Faculty of Engineering - Benha University > E-JUST PhD Student > Computer Science & Engineering Dept. > > _______________________________________________ > LLVM Developers mailing list > llvm-dev at lists.llvm.org > http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev > >-------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20150902/a9ed1a7a/attachment.html>
Tim Northover via llvm-dev
2015-Sep-02 14:37 UTC
[llvm-dev] creating a callinst to an external function
On 19 August 2015 at 23:42, marwayusuf at feng.bu.edu.eg via llvm-dev <llvm-dev at lists.llvm.org> wrote:> void myclass::foo(Function *f, BasicBlock* b) > [...] > call: call void @foo(i32 ()* @main, label %for.cond)The problem here is that a "Function *" isn't simply a function pointer, or even a function pointer at all. It's a compile-time representation of some function. Similar comments apply to BasicBlock. I'm quite surprised it even reached SelectionDAGBuilder before blowing up. That information is not normally available at runtime, though in principle you could get one in there if you were JITing. If you know where the Function lives when you're generating the IR (and can guarantee it won't move) you could aim for something like: call void @foo(i8* inttoptr(i64 0x123450 to i8*), inttoptr(i64 ...)) Something like: Function *Main = ...; Value *Arg = Constant::CreateIntToPtr(reinterpret_cast<uint64_t>(Main)); I.e. instead of using Main as a Value in the call expression, completely hide the fact that it's an LLVM object from the compiler and pass it in as an opaque integer. Also, don't forget the "this" pointer if "foo" is not a static method. Cheers. Tim.
marwayusuf@feng.bu.edu.eg via llvm-dev
2015-Sep-09 13:30 UTC
[llvm-dev] creating a callinst to an external function
Thanks a million for help. I got the general idea but I could not manage to implement it. I understood that I need to create IntToPtrInst that is supposed to convert an integer (that represents the function address) back to a function pointer at the callee side. But I have some questions: How I get this integer value at the first place? I tried something like: Value *Arg1 = new IntToPtrInst(reinterpret_cast<uint64_t>(F), F->getType()); It gave me this compilation error: error: no matching function for call to ‘llvm::IntToPtrInst::IntToPtrInst(uint64_t, llvm::PointerType*)’ and Value *Arg1 = new IntToPtrInst(F, F->getType()); It gave me this runtime error (during applying the pass): llvm::IntToPtrInst::IntToPtrInst(llvm::Value*, llvm::Type*, const llvm::Twine&, llvm::Instruction*): Assertion `castIsValid(getOpcode(), S, Ty) && "Illegal IntToPtr"' failed. Regards, Marwa Yusuf Teaching Assistant - Computer Engineering Department Faculty of Engineering - Benha University E-JUST PhD Student Computer Science & Engineering Dept. ________________________________________ From: Tim Northover <t.p.northover at gmail.com> Sent: Wednesday, September 2, 2015 4:37 PM To: marwayusuf at feng.bu.edu.eg Cc: llvm-dev at lists.llvm.org Subject: Re: [llvm-dev] creating a callinst to an external function On 19 August 2015 at 23:42, marwayusuf at feng.bu.edu.eg via llvm-dev <llvm-dev at lists.llvm.org> wrote:> void myclass::foo(Function *f, BasicBlock* b) > [...] > call: call void @foo(i32 ()* @main, label %for.cond)The problem here is that a "Function *" isn't simply a function pointer, or even a function pointer at all. It's a compile-time representation of some function. Similar comments apply to BasicBlock. I'm quite surprised it even reached SelectionDAGBuilder before blowing up. That information is not normally available at runtime, though in principle you could get one in there if you were JITing. If you know where the Function lives when you're generating the IR (and can guarantee it won't move) you could aim for something like: call void @foo(i8* inttoptr(i64 0x123450 to i8*), inttoptr(i64 ...)) Something like: Function *Main = ...; Value *Arg = Constant::CreateIntToPtr(reinterpret_cast<uint64_t>(Main)); I.e. instead of using Main as a Value in the call expression, completely hide the fact that it's an LLVM object from the compiler and pass it in as an opaque integer. Also, don't forget the "this" pointer if "foo" is not a static method. Cheers. Tim.
marwayusuf@feng.bu.edu.eg via llvm-dev
2015-Sep-09 14:21 UTC
[llvm-dev] creating a callinst to an external function
Thanks a million for your help. foo function is properly called now, if I pass no parameters. However, it stops if I try to pass an llvm Function as a prameter. The problem arises if I try to perform any operation (like getName) on this passed function. It gives me a segmentation fault. I checked and found it's not NULL. I understood from your answer that I should convert the function pointer into an integer that represents its address and then convert it back into a pointer in the instrumented IR. However, I could not get how exactly to do that. I tried some code but with no luck. If you please explain the idea more, I'll appreciate. Thanks in advance. Regards, Marwa Yusuf Teaching Assistant - Computer Engineering Department Faculty of Engineering - Benha University E-JUST PhD Student Computer Science & Engineering Dept. ________________________________________ From: Tim Northover <t.p.northover at gmail.com> Sent: Wednesday, September 2, 2015 4:37 PM To: marwayusuf at feng.bu.edu.eg Cc: llvm-dev at lists.llvm.org Subject: Re: [llvm-dev] creating a callinst to an external function On 19 August 2015 at 23:42, marwayusuf at feng.bu.edu.eg via llvm-dev <llvm-dev at lists.llvm.org> wrote:> void myclass::foo(Function *f, BasicBlock* b) > [...] > call: call void @foo(i32 ()* @main, label %for.cond)The problem here is that a "Function *" isn't simply a function pointer, or even a function pointer at all. It's a compile-time representation of some function. Similar comments apply to BasicBlock. I'm quite surprised it even reached SelectionDAGBuilder before blowing up. That information is not normally available at runtime, though in principle you could get one in there if you were JITing. If you know where the Function lives when you're generating the IR (and can guarantee it won't move) you could aim for something like: call void @foo(i8* inttoptr(i64 0x123450 to i8*), inttoptr(i64 ...)) Something like: Function *Main = ...; Value *Arg = Constant::CreateIntToPtr(reinterpret_cast<uint64_t>(Main)); I.e. instead of using Main as a Value in the call expression, completely hide the fact that it's an LLVM object from the compiler and pass it in as an opaque integer. Also, don't forget the "this" pointer if "foo" is not a static method. Cheers. Tim.