符号重定位和段重定位

链接器的第一遍扫描将得出各个段的位置,并收集程序中所有关于全局符号与段的相对偏移量。一旦链接器决定了每个段的位置,它就需要相应的调整程序中存储的符号地址。

     调整段中的数据地址和使用绝对地址的指令地址。例如,如果一个指针指向位置100,但是段基地址被重定位为1000,那么这个指针就需要被调整到位置1100.

     调整程序中的段间引用,需要根据目标地址新的段地址进行重新计算并调整,相对地址的引用,则需要根据目标段地址以及引用者所在段的地址进行调整。

    调整全局符号的引用,例如,如果一个指令调用了例程detonate,并且detonate 所在的段起始地址为1000,段内偏移地址500,则这个调用指令中涉及的地址要调整为1500.

重定位和符号解析所要求的条件有些许不同,对于重定位,需要调整的基地址的数量相当小,也就是一个输入文件中的段的个数,不过按目标文件格式的要求。重定位的功能设计需要支持对任何段中任何地址的引用进行重定位。对于符号解析,符号的数量远远大于段的数量,但是大多数情况下链接器的符号重定位只是将符号的值插入到程序中预留的位置。

    很多链接器将段重定位统一对待,这是因为他们将段当作是一种 伪符号。不同之处只是他的值是段基地址。 这使得基于段的相对偏移量的重定位就成了基于符号的相对偏移量的重定位特例。 即使在将两种重定位同意对待的链接器中,此二者仍然有一个重要区别,符号引入会包括两个参数,符号所在的段的基地址和符号在段内的偏移地址,而段就只有基地址,没有偏移量了。有一些链接器在开始进入重定位阶段之前会预先计算所有的符号地址,将符号表中的所有符号值与段基地址相加后重新存储。也有一些链接器选择每次都去查看段基地址,在重定位时将段基地址与符号的偏移量相加。大多数情况下,这种两种方案没有什么明显有劣势,都是可以实现重定位效果。

你可能感兴趣的:(开发语言)