一.文件解析(链接)过程
- 汇编器将汇编文件xxx.s编译成可重定位目标文件
- 目标文件由若干个Section组成,咱们在汇编程序中声明的.section会成为目标文件中的Section,此外汇编器还会自动添加一些Section(好比符号表)。
- 链接器将多个可重定位文件翻译成可执行目标文件
- 把目标文件中的Section(节)合并成几个Segment(段)。
TIPS: 例如将swap.o 和main.o 翻译成可执行文件P: ld -o P swap.o main.o编程
二.目标文件
- 在编译过程当中有多种文件,汇编和链接部分有三种文件(ELF文件)
-
- 可重定位目标文件: 包涵二进制代码和数据。其做用:在编译时与其它可重定位目标文件合并起来,建立一个可执行目标文件。
- 和可执行文件区别:自包含当前文件的符号解析,而且符号都没有实际的虚拟地址
-
- 可执行文件: 包含二进制代码和数据。做用:可用被直接拷贝到存储器并执行.
-
- 共享目标文件: 一种特殊类型的可重定位目标文件。做用:加载或者运行时呗动态地加载到存储器并连接。
-
三.汇编器
- 这个文件是汇编器编译单个文件生成的(xxx.o)文件,可重定位目标文件(ELF格式).下面是各section
- .text: 已编译程序的机器代码
- .rodata: 只读数据,好比printf语句中的格式串和开关语句的跳转表
- .data: 已初始化的全局C变量。局部变保存在栈中.
存放具体数据
- .bss: 未初始化的全局C变量,不占空间,仅仅是一个占位符。目标文件格式区分初始化和未初始uabianl是为了空间效率。
- .symtab: 一个符号表。存放在程序全部符号 (
函数/变量
) 的符号名、section号、地址、约束。约束信息:global、local这种限定
- .rel.text: 链接时.text 中须要修改地址的函数。
- .rel.data:链接时.data 中须要修改地址的变量。
- debug: 一个调试符号表
- line: 原始C源程序中的行号和.text节中机器指令之间的映射。
- .strtab: 一个字符串表
四.连接器
-
1.连接的做用的过程函数
- 编译时:将源代码翻译成机器代码
- 加载时: 程序被夹在器加载到存储器并执行
- 运行时:由程序执行
-
2.特色翻译
- 理解连接将帮助你构造大型程序。
- 理解链接将帮助你避免一些危险的编译错误
- 理解链接将帮助你理解语言的做用域规则是如何实现的。
- 理解链接将帮助你理解语其它重要的系统概念
- 理解链接将使你可以利用共享库
-
3.编译时的做用debug
- 符号解析: 汇编器生成的是从地址0开始的代码和数据节,链接器将每一个符号引用恰好和一个符号定义联系起来。将多个文件的全局变量和函数(默认全局)、static静态变量和static函数与
引用
,关联起来。若是有重复,则经过规则肯定引用的惟一性 - 重定位:
- 汇编器:生成的是从地址0开始的代码和数据节。
- 链接器:把每一个符号与一个存储器位置联系起来,而后修改全部对这些符号的引用,使它们指向这个存储器的位置,从而重定位这些字节。
- 就是给全局变量和函数(默认全局)、static静态变量和static函数分配地址
- 符号解析: 汇编器生成的是从地址0开始的代码和数据节,链接器将每一个符号引用恰好和一个符号定义联系起来。将多个文件的全局变量和函数(默认全局)、static静态变量和static函数与
-
4.符号和符号表调试
- 由模块m (文件m) 定义能被其它模块引用的全局符号
- 有其它模块定义能被模块m (文件m) 引用的全局符号
- 只被模块m (文件m) 定义和引用的本地符号:static 变量(全局/本地)和函数
-
5.符号解析规则code
- 将每一个引用与它的定义文件(可重定位目标文件)的符号表中的一个肯定的符号联系起来。
- 就是将引用符号替换成定义的虚拟地址空间中的地址(该地址记录在定义文件的符号表中)
- 将每一个引用与它的定义文件(可重定位目标文件)的符号表中的一个肯定的符号联系起来。
-
6.解析全局符号规则ip
- 不容许多个强符号。直接被初始化值的全局变量,不能同名定义多个
- 若是有一个强符号和多个弱符号,那么选强符号
- 若是有多个弱符号,那么从这些弱符号中任选一个
- tips:强符号:被初始化的值的全局变量或函数;弱符号
-
7.与静态库链接内存
- gcc main.c /usr/lib/libm.a /usr/lib/libc.a
-
8.解析静态库的引用作用域
- 三个集合:
- 1 可重定位目标文件E,会被合并形参可执行文件
- 2 引用了,可是还没有定义的符号集合U
- 3 前面输入文件已经定义的符号D
- 规则
- 先扫描符号到U
- 将定义了的符号(可能现阶段才刚刚扫描一部分)存放到D,未定义的存放到E
- 最后合并E中的目标文件,从而构建输出的可执行文件.
- 三个集合:
-
9.可重定位字符串
-
一旦链接器完成了符号解析这一步,它就把每一个符号引用和肯定的一个符号定义联系起来了
-
重定位节和符号定义:链接器将全部相同类型的节合并为同一类型的新的聚合节(段),并运行时的存储器地址赋给新的聚合节(段)。
虚拟内存是以页为单位加载的,同一页必须相同的读写修改权限,一段能够多个页
-
重定位节中的符号引用:链接器修改代码节和数据节中对每一个符号的引用,将他们指向正确的运行时地址。
生成可执行目标文件
-
-
10.可执行目标文件
ELF的格式的可执行目标文件,带有地址的聚合文件,可加载到系统中