(1)学习链接的意义
(2)源文件 -> 可执行文件
默认生成的可执行文件名为a.out
【预处理】
main.i 是一个ASCLL码的中间文件
【编译】
【汇编】
main.o 可重定位文件
【链接器构造可执行文件】
(3)可重定位目标文件
-c:只进行编译和汇编,不执行链接操作
查看main.o
【开头十六个字节的含义】
【section header table】
.test 存放函数
.data 存放已初始化的全局变量和静态变量
COMMON: 存放未初始化的全局变量
.bss 存放未初始化静态变量,初始化为0的全局变量和静态变量
【局部变量即不在.data中也不在.bss中,在栈中】
bss section 不占据实际的空间,仅仅是一个占位符
.rodata (read only)存放只读数据【eg. printf语句中的格式串,switch中的跳转表】
【其他section】
(4)符号
全局符号:由该模块定义,同时能被其他模块引用的全局符号
外部符号:被其他模块定义,同时被该模块引用的全局符号
局部符号:只能被该模块定义和引用的局部符号
【static:带有static属性的函数以及变量是不能被其他模块引用的】
(5)强符号和弱符号
(6)静态库
【archive是一组可重定位目标文件的集合】
【构造静态库】
(7)静态库解析过程
E:可重定位目标文件 => 在链接即将完成的时候,这个集合中的文件最终会被合并起来形成可执行文件【目标文件 】
U:引用了但是尚未定义的符号
D:存放输入文件中已定义的符号
目标文件 / 静态库文件
【文件的输入顺序十分重要】
(8)重定义
【第一步】
【第二步】
(9)重定义条目
功能:用来告诉链接器在合成可执行文件时应该如何修改这个引用
可重定义条目的结构体
offset: 被修改的引用的节偏移量
type: 根据type来修改新的引用
symbol: 表示被修改的引用是哪一个符号
addend: 常数;一些类型的重定位要使用它对被修改应用的值做偏移调整
(10)重定位相对引用
1. 链接器根据重定位条目计算出引用的运行时地址
2. 更新这个符号引用,使得它在运行时指向sum函数
(11)重定位绝对引用
【x86用的是小端法】
(12)可执行文件与可重定位目标文件的格式对比
(13)可执行目标文件
【程序运行时,可执行文件中的代码段和数据需要被加载到内存执行,符号表和调试信息等不会被加载到内存】
r:只读
w:可写
x:只执行
-:无权限
可执行程序prog的程序头部表
【程序头部表中描述了代码段(r-x)、数据段(rw-)与内存的映射关系】
对齐有要求
加载:将程序从磁盘复制到内存
(14)内存镜像
堆的生长方向:从低地址到高地址
(15)一些缺点
(16)动态链接共享库
共享库:可重定位目标文件(后缀为.so)
创建动态共享库
动态链接的过程
1. 将libc.so的代码和数据重定位到某个内存段
2. 重定位libvector.so中的代码和数据到另外一个内存段
3. 重定位prog2中由libc.so和libvector.so定义的符号引用
4. 重定位的操作完成后,动态链接器把控制权交给应用程序prog2
【优点】