在LLVM IR中调用函数

时间:2014-12-27 00:00:46

标签: llvm

我想在bitcode级别中调用程序的每个函数。 假设有一个函数void f(int a),我需要在main函数的开头检测以下代码。

int a;
klee_make_symbolic(&a, sizeof(a), "a");
f(a);

我写了一个传球来实现这一点。

 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);

}

}

但我断言失败了:

 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.

我是LLVm的新手,有人能告诉我实施中的错误吗?

1 个答案:

答案 0 :(得分:4)

您正在将a的指针传递给函数f。这就是你的实施问题。

在您的代码中:

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);
}

您正在arg向量中推送argsargAllocaInst的值,因此它是一个指针。您需要该值以适合您的函数签名。您需要发出从LoadInst加载的AllocaInst并将LoadInst推送到您的向量中。

对于你的问题:

 klee_args.push_back(arg);//I dont't know how to pass a argument of "const char *"

查看CreateGlobalStringPtr中的IRBuilder功能。文档hereIRBuilder是一个很好的帮助类,它使LLVM IR的生活更容易一些。