unwind_frame.c (8023e0e2a48d45e8d5363081fad9f7ed4402f953) unwind_frame.c (8b5e99f02264130782a10ba5c0c759797fb064ee)
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
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
9static void unwind_dump(struct unwind_state *state, unsigned long *sp)
10{
11 static bool dumped_before = false;
12 bool prev_zero, zero = false;
13 unsigned long word;
14
15 if (dumped_before)
16 return;
17
18 dumped_before = true;
19
20 printk_deferred("unwind stack type:%d next_sp:%p mask:%lx graph_idx:%d\n",
21 state->stack_info.type, state->stack_info.next_sp,
22 state->stack_mask, state->graph_idx);
23
24 for (sp = state->orig_sp; sp < state->stack_info.end; sp++) {
25 word = READ_ONCE_NOCHECK(*sp);
26
27 prev_zero = zero;
28 zero = word == 0;
29
30 if (zero) {
31 if (!prev_zero)
32 printk_deferred("%p: %016x ...\n", sp, 0);
33 continue;
34 }
35
36 printk_deferred("%p: %016lx (%pB)\n", sp, word, (void *)word);
37 }
38}
39
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
20 addr = ftrace_graph_ret_addr(state->task, &state->graph_idx, *addr_p,
21 addr_p);
22
23 if (!__kernel_text_address(addr)) {
24 printk_deferred_once(KERN_WARNING
25 "WARNING: unrecognized kernel stack return address %p at %p in %s:%d\n",
26 (void *)addr, addr_p, state->task->comm,
27 state->task->pid);
40unsigned long unwind_get_return_address(struct unwind_state *state)
41{
42 unsigned long addr;
43 unsigned long *addr_p = unwind_get_return_address_ptr(state);
44
45 if (unwind_done(state))
46 return 0;
47
48 if (state->regs && user_mode(state->regs))
49 return 0;
50
51 addr = ftrace_graph_ret_addr(state->task, &state->graph_idx, *addr_p,
52 addr_p);
53
54 if (!__kernel_text_address(addr)) {
55 printk_deferred_once(KERN_WARNING
56 "WARNING: unrecognized kernel stack return address %p at %p in %s:%d\n",
57 (void *)addr, addr_p, state->task->comm,
58 state->task->pid);
59 unwind_dump(state, addr_p);
28 return 0;
29 }
30
31 return addr;
32}
33EXPORT_SYMBOL_GPL(unwind_get_return_address);
34
35static size_t regs_size(struct pt_regs *regs)

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

69
70 return (struct pt_regs *)(regs & ~0x1);
71}
72
73static bool update_stack_state(struct unwind_state *state, void *addr,
74 size_t len)
75{
76 struct stack_info *info = &state->stack_info;
60 return 0;
61 }
62
63 return addr;
64}
65EXPORT_SYMBOL_GPL(unwind_get_return_address);
66
67static size_t regs_size(struct pt_regs *regs)

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

101
102 return (struct pt_regs *)(regs & ~0x1);
103}
104
105static bool update_stack_state(struct unwind_state *state, void *addr,
106 size_t len)
107{
108 struct stack_info *info = &state->stack_info;
109 enum stack_type orig_type = info->type;
77
78 /*
79 * If addr isn't on the current stack, switch to the next one.
80 *
81 * We may have to traverse multiple stacks to deal with the possibility
82 * that 'info->next_sp' could point to an empty stack and 'addr' could
83 * be on a subsequent stack.
84 */
85 while (!on_stack(info, addr, len))
86 if (get_stack_info(info->next_sp, state->task, info,
87 &state->stack_mask))
88 return false;
89
110
111 /*
112 * If addr isn't on the current stack, switch to the next one.
113 *
114 * We may have to traverse multiple stacks to deal with the possibility
115 * that 'info->next_sp' could point to an empty stack and 'addr' could
116 * be on a subsequent stack.
117 */
118 while (!on_stack(info, addr, len))
119 if (get_stack_info(info->next_sp, state->task, info,
120 &state->stack_mask))
121 return false;
122
123 if (!state->orig_sp || info->type != orig_type)
124 state->orig_sp = addr;
125
90 return true;
91}
92
93bool unwind_next_frame(struct unwind_state *state)
94{
95 struct pt_regs *regs;
96 unsigned long *next_bp, *next_frame;
97 size_t next_len;

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

180 return true;
181
182bad_address:
183 if (state->regs) {
184 printk_deferred_once(KERN_WARNING
185 "WARNING: kernel stack regs at %p in %s:%d has bad 'bp' value %p\n",
186 state->regs, state->task->comm,
187 state->task->pid, next_frame);
126 return true;
127}
128
129bool unwind_next_frame(struct unwind_state *state)
130{
131 struct pt_regs *regs;
132 unsigned long *next_bp, *next_frame;
133 size_t next_len;

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

216 return true;
217
218bad_address:
219 if (state->regs) {
220 printk_deferred_once(KERN_WARNING
221 "WARNING: kernel stack regs at %p in %s:%d has bad 'bp' value %p\n",
222 state->regs, state->task->comm,
223 state->task->pid, next_frame);
224 unwind_dump(state, (unsigned long *)state->regs);
188 } else {
189 printk_deferred_once(KERN_WARNING
190 "WARNING: kernel stack frame pointer at %p in %s:%d has bad value %p\n",
191 state->bp, state->task->comm,
192 state->task->pid, next_frame);
225 } else {
226 printk_deferred_once(KERN_WARNING
227 "WARNING: kernel stack frame pointer at %p in %s:%d has bad value %p\n",
228 state->bp, state->task->comm,
229 state->task->pid, next_frame);
230 unwind_dump(state, state->bp);
193 }
194the_end:
195 state->stack_info.type = STACK_TYPE_UNKNOWN;
196 return false;
197}
198EXPORT_SYMBOL_GPL(unwind_next_frame);
199
200void __unwind_start(struct unwind_state *state, struct task_struct *task,

--- 43 unchanged lines hidden ---
231 }
232the_end:
233 state->stack_info.type = STACK_TYPE_UNKNOWN;
234 return false;
235}
236EXPORT_SYMBOL_GPL(unwind_next_frame);
237
238void __unwind_start(struct unwind_state *state, struct task_struct *task,

--- 43 unchanged lines hidden ---