链接
链接是将各种代码和数据片段收集并组合成为一个单一文件的过程,其可以发生在:
编译时
加载时
运行时
在现代系统中,链接是由链接器
自动执行的
静态链接
以一组可重定位目标文件和命令行参数作为输入,生成一个完全链接的、可以加载和运行的可执行目标文件作为输出
静态连接器
通过两个任务完成可执行文件的构造
- 符号解析:将每个符号的引用正好和每一个符号定义关联起来
- 重定位:通过把每个符号定义与一个内存位置关联起来,从而重定位这些节,然后修改所有对这些符号的引用,使得它们指向内存位置
目标文件
包含三种形式:
- 可重定位目标文件:包含二进制代码和数据,其形式可以在编译时与其他可重定位文件合并起来,创建一个可执行目标文件
- 可执行目标文件:包含二进制代码和数据,其形式可以被直接复制到内存并执行
- 共享目标文件:一种特殊类型的重定位目标文件,可以在加载或者运行时被动态的加载进内存并连接
可重定位目标文件
一个典型的ELF可重定位目标文件
如下:
- .text:已编译程序的机器码
- .rodata:只读数据
- .data:已初始化的全局和静态C变量
- .bss:未初始化的全局和静态C变量,以及所有被初始化为0的全局或静态变量
- .symtab:符号表,存放在程序中定义和引用函数和全局变量的信息
-
.rel.text:一个
.text
节中位置的列表,当链接器
把这个目标文件和其它文件组合时,需要修改这些位置 - .rel.data:被模块引用或定义的所有全局变量的重定位信息
- .debug:调试符号表
-
.line:原始C源程序中的行号和
.text
节中机器指令之间的映射 - .strtab:字符串表