Я пишу LLVM
пропуск на инструмент C
исходной программы. Я хочу вставить вызов функции перед каждой инструкцией ветвления, которая вызывает внешнюю функцию, например:
void print(int x){
printf("x = %d\n", x);
return;
}
Я хочу связать эту внешнюю функцию с C
исходным кодом с помощью инструмента llvm-link
, а затем обработать код с помощью инструмента opt
.
Этот шаг, который я реализовал, выглядит следующим образом:
#include "llvm/Pass.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/Function.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/IR/Type.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/Instruction.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/IR/IRBuilder.h"
#include <vector>
using namespace llvm;
namespace{
struct ir_instrumentation : public ModulePass{
static char ID;
Function *monitor;
ir_instrumentation() : ModulePass(ID) {}
virtual bool runOnModule(Module &M)
{
std::vector<Type *> args;
args.push_back(Type::getInt32Ty(M.getContext()));
ArrayRef<Type*> argsRef(args);
FunctionType *FT = FunctionType::get(Type::getVoidTy(M.getContext()), args, false);
Constant* myFunc = M.getOrInsertFunction("print", FT, NULL);
minitor = cast<Function>(myFunc);
for(Module::iterator F = M.begin(), E = M.end(); F!= E; ++F)
{
for(Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB)
{
for(BasicBlock::iterator BI = BB->begin(), BE = BB->end(); BI != BE; ++BI)
{
if(isa<BranchInst>(&(*BI)) )
{
errs() << "found a brach instruction!\n";
ArrayRef< Value* > arguments(ConstantInt::get(Type::getInt32Ty(M.getContext()), 5, true));
Instruction *newInst = CallInst::Create(monitor, arguments, "");
BB->getInstList().insert(BI, newInst);
errs() << "Inserted the function!\n";
}
}
}
}
return true;
}
};
char ir_instrumentation::ID = 0;
static RegisterPass<ir_instrumentation> X("ir-instrumentation", "LLVM IR Instrumentation Pass");
}
LLVM
настроен и построен нормально с этим проходом, но когда я использую opt
, я получаю это error
:
opt: /llvm/lib/IR/Type.cpp:281:
llvm :: FunctionType :: FunctionType (llvm :: Type *, llvm :: ArrayRef, bool):
Утверждение `isValidReturnType (Result) &&" неверный тип возврата для функции "'не выполнено.
Я думаю, что проблема в чем-то вроде несоответствия между объявленным мной типом функции и внешней функцией (например, контекстом).
LLVM версия: LLVM версия 7.0.0svn
До сих пор я не решил проблему.
Спасибо