使用的编译环境:
Ubuntu16.04,LLVM3.6.0,GCC5.3.1
在编写Pass之前首先要编译LLVM源码,具体编译方法在之前的帖子中有介绍。
下面编写一个打印函数名的Pass
1.在llvm\lib\Transforms\目录下创建FunctionName目录
2.在llvm\lib\Transforms\FunctionName\目录下创建CMakeLists.txt文件,并在CMakeLists.txt中增加如下内容:
if( NOT LLVM_REQUIRES_RTTI )
if( NOT LLVM_REQUIRES_EH )
set(LLVM_EXPORTED_SYMBOL_FILE ${CMAKE_CURRENT_SOURCE_DIR}/FunctionName.exports)
endif()
endif()
if(WIN32 OR CYGWIN)
set(LLVM_LINK_COMPONENTS Core Support)
endif()
add_llvm_loadable_module( FunctionName
FunctionName.cpp
)
3.在llvm\lib\Transforms\FunctionName\目录下创建Makefile文件,并在Makefile中增加如下内容:
LEVEL = ../../..
LIBRARYNAME = FunctionName
LOADABLE_MODULE = 1
USEDLIBS =
ifneq ($(REQUIRES_RTTI), 1)
ifneq ($(REQUIRES_EH), 1)
EXPORTED_SYMBOL_FILE = $(PROJ_SRC_DIR)/FunctionName.exports
endif
endif
include $(LEVEL)/Makefile.common
4.在llvm\lib\Transforms\FunctionName\目录下创建FunctionName.exports文件,这个文件内容为空即可
5.在llvm\lib\Transforms\FunctionName\目录下创建FunctionName.cpp文件,并在FunctionName.cpp中增加如下代码:
#include "llvm/Pass.h"
#include "llvm/IR/Function.h"
#include "llvm/Support/raw_ostream.h"
using namespace llvm;
namespace {
struct Test : public FunctionPass {
static char ID;
Test() : FunctionPass(ID) { ; }
virtual bool runOnFunction(Function &function) {
errs() << "Function name:";
errs().write_escaped(function.getName()) << "\n";
return false;
}
};
}
char Test::ID = 0;
static RegisterPass<Test> X("function-name", "FunctionName.", false, false);
6.在llvm\lib\Transforms\CMakeLists.txt中增加子目录
7.编译(输出在llvm/build/lib/FunctionName.so)
Terminal command |
---|
$ cd llvm/build |
$ make |
8.测试
Terminal command |
---|
$ opt -load ./FunctionName.so -function-name demo.ll |