重定位学习

本文介绍了目标文件链接与重定位相关知识。重定位目的是处理代码段和数据段中对绝对地址引用的位置。链接过程是将输入目标文件合并为输出文件,涉及扫描文件、收集符号、解析重定位等。还介绍了重定位表,它记录重定位信息,包含重定位入口等内容。

1、重定位的目的

链接器在处理目标文件时,须要对目标文件中某些部位进行重定位,即代码段和数据段中那些对绝对地址的引用的位置。

2、链接的过程

对于链接器来说,整个链接过程中就是将几个输入目标文件加工后合并成为一个输出文件。它首先扫描所有的输入目标文件,并且获得它们的各个段的长度、属性和位置,并且将输入目标文件中的符号表中所有的符号定义和符号引用收集起来,统一放到一个全局符号表中。接着,读取输入文件中段的数据、重定位信息,并且进行符号解析与重定位、调整代码中的地址等。

VMA表示Virtual Memory Address,即虚拟地址。链接前,目标文件中的所有段的VMA都是0,因为虚拟空间还没有被分配,所以它们默认都是0。链接后的程序中所使用的地址已经是程序在进程中的虚拟地址。

3、重定位表
目标文件的重定位信息都记录在重定位表里面,对于每个须要重定位的代码段和数据段,都会有一个相应的重定位表。一个重定位表往往就是ELF文件中的一个段。这个段的类型(sh_type)就是“SHT_REL”类型的,它的“sh_link”表示符号表的下标,它的“sh_info”表示它作用于哪个段。

对于可重定位的ELF文件来说,重定位表用来描述如何修改相应的段里的内容。在重定位表中,每个要被重定位的地方叫一个重定位入口(relocation entry)。重定位入口的偏移(Offset)表示该入口在要被重定位的段中的位置,可通过 objdump -r  object-file 命令来查看这个Offset值。

对于32位的Intel x86系列处理器来说,重定位表的结构也很简单,它是一个Elf32_Rel结构的数组,每个数组元素对应一个重定位入口。Elf32_Rel的定义如下:

typedef struct {
    Elf32_Addr r_offset;
    Elf32_word r_info;
} Elf32_Rel;

r_offset:重定位入口的偏移。对于可重定位文件来说,这个值是该重定位入口所要修正的位置的第一个字节相对于段起始的偏移;对于可执行文件或共享对象文件来说,这个值是该重定位入口所要修正的位置的第一个字节的虚拟地址。

r_info:重定位入口的类型和符号。这个成员的低8位表示重定位入口的类型,高24位表示重定位入口的符号在符号表中的下标。因为各种处理器的指令格式不一样,所以重定位所修正的指令地址格式也不一样。每种处理器都有自己一套重定位入口的类型。

 

 

 

 

参考资料:

1、《程序员的自我修养--链接、装载与库》,俞甲子,石凡,潘爱民,电子工业出版社。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值