[PATCH v3 09/10] ARM: call_with_stack: add unwind support
Nick Desaulniers
ndesaulniers at google.com
Mon Oct 18 13:50:35 PDT 2021
On Sun, Oct 17, 2021 at 6:17 AM Ard Biesheuvel <ardb at kernel.org> wrote:
>
> 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.
Thanks for the patch!
Reviewed-by: Nick Desaulniers <ndesaulniers at google.com>
>
> Signed-off-by: Ard Biesheuvel <ardb at kernel.org>
> Acked-by: Linus Walleij <linus.walleij at linaro.org>
> Tested-by: Keith Packard <keithpac at amazon.com>
> ---
> arch/arm/lib/call_with_stack.S | 33 +++++++++++++++-----
> 1 file changed, 25 insertions(+), 8 deletions(-)
>
> diff --git a/arch/arm/lib/call_with_stack.S b/arch/arm/lib/call_with_stack.S
> index 28b0341ae786..0a268a6c513c 100644
> --- a/arch/arm/lib/call_with_stack.S
> +++ b/arch/arm/lib/call_with_stack.S
> @@ -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)
> --
> 2.30.2
>
--
Thanks,
~Nick Desaulniers
More information about the linux-arm-kernel
mailing list