第四章 静态链接
空间与地址分配
链接器获得所有输入目标文件的段长度,将每种段合并,计算出输出文件中各个段合并后的长度与位置,并建立映射关系。
符号解析与重定位
链接器将目标文件合并后,根据合并文件中的段的数据、重定位信息进行符号解析与重定位,调整代码中的地址。
重定位
目标文件中每个需要重定位的段都有一个对应的重定位段。例如,如果代码段需要重定位,则目标文件中会有一个.rela.text段,重定位表是所有重定位段的统称。使用objdump工具来查看目标文件的重定位表。
1 | objdump -r simple_section.o |
重定位表的每一项的结构定义如下。
1 | typedef struct { |
- r_offset。重定位入口的偏移。对于可重定位文件来说,r_offset为该重定位入口所要修正的位置的第一个字节相对于段起始的偏移。对于可执行文件或共享对象来说,r_offset是该重定位入口所要修正的位置的第一个字节的虚拟地址。
- r_info。重定位入口的类型与符号。低8位表示重定位入口的类型,高24位表示重定位入口的符号在符号表中的下标。
指令修正方式
重定位入口的类型有两种:绝对近址32位寻址与相对近址32位寻址,不同的重定位入口类型的指令修正方式也不同。记
A为保存在修正位置的值
P为被修正的位置
S为符号的实际地址
则绝对近址32位寻址的修正方法为S+A,相对近址32位寻址的修正方法为S+A-P。
BFD库
不同的软硬件平台导致了不同的目标文件格式不同,为了使编译器能够统一地处理这些目标文件,BFD库提供一个统一的接口来处理不同的目标文件格式。