计算arm文字池中全局偏移表的地址

时间:2014-08-25 10:02:36

标签: c assembly arm

我正在尝试理解用于编写Literal Pool和Global OFFSET表的arm汇编代码

使用GNU ARM GCC编译C代码

extern int i;
int foo(int j)
{
int t = i;
i = j;
return t;
}

GCC生成以下代码:

foo:
    ldr     r3, .L2        
    ldr     r2, .L2+4      
.LPIC0:
    add     r3, pc         
    ldr     r3, [r3, r2]   
    @ sp needed for prologue
    ldr     r2, [r3]
    str     r0, [r3]
    mov     r0, r2
    bx      lr

.L3:
    .align  2

.L2:
    .word   _GLOBAL_OFFSET_TABLE_-(.LPIC0+4)  
    .word   i(GOT)

我想在arm组件中手动处理全局偏移表。 现在我很难理解上面的代码。 任何人都可以按照代码行描述文字池计算吗?

.L2:
    .word   _GLOBAL_OFFSET_TABLE_-(.LPIC0+4) 
    .word   i(GOT) 

1 个答案:

答案 0 :(得分:1)

当编译为PIC(位置独立代码)文件时,需要重新定位全局变量。

foo:
    ldr     r3, .L2        
    ldr     r2, .L2+4      
.LPIC0:
    add     r3, pc         
    ldr     r3, [r3, r2]

注意add r3, pc,在此说明中,pc.LPIC0+4,因此add的结果为_GLOBAL_OFFSET_TABLE_,即GOT的条目1}}。 .L2+4i(GOT),它是i中varaibel GOT的偏移量。

查看objdump的结果更直观。

00000450 <foo>:
 450:   4b03        ldr r3, [pc, #12]   ; (460 <foo+0x10>)
 452:   4a04        ldr r2, [pc, #16]   ; (464 <foo+0x14>)
 454:   447b        add r3, pc
 456:   589b        ldr r3, [r3, r2]
 458:   681a        ldr r2, [r3, #0]
 45a:   6018        str r0, [r3, #0]
 45c:   4610        mov r0, r2
 45e:   4770        bx  lr
 460:   00008ba8    andeq   r8, r0, r8, lsr #23
 464:   0000001c    andeq   r0, r0, ip, lsl r0
 468:   f3af 8000   nop.w
 46c:   f3af 8000   nop.w

在反汇编中,.L2.L2+4将替换为特定的偏移量。 add r3, pc的结果是0x8ba8 + 0x458 = 0x9000。然后ldr r3, [r3, r2]将从地址0x901c加载。在章节标题中查找这些地址:

  [Nr] Name              Type            Addr     Off    Size   ES Flg Lk Inf Al
  ...
  [17] .got              PROGBITS        00009000 001000 000024 04  WA  0   0  4
  ...

地址0x9000是全局偏移表的条目,0x901c也在此部分中。可以在0x901c部分找到.rel.dyn的符号信息:

Relocation section '.rel.dyn' at offset 0x348 contains 7 entries:
 Offset     Info    Type            Sym.Value  Sym. Name
...
00009018  00000415 R_ARM_GLOB_DAT    00000000   _Jv_RegisterClasses
0000901c  00000515 R_ARM_GLOB_DAT    00000000   i
00009020  00000615 R_ARM_GLOB_DAT    00000000   __cxa_finalize