对于链接器来说,整个链接过程中,它就是将几个输入目标文件加工后合成一个输出文件。
输出文件中的空间如何分配给输入文件
按序叠加
将输入的目标文件按照次序依次叠加起来。
缺点:在由很多输入文件的情况下,输出文件将会有很多零散的段。==》浪费很多空间,因为每个段都有一定的地址和空间对齐要求。
相似段合并
将相同性质的段合并到一起。
链接器为目标文件分配地址和空间中的“地址和空间”含义:
- 在输出的可执行文件中的空间
- 在装载后的虚拟地址中的虚拟地址空间
链接器空间分配策略
一般采用上述的第二种方法(相似段合并),使用这种方法的链接器一般采用**“两步链接”**的方式:
- 空间与地址分配
这一步链接器能够获得所有输入目标文件的段长度,并且将它们合并,计算出输出文件中各个段合并后的长度和位置,并建立映射关系。 - 符号解析和定位
这一步会使用第一步中收集到的信息,读取输入文件中段的数据、重定位信息,并且进行符号解析与重定位(核心)、调整代码中的地址等
VMA
- VMA:虚拟地址
- LMA:加载地址
链接后的程序中使用的地址是程序在进程中的虚拟地址,因此我们关心VMA和size,而忽略文件便宜。
操作系统的进程虚拟地址空间的分配规则
在Linux下,ELF可执行文件默认地址从0x08048000开始分配。
(之后的章节再深入学习)
符号地址的确定
计算各个符号的虚拟地址:
段首地址+符号相对于段的偏移值