162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */ 262306a36Sopenharmony_ci#ifndef _ASM_STACKTRACE_H 362306a36Sopenharmony_ci#define _ASM_STACKTRACE_H 462306a36Sopenharmony_ci 562306a36Sopenharmony_ci#include <asm/ptrace.h> 662306a36Sopenharmony_ci#include <asm/asm.h> 762306a36Sopenharmony_ci#include <linux/stringify.h> 862306a36Sopenharmony_ci 962306a36Sopenharmony_ci#ifdef CONFIG_KALLSYMS 1062306a36Sopenharmony_ciextern int raw_show_trace; 1162306a36Sopenharmony_ciextern unsigned long unwind_stack(struct task_struct *task, unsigned long *sp, 1262306a36Sopenharmony_ci unsigned long pc, unsigned long *ra); 1362306a36Sopenharmony_ciextern unsigned long unwind_stack_by_address(unsigned long stack_page, 1462306a36Sopenharmony_ci unsigned long *sp, 1562306a36Sopenharmony_ci unsigned long pc, 1662306a36Sopenharmony_ci unsigned long *ra); 1762306a36Sopenharmony_ci#else 1862306a36Sopenharmony_ci#define raw_show_trace 1 1962306a36Sopenharmony_cistatic inline unsigned long unwind_stack(struct task_struct *task, 2062306a36Sopenharmony_ci unsigned long *sp, unsigned long pc, unsigned long *ra) 2162306a36Sopenharmony_ci{ 2262306a36Sopenharmony_ci return 0; 2362306a36Sopenharmony_ci} 2462306a36Sopenharmony_ci#endif 2562306a36Sopenharmony_ci 2662306a36Sopenharmony_ci#define STR_PTR_LA __stringify(PTR_LA) 2762306a36Sopenharmony_ci#define STR_LONG_S __stringify(LONG_S) 2862306a36Sopenharmony_ci#define STR_LONG_L __stringify(LONG_L) 2962306a36Sopenharmony_ci#define STR_LONGSIZE __stringify(LONGSIZE) 3062306a36Sopenharmony_ci 3162306a36Sopenharmony_ci#define STORE_ONE_REG(r) \ 3262306a36Sopenharmony_ci STR_LONG_S " $" __stringify(r)",("STR_LONGSIZE"*"__stringify(r)")(%1)\n\t" 3362306a36Sopenharmony_ci 3462306a36Sopenharmony_cistatic __always_inline void prepare_frametrace(struct pt_regs *regs) 3562306a36Sopenharmony_ci{ 3662306a36Sopenharmony_ci#ifndef CONFIG_KALLSYMS 3762306a36Sopenharmony_ci /* 3862306a36Sopenharmony_ci * Remove any garbage that may be in regs (specially func 3962306a36Sopenharmony_ci * addresses) to avoid show_raw_backtrace() to report them 4062306a36Sopenharmony_ci */ 4162306a36Sopenharmony_ci memset(regs, 0, sizeof(*regs)); 4262306a36Sopenharmony_ci#endif 4362306a36Sopenharmony_ci __asm__ __volatile__( 4462306a36Sopenharmony_ci ".set push\n\t" 4562306a36Sopenharmony_ci ".set noat\n\t" 4662306a36Sopenharmony_ci /* Store $1 so we can use it */ 4762306a36Sopenharmony_ci STR_LONG_S " $1,"STR_LONGSIZE"(%1)\n\t" 4862306a36Sopenharmony_ci /* Store the PC */ 4962306a36Sopenharmony_ci "1: " STR_PTR_LA " $1, 1b\n\t" 5062306a36Sopenharmony_ci STR_LONG_S " $1,%0\n\t" 5162306a36Sopenharmony_ci STORE_ONE_REG(2) 5262306a36Sopenharmony_ci STORE_ONE_REG(3) 5362306a36Sopenharmony_ci STORE_ONE_REG(4) 5462306a36Sopenharmony_ci STORE_ONE_REG(5) 5562306a36Sopenharmony_ci STORE_ONE_REG(6) 5662306a36Sopenharmony_ci STORE_ONE_REG(7) 5762306a36Sopenharmony_ci STORE_ONE_REG(8) 5862306a36Sopenharmony_ci STORE_ONE_REG(9) 5962306a36Sopenharmony_ci STORE_ONE_REG(10) 6062306a36Sopenharmony_ci STORE_ONE_REG(11) 6162306a36Sopenharmony_ci STORE_ONE_REG(12) 6262306a36Sopenharmony_ci STORE_ONE_REG(13) 6362306a36Sopenharmony_ci STORE_ONE_REG(14) 6462306a36Sopenharmony_ci STORE_ONE_REG(15) 6562306a36Sopenharmony_ci STORE_ONE_REG(16) 6662306a36Sopenharmony_ci STORE_ONE_REG(17) 6762306a36Sopenharmony_ci STORE_ONE_REG(18) 6862306a36Sopenharmony_ci STORE_ONE_REG(19) 6962306a36Sopenharmony_ci STORE_ONE_REG(20) 7062306a36Sopenharmony_ci STORE_ONE_REG(21) 7162306a36Sopenharmony_ci STORE_ONE_REG(22) 7262306a36Sopenharmony_ci STORE_ONE_REG(23) 7362306a36Sopenharmony_ci STORE_ONE_REG(24) 7462306a36Sopenharmony_ci STORE_ONE_REG(25) 7562306a36Sopenharmony_ci STORE_ONE_REG(26) 7662306a36Sopenharmony_ci STORE_ONE_REG(27) 7762306a36Sopenharmony_ci STORE_ONE_REG(28) 7862306a36Sopenharmony_ci STORE_ONE_REG(29) 7962306a36Sopenharmony_ci STORE_ONE_REG(30) 8062306a36Sopenharmony_ci STORE_ONE_REG(31) 8162306a36Sopenharmony_ci /* Restore $1 */ 8262306a36Sopenharmony_ci STR_LONG_L " $1,"STR_LONGSIZE"(%1)\n\t" 8362306a36Sopenharmony_ci ".set pop\n\t" 8462306a36Sopenharmony_ci : "=m" (regs->cp0_epc) 8562306a36Sopenharmony_ci : "r" (regs->regs) 8662306a36Sopenharmony_ci : "memory"); 8762306a36Sopenharmony_ci} 8862306a36Sopenharmony_ci 8962306a36Sopenharmony_ci#endif /* _ASM_STACKTRACE_H */ 90