文章目录
  1. 空间与地址分配
  2. 符号解析与重定位
    1. 重定位
    2. 指令修正方式
  3. BFD库

空间与地址分配

链接器获得所有输入目标文件的段长度,将每种段合并,计算出输出文件中各个段合并后的长度与位置,并建立映射关系。

符号解析与重定位

链接器将目标文件合并后,根据合并文件中的段的数据、重定位信息进行符号解析与重定位,调整代码中的地址。

重定位

目标文件中每个需要重定位的段都有一个对应的重定位段。例如,如果代码段需要重定位,则目标文件中会有一个.rela.text段,重定位表是所有重定位段的统称。使用objdump工具来查看目标文件的重定位表。

1
objdump -r simple_section.o

重定位表的每一项的结构定义如下。

1
2
3
4
typedef struct {
Elf32_Addr r_offset;
Elf32_Word r_info;
}
  • r_offset。重定位入口的偏移。对于可重定位文件来说,r_offset为该重定位入口所要修正的位置的第一个字节相对于段起始的偏移。对于可执行文件或共享对象来说,r_offset是该重定位入口所要修正的位置的第一个字节的虚拟地址。
  • r_info。重定位入口的类型与符号。低8位表示重定位入口的类型,高24位表示重定位入口的符号在符号表中的下标。

指令修正方式

重定位入口的类型有两种:绝对近址32位寻址与相对近址32位寻址,不同的重定位入口类型的指令修正方式也不同。记

A为保存在修正位置的值

P为被修正的位置

S为符号的实际地址

则绝对近址32位寻址的修正方法为S+A,相对近址32位寻址的修正方法为S+A-P。

BFD库

不同的软硬件平台导致了不同的目标文件格式不同,为了使编译器能够统一地处理这些目标文件,BFD库提供一个统一的接口来处理不同的目标文件格式。