Equation Solver
Equation Solver

Reputation: 553

calculating the address of global offset table in arm literal pool

I am trying to understand the arm assembly code for writing the Literal Pool and Global OFFSET table

Compiling the C code with GNU ARM GCC

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

GCC generates following code:

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)

I want to manually handle the global offset table in arm assembly. Now I am facing difficulty to understand the above code. Can any one please describe the literal pool calculation following lines of code?

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

Upvotes: 2

Views: 2232

Answers (1)

winter333
winter333

Reputation: 347

When compiled to a PIC(position independet code) file, global variable need to be relocated.

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

Notice add r3, pc, in this instruction, pc is .LPIC0+4, so the result of add is _GLOBAL_OFFSET_TABLE_, which is the entry of the GOT. .L2+4 is i(GOT), it is the offset of varaibel i in GOT.

Look at the result of objdump is more intuitive.

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

In the disassembly, .L2 and .L2+4 is replaced with specific offset. the result of add r3, pc is 0x8ba8 + 0x458 = 0x9000. Then ldr r3, [r3, r2] would load from address 0x901c. Look up these address in the section header:

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

the address 0x9000 is the entry of global offset table, and 0x901c is also in this section. the symbol info of 0x901c could be find in the .rel.dyn section:

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 

Upvotes: 1

Related Questions