From f8328853031ab6dfc57059ff181138babc7779a0 Mon Sep 17 00:00:00 2001 From: Boyan Karatotev Date: Fri, 10 Mar 2023 18:24:50 +0000 Subject: [PATCH] feat(aarch64): add stack debug information to assembly routines Debugging assembly is painful as it is, and having no useful stack trace does not help. Code must emit CFI directives whenever the stack moves to enable stack traces. Otherwise, the layout of the stack frame is ambiguous, the debugger gives up, and shows nothing. The compiler does this automatically for C but not assembly. Add this information to the (currently unused) func_prologue macro. Signed-off-by: Boyan Karatotev Change-Id: Ief5fd672285df8d9d90fa6a2214b5c6e45eddd81 --- include/arch/aarch64/asm_macros.S | 42 +++++++++++++++++++++++++++++-- 1 file changed, 40 insertions(+), 2 deletions(-) diff --git a/include/arch/aarch64/asm_macros.S b/include/arch/aarch64/asm_macros.S index 7d1407a22..6091f6294 100644 --- a/include/arch/aarch64/asm_macros.S +++ b/include/arch/aarch64/asm_macros.S @@ -25,12 +25,50 @@ #endif - .macro func_prologue + /* + * Create a stack frame at the start of an assembly function. Will also + * add all necessary call frame information (cfi) directives for a + * pretty stack trace. This is necessary as there is quite a bit of + * flexibility within a stack frame and the stack pointer can move + * around throughout the function. If the debugger isn't told where to + * find things, it gets lost, gives up and displays nothing. So inform + * the debugger of what's where. Anchor the Canonical Frame Address + * (CFA; the thing used to track what's where) to the frame pointer as + * that's not expected to change in the function body and no extra + * bookkeeping will be necessary, allowing free movement of the sp + * + * _frame_size: requested space for caller to use. Must be a mutliple + * of 16 for stack pointer alignment + */ + .macro func_prologue _frame_size=0 + .if \_frame_size & 0xf + .error "frame_size must have stack pointer alignment (multiple of 16)" + .endif + + /* put frame record at top of frame */ stp x29, x30, [sp, #-0x10]! mov x29,sp + .if \_frame_size + sub sp, sp, #\_frame_size + .endif + + /* point CFA to start of frame record, i.e. x29 + 0x10 */ + .cfi_def_cfa x29, 0x10 + /* inform it about x29, x30 locations */ + .cfi_offset x30, -0x8 + .cfi_offset x29, -0x10 .endm - .macro func_epilogue + /* + * Clear stack frame at the end of an assembly function. + * + * _frame_size: the value passed to func_prologue + */ + .macro func_epilogue _frame_size=0 + /* remove requested space */ + .if \_frame_size + add sp, sp, #\_frame_size + .endif ldp x29, x30, [sp], #0x10 .endm