对于X86平台下的ELF文件的重定位入口所修正的指令寻址方式只有两种:绝对近址32寻址和相对近址32寻址。

这两种指令修正方式每个被修正的位置的长度都为32位,即4个字节,而且都是近址寻址,不用考虑Intel的段间远址寻址。r_info成员的低8位表示重定位入口的类型。

X86基本重定位类型

宏定义                        值      重定位修正方法

R_386_32      1     绝对寻址修正  S + A

R_386_PC32    2     相对寻址修正  S + A - P

A = 保存在指令中被修正位置的值

P = 被修正的位置(相对于段开始的偏移量或者虚拟地址),该值可以通过r_offset计算得到。

S = 符号的实际地址,即由r_info的高24位指定的符号的实际地址。

因为a.o中shared和swap需要地址重定位,以此为例子说明重定位地址修正方法。用objdump -r a.o可以得到a.o中需要重定位的符号如图4.2.7所示:

Chap-4 Section 4.2.4 指令修正方式

***图4.2.7(同4.2.4相同)***

从图中可知,shared的重定位类型为R_386_32,因此为绝对寻址修正方式。那么S的值怎么得到,可以从a.o,b.o链接成的可执行文件的符号表中得到,可执行文件的符号表如图4.2.8:

Chap-4 Section 4.2.4 指令修正方式

***图4.2.8***

从图中看出shared的实际地址为0x08049158,即是S的值。从a.o反汇编指令中可知A的值,如图4.2.9所示:

Chap-4 Section 4.2.4 指令修正方式

***图4.2.9***

从图4.2.7中得知shared相对段开始的偏移为0x15,所以A的值是0x0。那么shared重定位后的地址为S + A = 0x08049158 + 0x0 = 0x08049158。怎样验证该数值的正确性?可以通过可执行文件的反汇编代码验证,如图4.2.10所示:

Chap-4 Section 4.2.4 指令修正方式

***图4.2.10***

指令的地址,0x07 + 0x080480b9 = 0x080480c0,该地址即为swap函数的地址。

Chap-4 Section 4.2.4 指令修正方式

***图4.2.11***

相关文章:

  • 2022-12-23
  • 2022-12-23
  • 2021-10-10
  • 2021-07-24
  • 2021-05-28
  • 2022-12-23
  • 2021-08-08
  • 2021-04-26
猜你喜欢
  • 2022-12-23
  • 2022-01-25
  • 2022-12-23
  • 2021-11-17
  • 2021-09-28
  • 2021-06-15
  • 2022-12-23
相关资源
相似解决方案