操作系统课程2

 

image

image

image

 

 

 

image

 

 

image

 

image

 

 

image

 

image

 

image

 

 

image

 

下面是将 GCC 编译流程拆解到较细粒度后的表格版,便于查阅和排障。

阶段子步骤组件输入输出核心工作
1 参数解析 gcc Driver 命令行 内部配置 识别语言类型、目标架构、优化等级
2 编译任务调度 gcc Driver 参数配置 cc1/as/ld调用链 决定调用哪些后端程序
3 预处理 cpp C源码 预处理源码(.i) 展开宏、处理#include、条件编译
4 词法分析(Lexer) cc1 字符流 Token流 关键字、标识符、常量识别
5 语法分析(Parser) cc1 Token流 AST 构建抽象语法树
6 语义分析 cc1 AST Annotated AST 类型检查、作用域检查
7 AST Lowering cc1 AST GENERIC Tree GCC内部树结构转换
8 GIMPLE生成 cc1 GENERIC GIMPLE SSA 转换为三地址码
9 SSA构建 cc1 GIMPLE SSA GIMPLE 插入PHI节点
10 常量传播 Optimizer SSA 优化SSA 编译期计算常量
11 Copy Propagation Optimizer SSA 优化SSA 变量替换
12 Dead Code Elimination Optimizer SSA 优化SSA 删除无用代码
13 Value Range Analysis Optimizer SSA 优化SSA 推断变量范围
14 Function Inline Optimizer SSA 优化SSA 函数内联
15 Loop Optimization Optimizer SSA 优化SSA 循环展开、融合
16 Vectorization Optimizer SSA SIMD代码 自动SIMD化
17 RTL生成 Backend SSA RTL 面向目标架构
18 指令选择 Backend RTL RTL 选择CPU指令
19 寄存器活跃分析 Backend RTL 活跃区间 构建干涉图
20 寄存器分配 Backend RTL RTL Graph Coloring
21 Spill处理 Backend RTL RTL 溢出到栈
22 指令调度 Backend RTL RTL 优化流水线
23 Peephole优化 Backend RTL RTL 局部替换
24 汇编生成 Backend RTL .s 输出汇编代码
25 汇编解析 as .s AST 解析助记符
26 指令编码 as 汇编指令 机器码 Opcode编码
27 符号生成 as 汇编 Symbol Table 记录符号
28 重定位生成 as 外部引用 Relocation 生成.rela节
29 ELF目标文件封装 as 机器码 .o 生成ELF
30 读取目标文件 ld .o/.a 内存映像 加载所有输入
31 Section合并 ld 多个.o 合并节区 .text/.data合并
32 Symbol Resolution ld 符号表 全局符号表 解析引用
33 地址分配 ld 节区 虚拟地址 分配最终地址
34 Relocation Fixup ld 重定位表 已修正机器码 地址回填
35 GOT生成 ld 动态符号 .got 全局偏移表
36 PLT生成 ld 动态函数 .plt 延迟绑定
37 crt对象链接 ld crt1.o等 启动代码 _start入口
38 Segment布局 ld Sections Segments ELF Program Header
39 ELF Header生成 ld 所有数据 ELF Header 文件头
40 输出可执行文件 ld ELF映像 a.out 最终程序

Linux ELF视角

最终形成的 ELF 大致如下:

ELF
├── ELF Header
├── Program Header Table
│
├── LOAD Segment(R-X)
│   ├── .text
│   ├── .plt
│   └── .rodata
│
├── LOAD Segment(RW-)
│   ├── .data
│   ├── .got
│   ├── .got.plt
│   └── .bss
│
├── .symtab
├── .strtab
├── .rela.text
├── .rela.plt
└── Section Header Table

GCC 实际调用链

执行:

gcc -O2 main.c -o main

实际近似于:

cpp main.c > main.i

cc1 main.i -O2 -o main.s

as main.s -o main.o

collect2 \
    crt1.o crti.o crtbegin.o \
    main.o \
    -lc \
    crtend.o crtn.o \
    -o main

其中:

gcc
 ├── cpp
 ├── cc1
 ├── as
 └── collect2
        └── ld

SRE/内核排障最常关注的位置

问题类型关注阶段
宏展开异常 cpp
编译报语法错误 Lexer/Parser
类型错误 Semantic Analysis
O0正常 O2异常 GIMPLE优化
CPU指令异常 RTL/Instruction Selection
符号找不到 Symbol Resolution
multiple definition Symbol Resolution
relocation truncated Relocation
undefined reference Relocation
动态库加载失败 GOT/PLT
程序入口异常 crt/_start
段错误 Segment Layout
ASLR相关问题 ELF Loader

对于做内核、Ceph、Kubernetes、存储或网络方向的 SRE,最值得深入的是:

  1. GIMPLE SSA 优化机制(为什么 O2/O3 会引入诡异 Bug)

  2. ELF 重定位机制(Relocation)

  3. GOT/PLT 动态链接原理

  4. _start → __libc_start_main → main 启动链路

  5. Linux Loader 如何 mmap ELF 到进程地址空间

这五部分直接对应生产环境中最常见的 coredump、符号解析、动态库和性能问题。

posted on 2026-07-12 17:49  小镇-做题家  阅读(2)  评论(0)    收藏  举报

导航