LLVM学习之基础知识

介绍:

学习LLVM与代码混淆技术课程总结出来的经验,希望能够帮助到大家理解。

1、我们首先学会LLVM的基础知识

2、如何搭建LLVM的环境

3、编译一个Hello world

4、LLVM IR基本语法

LLVM搭建环境:

Ubuntu 20.04.3

LLVM 12.0.1

Cmake 3.21.1(项目管理工具)

Cmake注意事项:

刚装完系统要检查cmake是否安装成功,输入:cmake -version

1、LLVM简介

1、1  什么是LLVM

    LLVM项目是模块化、可重用的编译器以及工具链技术的集合。也可以把它理解为一个编译器。

 

1、2  GCC传统编译器架构

    传统编译器都是分为三个阶段:前端(词法分析、语法分析、语义分析、生成中间代码)、优化(中间代码优化)和后端(生成机器码)

     我们发现GCC的前端和后端没有分开的,当gcc需要支持一门新的语言或则平台则会变得非常困难。

1、3  LLVM编译器架构

    通过这种设计,移植编译器以支持新的源代码 语言(例如:Algol 或 BASIC)需要实现一个新的前端, 但是可以重用现有的优化器和后端。

1、4  Clang和LLVM的关系

     LLVM整体架构,前端用的是clang,广义的LLVM是指整个LLVM架构,一般狭义的LLVM指的是LLVM后端(包含代码优化和目标代码生成)。

源代码(c/c++)经过clang--> 中间代码(经过一系列的优化,优化用的是Pass) --> 机器码

2、搭建环境

2、1 下载 LLVM-Core 和 Clang 源代码

llvm-12.0.1.src.tar.xz

clang-12.0.1.src.tar.xz

然后解包后存放路径如下,并把文件改成llvm和clang

        

2、2  编译LLVM项目

还是在同一文件夹内创建build.sh 文件,内容如下:

cd build

cmake -G "Unix Makefiles" -DLLVM_ENABLE_PROJECTS="clang" \

-DCMAKE_BUILD_TYPE=Release -DLLVM_TARGETS_TO_BUILD="X86" \

-DBUILD_SHARED_LIBS=On ../llvm

make

make install

cmake 参数解释:

-G “Unix Makefiles”:生成Unix下的Makefile

-DLLVM_ENABLE_PROJECTS=“clang”:除了 LLVM Core 外,还需要编译的子项目。

-DLLVM_BUILD_TYPE=Release:在cmake里,有四种编译模式:Debug, Release,

RelWithDebInfo, 和MinSizeRel。使用 Release 模式编译会节省很多空间。

-DLLVM_TARGETS_TO_BUILD=“X86”:默认是ALL,选择X86可节约很多编译时间。

-DBUILD_SHARED_LIBS=On:指定动态链接 LLVM 的库,可以节省空间。

make install 指令是将编译好的二进制文件和头文件等安装到本机的/usr/local/bin

和/usr/local/include 目录,方便后续使用。

执行build.sh 文件自动安装和编译,编译时长从十多分钟到数小时,具体时间由机器性能决定。

输入clang -v确认编译和安装是否完成:

并且在build生成对应的文件

3、编写个Hello World测试

代码如下:

#include <cstdio>

int main(int argcchar *argv[])

    printf("Hello World...\n");

    return 0;

}

LLVM IR主要有三种格式:一种是在内存中的编译中间语言;一种是硬盘上存储的二进制中间语言(以.bc结尾),最后一种是可读的中间格式(以.ll结尾)。这三种中间格式是完全相等的。

clang -S -emit-llvm TestProgram.cpp -o TestProgram.ll

 clang -c -emit-llvm TestProgram.cpp -o TestProgram.bc

 clang TestProgram.ll -o TestProgram_orig

4、LLVM IR基本语法

我们拿前面的例子反汇编出来的.II文件来阅读

LLVM IR中的标识符有两种基本类型:全局标识符(以@开头)和局部标识符(以%开头)

6行是定义了一个全局变量字符串

10~12行分别分配3个局部变量%3、%4、%5其中i32是所占位数,后面align 4是对齐,这就是栈分配的局部变量

 13~15行分别是填充分配的局部变量内容

16行是调用call,其中@.str是全局变量,在最前面可以开到这个全局变量字符串的定义

17行是ret返回

  • 0
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值