arm32 asm -- fp is not set to old sp

2

I have a dump of an arm32 v7a function, and in its prologue I see the following:

   0xef8137a4   ldr     r3, [pc, #248]  
   0xef8137a8   strd    r4, [sp, #-24]! 
   0xef8137ac   cmp     r0, #1
   0xef8137b0   ldr     r12, [pc, #240] 
   0xef8137b4   strd    r6, [sp, #8]
   0xef8137b8   mov     r4, r0
   0xef8137bc   ldr     r2, [pc, #232] 
   0xef8137c0   str     r11, [sp, #16] 
   0xef8137c4   mov     r5, r1
   0xef8137c8   str     lr, [sp, #20]  
   0xef8137cc   add     r11, sp, #20  

On the second line ( strd r4 [sp, #-24]! ), it is decrementing the stack pointer by 24, but then on the last line ( add r11, sp, #20 ) it sets fp to be the current stack pointer + 20. I do not see any other lines that would modify sp. Thus r11 (fp) would be 4 greater than the old sp.

As far as I'm aware, fp should be set to the old sp (which would be required for stack unwinding). Do I have that wrong, or am I missing something in the ASM code? (note -- code is compiled with -fno-omit-frame-pointer, and r11 is not modified in the body of the function)

------------------- EDIT -------------

A more complete objdump (built on another machine but same principles apply) looks like this:

/* Get current value of CLOCK and store it in TP.  */
int
__clock_gettime (clockid_t clock_id, struct timespec *tp)
{
   0:   e59f30a0        ldr     r3, [pc, #160]  ; a8 <__clock_gettime+0xa8>
   4:   e16d41f8        strd    r4, [sp, #-24]! ; 0xffffffe8
   8:   e1a04000        mov     r4, r0
  return INLINE_VSYSCALL (clock_gettime, 2, clock_id, tp);
   c:   e59fc098        ldr     ip, [pc, #152]  ; ac <__clock_gettime+0xac>
{
  10:   e1cd60f8        strd    r6, [sp, #8]
  14:   e1a05001        mov     r5, r1
  return INLINE_VSYSCALL (clock_gettime, 2, clock_id, tp);
  18:   e59f2090        ldr     r2, [pc, #144]  ; b0 <__clock_gettime+0xb0>
{
  1c:   e58db010        str     fp, [sp, #16]
  20:   e28db014        add     fp, sp, #20
  24:   e58de014        str     lr, [sp, #20]
  28:   e08f3003        add     r3, pc, r3
  return INLINE_VSYSCALL (clock_gettime, 2, clock_id, tp);
  2c:   e793c00c        ldr     ip, [r3, ip]

...

  74:   e24bd014        sub     sp, fp, #20
  78:   e1cd40d0        ldrd    r4, [sp]
  7c:   e1cd60d8        ldrd    r6, [sp, #8]
  80:   e59db010        ldr     fp, [sp, #16]
  84:   e28dd014        add     sp, sp, #20
  88:   e49df004        pop     {pc}            ; (ldr pc, [sp], #4)
  return INLINE_VSYSCALL (clock_gettime, 2, clock_id, tp);
  8c:   e59f3020        ldr     r3, [pc, #32]   ; b4 <__clock_gettime+0xb4>
  90:   e2601000        rsb     r1, r0, #0
  94:   ee1d2f70        mrc     15, 0, r2, cr13, cr0, {3}
  98:   e3e00000        mvn     r0, #0
  9c:   e79f3003        ldr     r3, [pc, r3]
  a0:   e7821003        str     r1, [r2, r3]
  a4:   eafffff2        b       74 <__clock_gettime+0x74>
  a8:   00000078        .word   0x00000078
assembly
arm
callstack
stack-frame
asked on Stack Overflow Apr 23, 2021 by HardcoreHenry • edited Apr 24, 2021 by Peter Cordes

0 Answers

Nobody has answered this question yet.


User contributions licensed under CC BY-SA 3.0