六、重定位项
重定位是将ELF文件中未定义的符 关联到有效位置的过程,特别是目标文件中这一项尤为重要。本例中引用了C语言库函数printf和exit,链接时必须替换为该进程的虚拟地址空间中机器代码所在位置。
每个ELF中,都有专门的类型为REL的节包含重定位项,标识了需要进行重定位的位置。每一项都是用相同的数据结构表示的。
1. 数据结构
由于历史原因,有两种类型的重定位信息,由两种不同数据结构。第一种重定位结构称为普通重定位,对应的节的类型为SHT_REL,结构如下:
r_offset指定需要重定位项的位置,r_info不仅提供了符 表中的位置,还包括重定位类型的信息。其中高8位中指示符 表中位置,低8位指示重定位类型。在计算重定位位置时,将根据重定位类型,对该值进行不同处理。获取相应值的宏定义如下:
第二种重定位结构称为添加常数的重定位,对应节的类型为SHT_RELA,结构如下:
需要注意的是,第一种重定位结构也存在这个加数值,该加数值不在结构中存储,而是链接器根据该值应该出现的位置获取的。
目标文件中这个加数值在链接成可执行文件时会参与运算得到一个新的值,后面将会用例子进行说明如何计算得出新结果。
查看本例中目标文件的重定位项,结果如下:
可以看到,main函数在文件中偏移为0x1C,0x44处调用了子过程add,0x45开始的4字节值为0xFFFFFFFC,也就是加数,他是以补码形式表示的,换算成十进制为-4,即A=-4。对照上一小节目标文件重定位表可知,偏移为0x45的重定位项名字是add,汇编代码“call 45”即表示调用了该重定位项。
汇编方式查看可执行文件代码如下:
.dynamic保存了一个数组,数组类型为Elf32_Dyn类型,以下内容都是关于这个节的。
1. 数据结构
d_tag用于区分各种指定信息类型的标记,该结构中的联合根据该标记进行解释。d_un或者保存一个虚拟地址,或者保存一个整数。
最重要的标记如下:
DT_NEEDED指定改程序执行所需的一个动态库,d_un指向一个字符串表项,给出库的名称。本例当中只用到标准库。
DT_STRTAB保存了字符表的位置,其中包括了dynamic节所需的所有动态链接库和符 名称。
DT_SYMTAB保存了符 表的位置,其中包含了dynamic节所需的所有信息。
DT_INIT和DT_FINT保存了用于初始化和结束程序的函数。
2. 动态链接信息
用命令查看本例动态链接信息如下:

至此,关于Linux系统中ELF文件的格式已基本分析完毕。
文章知识点与官方知识档案匹配,可进一步学习相关知识CS入门技能树Linux入门初识Linux24976 人正在系统学习中
声明:本站部分文章及图片源自用户投稿,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!