Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jikos/hid
[linux-2.6-block.git] / arch / x86 / include / asm / unwind.h
1 #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
9 struct 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         bool got_irq;
16         unsigned long *bp, *orig_sp;
17         struct pt_regs *regs;
18         unsigned long ip;
19 #else
20         unsigned long *sp;
21 #endif
22 };
23
24 void __unwind_start(struct unwind_state *state, struct task_struct *task,
25                     struct pt_regs *regs, unsigned long *first_frame);
26
27 bool unwind_next_frame(struct unwind_state *state);
28
29 unsigned long unwind_get_return_address(struct unwind_state *state);
30
31 static inline bool unwind_done(struct unwind_state *state)
32 {
33         return state->stack_info.type == STACK_TYPE_UNKNOWN;
34 }
35
36 static inline
37 void unwind_start(struct unwind_state *state, struct task_struct *task,
38                   struct pt_regs *regs, unsigned long *first_frame)
39 {
40         first_frame = first_frame ? : get_stack_pointer(task, regs);
41
42         __unwind_start(state, task, regs, first_frame);
43 }
44
45 #ifdef CONFIG_FRAME_POINTER
46
47 static inline
48 unsigned long *unwind_get_return_address_ptr(struct unwind_state *state)
49 {
50         if (unwind_done(state))
51                 return NULL;
52
53         return state->regs ? &state->regs->ip : state->bp + 1;
54 }
55
56 static inline struct pt_regs *unwind_get_entry_regs(struct unwind_state *state)
57 {
58         if (unwind_done(state))
59                 return NULL;
60
61         return state->regs;
62 }
63
64 #else /* !CONFIG_FRAME_POINTER */
65
66 static inline
67 unsigned long *unwind_get_return_address_ptr(struct unwind_state *state)
68 {
69         return NULL;
70 }
71
72 static inline struct pt_regs *unwind_get_entry_regs(struct unwind_state *state)
73 {
74         return NULL;
75 }
76
77 #endif /* CONFIG_FRAME_POINTER */
78
79 #endif /* _ASM_X86_UNWIND_H */