空间与地址的分配
静态链接的目标是将多个目标文件(.o)链接在一起,形成可执行文件。可执行文件中的数据段与代码段由各个目标文件合并而来。
(1)按序叠加
将所有的目标文件的数据端代码段按照顺序叠加在一起,缺点是造成由成千上百个零散的段,这样非常浪费空间,因为每个段都有一定的地址和空间对其要求。比如x86中,如果段中只有一个字节也要占用一个页,也就是4096字节。这样会造成大量的内存空间的内部碎片。
(2)相似段合并
这个方法是要把所有目标文件相同的段进行合并,比如a.o与b.o文件的.text段进行合并,.bss在目标文件中不占用空间但是在装载时占用虚拟空间,所以在合并.bss段时也要为.bss分配虚拟空间,但是对于.bss来说只在虚拟空间中有意义在文件中并没有实际内容。但是对于.text段与.data段在文件中与虚拟空间中都要占有空间。
现在链接器空间分配策略基本上都采用第二种策略,其中分两步:
(1)空间与地址分配
扫描所有输入的目标文件,获得他们各个段的长度、属性和位置。并肩输入目标文件中所有的符号定义和符号引用收集起来,统一放到一个符号表中。
(2)符号解析和重定位
使用第一步中收集到的信息,读取输入文件中段的数据、重定位信息。并且进行符号解析与重定位、调整代码中的的地址。链接前后的程序使用的地址已经是虚拟空间地址了。
符号解析:在链接器扫描完所有输入文件之后,所有未定义的的符号都应该在全局符号表中找到,否则链接器就会报符号未定义的错误。