编写第一个llvm pass
llvm pass既可以在源码目录编译,也可以在任务其他目录编译。用到的源码为 9.0
一:在源码目录编译
在 llvm/lib/Transforms的CMakeLists.txt中添加
add_subdirectory(MyPass)
然后创建目录 llvm/lib/Transforms/MyPass
创建文件:
llvm/lib/Transforms/MyPass/
|-- CMakeLists.txt
`-- MyPass.cpp
CMakeLists.txt内容如下
add_library( LLVMMyPass MODULE
MyPass.cpp
)
# Use C++11 to compile our pass (i.e., supply -std=c++11).
target_compile_features(LLVMMyPass PRIVATE cxx_range_for cxx_auto_type)
# LLVM is (typically) built with no C++ RTTI. We need to match that;
# otherwise, we'll get linker errors about missing RTTI data.
set_target_properties(LLVMMyPass PROPERTIES
COMPILE_FLAGS "-fno-rtti"
)
MyPass.cpp内容
#include "llvm/Pass.h"
#include "llvm/IR/Function.h"
#include "llvm/Support/raw_ostream.h"
using namespace llvm;
namespace {
struct MyPass : public FunctionPass {
static char ID;
MyPass() : FunctionPass(ID) {}
bool runOnFunction(Function &F) override {
errs() << "MyPass:";
errs().write_escaped(F.getName()) << '\n';
return false;
}
};
}
char MyPass::ID = 0;
static RegisterPass X("myPass", "Hello MyPass", false, false);
编译
cmake -G "Unix Makefiles" ../llvm/
make
运行
opt -load ./lib/libLLVMMyPass.so -myPass hello.bc
其中 hello.bc 是从http://hello.cc文件编译而来,http://hello.cc内容
#include
using namespace std;
int main(int argc, char* argv[]) {
cout << "hello" << endl;
return 0;
}
编译命令:
clang -emit-llvm -c hello.cc
参考:
https://www.zhihu.com/question/47631469
https://github.com/sampsyo/llvm-pass-skeleton/tree/master/skeleton
二: 在任意目录编译
创建目录 pass
把前面的MyPass.cpp拷贝到pass目录,执行编译命令:
clang++ -c MyPass.cpp `llvm-config --cxxflags`
此时,会生成文件 MyPass.o,再次执行命令:
clang++ -shared -o MyPass.so MyPass.o `llvm-config --ldflags`
生成了 MyPass.so,运行
opt -load ./MyPass.so -myPass ../hello.bc
参考:
https://stackoverflow.com/questions/22007458/how-to-create-you-own-pass-in-llvm
Comments