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