问题 如何使用LLVM正确插入函数调用?


我正在尝试设置一个传递,它将在main的开头插入几个全局变量以及几个函数调用。但是,我认为我在正确设置功能描述时遇到问题。我的代码编译,但当我尝试运行传递时,我收到此错误:

void 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. 

这是我到目前为止编写的代码:

#include "llvm/IR/Instructions.h"
#include "llvm/Pass.h"
#include "llvm/Support/InstIterator.h"
#include "llvm/IR/Function.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/Value.h"
#include "llvm/IR/GlobalValue.h"
#include "llvm/IR/GlobalVariable.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Type.h"
#include "llvm/IR/Module.h"

using namespace llvm;
namespace{

struct fun_insert : public FunctionPass{
  static char ID;

  fun_insert():FunctionPass(ID){}

  virtual bool runOnFunction(Function &F){
    if (F.getName() == "main"){
      for (inst_iterator I = inst_begin(F), E= inst_end(F); I != E; ++I){               
        Instruction *inst = &*I;
        if(dyn_cast<AllocaInst> (inst)){
          errs() << "test" << "\n";
          GlobalVariable *virtAddr = new GlobalVariable(*F.getParent(),
              Type::getInt8PtrTy(F.getContext()), false,
              GlobalValue::ExternalLinkage, 0, "virt_addr");
          virtAddr->setAlignment(4);                    

          Module *M = F.getParent();

          Constant *c = M->getOrInsertFunction("open",
              IntegerType::get(F.getContext(),32),
              PointerType::get(Type::getInt8PtrTy(F.getContext(), 8),8),
              IntegerType::get(F.getContext(),32), NULL);
          Function *open = cast<Function>(c);

          //ConstantInt *a = ConstantInt::get(M->getContext(), APInt(32, 9437184));

          IRBuilder<> builder(inst);
          Value *strPtr = builder.CreateGlobalStringPtr("/dev/mem", ".str");

          ConstantInt *a = builder.getInt32(9437184);
          //CallInst *openRet = builder.CreateCall2(open, strPtr, a, "open");

          builder.CreateCall2(open, strPtr, a, "open");
        }
        errs() << *inst <<"\n"; 
      }
    }   
    return false;
  }
};

}



char fun_insert::ID=0;
static RegisterPass<fun_insert> 
X("fun_insert", "Insert Function Test", false, false);

谢谢你的帮助!


12991
2018-03-20 14:31


起源



答案:


我相信我已经解决了这个问题。问题确实在于函数声明和调用。我调整了代码如下:

Constant *c = M->getOrInsertFunction("open", 
    FunctionType::getInt32Ty(F.getContext()), 
    Type::getInt8PtrTy(F.getContext()), 
    Type::getInt32Ty(F.getContext()), 
    NULL);
Function *open = cast<Function>(c);

IRBuilder<> builder(inst);
Value *strPtr = builder.CreateGlobalStringPtr("/dev/mem", ".str");
ConstantInt *a = builder.getInt32(9437184);
builder.CreateCall2(open,strPtr,a);

9
2018-03-21 17:35



你是一个救生员。 - Ahmed Akhtar
它似乎不是 NULL 是必要的。实际上,使用null ptr会导致运行时崩溃。看起来这个函数之前使用C vararfs实现,但它不使用C ++变量模板。 - Dan M.


答案:


我相信我已经解决了这个问题。问题确实在于函数声明和调用。我调整了代码如下:

Constant *c = M->getOrInsertFunction("open", 
    FunctionType::getInt32Ty(F.getContext()), 
    Type::getInt8PtrTy(F.getContext()), 
    Type::getInt32Ty(F.getContext()), 
    NULL);
Function *open = cast<Function>(c);

IRBuilder<> builder(inst);
Value *strPtr = builder.CreateGlobalStringPtr("/dev/mem", ".str");
ConstantInt *a = builder.getInt32(9437184);
builder.CreateCall2(open,strPtr,a);

9
2018-03-21 17:35



你是一个救生员。 - Ahmed Akhtar
它似乎不是 NULL 是必要的。实际上,使用null ptr会导致运行时崩溃。看起来这个函数之前使用C vararfs实现,但它不使用C ++变量模板。 - Dan M.