Line data Source code
1 : /* SPDX-License-Identifier: GPL-2.0 */ 2 : /* 3 : * Copyright (C) 1991, 1992 Linus Torvalds 4 : * Copyright (C) 2000, 2001, 2002 Andi Kleen, SuSE Labs 5 : */ 6 : 7 : #ifndef _ASM_X86_STACKTRACE_H 8 : #define _ASM_X86_STACKTRACE_H 9 : 10 : #include <linux/uaccess.h> 11 : #include <linux/ptrace.h> 12 : 13 : #include <asm/cpu_entry_area.h> 14 : #include <asm/switch_to.h> 15 : 16 : enum stack_type { 17 : STACK_TYPE_UNKNOWN, 18 : STACK_TYPE_TASK, 19 : STACK_TYPE_IRQ, 20 : STACK_TYPE_SOFTIRQ, 21 : STACK_TYPE_ENTRY, 22 : STACK_TYPE_EXCEPTION, 23 : STACK_TYPE_EXCEPTION_LAST = STACK_TYPE_EXCEPTION + N_EXCEPTION_STACKS-1, 24 : }; 25 : 26 : struct stack_info { 27 : enum stack_type type; 28 : unsigned long *begin, *end, *next_sp; 29 : }; 30 : 31 : bool in_task_stack(unsigned long *stack, struct task_struct *task, 32 : struct stack_info *info); 33 : 34 : bool in_entry_stack(unsigned long *stack, struct stack_info *info); 35 : 36 : int get_stack_info(unsigned long *stack, struct task_struct *task, 37 : struct stack_info *info, unsigned long *visit_mask); 38 : bool get_stack_info_noinstr(unsigned long *stack, struct task_struct *task, 39 : struct stack_info *info); 40 : 41 : const char *stack_type_name(enum stack_type type); 42 : 43 373822151 : static inline bool on_stack(struct stack_info *info, void *addr, size_t len) 44 : { 45 373822151 : void *begin = info->begin; 46 373822151 : void *end = info->end; 47 : 48 373822151 : return (info->type != STACK_TYPE_UNKNOWN && 49 372246533 : addr >= begin && addr < end && 50 741015650 : addr + len > begin && addr + len <= end); 51 : } 52 : 53 : #ifdef CONFIG_X86_32 54 : #define STACKSLOTS_PER_LINE 8 55 : #else 56 : #define STACKSLOTS_PER_LINE 4 57 : #endif 58 : 59 : #ifdef CONFIG_FRAME_POINTER 60 : static inline unsigned long * 61 : get_frame_pointer(struct task_struct *task, struct pt_regs *regs) 62 : { 63 : if (regs) 64 : return (unsigned long *)regs->bp; 65 : 66 : if (task == current) 67 : return __builtin_frame_address(0); 68 : 69 : return &((struct inactive_task_frame *)task->thread.sp)->bp; 70 : } 71 : #else 72 : static inline unsigned long * 73 : get_frame_pointer(struct task_struct *task, struct pt_regs *regs) 74 : { 75 : return NULL; 76 : } 77 : #endif /* CONFIG_FRAME_POINTER */ 78 : 79 : static inline unsigned long * 80 6784789 : get_stack_pointer(struct task_struct *task, struct pt_regs *regs) 81 : { 82 6784789 : if (regs) 83 2 : return (unsigned long *)regs->sp; 84 : 85 6784787 : if (task == current) 86 6784787 : return __builtin_frame_address(0); 87 : 88 0 : return (unsigned long *)task->thread.sp; 89 : } 90 : 91 : /* The form of the top of the frame on the stack */ 92 : struct stack_frame { 93 : struct stack_frame *next_frame; 94 : unsigned long return_address; 95 : }; 96 : 97 : struct stack_frame_ia32 { 98 : u32 next_frame; 99 : u32 return_address; 100 : }; 101 : 102 : void show_opcodes(struct pt_regs *regs, const char *loglvl); 103 : void show_ip(struct pt_regs *regs, const char *loglvl); 104 : #endif /* _ASM_X86_STACKTRACE_H */