1b2441318SGreg Kroah-Hartman /* SPDX-License-Identifier: GPL-2.0 */ 28637c099SIngo Molnar #ifndef __LINUX_STACKTRACE_H 38637c099SIngo Molnar #define __LINUX_STACKTRACE_H 48637c099SIngo Molnar 59a92a6ceSJoonsoo Kim #include <linux/types.h> 6e9b98e16SThomas Gleixner #include <asm/errno.h> 79a92a6ceSJoonsoo Kim 8897312bdSAndrew Morton struct task_struct; 99c0729dcSSoeren Sandmann Pedersen struct pt_regs; 10897312bdSAndrew Morton 118637c099SIngo Molnar #ifdef CONFIG_STACKTRACE 12a2970421SBart Van Assche void stack_trace_print(const unsigned long *trace, unsigned int nr_entries, 13e9b98e16SThomas Gleixner int spaces); 14a2970421SBart Van Assche int stack_trace_snprint(char *buf, size_t size, const unsigned long *entries, 15e9b98e16SThomas Gleixner unsigned int nr_entries, int spaces); 16e9b98e16SThomas Gleixner unsigned int stack_trace_save(unsigned long *store, unsigned int size, 17e9b98e16SThomas Gleixner unsigned int skipnr); 18e9b98e16SThomas Gleixner unsigned int stack_trace_save_tsk(struct task_struct *task, 19e9b98e16SThomas Gleixner unsigned long *store, unsigned int size, 20e9b98e16SThomas Gleixner unsigned int skipnr); 21e9b98e16SThomas Gleixner unsigned int stack_trace_save_regs(struct pt_regs *regs, unsigned long *store, 22e9b98e16SThomas Gleixner unsigned int size, unsigned int skipnr); 23e9b98e16SThomas Gleixner unsigned int stack_trace_save_user(unsigned long *store, unsigned int size); 24e9b98e16SThomas Gleixner 25e9b98e16SThomas Gleixner /* Internal interfaces. Do not use in generic code */ 26214d8ca6SThomas Gleixner #ifdef CONFIG_ARCH_STACKWALK 27214d8ca6SThomas Gleixner 28214d8ca6SThomas Gleixner /** 29214d8ca6SThomas Gleixner * stack_trace_consume_fn - Callback for arch_stack_walk() 30214d8ca6SThomas Gleixner * @cookie: Caller supplied pointer handed back by arch_stack_walk() 31214d8ca6SThomas Gleixner * @addr: The stack entry address to consume 32214d8ca6SThomas Gleixner * 33214d8ca6SThomas Gleixner * Return: True, if the entry was consumed or skipped 34214d8ca6SThomas Gleixner * False, if there is no space left to store 35214d8ca6SThomas Gleixner */ 36264c03a2SMark Brown typedef bool (*stack_trace_consume_fn)(void *cookie, unsigned long addr); 37214d8ca6SThomas Gleixner /** 38214d8ca6SThomas Gleixner * arch_stack_walk - Architecture specific function to walk the stack 39214d8ca6SThomas Gleixner * @consume_entry: Callback which is invoked by the architecture code for 40214d8ca6SThomas Gleixner * each entry. 41214d8ca6SThomas Gleixner * @cookie: Caller supplied pointer which is handed back to 42214d8ca6SThomas Gleixner * @consume_entry 43214d8ca6SThomas Gleixner * @task: Pointer to a task struct, can be NULL 44214d8ca6SThomas Gleixner * @regs: Pointer to registers, can be NULL 45214d8ca6SThomas Gleixner * 46214d8ca6SThomas Gleixner * ============ ======= ============================================ 47214d8ca6SThomas Gleixner * task regs 48214d8ca6SThomas Gleixner * ============ ======= ============================================ 49214d8ca6SThomas Gleixner * task NULL Stack trace from task (can be current) 50214d8ca6SThomas Gleixner * current regs Stack trace starting on regs->stackpointer 51214d8ca6SThomas Gleixner * ============ ======= ============================================ 52214d8ca6SThomas Gleixner */ 53214d8ca6SThomas Gleixner void arch_stack_walk(stack_trace_consume_fn consume_entry, void *cookie, 54214d8ca6SThomas Gleixner struct task_struct *task, struct pt_regs *regs); 55*b18adee4SMark Brown 56*b18adee4SMark Brown /** 57*b18adee4SMark Brown * arch_stack_walk_reliable - Architecture specific function to walk the 58*b18adee4SMark Brown * stack reliably 59*b18adee4SMark Brown * 60*b18adee4SMark Brown * @consume_entry: Callback which is invoked by the architecture code for 61*b18adee4SMark Brown * each entry. 62*b18adee4SMark Brown * @cookie: Caller supplied pointer which is handed back to 63*b18adee4SMark Brown * @consume_entry 64*b18adee4SMark Brown * @task: Pointer to a task struct, can be NULL 65*b18adee4SMark Brown * 66*b18adee4SMark Brown * This function returns an error if it detects any unreliable 67*b18adee4SMark Brown * features of the stack. Otherwise it guarantees that the stack 68*b18adee4SMark Brown * trace is reliable. 69*b18adee4SMark Brown * 70*b18adee4SMark Brown * If the task is not 'current', the caller *must* ensure the task is 71*b18adee4SMark Brown * inactive and its stack is pinned. 72*b18adee4SMark Brown */ 73214d8ca6SThomas Gleixner int arch_stack_walk_reliable(stack_trace_consume_fn consume_entry, void *cookie, 74214d8ca6SThomas Gleixner struct task_struct *task); 75*b18adee4SMark Brown 76214d8ca6SThomas Gleixner void arch_stack_walk_user(stack_trace_consume_fn consume_entry, void *cookie, 77214d8ca6SThomas Gleixner const struct pt_regs *regs); 78214d8ca6SThomas Gleixner 79214d8ca6SThomas Gleixner #else /* CONFIG_ARCH_STACKWALK */ 808637c099SIngo Molnar struct stack_trace { 818637c099SIngo Molnar unsigned int nr_entries, max_entries; 828637c099SIngo Molnar unsigned long *entries; 832c34f6f7SWalter Wu unsigned int skip; /* input argument: How many entries to skip */ 848637c099SIngo Molnar }; 858637c099SIngo Molnar 86ab1b6f03SChristoph Hellwig extern void save_stack_trace(struct stack_trace *trace); 8739581062SMasami Hiramatsu extern void save_stack_trace_regs(struct pt_regs *regs, 8839581062SMasami Hiramatsu struct stack_trace *trace); 899745512cSArjan van de Ven extern void save_stack_trace_tsk(struct task_struct *tsk, 909745512cSArjan van de Ven struct stack_trace *trace); 91af085d90SJosh Poimboeuf extern int save_stack_trace_tsk_reliable(struct task_struct *tsk, 92af085d90SJosh Poimboeuf struct stack_trace *trace); 9302b67518STörök Edwin extern void save_stack_trace_user(struct stack_trace *trace); 94214d8ca6SThomas Gleixner #endif /* !CONFIG_ARCH_STACKWALK */ 95af085d90SJosh Poimboeuf #endif /* CONFIG_STACKTRACE */ 968637c099SIngo Molnar 97e9b98e16SThomas Gleixner #if defined(CONFIG_STACKTRACE) && defined(CONFIG_HAVE_RELIABLE_STACKTRACE) 98e9b98e16SThomas Gleixner int stack_trace_save_tsk_reliable(struct task_struct *tsk, unsigned long *store, 99e9b98e16SThomas Gleixner unsigned int size); 100e9b98e16SThomas Gleixner #else 101e9b98e16SThomas Gleixner static inline int stack_trace_save_tsk_reliable(struct task_struct *tsk, 102e9b98e16SThomas Gleixner unsigned long *store, 103e9b98e16SThomas Gleixner unsigned int size) 104e9b98e16SThomas Gleixner { 105e9b98e16SThomas Gleixner return -ENOSYS; 106e9b98e16SThomas Gleixner } 107e9b98e16SThomas Gleixner #endif 108e9b98e16SThomas Gleixner 109af085d90SJosh Poimboeuf #endif /* __LINUX_STACKTRACE_H */ 110