unwind_frame.c (aea983801c6b5e4e9af333a32220d580a77f6783) unwind_frame.c (946c191161cef10c667b5ee3179db1714fa5b7c0)
1#include <linux/sched.h>
2#include <asm/ptrace.h>
3#include <asm/bitops.h>
4#include <asm/stacktrace.h>
5#include <asm/unwind.h>
6
7#define FRAME_HEADER_SIZE (sizeof(long) * 2)
8
9unsigned long unwind_get_return_address(struct unwind_state *state)
10{
11 unsigned long addr;
12 unsigned long *addr_p = unwind_get_return_address_ptr(state);
13
14 if (unwind_done(state))
15 return 0;
16
1#include <linux/sched.h>
2#include <asm/ptrace.h>
3#include <asm/bitops.h>
4#include <asm/stacktrace.h>
5#include <asm/unwind.h>
6
7#define FRAME_HEADER_SIZE (sizeof(long) * 2)
8
9unsigned long unwind_get_return_address(struct unwind_state *state)
10{
11 unsigned long addr;
12 unsigned long *addr_p = unwind_get_return_address_ptr(state);
13
14 if (unwind_done(state))
15 return 0;
16
17 if (state->regs && user_mode(state->regs))
18 return 0;
19
17 addr = ftrace_graph_ret_addr(state->task, &state->graph_idx, *addr_p,
18 addr_p);
19
20 return __kernel_text_address(addr) ? addr : 0;
21}
22EXPORT_SYMBOL_GPL(unwind_get_return_address);
23
20 addr = ftrace_graph_ret_addr(state->task, &state->graph_idx, *addr_p,
21 addr_p);
22
23 return __kernel_text_address(addr) ? addr : 0;
24}
25EXPORT_SYMBOL_GPL(unwind_get_return_address);
26
27/*
28 * This determines if the frame pointer actually contains an encoded pointer to
29 * pt_regs on the stack. See ENCODE_FRAME_POINTER.
30 */
31static struct pt_regs *decode_frame_pointer(unsigned long *bp)
32{
33 unsigned long regs = (unsigned long)bp;
34
35 if (!(regs & 0x1))
36 return NULL;
37
38 return (struct pt_regs *)(regs & ~0x1);
39}
40
24static bool update_stack_state(struct unwind_state *state, void *addr,
25 size_t len)
26{
27 struct stack_info *info = &state->stack_info;
28
29 /*
30 * If addr isn't on the current stack, switch to the next one.
31 *

--- 6 unchanged lines hidden (view full) ---

38 &state->stack_mask))
39 return false;
40
41 return true;
42}
43
44bool unwind_next_frame(struct unwind_state *state)
45{
41static bool update_stack_state(struct unwind_state *state, void *addr,
42 size_t len)
43{
44 struct stack_info *info = &state->stack_info;
45
46 /*
47 * If addr isn't on the current stack, switch to the next one.
48 *

--- 6 unchanged lines hidden (view full) ---

55 &state->stack_mask))
56 return false;
57
58 return true;
59}
60
61bool unwind_next_frame(struct unwind_state *state)
62{
46 unsigned long *next_bp;
63 struct pt_regs *regs;
64 unsigned long *next_bp, *next_frame;
65 size_t next_len;
47
48 if (unwind_done(state))
49 return false;
50
66
67 if (unwind_done(state))
68 return false;
69
51 next_bp = (unsigned long *)*state->bp;
70 /* have we reached the end? */
71 if (state->regs && user_mode(state->regs))
72 goto the_end;
52
73
74 /* get the next frame pointer */
75 if (state->regs)
76 next_bp = (unsigned long *)state->regs->bp;
77 else
78 next_bp = (unsigned long *)*state->bp;
79
80 /* is the next frame pointer an encoded pointer to pt_regs? */
81 regs = decode_frame_pointer(next_bp);
82 if (regs) {
83 next_frame = (unsigned long *)regs;
84 next_len = sizeof(*regs);
85 } else {
86 next_frame = next_bp;
87 next_len = FRAME_HEADER_SIZE;
88 }
89
53 /* make sure the next frame's data is accessible */
90 /* make sure the next frame's data is accessible */
54 if (!update_stack_state(state, next_bp, FRAME_HEADER_SIZE))
91 if (!update_stack_state(state, next_frame, next_len))
55 return false;
92 return false;
56
57 /* move to the next frame */
93 /* move to the next frame */
58 state->bp = next_bp;
94 if (regs) {
95 state->regs = regs;
96 state->bp = NULL;
97 } else {
98 state->bp = next_bp;
99 state->regs = NULL;
100 }
101
59 return true;
102 return true;
103
104the_end:
105 state->stack_info.type = STACK_TYPE_UNKNOWN;
106 return false;
60}
61EXPORT_SYMBOL_GPL(unwind_next_frame);
62
63void __unwind_start(struct unwind_state *state, struct task_struct *task,
64 struct pt_regs *regs, unsigned long *first_frame)
65{
107}
108EXPORT_SYMBOL_GPL(unwind_next_frame);
109
110void __unwind_start(struct unwind_state *state, struct task_struct *task,
111 struct pt_regs *regs, unsigned long *first_frame)
112{
113 unsigned long *bp, *frame;
114 size_t len;
115
66 memset(state, 0, sizeof(*state));
67 state->task = task;
68
69 /* don't even attempt to start from user mode regs */
70 if (regs && user_mode(regs)) {
71 state->stack_info.type = STACK_TYPE_UNKNOWN;
72 return;
73 }
74
75 /* set up the starting stack frame */
116 memset(state, 0, sizeof(*state));
117 state->task = task;
118
119 /* don't even attempt to start from user mode regs */
120 if (regs && user_mode(regs)) {
121 state->stack_info.type = STACK_TYPE_UNKNOWN;
122 return;
123 }
124
125 /* set up the starting stack frame */
76 state->bp = get_frame_pointer(task, regs);
126 bp = get_frame_pointer(task, regs);
127 regs = decode_frame_pointer(bp);
128 if (regs) {
129 state->regs = regs;
130 frame = (unsigned long *)regs;
131 len = sizeof(*regs);
132 } else {
133 state->bp = bp;
134 frame = bp;
135 len = FRAME_HEADER_SIZE;
136 }
77
78 /* initialize stack info and make sure the frame data is accessible */
137
138 /* initialize stack info and make sure the frame data is accessible */
79 get_stack_info(state->bp, state->task, &state->stack_info,
139 get_stack_info(frame, state->task, &state->stack_info,
80 &state->stack_mask);
140 &state->stack_mask);
81 update_stack_state(state, state->bp, FRAME_HEADER_SIZE);
141 update_stack_state(state, frame, len);
82
83 /*
84 * The caller can provide the address of the first frame directly
85 * (first_frame) or indirectly (regs->sp) to indicate which stack frame
86 * to start unwinding at. Skip ahead until we reach it.
87 */
88 while (!unwind_done(state) &&
89 (!on_stack(&state->stack_info, first_frame, sizeof(long)) ||
90 state->bp < first_frame))
91 unwind_next_frame(state);
92}
93EXPORT_SYMBOL_GPL(__unwind_start);
142
143 /*
144 * The caller can provide the address of the first frame directly
145 * (first_frame) or indirectly (regs->sp) to indicate which stack frame
146 * to start unwinding at. Skip ahead until we reach it.
147 */
148 while (!unwind_done(state) &&
149 (!on_stack(&state->stack_info, first_frame, sizeof(long)) ||
150 state->bp < first_frame))
151 unwind_next_frame(state);
152}
153EXPORT_SYMBOL_GPL(__unwind_start);