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