美文网首页
LLVM 之 实战(一)

LLVM 之 实战(一)

作者: 脚踏实地的小C | 来源:发表于2020-03-17 17:46 被阅读0次

由于国内的网络限制,我们需要借助镜像下载LLVM的代码,这边推荐使用清华的镜像:https://mirror.tuna.tsinghua.edu.cn/help/llvm/

一、准备工作:
1.1 下载llvm项目

git clone https://mirrors.tuna.tsinghua.edu.cn/git/llvm/llvm.git

1.2 在llvm的 tools 目录下下载 Clang

cd llvm/tools
git clone https://mirrors.tuna.tsinghua.edu.cn/git/llvm/clang.git

1.3 在llvm的 projects 目录下下载 compiler-rt、libcxx、libcxxabi

cd ../projects
git clone https://mirrors.tuna.tsinghua.edu.cn/git/llvm/compiler-rt.g it
git clone https://mirrors.tuna.tsinghua.edu.cn/git/llvm/libcxx.git git clone https://mirrors.tuna.tsinghua.edu.cn/git/llvm/libcxxabi.git

1.4 在Clang的 tools 下安装 ertra 工具

cd ../tools/clang/tools
git clone https://mirrors.tuna.tsinghua.edu.cn/git/llvm/clang-tools-e xtra.git

二、编译LLVM工程
2.1 安装 Cmake

brew install cmake

2.2 cmake编译生成Xcode项目

mkdir build_xcode
cd build_xcode
cmake -G Xcode ../llvm

2.3 打开生成的工程,并选择 Manually Manage Schemes

创建Schemes.png

2.4 我们添加 clanglibclang,并一一编译

添加Schemes.png

三、创建Clang插件
3.1 在 llvm/tools/clang/tools 目录下新建插件 CHJPlugin

新建 CHJPlugin.png

3.2 修改 llvm/tools/clang/tools 目录下的 CMakeLists.text 文件,新增 add_clang_subdirectory(CHJPlugin)

修改CMakeLists.png

3.3 在 CHJPlugin 目录下新建一个名为 CHJPlugin.cpp 的文件和 CMakeLists.text 的文件,并在 CMakeLists.text 中写上

add_llvm_library( CHJPlugin MODULE BUILDTREE_ONLY
 CHJPlugin.cpp
)
CHJPlugin目录下添加文件.png

3.4 接下来就是利用 cmake 重新生成 Xcode 项目,在 build_xcodecmake -G Xcode ../llvm

build_xcode.png

四、一个简单插件 CHJPlugin.cpp 的实现:

#include <iostream>
#include "clang/AST/AST.h"
#include "clang/AST/DeclObjC.h"
#include "clang/AST/ASTConsumer.h"
#include "clang/ASTMatchers/ASTMatchers.h"
#include "clang/Frontend/CompilerInstance.h"
#include "clang/ASTMatchers/ASTMatchFinder.h"
#include "clang/Frontend/FrontendPluginRegistry.h"

using namespace clang;
using namespace std;
using namespace llvm;
using namespace clang::ast_matchers;

namespace CHJPlugin {
    //Cosumer :专门解析我们语法树中的节点
    class CHJCosumer : public ASTConsumer {
    public:
        //解析完一个顶级的声明就会来这里执行!
        bool HandleTopLevelDecl(DeclGroupRef D) {
            cout<<"正在解析..."<<endl;
            return true;
        }
        //解析完整个文件后调用
        void HandleTranslationUnit(ASTContext &Ctx) {
            cout<<"文件解析完毕!"<<endl;
        }
    };
    //继承PluginASTAction实现我们自定义的Action
    class CHJASTAction: public PluginASTAction{
    public:
        //直接 return 一个 true 就可以,不用管
        bool ParseArgs(const CompilerInstance &CI,
                       const std::vector<std::string> &arg){
            return true;
        }
        //自定义返回一个CHJCosumer
        unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI,
                                                              StringRef InFile){
            return unique_ptr<CHJCosumer>(new CHJCosumer);
        }
    };
}
//注册插件
static FrontendPluginRegistry::Add<CHJPlugin::CHJASTAction>
    X("CHJPlugin", "This is the description of the plugin");

自定义插件编码流程:

  • 注册插件 FrontendPluginRegistry::Add
  • 自定义一个 Action PluginASTAction
  • 实现 ParseArgs
  • 创建一个 Cosumer(CreateASTConsumer)
  • 自定义 Cosumer内容(class CHJCosumer : public * ASTConsumer)
  • 解析顶级节点HandleTopLevelDecl
  • 解析完实现 HandleTranslationUnit

将要被编译的.m:

int sum(int a);
int a;
int sum(int a) {
    int b = 10;
    return 10 + b;
}
int sum2(int a,int b) {
    int c = 10;
    return a + b + 10;
}

注意:这里面只有 4顶级(最外面的)节点

终端打印:

xxxx/clang(自己编译的clang文件路径) -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator13.1.sdk(SDK地址) -Xclang -load -Xclang xxx/CHJPlugin.dylib(自己的插件.dylib地址) -Xclang -add-plugin -Xclang CHJPlugin(插件名) -c xxxx.m(源码路径)
正在解析...
正在解析...
正在解析...
正在解析...
文件解析完毕!

格式为自己编译的clang文件路径 -isysroot SDK地址 -Xclang -load -Xclang 自己的插件.dylib地址 -Xclang -add-plugin -Xclang 插件名 -c 源码路径
注意点:当两个 -Xclang 出现的时候,是为了把处于中间的指令传给 link。如:-Xclang -load -Xclang 是为了把 load 传给 link

小结:

  1. Cosumer:专门解析我们语法树中的节点
  2. HandleTopLevelDecl:解析语法树中的 顶级 节点
  3. HandleTranslationUnit:解析完整个文件后执行
  4. AST:代表语法树

相关文章

  • LLVM 之 实战(一)

    由于国内的网络限制,我们需要借助镜像下载LLVM的代码,这边推荐使用清华的镜像:https://mirror.tu...

  • 逆向 - init

    book 汇编语言 LLVM CookBook 密码学 攻防实战 OS X 与 iOS 内核 iOS 应用安全 黑...

  • iOS 逆向 day 18 GCC LLVM Clang

    一、LLVM 1. 什么是 LLVM 官网:https://llvm.org/ The LLVM Project ...

  • iOS底层探索之LLVM(一)——初识LLVM

    1. 写在前面 现在出去面试,启动优化是绕不开的,到底我们的 APP 该如何去进行优化呢 ?在优化之前我们必须要先...

  • LLVM

    LLVM 什么是LLVM? 官网:https://llvm.org/ The LLVM Project is a ...

  • iOS_LLVM

    LLVM 官网:https://llvm.org/[https://llvm.org/] The LLVM Pro...

  • iOS逆向-day10:LLVM 编译器

    一、LLVM的简单介绍 1.1、什么是LLVM官网:https://llvm.org/LLVM官网解释:The L...

  • LLVM(1)LLVM了解

    一、什么是LLVM 1、官网:https://llvm.org/The LLVM Project is a col...

  • LLVM 工具

    llvm-dis llvm-dis 是一个反汇编工具,通过 LLVM 字节码文件(.bc)得到 LLVM 汇编文件...

  • LLVM 之 初探

    一、编译器概述 编译器就是说将高级语言 翻译 为低级语言的程序。 二、LLVM概述   LLVM 是 构架编译器 ...

网友评论

      本文标题:LLVM 之 实战(一)

      本文链接:https://www.haomeiwen.com/subject/guanshtx.html