[hellogcc] Re: [hellogcc] [投稿] 一个关于重定位的例子

  • From: Yao Qi <qiyaoltc@xxxxxxxxx>
  • To: hellogcc@xxxxxxxxxxxxx
  • Date: Wed, 24 Aug 2011 14:27:32 +0800

2011/8/24 Mingjie Xing <mingjie.xing@xxxxxxxxx>:
> 一个关于重定位的例子
>

我是mips和relocate的白痴,所以问几个白痴问题 :)

>
> $ mipsel-linux-objdump -Dr sysconf.o
>
> Disassembly of section .rodata:
>
> 00000000 <.rodata>:
>   0:   ffffc064        0xffffc064
>                        0: R_MIPS_GPREL32       .text

".text" 在这里什么意思?

>
> 这里将.rodata中需要重定位的地方和对应的重定位项结合在一起打印出来。可以看出,对于.rodata中的第一个字,其保存的addend值为0xffffc064。
>
> 3、MIPS ABI文档如下描述R_MIPS_GPREL_32:
>
> Name                        Value    Field     Symbol       Calculation
> R_MIPS_GPREL_32    12    T-word32    local    A + S + GP0 - GP
>
> A
>  Represents the addend used to compute the value of the relocatable
>  field.
>
> S
>  Represents the value of the symbol whose index resides in the relocation
>  entry, unless the the symbol is STB_LOCAL and is of type
>  STT_SECTION in which case S represents the original sh_addr minus
>  the final sh_addr.
>
> GP
>  Represents the final gp value to be used for the relocatable, executable,
>  or shared object file being produced.
>
> GP0
>  Represents the gp value used to create the relocatable object.
>
> $ mipsel-linux-objdump -Dr sysconf.o
>
> Disassembly of section .reginfo:
>
> 00000000 <.reginfo>:
>   0:   b200001e        0xb200001e
>        ...
>  14:   00004000        sll     t0,zero,0x0
>
> .reginfo段中记录了ri_gp_value,可以看到,GP0的值为0x4000。
>

ri_gp_value是什么? 我还是不理解gp0为啥是0x4000。我的理解是0x00004000 就只这个位置指令的binary,对吗?

我的理解是这个指令是要将来在reloc的时候,被修改的吧。

> 4、当链接成可执行程序时,依照同样的方法,我们可以找到
>
> 00400094 <.reginfo>:
>  400094:       b20000f4        0xb20000f4
>        ...
>  4000a8:       10008a70        b       3e2a6c <__start-0x1d6a4>
>
> 所以,gp的值为0x10008a70,
>

0x10008a70是指令的binary吗?

> 00425c70 <__sysconf>:
>  425c70:       3c1c0fbe        lui     gp,0xfbe
>
> 所以,S的值为0x425c70,
>

这里有点confusing,根据你前边对R_MIPS_GPREL_32 的描述,S是syombl的地址,那么你这里的symbol应该就是__sysconf。

> 根据公式"A + S + GP0 - GP",可以计算出.rodata中需要重定位的地方的最终内容。比如,对于.rodata中的第一个字,
>
> 0xffffc064 + 0x425c70 + 0x4000 - 0x10008a70 = 0xf041d264
>
> 5、附注
>
> 如果查看一下binutils/bfd/elf32-mips.c,就可以找到R_MIPS_GPREL32相应的HOWTO数据结构,以及处理函数。
>
> 6、其它
>
> 这里,我个人有一个地方没有搞明白,MIPS ABI中介绍说S是初始的sh_addr减去最终的sh_addr,但是,看起来,似乎应该反过来才正确。

你在mips abi哪里看到的?原话是怎样的?



-- 
Yao Qi <qiyaoltc AT gmail DOT com>
http://sites.google.com/site/duewayqi/

Other related posts: