在LLVM IR中实现对函数的调用

4

我希望在位码级别为程序中的每个函数添加调用检测。 假设有一个函数void f(int a),我需要在主函数开头插入以下代码。

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个回答

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推入你的args向量中。 argAllocaInst的值,因此它是一个指针。你需要该值符合函数签名。你需要发出一个LoadInst来从AllocaInst中加载并将LoadInst推入你的向量中。
对于你的问题:
 klee_args.push_back(arg);//I dont't know how to pass a argument of "const char *"

请查看IRBuilder中的CreateGlobalStringPtr函数。文档可以在这里找到。 IRBuilder是一个方便的帮助类,使得使用LLVM IR更加容易些。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接