LLVM Pass 环境搭建与调试

2019/07/02 LLVM

1、下载和编译LLVM LLVM 下载地址:推荐使用git

git clone https://github.com/llvm/llvm-project.git

2、检查是否安装cmake

$ cmake -version
cmake version 3.14.5

CMake suite maintained and supported by Kitware (kitware.com/cmake).

如果没有 brew install cmake

网上教程很多。

3、在llvm 根目录下创建build目录

cd llvm-project
mkdir build
cd build
//这是clang 和llvm 都编译
cmake -DLLVM_ENABLE_PROJECTS=clang -G Xcode ../llvm
//只编译llvm
//cmake -G Xcode -DLLVM_ENABLE_ASSERTIONS=On -DCMAKE_BUILD_TYPE=Debug ../

更多参考:Getting Started with the LLVM System

执行完以后,可以看到llvm 目录下多了一个xcode工程,点击打开,创建所有scheme

然后使用xcode 进行编译,编译过程比较慢,大概30分钟就OK

2、编写第一个Pass代码

我们编写第一个 Pass 的功能很简单,只是输出程序中的每个方法名,操作步骤如下:

(1)在lib/Transform 目录下新建一个文件夹,文件夹结构可以惨遭Transform 目录下的Hello目录创建。我直接讲hello 复制一份,然后在里边更改: 目录结构如图:

(2)修改FirstPass.cpp ,代码如下:

//导入头文件
#include "llvm/ADT/Statistic.h"
#include "llvm/IR/Function.h"
#include "llvm/Pass.h"
#include "llvm/Support/raw_ostream.h"

using namespace llvm;  //指定所使用的 LLVM 命名空间

namespace {
    
    //定义 First 类继承自 FunctionPass
    struct First : public FunctionPass {
        static char ID; // Pass ID
        First() : FunctionPass(ID) {}
        
        //定义 runOnFunction 重载继承父类的抽象虚函数
        bool runOnFunction(Function &F) override {
            
            //打印每个函数的名字
            errs() << "First: ";
            errs().write_escaped(F.getName()) << '\n';
            return false;
        }
    };
}

char First::ID = 0;  //初始化 Pass ID

//最后注册 FirstPass, 指定命令行参数为 First
static RegisterPass <First>X("First", "First Pass");

(3)修改CMakeLists.txt 文件如下:

if( NOT LLVM_REQUIRES_RTTI )
  if( NOT LLVM_REQUIRES_EH )
    set(LLVM_EXPORTED_SYMBOL_FILE ${CMAKE_CURRENT_SOURCE_DIR}/FirstPass.exports)
  endif()
endif()

if(WIN32 OR CYGWIN)
  set(LLVM_LINK_COMPONENTS Core Support)
endif()

add_llvm_library( LLVMFirstPass MODULE BUILDTREE_ONLY
  FirstPass.cpp
 
  DEPENDS
  intrinsics_gen
  PLUGIN_TOOL
  opt
  )

(4)修改lib/Transform/CMakeLists.txt 如下: add_subdirectory(FirstPass)

最后xcode 中目录结构如下:

然后在xcode中选择all_build 点击编译,target 中就会出现FirstPass。或者使用命令行

cd build
cmake -G Xcode CMAKE_BUILD_TYPE="" Debug ../

最后编译:编译成功后会生成一个LLVMFirstPass.dylib 的动态库。

到这一步,只是编译成功了,接下来就是加载和调试。

3、我们写一段测试代码

(1)编写一段测试代码:

#include <stdio.h>
 
int test() {
 
        printf("test\n");
        return 0;
}
int main(){
 
        int num = 1;
        printf("main %d\n", num);
        test();
        return 0;
}
 

编译源文件 clang -emit-llvm -c test.c -o test.bc

(2)调试

如图所示:

成功,完美输出结果

另外,我在编译的时候遇到一个问题,当时编译的时候没有记录下来错误。最后查出来是因为xcode-select 设置不正确。将xcode-select 设置正确后,解决。

参考:

[1]:Getting Started: Building and Running Clang

[2]:开发和调试第一个-llvm-pass

Search

    Post Directory