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 */ 36*264c03a2SMark 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); 55214d8ca6SThomas Gleixner int arch_stack_walk_reliable(stack_trace_consume_fn consume_entry, void *cookie, 56214d8ca6SThomas Gleixner struct task_struct *task); 57214d8ca6SThomas Gleixner void arch_stack_walk_user(stack_trace_consume_fn consume_entry, void *cookie, 58214d8ca6SThomas Gleixner const struct pt_regs *regs); 59214d8ca6SThomas Gleixner 60214d8ca6SThomas Gleixner #else /* CONFIG_ARCH_STACKWALK */ 618637c099SIngo Molnar struct stack_trace { 628637c099SIngo Molnar unsigned int nr_entries, max_entries; 638637c099SIngo Molnar unsigned long *entries; 642c34f6f7SWalter Wu unsigned int skip; /* input argument: How many entries to skip */ 658637c099SIngo Molnar }; 668637c099SIngo Molnar 67ab1b6f03SChristoph Hellwig extern void save_stack_trace(struct stack_trace *trace); 6839581062SMasami Hiramatsu extern void save_stack_trace_regs(struct pt_regs *regs, 6939581062SMasami Hiramatsu struct stack_trace *trace); 709745512cSArjan van de Ven extern void save_stack_trace_tsk(struct task_struct *tsk, 719745512cSArjan van de Ven struct stack_trace *trace); 72af085d90SJosh Poimboeuf extern int save_stack_trace_tsk_reliable(struct task_struct *tsk, 73af085d90SJosh Poimboeuf struct stack_trace *trace); 7402b67518STörök Edwin extern void save_stack_trace_user(struct stack_trace *trace); 75214d8ca6SThomas Gleixner #endif /* !CONFIG_ARCH_STACKWALK */ 76af085d90SJosh Poimboeuf #endif /* CONFIG_STACKTRACE */ 778637c099SIngo Molnar 78e9b98e16SThomas Gleixner #if defined(CONFIG_STACKTRACE) && defined(CONFIG_HAVE_RELIABLE_STACKTRACE) 79e9b98e16SThomas Gleixner int stack_trace_save_tsk_reliable(struct task_struct *tsk, unsigned long *store, 80e9b98e16SThomas Gleixner unsigned int size); 81e9b98e16SThomas Gleixner #else 82e9b98e16SThomas Gleixner static inline int stack_trace_save_tsk_reliable(struct task_struct *tsk, 83e9b98e16SThomas Gleixner unsigned long *store, 84e9b98e16SThomas Gleixner unsigned int size) 85e9b98e16SThomas Gleixner { 86e9b98e16SThomas Gleixner return -ENOSYS; 87e9b98e16SThomas Gleixner } 88e9b98e16SThomas Gleixner #endif 89e9b98e16SThomas Gleixner 90af085d90SJosh Poimboeuf #endif /* __LINUX_STACKTRACE_H */ 91