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