1 /* SPDX-License-Identifier: GPL-2.0 */ 2 #ifndef __ASM_STACKTRACE_H 3 #define __ASM_STACKTRACE_H 4 5 #include <linux/llist.h> 6 #include <asm/ptrace.h> 7 #include <asm/sections.h> 8 9 struct stackframe { 10 /* 11 * FP member should hold R7 when CONFIG_THUMB2_KERNEL is enabled 12 * and R11 otherwise. 13 */ 14 unsigned long fp; 15 unsigned long sp; 16 unsigned long lr; 17 unsigned long pc; 18 19 /* address of the LR value on the stack */ 20 unsigned long *lr_addr; 21 #ifdef CONFIG_KRETPROBES 22 struct llist_node *kr_cur; 23 struct task_struct *tsk; 24 #endif 25 #ifdef CONFIG_UNWINDER_FRAME_POINTER 26 bool ex_frame; 27 #endif 28 }; 29 30 static inline bool on_thread_stack(void) 31 { 32 unsigned long delta = current_stack_pointer ^ (unsigned long)current->stack; 33 34 return delta < THREAD_SIZE; 35 } 36 37 static __always_inline 38 void arm_get_current_stackframe(struct pt_regs *regs, struct stackframe *frame) 39 { 40 frame->fp = frame_pointer(regs); 41 frame->sp = regs->ARM_sp; 42 frame->lr = regs->ARM_lr; 43 frame->pc = regs->ARM_pc; 44 #ifdef CONFIG_KRETPROBES 45 frame->kr_cur = NULL; 46 frame->tsk = current; 47 #endif 48 #ifdef CONFIG_UNWINDER_FRAME_POINTER 49 frame->ex_frame = in_entry_text(frame->pc); 50 #endif 51 } 52 53 extern int unwind_frame(struct stackframe *frame); 54 extern void walk_stackframe(struct stackframe *frame, 55 bool (*fn)(void *, unsigned long), void *data); 56 extern void dump_mem(const char *lvl, const char *str, unsigned long bottom, 57 unsigned long top); 58 extern void dump_backtrace(struct pt_regs *regs, struct task_struct *tsk, 59 const char *loglvl); 60 61 #endif /* __ASM_STACKTRACE_H */ 62