This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
Re: ARM long branch stub: thumb
- From: Paul Brook <paul at codesourcery dot com>
- To: binutils at sourceware dot org
- Cc: Christophe LYON <christophe dot lyon at st dot com>
- Date: Thu, 19 Feb 2009 17:04:06 +0000
- Subject: Re: ARM long branch stub: thumb
- References: <499D8BF6.6060809@st.com>
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