美文网首页selector
LLVM编译器架构

LLVM编译器架构

作者: conowen | 来源:发表于2021-04-14 16:16 被阅读0次

编译过程

传统编译过程一般分为以下步骤。

源代码(source code)→ 预处理器(preprocessor)→ 编译器(compiler)→ 汇编程序(assembler)→ 目标代码(object code)→ 链接器(linker)→ 可执行文件(executables)

其中预处理主要工作是宏定义的替换和头文件的引入

编译器

简单而言,编译器的设计一般分为三部分

传统编译器(compiler)的设计一般如下图所示


image.png

LLVM编译器设计如图所示

image.png
  • 前端 Frontend:前端的主要工作是解析源代码, 词法分析、语法分析、语义分析、检查源代码是否存在错误,然后构建抽象语法树(Abstract Syntax Tree AST)。
  • 优化器 Optimizer:负责优化代码,例如消除冗余。
  • 后端 Backend:将代码映射到目标指令集,生成机器代码。

LLVM

底层虚拟机(Low Level Virtual Machine),LLVM是一套编译器基础设施项目,以C++写成,包含一系列模块化的编译器组件和工具链,用来开发编译器前端和后端。优化各种语言写的程序在编译过程中环节,如编译时期、链接时期、运行时期以及闲置时期。

LLVM前端

Clang是LLVM编译器工具集的前端(front-end),属于LLVM项目中的一个子项目,它是基于LLVM架构图的轻量级编译器,Clang的现在已经取代GCC,负责C、C++、OC语言的编译。Clang主要工作是输出代码对应的抽象语法树(Abstract Syntax Tree, AST),并将代码编译成LLVM Bitcode。接着在后端(back-end)使用LLVM编译成平台相关的机器语言。

LLVM中间端

LLVM的核心是中间端表达式(Intermediate Representation,IR),一种类似汇编的底层语言。

LLVM后端

LLVM后端的主要工作是将LLVM中间端表达式(IR)转换成特定目标机器代码(object code),机器代码一般由机器代码或接近于机器语言的代码组成。即存放目标代码的计算机文件,它常被称作二进制文件(binaries)。目前LLVM支持输出多种后端指令集,包括X86、PowerPC、ARM以及SPARC等。目标文件包含着机器代码(可直接被CPU执行)以及代码在运行时使用的数据,如重定位信息,如用于链接或调试的程序符号(变量和函数的名字),此外还包括其他调试信息。目标文件是从源代码文件产生程序文件这一过程的中间产物。

LLVM链接器

LLD是LLVM项目中的链接器,替换GNU系统链接器。LLD把目标文件(.o文件和 .dyld .a)链接在一起来生成可执行文件或库文件(mach-o文件)。

Mach-O文件格式

Mach-O 是 iOS 可执行文件的格式,典型的 Mach-O 是主二进制和动态库。Mach-O 可以分为三部分:

  • Header
  • Load Commands
  • Data
image.png

Header 的最开始是 Magic Number,表示这是一个 Mach-O 文件,除此之外还包含一些 Flags,这些 flags 会影响 Mach-O 的解析。

Load Commands 存储 Mach-O 的布局信息,比如 Segment command 和 Data 中的 Segment/Section 是一一对应的。除了布局信息之外,还包含了依赖的动态库等启动 App 需要的信息。

Data 部分包含了实际的代码和数据,Data 被分割成很多个 Segment,每个 Segment 又被划分成很多个 Section,分别存放不同类型的数据。

标准的三个 Segment 是 TEXT,DATA,LINKEDIT,也支持自定义:

  • TEXT,代码段,只读可执行,存储函数的二进制代码(__text),常量字符串(__cstring),Objective C 的类/方法名等信息
  • DATA,数据段,读写,存储 Objective C 的字符串(__cfstring),以及运行时的元数据:class/protocol/method…
  • LINKEDIT,启动 App 需要的信息,如 bind & rebase 的地址,代码签名,符号表…

iTunes Connect 会对上传 Mach-O 的 TEXT 段进行加密,防止 IPA 下载下来就直接可以看到代码。这也就是为什么逆向里会有个概念叫做“砸壳”,砸的就是这一层 TEXT 段加密。iOS 13 对这个过程进行了优化,在博文中的page fault过程中,需要读取Page In 的时候不需要解密了。

参考文章
http://www.aosabook.org/en/llvm.html
抖音品质建设 - iOS启动优化《原理篇》

相关文章

  • iOS LLVM-Clang 浅谈

    LLVM概念 LLVM官网: https://llvm.org/ 编译器架构图:image Frontend:前端...

  • oc- APP编译过程以及启动过程

    简单介绍 - LLVM编译器 苹果使用的是LLVM编译器,LLVM架构设计的非常好,主要分为前端,中间,后端 Fr...

  • 30.iOS底层学习之LLVM初了解

    本篇提纲1、LLVM简介2、编译器的一些基础知识 1.LLVM简介 基本介绍 LLVM是架构编译器的框架系统,以c...

  • LLVM

    是模块化、可重用的编译器以及工具链技术的集合 广义的LLVM:整个LLVM架构狭义的LLVM:LLVM后端(代码优...

  • LLVM资料整理

    LLVM是模块化、可重用的编译器以及工具链技术的 GCC、LLVM、clang 传统的编译器架构:前端-优化器(中...

  • iOS-OC底层25:LLVM和自定义LLVM插件

    1.概念 1.LLVM?? LLVM????????是架构编译器(compiler)的框架系统,以c++编写而成,...

  • LLVM编译流程 & Clang插件开发

    本文主要是理解LLVM的编译流程以及clang插件的开发 LLVM LLVM是架构编译器的框架系统,以C++编写而...

  • iOS-底层原理:LLVM编译流程 & Clang插件开发

    本文主要是理解LLVM的编译流程以及clang插件的开发 LLVM LLVM是架构编译器的框架系统,以C++编写而...

  • iOS llvm-2

    本文主要是理解LLVM的编译流程以及clang插件的开发 LLVM LLVM是架构编译器的框架系统,以C++编写而...

  • 下载与编译LLVM和Clang

    最近写编译器,要用到LLVM,记录一下在Linux下编译和安装的过程。 准备 LLVM编译器架构的前端是Clang...

网友评论

    本文标题:LLVM编译器架构

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