1 /* SPDX-License-Identifier: GPL-2.0 */ 2 #ifndef _ASM_STACKTRACE_H 3 #define _ASM_STACKTRACE_H 4 5 #include <asm/ptrace.h> 6 #include <asm/asm.h> 7 #include <linux/stringify.h> 8 9 #ifdef CONFIG_KALLSYMS 10 extern int raw_show_trace; 11 extern unsigned long unwind_stack(struct task_struct *task, unsigned long *sp, 12 unsigned long pc, unsigned long *ra); 13 extern unsigned long unwind_stack_by_address(unsigned long stack_page, 14 unsigned long *sp, 15 unsigned long pc, 16 unsigned long *ra); 17 #else 18 #define raw_show_trace 1 19 static inline unsigned long unwind_stack(struct task_struct *task, 20 unsigned long *sp, unsigned long pc, unsigned long *ra) 21 { 22 return 0; 23 } 24 #endif 25 26 #define STR_PTR_LA __stringify(PTR_LA) 27 #define STR_LONG_S __stringify(LONG_S) 28 #define STR_LONG_L __stringify(LONG_L) 29 #define STR_LONGSIZE __stringify(LONGSIZE) 30 31 #define STORE_ONE_REG(r) \ 32 STR_LONG_S " $" __stringify(r)",("STR_LONGSIZE"*"__stringify(r)")(%1)\n\t" 33 34 static __always_inline void prepare_frametrace(struct pt_regs *regs) 35 { 36 #ifndef CONFIG_KALLSYMS 37 /* 38 * Remove any garbage that may be in regs (specially func 39 * addresses) to avoid show_raw_backtrace() to report them 40 */ 41 memset(regs, 0, sizeof(*regs)); 42 #endif 43 __asm__ __volatile__( 44 ".set push\n\t" 45 ".set noat\n\t" 46 /* Store $1 so we can use it */ 47 STR_LONG_S " $1,"STR_LONGSIZE"(%1)\n\t" 48 /* Store the PC */ 49 "1: " STR_PTR_LA " $1, 1b\n\t" 50 STR_LONG_S " $1,%0\n\t" 51 STORE_ONE_REG(2) 52 STORE_ONE_REG(3) 53 STORE_ONE_REG(4) 54 STORE_ONE_REG(5) 55 STORE_ONE_REG(6) 56 STORE_ONE_REG(7) 57 STORE_ONE_REG(8) 58 STORE_ONE_REG(9) 59 STORE_ONE_REG(10) 60 STORE_ONE_REG(11) 61 STORE_ONE_REG(12) 62 STORE_ONE_REG(13) 63 STORE_ONE_REG(14) 64 STORE_ONE_REG(15) 65 STORE_ONE_REG(16) 66 STORE_ONE_REG(17) 67 STORE_ONE_REG(18) 68 STORE_ONE_REG(19) 69 STORE_ONE_REG(20) 70 STORE_ONE_REG(21) 71 STORE_ONE_REG(22) 72 STORE_ONE_REG(23) 73 STORE_ONE_REG(24) 74 STORE_ONE_REG(25) 75 STORE_ONE_REG(26) 76 STORE_ONE_REG(27) 77 STORE_ONE_REG(28) 78 STORE_ONE_REG(29) 79 STORE_ONE_REG(30) 80 STORE_ONE_REG(31) 81 /* Restore $1 */ 82 STR_LONG_L " $1,"STR_LONGSIZE"(%1)\n\t" 83 ".set pop\n\t" 84 : "=m" (regs->cp0_epc) 85 : "r" (regs->regs) 86 : "memory"); 87 } 88 89 #endif /* _ASM_STACKTRACE_H */ 90