Tool to call in LLVM IR
I want to handle the call to each function of the program at the bitcode level. Suppose there is a function void f(int a)
, I need to enter the following code at the beginning of the main function.
int a;
klee_make_symbolic(&a, sizeof(a), "a");
f(a);
I wrote a pass to achieve this.
for (Module::iterator f = M.begin(), fe = M.end(); f != fe; ++f) {
std::vector<llvm::Value*> args;
for(Function::arg_iterator ai = f->arg_begin(), ae = f->arg_end(); ai != ae; ++ai){
Type* tp = ai->getType();
AllocaInst* arg = new AllocaInst(tp, "name", firstInst);
args.push_back(arg);
LLVM_TYPE_Q llvm::Type *i8Ty = Type::getInt8Ty(getGlobalContext());
Constant *fc = M.getOrInsertFunction("klee_make_symbolic",
PointerType::getUnqual(i8Ty),
Type::getInt64Ty(getGlobalContext()),
PointerType::getUnqual(i8Ty),
NULL);
Function* kleeMakeSymbolic = cast<Function>(fc);
std::vector<Value* > klee_args;
klee_args.push_back(arg);
klee_args.push_back(ConstantInt::get(Type::getInt64Ty(getGlobalContext()),
dl->getTypeAllocSizeInBits(tp)));// dl is DataLayout
klee_args.push_back(arg);//I dont't know how to pass a argument of "const char *"
// Inject a call to klee_make_symbolic
CallInst::Create(kleeMakeSymbolic, klee_args, "", firstInst);
}
// Inject a call to the function
CallInst::Create(f, args, "", firstInst);
}
}
But I got rejected assertion:
llvm::CallInst::init(llvm::Value*, llvm::ArrayRef<llvm::Value*>, const llvm::Twine&): Assertion `(Args.size() == FTy->getNumParams() || (FTy->isVarArg() && Args.size() > FTy->getNumParams())) && "Calling a function with bad signature!"' failed.
I'm new to LLVm, can anyone tell me what is wrong with my implementation?
source to share
You are passing a pointer a
to a function f
. This is a problem with your implementation.
In your code:
for (Module::iterator f = M.begin(), fe = M.end(); f != fe; ++f) {
std::vector<llvm::Value*> args;
for(Function::arg_iterator ai = f->arg_begin(), ae = f->arg_end(); ai != ae; ++ai){
Type* tp = ai->getType();
AllocaInst* arg = new AllocaInst(tp, "name", firstInst);
args.push_back(arg);
...
}
// Inject a call to the function
CallInst::Create(f, args, "", firstInst);
}
you click arg
in your vector args
. arg
is a value AllocaInst
, so it is a pointer. You need a value that matches your function. You need to fix LoadInst
which one is loading from AllocaInst
and pushing LoadInst
into your vector.
For your problem:
klee_args.push_back(arg);//I dont't know how to pass a argument of "const char *"
Look at the function CreateGlobalStringPtr
from IRBuilder
. The documentation is here . IRBuilder
is a nice helper class that makes life with LLVM IR easier.
source to share