如何使用LLVM正确插入函数调用?
我试图设置一个过程,在main的开头插入几个全局变量和几个函数调用。但是,我认为我在正确设置函数描述方面存在问题。我的代码可以编译,但当我尝试运行pass时,会出现以下错误:如何使用LLVM正确插入函数调用?,llvm,Llvm,我试图设置一个过程,在main的开头插入几个全局变量和几个函数调用。但是,我认为我在正确设置函数描述方面存在问题。我的代码可以编译,但当我尝试运行pass时,会出现以下错误: void llvm::CallInst::init(llvm::Value*, llvm::ArrayRef<llvm::Value*>, const llvm::Twine&): Assertion `(Args.size() == FTy->getNumParams() ||
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.
void llvm::CallInst::init(llvm::Value*,llvm::ArrayRef,const llvm::Twine&):
断言`(Args.size()==FTy->getNumParams()| |(FTy->isVarArg()&&Args.size()>FTy-
>getNumParams())&&“调用签名错误的函数!”失败。
以下是我迄今为止编写的代码:
#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);
#包括“llvm/IR/Instructions.h”
#包括“llvm/Pass.h”
#包括“llvm/Support/InstIterator.h”
#包括“llvm/IR/Function.h”
#包括“llvm/Support/raw_ostream.h”
#包括“llvm/ADT/Statistic.h”
#包括“llvm/IR/IRBuilder.h”
#包括“llvm/IR/Value.h”
#包括“llvm/IR/GlobalValue.h”
#包括“llvm/IR/GlobalVariable.h”
#包括“llvm/IR/LLVMContext.h”
#包括“llvm/IR/Type.h”
#包括“llvm/IR/Module.h”
使用名称空间llvm;
名称空间{
结构乐趣插入:公共功能通行证{
静态字符ID;
fun_insert():FunctionPass(ID){}
虚拟布尔运行函数(函数&F){
如果(F.getName()=“main”){
对于(inst_迭代器I=inst_begin(F),E=inst_end(F);I!=E;++I){
指令*inst=&*I;
if(动态铸造(仪表)){
errs()getOrInsertFunction(“打开”,
IntegerType::get(F.getContext(),32),
PointerType::get(类型::getInt8PtrTy(F.getContext(),8),8),
IntegerType::get(F.getContext(),32),NULL);
功能*打开=铸造(c);
//ConstantInt*a=ConstantInt::get(M->getContext(),APInt(329437184));
建造商(inst);
Value*strprtr=builder.CreateGlobalStringPtr(“/dev/mem”,“.str”);
ConstantInt*a=builder.getInt32(9437184);
//CallInst*openRet=builder.CreateCall2(open,strprtr,a,“open”);
CreateCall2(open,strPtr,a,“open”);
}
errs()我相信我已经解决了这个问题。问题确实在于函数声明和调用。我对代码进行了如下调整:
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);
Constant*c=M->getOrInsertFunction(“打开”,
FunctionType::getInt32Ty(F.getContext()),
类型::getInt8PtrTy(F.getContext()),
类型::getInt32Ty(F.getContext()),
无效);
功能*打开=铸造(c);
建造商(inst);
Value*strprtr=builder.CreateGlobalStringPtr(“/dev/mem”,“.str”);
ConstantInt*a=builder.getInt32(9437184);
CreateCall2(open,strPtr,a);
您是一个救生员。它似乎不再需要 NULL//CUT>。实际上,使用NULTR PTR导致运行崩溃。看起来这个函数是用C VARARFS实现的,但它不是使用C++变量模板。