This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: ARM long branch stub: thumb


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

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]