目前,我有一个C ++代码,如下所示:
/*
* class declarations
*/
int main() {
Object1 obj;
obj->foo();
}
我想传递一个llvm函数,该函数插入一条指令使其看起来像这样:
/*
* class declarations
*/
int main() {
Object1 obj;
bar(&obj);
obj.foo();
}
当前,我可以检测到需要插入的位置。但是,插入bar()函数调用有点麻烦。
具体地说,在我的llvm传递中,我能够通过指令“ obj.foo();”获得对象“ obj”。但是,在创建函数之后,我很难将“ obj”的引用传递给函数bar()。
下面是我的函数传递:
bool runOnFunction(Function &F) {
for (auto &BB : F) {
for (auto &I : BB) {
if (I.getOpcode() == Instruction::Call || I.getOpcode() == Instruction::Invoke) {
/*
* few more filters to get the virtual function calls
*/
// Grabbing "obj" from "obj.foo();"
Value *currOperand = I.getOperand(0);
Type *currType = const_cast<Type*> (currOperand->getType());
// Inserting bar(&obj);
IRBuilder<> builder(F.getContext());
Type *result = Type::getVoidTy(F.getContext());
ArrayRef<Type*> params = {
PointerType::getUnqual(currType)
};
FunctionType *func_type = FunctionType::get(result, params, false);
FunctionCallee bar = I.getModule()->getOrInsertFunction("bar", func_type);
ArrayRef<Value*> args = {
// I think this line below is wrong
builder.CreateIntToPtr(currOperand, currType)
};
builder.CreateCall(bar, args);
}
}
}
}
当前在builder.CreateCall(bar。args);处出错。并显示以下错误消息。
"Calling a function with a bad signature!" failed.
这使我相信我的“ args”变量是错误的。任何帮助,将不胜感激!
答案 0 :(得分:1)
好的,我已解决此问题。我将为所有在这个问题上苦苦挣扎的兄弟姐妹分享以下解决方案:
bool runOnFunction(Function &F) {
for (auto &BB : F) {
for (auto &I : BB) {
if (I.getOpcode() == Instruction::Call || I.getOpcode() == Instruction::Invoke) {
/*
* few more filters here to get the virtual function calls
*/
// Grabbing "obj" from "obj.foo();"
Value *currOperand = I.getOperand(0);
Type *currType = const_cast<Type*> (currOperand->getType());
// Inserting bar(&obj);
LLVMContext &ctx = F.getContext();
IRBuilder<> builder(ctx);
builder.SetInsertPoint(&I);
ArrayRef<Type*> params = {
currType->getPointerTo()
};
Type *result = Type::getVoidTy(ctx);
FunctionType *func_type = FunctionType::get(result, params, false);
FunctionCallee bar = I.getModule()->getOrInsertFunction("bar", func_type);
ArrayRef<Value*> args = {
builder.CreatePointerCast(currOperand, currType->getPointerTo())
};
builder.CreateCall(bar, args);
}
}
}
}