自己动手构造编译系统:编译、汇编与链接2.5.3 重定位 -阿里云开发者社区

开发者社区> 华章出版社> 正文
登录阅读全文

自己动手构造编译系统:编译、汇编与链接2.5.3 重定位 

简介:

2.5.3  重定位 

      

     重定位从本质上来说就是地址修正。由于目标文件在链接之前不能获取自己所使用符号的虚拟地址信息,因此导致依赖于这些符号的数据定义或者指令信息缺失。汇编器在生成目标文件的时候就记录下所有需要重定位的信息。链接器获取这些重定位信息,并按照重定位信息的含义修改已经生成的代码,使得最终的代码正确、完整。

  之所以称重定位是链接器最关键的操作,主要是因为地址空间分配和符号解析都是为重定位做准备的。程序在运行时,段的信息、符号的信息都显得“微不足道”,因为CPU只关心文件内的代码和数据。即便如此,也不能忽略地址空间分配和符号解析的重要性。既然重定位是对已有二进制信息的修改,因此作为链接器需要清楚几件事情:

  1)在哪里修改二进制信息?

  2)用什么信息进行修改?

  3)按照怎样的方式修改?

  这三个问题反映在重定位中对应的三个参数:重定位地址、重定位符号和重定位类型。

  重定位地址在重定位表中没有直接记录,因为在重定位目标文件内,段地址还没确定下来,它只记录了重定位位置所在段内的偏移,在地址空间分配结束后,我们使用如下公式计算出重定位地址:

  重定位地址 = 重定位位置所在段基址 + 重定位位置的段内偏移

  重定位符号记录着被指令或者数据使用的符号信息,比如call指令的标号、mov指令使用的变量符号等。在符号解析结束后,重定位符号的地址就已经确定了。

  重定位类型决定修改二进制信息的方式,即绝对地址重定位和相对地址重定位。

  在确定了重定位符号地址和重定位地址后,根据重定位的类型,链接器便可以正确修改重定位地址处的符号地址信息。

  至此,链接器的主要工作流程描述完毕。作为编译系统的最后一个功能模块,链接器与操作系统的关系是最密切的,比如它需要考虑页面地址对齐、指令系统结构以及加载器工作的特点等。

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

分享:

华章出版社

官方博客
官网链接