ARM long branch stub: thumb

Paul Brook paul@codesourcery.com
Thu Feb 19 17:04:00 GMT 2009


On Thursday 19 February 2009, Christophe LYON wrote:
> +00001000 <__bar_veneer>:
> +    1000:      b540            push    {r6, lr}
> +    1002:      4e02            ldr     r6, \[pc, #8\]
> +    1004:      46fe            mov     lr, pc
> +    1006:      4730            bx      r6
> +    1008:      bd40            pop     {r6, pc}
> +    100a:      bf00            nop

Waitaminute. This code is completely bogus.
(1) You're creating an extra stack frame. This will break any function that 
passes args on the stack.
(2) mov lr, pc doesn't set the low bit of lr, so the callee will return to the 
stub in ARM mode.

What you need to do is:

__bar_veneer:
 push {r0}
 ldr r0, 1f
 mov ip, r0
 pop {r0}
 bx ip
.align 2
1: .word bar

Or if you really want to save a few bytes (but probably slower) on v5+ cores:

__bar_veneer:
 push {r0, r1}
 ldr r0, 1f
 str r0, [sp, #4]
 pop {r0, pc}
1: .word bar

Paul


More information about the Binutils mailing list