参考书:《Getting Started with LLVM Core Libraries》
书上这一部分有点out了,我就参考官网的文档:
http://llvm.org/docs/WritingAnLLVMPass.html#introduction-what-is-a-pass
一、创建源代码文件 lib/Transforms/FnArgCnt/FnArgCnt.cpp
#include "llvm/IR/Function.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/BasicBlock.h"
#include "llvm/IR/Instructions.h"
#include "llvm/Pass.h"
#include "llvm/Support/raw_ostream.h"
using namespace llvm;
namespace {
struct FnArgCnt : public FunctionPass {
static char ID;
FnArgCnt() : FunctionPass(ID) {
}
virtual bool runOnFunction(Function &F) {
errs() << "FnArgCnt --- ";
errs() << F.getName() << "\n";
for (auto& B : F) {
for (auto& I : B) {
if(CallInst* call_inst = dyn_cast<CallInst>(&I)) {
Function* fn = call_inst->getCalledFunction();
StringRef fn_name = fn->getName();
errs() << fn_name << " : " << call_inst->getArgOperand(0) << "(getArgOperand)\n";
for(auto arg = fn->arg_begin(); arg != fn->arg_end(); ++arg) {
if(auto* ci = dyn_cast<ConstantInt>(arg))
errs() << ci->getValue() << "(getValue)\n";
errs() << *arg << "\n";
}
}
}
}
return false;
}
};
}
char FnArgCnt::ID = 0;
static RegisterPass<FnArgCnt> X("fnargcnt", "Function Argument Count Pass", false, false);
- 区别于官网给的hello,我新增了一个for循环获取函数参数,网上找到的试了试;
二、创建 lib/Transforms/FnArgCnt/CMakeLists.txt
add_llvm_library( LLVMFnArgCnt MODULE BUILDTREE_ONLY
FnArgCnt.cpp
DEPENDS
intrinsics_gen
PLUGIN_TOOL
opt
)
三、添加依赖 lib/Transforms/CMakeLists.txt:
- 新增一行代码如下:
add_subdirectory(FnArgCnt)
四、构建运行
和构建llvm的步骤一样,这次速度会很快,只会重新构建我们新添加的一个库
构建完成会生成新的动态库 lib/LLVMFnArgCnt.dylib使用opt加载测试:
// 加载运行
opt -load lib/LLVMHello.so -hello < hello.bc > /dev/null
// 查看help命令
opt -load lib/LLVMFnArgCnt.dylib -help
-
命令行输出如下:
image.png -
这里可以看到我们新增的参数:
image.png