[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