blob: 46de9ac4b9905b9e152a937b2b76613b01e0f5ee [file] [log] [blame]
Josh Poimboeuf7c7900f2016-09-16 14:18:12 -05001#ifndef _ASM_X86_UNWIND_H
2#define _ASM_X86_UNWIND_H
3
4#include <linux/sched.h>
5#include <linux/ftrace.h>
6#include <asm/ptrace.h>
7#include <asm/stacktrace.h>
8
9struct unwind_state {
10 struct stack_info stack_info;
11 unsigned long stack_mask;
12 struct task_struct *task;
13 int graph_idx;
14#ifdef CONFIG_FRAME_POINTER
15 unsigned long *bp;
16#else
17 unsigned long *sp;
18#endif
19};
20
21void __unwind_start(struct unwind_state *state, struct task_struct *task,
22 struct pt_regs *regs, unsigned long *first_frame);
23
24bool unwind_next_frame(struct unwind_state *state);
25
Josh Poimboeufcfee9ed2016-10-06 00:28:40 -050026unsigned long unwind_get_return_address(struct unwind_state *state);
27
Josh Poimboeuf7c7900f2016-09-16 14:18:12 -050028static inline bool unwind_done(struct unwind_state *state)
29{
30 return state->stack_info.type == STACK_TYPE_UNKNOWN;
31}
32
33static inline
34void unwind_start(struct unwind_state *state, struct task_struct *task,
35 struct pt_regs *regs, unsigned long *first_frame)
36{
37 first_frame = first_frame ? : get_stack_pointer(task, regs);
38
39 __unwind_start(state, task, regs, first_frame);
40}
41
42#ifdef CONFIG_FRAME_POINTER
43
44static inline
45unsigned long *unwind_get_return_address_ptr(struct unwind_state *state)
46{
47 if (unwind_done(state))
48 return NULL;
49
50 return state->bp + 1;
51}
52
Josh Poimboeuf7c7900f2016-09-16 14:18:12 -050053#else /* !CONFIG_FRAME_POINTER */
54
55static inline
56unsigned long *unwind_get_return_address_ptr(struct unwind_state *state)
57{
58 return NULL;
59}
60
Josh Poimboeuf7c7900f2016-09-16 14:18:12 -050061#endif /* CONFIG_FRAME_POINTER */
62
63#endif /* _ASM_X86_UNWIND_H */