提交 0b78f2e9 编写于 作者: A Ard Biesheuvel

ARM: call_with_stack: add unwind support

Restructure the code and add the unwind annotations so that both the
frame pointer unwinder as well as the EHABI unwind info based unwinder
will be able to follow the call stack through call_with_stack().

Since GCC and Clang use different formats for the stack frame, two
methods are implemented: a GCC version that pushes fp, sp, lr and pc for
compatibility with the frame pointer unwinder, and a second version that
works with Clang, as well as with the EHABI unwinder both in ARM and
Thumb2 modes.
Signed-off-by: NArd Biesheuvel <ardb@kernel.org>
Acked-by: NLinus Walleij <linus.walleij@linaro.org>
Tested-by: NKeith Packard <keithpac@amazon.com>
Reviewed-by: NNick Desaulniers <ndesaulniers@google.com>
Tested-by: NMarc Zyngier <maz@kernel.org>
Tested-by: Vladimir Murzin <vladimir.murzin@arm.com> # ARMv7M
上级 d4664b6c
......@@ -8,25 +8,42 @@
#include <linux/linkage.h>
#include <asm/assembler.h>
#include <asm/unwind.h>
/*
* void call_with_stack(void (*fn)(void *), void *arg, void *sp)
*
* Change the stack to that pointed at by sp, then invoke fn(arg) with
* the new stack.
*
* The sequence below follows the APCS frame convention for frame pointer
* unwinding, and implements the unwinder annotations needed by the EABI
* unwinder.
*/
ENTRY(call_with_stack)
str sp, [r2, #-4]!
str lr, [r2, #-4]!
ENTRY(call_with_stack)
#if defined(CONFIG_UNWINDER_FRAME_POINTER) && defined(CONFIG_CC_IS_GCC)
mov ip, sp
push {fp, ip, lr, pc}
sub fp, ip, #4
#else
UNWIND( .fnstart )
UNWIND( .save {fpreg, lr} )
push {fpreg, lr}
UNWIND( .setfp fpreg, sp )
mov fpreg, sp
#endif
mov sp, r2
mov r2, r0
mov r0, r1
badr lr, 1f
ret r2
bl_r r2
1: ldr lr, [sp]
ldr sp, [sp, #4]
ret lr
#if defined(CONFIG_UNWINDER_FRAME_POINTER) && defined(CONFIG_CC_IS_GCC)
ldmdb fp, {fp, sp, pc}
#else
mov sp, fpreg
pop {fpreg, pc}
UNWIND( .fnend )
#endif
ENDPROC(call_with_stack)
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册