I'm trying to add function calls in the LLVM IR using the IRBuilder
class. I've read both tutorials about functions but I still get
assertion errors. I allocate memory for all function arguments and pass
them as explained in the tutorial.
My code is (this function is supposed to add a call to f in bb at pos):
void addCallSite(Function *f, BasicBlock *bb, BasicBlock::iterator pos) {
std::vector<Value*> args;
IRBuilder<> builder(bb,pos);
for(Function::arg_iterator argit =
f->arg_begin();argit!=f->arg_end();argit++){
AllocaInst* allocInst = builder.CreateAlloca(argit->getType());
args.push_back(allocInst);
}
builder.CreateCall(f,args.begin(),args.end());
}
This seems to work for functions without parameters (eg. int foo()), but
once a function has a parameter I get the following assertion error:
<llvmpath>/lib/VMCore/Instructions.cpp:297: void
llvm::CallInst::init(llvm::Value*, llvm::Value* const*, unsigned int):
Assertion `(i >= FTy->getNumParams() || FTy->getParamType(i) ==
Params[i]->getType()) && "Calling a function with a bad signature!"' failed.
I've checked everything I can think of and it all seems correct to me
... Any help would be greatly appreciated!
Thanks in advance,
Marc Claesen
_______________________________________________
LLVM Developers mailing list
LLV...@cs.uiuc.edu http://llvm.cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
In general, when I hit one of those assertions, I gdb to it, use "p
f->dump()" to see the types of the function's arguments, and use "p
Params[i]->dump()" to see the parameter with the bad type.
I used CreateAllocA(Type) because I assumed that was the correct way to
create a variable of a given type.
What I'm trying to do is create new variables of the types required by a
function and then call the function, so it's quite simple ... I just
don't know how to initialise correctly by the looks of it. What function
should I use if not CreateAllocA(Type)?
Thanks in advance,
Marc
> I'm trying to add function calls in the LLVM IR using the IRBuilder
> class. I've read both tutorials about functions but I still get
> assertion errors. I allocate memory for all function arguments and pass
> them as explained in the tutorial.
>
> My code is (this function is supposed to add a call to f in bb at pos):
> void addCallSite(Function *f, BasicBlock *bb, BasicBlock::iterator pos) {
> std::vector<Value*> args;
> IRBuilder<> builder(bb,pos);
> for(Function::arg_iterator argit =
> f->arg_begin();argit!=f->arg_end();argit++){
> AllocaInst* allocInst = builder.CreateAlloca(argit->getType());
> args.push_back(allocInst);
> }
> builder.CreateCall(f,args.begin(),args.end());
> }
>
> This seems to work for functions without parameters (eg. int foo()), but
> once a function has a parameter I get the following assertion error:
> <llvmpath>/lib/VMCore/Instructions.cpp:297: void
> llvm::CallInst::init(llvm::Value*, llvm::Value* const*, unsigned int):
> Assertion `(i >= FTy->getNumParams() || FTy->getParamType(i) ==
> Params[i]->getType()) && "Calling a function with a bad signature!"' failed.
CreateAlloca(someType) returns an AllocaInst* which has type
someType*. So if your function takes a parameter of type int, with this
chunk of code
AllocaInst* allocInst = builder.CreateAlloca(argit->getType());
args.push_back(allocInst);
you are passing an int*. This triggers the assert.
For now, forget about the allocas.
Another issue is that I don't see in your code the _values_ you want to
pass to the called function. Apparently you already have the function
declaration (Function *f) but you are creating a call to that function,
and you need the actual arguments (not the argument types):
inf foo(int); // declaration. you already have this elsewhere.
foo(10); // call. you need the value (10) to pass to the function.
--
Óscar
Marc Claesen <clae...@gmail.com> writes:
>> Another issue is that I don't see in your code the _values_ you want to
>> pass to the called function. Apparently you already have the function
>> declaration (Function *f) but you are creating a call to that function,
>> and you need the actual arguments (not the argument types):
>
> That's exactly the problem. I'm trying to initialise values of the
> appropriate types as required by a given function and pass those. What
> I'm looking for is the appropriate instructions to initialise a
> variable of a given type to it's type's default value. I realise this
> program will generate useless function calls but it's part of a binary
> obfuscation chain.
In LLVM there is no such a thing as a type default value. Maybe that
concept exists on your language.
Creating allocas is not the solution, as the alloca is just
uninitialized space on the stack.
Suppossing that the function parameters simple enough, like integral or
floating point types, and the "default value" is zero, something like
this will do (untested):
std::vector<Value*> args;
IRBuilder<> builder(bb,pos);
for(Function::arg_iterator argit =
f->arg_begin();argit!=f->arg_end();
argit++)
{
Value *arg = Constant::getNullValue(argit->getType());
args.push_back(arg);
}
builder.CreateCall(f,args.begin(),args.end());
If your arguments are something more fancy, you have more work ahead
(for following the platform/language ABI, etc).