Branch data Line data Source code
1 : : // SPDX-License-Identifier: GPL-2.0-only
2 : : #include <linux/module.h>
3 : : #include <linux/sort.h>
4 : : #include <asm/ptrace.h>
5 : : #include <asm/stacktrace.h>
6 : : #include <asm/unwind.h>
7 : : #include <asm/orc_types.h>
8 : : #include <asm/orc_lookup.h>
9 : :
10 : : #define orc_warn(fmt, ...) \
11 : : printk_deferred_once(KERN_WARNING pr_fmt("WARNING: " fmt), ##__VA_ARGS__)
12 : :
13 : : extern int __start_orc_unwind_ip[];
14 : : extern int __stop_orc_unwind_ip[];
15 : : extern struct orc_entry __start_orc_unwind[];
16 : : extern struct orc_entry __stop_orc_unwind[];
17 : :
18 : : static DEFINE_MUTEX(sort_mutex);
19 : : int *cur_orc_ip_table = __start_orc_unwind_ip;
20 : : struct orc_entry *cur_orc_table = __start_orc_unwind;
21 : :
22 : : unsigned int lookup_num_blocks;
23 : : bool orc_init;
24 : :
25 : 80183000 : static inline unsigned long orc_ip(const int *ip)
26 : : {
27 : 80183000 : return (unsigned long)ip + *ip;
28 : : }
29 : :
30 : 4731760 : static struct orc_entry *__orc_find(int *ip_table, struct orc_entry *u_table,
31 : : unsigned int num_entries, unsigned long ip)
32 : : {
33 : 4731760 : int *first = ip_table;
34 : 4731760 : int *last = ip_table + num_entries - 1;
35 : 4731760 : int *mid = first, *found = first;
36 : :
37 [ + - ]: 4731760 : if (!num_entries)
38 : : return NULL;
39 : :
40 : : /*
41 : : * Do a binary range search to find the rightmost duplicate of a given
42 : : * starting address. Some entries are section terminators which are
43 : : * "weak" entries for ensuring there are no gaps. They should be
44 : : * ignored when they conflict with a real entry.
45 : : */
46 [ + + ]: 83358120 : while (first <= last) {
47 : 78626340 : mid = first + ((last - first) / 2);
48 : :
49 [ + + ]: 78626340 : if (orc_ip(mid) <= ip) {
50 : 41186920 : found = mid;
51 : 41186920 : first = mid + 1;
52 : : } else
53 : 37439420 : last = mid - 1;
54 : : }
55 : :
56 : 4731760 : return u_table + (found - ip_table);
57 : : }
58 : :
59 : : #ifdef CONFIG_MODULES
60 : 10794 : static struct orc_entry *orc_module_find(unsigned long ip)
61 : : {
62 : 10794 : struct module *mod;
63 : :
64 : 10794 : mod = __module_address(ip);
65 [ + - + - : 10794 : if (!mod || !mod->arch.orc_unwind || !mod->arch.orc_unwind_ip)
+ - ]
66 : : return NULL;
67 : 10794 : return __orc_find(mod->arch.orc_unwind_ip, mod->arch.orc_unwind,
68 : : mod->arch.num_orcs, ip);
69 : : }
70 : : #else
71 : : static struct orc_entry *orc_module_find(unsigned long ip)
72 : : {
73 : : return NULL;
74 : : }
75 : : #endif
76 : :
77 : : #ifdef CONFIG_DYNAMIC_FTRACE
78 : : static struct orc_entry *orc_find(unsigned long ip);
79 : :
80 : : /*
81 : : * Ftrace dynamic trampolines do not have orc entries of their own.
82 : : * But they are copies of the ftrace entries that are static and
83 : : * defined in ftrace_*.S, which do have orc entries.
84 : : *
85 : : * If the unwinder comes across a ftrace trampoline, then find the
86 : : * ftrace function that was used to create it, and use that ftrace
87 : : * function's orc entry, as the placement of the return code in
88 : : * the stack will be identical.
89 : : */
90 : : static struct orc_entry *orc_ftrace_find(unsigned long ip)
91 : : {
92 : : struct ftrace_ops *ops;
93 : : unsigned long caller;
94 : :
95 : : ops = ftrace_ops_trampoline(ip);
96 : : if (!ops)
97 : : return NULL;
98 : :
99 : : if (ops->flags & FTRACE_OPS_FL_SAVE_REGS)
100 : : caller = (unsigned long)ftrace_regs_call;
101 : : else
102 : : caller = (unsigned long)ftrace_call;
103 : :
104 : : /* Prevent unlikely recursion */
105 : : if (ip == caller)
106 : : return NULL;
107 : :
108 : : return orc_find(caller);
109 : : }
110 : : #else
111 : : static struct orc_entry *orc_ftrace_find(unsigned long ip)
112 : : {
113 : : return NULL;
114 : : }
115 : : #endif
116 : :
117 : : /*
118 : : * If we crash with IP==0, the last successfully executed instruction
119 : : * was probably an indirect function call with a NULL function pointer,
120 : : * and we don't have unwind information for NULL.
121 : : * This hardcoded ORC entry for IP==0 allows us to unwind from a NULL function
122 : : * pointer into its parent and then continue normally from there.
123 : : */
124 : : static struct orc_entry null_orc_entry = {
125 : : .sp_offset = sizeof(long),
126 : : .sp_reg = ORC_REG_SP,
127 : : .bp_reg = ORC_REG_UNDEFINED,
128 : : .type = ORC_TYPE_CALL
129 : : };
130 : :
131 : : /* Fake frame pointer entry -- used as a fallback for generated code */
132 : : static struct orc_entry orc_fp_entry = {
133 : : .type = ORC_TYPE_CALL,
134 : : .sp_reg = ORC_REG_BP,
135 : : .sp_offset = 16,
136 : : .bp_reg = ORC_REG_PREV_SP,
137 : : .bp_offset = -16,
138 : : .end = 0,
139 : : };
140 : :
141 : 774499 : static struct orc_entry *orc_find(unsigned long ip)
142 : : {
143 : 774499 : static struct orc_entry *orc;
144 : :
145 [ + - ]: 774499 : if (!orc_init)
146 : : return NULL;
147 : :
148 [ + - ]: 774499 : if (ip == 0)
149 : : return &null_orc_entry;
150 : :
151 : : /* For non-init vmlinux addresses, use the fast lookup table: */
152 [ + - + + ]: 774499 : if (ip >= LOOKUP_START_IP && ip < LOOKUP_STOP_IP) {
153 : 763621 : unsigned int idx, start, stop;
154 : :
155 : 763621 : idx = (ip - LOOKUP_START_IP) / LOOKUP_BLOCK_SIZE;
156 : :
157 [ - + ]: 763621 : if (unlikely((idx >= lookup_num_blocks-1))) {
158 [ # # ]: 0 : orc_warn("WARNING: bad lookup idx: idx=%u num=%u ip=%pB\n",
159 : : idx, lookup_num_blocks, (void *)ip);
160 : 0 : return NULL;
161 : : }
162 : :
163 : 763621 : start = orc_lookup[idx];
164 : 763621 : stop = orc_lookup[idx + 1] + 1;
165 : :
166 [ + - - + ]: 763621 : if (unlikely((__start_orc_unwind + start >= __stop_orc_unwind) ||
167 : : (__start_orc_unwind + stop > __stop_orc_unwind))) {
168 [ # # ]: 0 : orc_warn("WARNING: bad lookup value: idx=%u num=%u start=%u stop=%u ip=%pB\n",
169 : : idx, lookup_num_blocks, start, stop, (void *)ip);
170 : 0 : return NULL;
171 : : }
172 : :
173 : 763621 : return __orc_find(__start_orc_unwind_ip + start,
174 : : __start_orc_unwind + start, stop - start, ip);
175 : : }
176 : :
177 : : /* vmlinux .init slow lookup: */
178 [ + + ]: 10878 : if (init_kernel_text(ip))
179 : 84 : return __orc_find(__start_orc_unwind_ip, __start_orc_unwind,
180 : 84 : __stop_orc_unwind_ip - __start_orc_unwind_ip, ip);
181 : :
182 : : /* Module lookup: */
183 : 10794 : orc = orc_module_find(ip);
184 [ + - ]: 10794 : if (orc)
185 : 10794 : return orc;
186 : :
187 : : return orc_ftrace_find(ip);
188 : : }
189 : :
190 : : #ifdef CONFIG_MODULES
191 : :
192 : 1483482 : static void orc_sort_swap(void *_a, void *_b, int size)
193 : : {
194 : 1483482 : struct orc_entry *orc_a, *orc_b;
195 : 1483482 : struct orc_entry orc_tmp;
196 : 1483482 : int *a = _a, *b = _b, tmp;
197 : 1483482 : int delta = _b - _a;
198 : :
199 : : /* Swap the .orc_unwind_ip entries: */
200 : 1483482 : tmp = *a;
201 : 1483482 : *a = *b + delta;
202 : 1483482 : *b = tmp - delta;
203 : :
204 : : /* Swap the corresponding .orc_unwind entries: */
205 : 1483482 : orc_a = cur_orc_table + (a - cur_orc_ip_table);
206 : 1483482 : orc_b = cur_orc_table + (b - cur_orc_ip_table);
207 : 1483482 : orc_tmp = *orc_a;
208 : 1483482 : *orc_a = *orc_b;
209 : 1483482 : *orc_b = orc_tmp;
210 : 1483482 : }
211 : :
212 : 1556646 : static int orc_sort_cmp(const void *_a, const void *_b)
213 : : {
214 : 1556646 : struct orc_entry *orc_a;
215 : 1556646 : const int *a = _a, *b = _b;
216 : 1556646 : unsigned long a_val = orc_ip(a);
217 : 1556646 : unsigned long b_val = orc_ip(b);
218 : :
219 [ + + ]: 1556646 : if (a_val > b_val)
220 : : return 1;
221 [ + + ]: 854679 : if (a_val < b_val)
222 : : return -1;
223 : :
224 : : /*
225 : : * The "weak" section terminator entries need to always be on the left
226 : : * to ensure the lookup code skips them in favor of real entries.
227 : : * These terminator entries exist to handle any gaps created by
228 : : * whitelisted .o files which didn't get objtool generation.
229 : : */
230 : 63 : orc_a = cur_orc_table + (a - cur_orc_ip_table);
231 [ + - - + ]: 63 : return orc_a->sp_reg == ORC_REG_UNDEFINED && !orc_a->end ? -1 : 1;
232 : : }
233 : :
234 : 63 : void unwind_module_init(struct module *mod, void *_orc_ip, size_t orc_ip_size,
235 : : void *_orc, size_t orc_size)
236 : : {
237 : 63 : int *orc_ip = _orc_ip;
238 : 63 : struct orc_entry *orc = _orc;
239 : 63 : unsigned int num_entries = orc_ip_size / sizeof(int);
240 : :
241 [ + - + - : 126 : WARN_ON_ONCE(orc_ip_size % sizeof(int) != 0 ||
+ - - + ]
242 : : orc_size % sizeof(*orc) != 0 ||
243 : : num_entries != orc_size / sizeof(*orc));
244 : :
245 : : /*
246 : : * The 'cur_orc_*' globals allow the orc_sort_swap() callback to
247 : : * associate an .orc_unwind_ip table entry with its corresponding
248 : : * .orc_unwind entry so they can both be swapped.
249 : : */
250 : 63 : mutex_lock(&sort_mutex);
251 : 63 : cur_orc_ip_table = orc_ip;
252 : 63 : cur_orc_table = orc;
253 : 63 : sort(orc_ip, num_entries, sizeof(int), orc_sort_cmp, orc_sort_swap);
254 : 63 : mutex_unlock(&sort_mutex);
255 : :
256 : 63 : mod->arch.orc_unwind_ip = orc_ip;
257 : 63 : mod->arch.orc_unwind = orc;
258 : 63 : mod->arch.num_orcs = num_entries;
259 : 63 : }
260 : : #endif
261 : :
262 : 21 : void __init unwind_init(void)
263 : : {
264 : 21 : size_t orc_ip_size = (void *)__stop_orc_unwind_ip - (void *)__start_orc_unwind_ip;
265 : 21 : size_t orc_size = (void *)__stop_orc_unwind - (void *)__start_orc_unwind;
266 : 21 : size_t num_entries = orc_ip_size / sizeof(int);
267 : 21 : struct orc_entry *orc;
268 : 21 : int i;
269 : :
270 [ + - + - ]: 21 : if (!num_entries || orc_ip_size % sizeof(int) != 0 ||
271 [ + - ]: 21 : orc_size % sizeof(struct orc_entry) != 0 ||
272 [ - + ]: 21 : num_entries != orc_size / sizeof(struct orc_entry)) {
273 [ # # ]: 0 : orc_warn("WARNING: Bad or missing .orc_unwind table. Disabling unwinder.\n");
274 : 0 : return;
275 : : }
276 : :
277 : : /*
278 : : * Note, the orc_unwind and orc_unwind_ip tables were already
279 : : * sorted at build time via the 'sorttable' tool.
280 : : * It's ready for binary search straight away, no need to sort it.
281 : : */
282 : :
283 : : /* Initialize the fast lookup table: */
284 : 21 : lookup_num_blocks = orc_lookup_end - orc_lookup;
285 [ + + ]: 3957261 : for (i = 0; i < lookup_num_blocks-1; i++) {
286 : 3957240 : orc = __orc_find(__start_orc_unwind_ip, __start_orc_unwind,
287 : : num_entries,
288 : 3957240 : LOOKUP_START_IP + (LOOKUP_BLOCK_SIZE * i));
289 [ - + ]: 3957240 : if (!orc) {
290 [ # # ]: 0 : orc_warn("WARNING: Corrupt .orc_unwind table. Disabling unwinder.\n");
291 : 0 : return;
292 : : }
293 : :
294 : 3957240 : orc_lookup[i] = orc - __start_orc_unwind;
295 : : }
296 : :
297 : : /* Initialize the ending block: */
298 : 21 : orc = __orc_find(__start_orc_unwind_ip, __start_orc_unwind, num_entries,
299 : : LOOKUP_STOP_IP);
300 [ - + ]: 21 : if (!orc) {
301 [ # # ]: 0 : orc_warn("WARNING: Corrupt .orc_unwind table. Disabling unwinder.\n");
302 : 0 : return;
303 : : }
304 : 21 : orc_lookup[lookup_num_blocks-1] = orc - __start_orc_unwind;
305 : :
306 : 21 : orc_init = true;
307 : : }
308 : :
309 : 677558 : unsigned long unwind_get_return_address(struct unwind_state *state)
310 : : {
311 [ + - ]: 677558 : if (unwind_done(state))
312 : : return 0;
313 : :
314 [ + - ]: 677558 : return __kernel_text_address(state->ip) ? state->ip : 0;
315 : : }
316 : : EXPORT_SYMBOL_GPL(unwind_get_return_address);
317 : :
318 : 1092 : unsigned long *unwind_get_return_address_ptr(struct unwind_state *state)
319 : : {
320 [ + + ]: 1092 : if (unwind_done(state))
321 : : return NULL;
322 : :
323 [ - + ]: 651 : if (state->regs)
324 : 0 : return &state->regs->ip;
325 : :
326 [ + - ]: 651 : if (state->sp)
327 : 651 : return (unsigned long *)state->sp - 1;
328 : :
329 : : return NULL;
330 : : }
331 : :
332 : 1452099 : static bool stack_access_ok(struct unwind_state *state, unsigned long _addr,
333 : : size_t len)
334 : : {
335 : 1452099 : struct stack_info *info = &state->stack_info;
336 : 1452099 : void *addr = (void *)_addr;
337 : :
338 [ + - - + : 2904198 : if (!on_stack(info, addr, len) &&
- - ]
339 : 0 : (get_stack_info(addr, state->task, info, &state->stack_mask)))
340 : 0 : return false;
341 : :
342 : : return true;
343 : : }
344 : :
345 : 1452099 : static bool deref_stack_reg(struct unwind_state *state, unsigned long addr,
346 : : unsigned long *val)
347 : : {
348 [ + - ]: 1452099 : if (!stack_access_ok(state, addr, sizeof(long)))
349 : : return false;
350 : :
351 : 1452099 : *val = READ_ONCE_NOCHECK(*(unsigned long *)addr);
352 : 1452099 : return true;
353 : : }
354 : :
355 : 0 : static bool deref_stack_regs(struct unwind_state *state, unsigned long addr,
356 : : unsigned long *ip, unsigned long *sp)
357 : : {
358 : 0 : struct pt_regs *regs = (struct pt_regs *)addr;
359 : :
360 : : /* x86-32 support will be more complicated due to the ®s->sp hack */
361 : 0 : BUILD_BUG_ON(IS_ENABLED(CONFIG_X86_32));
362 : :
363 [ # # ]: 0 : if (!stack_access_ok(state, addr, sizeof(struct pt_regs)))
364 : : return false;
365 : :
366 : 0 : *ip = regs->ip;
367 : 0 : *sp = regs->sp;
368 : 0 : return true;
369 : : }
370 : :
371 : 0 : static bool deref_stack_iret_regs(struct unwind_state *state, unsigned long addr,
372 : : unsigned long *ip, unsigned long *sp)
373 : : {
374 : 0 : struct pt_regs *regs = (void *)addr - IRET_FRAME_OFFSET;
375 : :
376 [ # # ]: 0 : if (!stack_access_ok(state, addr, IRET_FRAME_SIZE))
377 : : return false;
378 : :
379 : 0 : *ip = regs->ip;
380 : 0 : *sp = regs->sp;
381 : 0 : return true;
382 : : }
383 : :
384 : 774499 : bool unwind_next_frame(struct unwind_state *state)
385 : : {
386 : 774499 : unsigned long ip_p, sp, orig_ip = state->ip, prev_sp = state->sp;
387 : 774499 : enum stack_type prev_type = state->stack_info.type;
388 : 774499 : struct orc_entry *orc;
389 : 774499 : bool indirect = false;
390 : :
391 [ + - ]: 774499 : if (unwind_done(state))
392 : : return false;
393 : :
394 : : /* Don't let modules unload while we're reading their ORC data. */
395 : 774499 : preempt_disable();
396 : :
397 : : /* End-of-stack check for user tasks: */
398 [ + + - + ]: 774499 : if (state->regs && user_mode(state->regs))
399 : 0 : goto the_end;
400 : :
401 : : /*
402 : : * Find the orc_entry associated with the text address.
403 : : *
404 : : * Decrement call return addresses by one so they work for sibling
405 : : * calls and calls to noreturn functions.
406 : : */
407 [ + + ]: 774499 : orc = orc_find(state->signal ? state->ip : state->ip - 1);
408 [ - + ]: 774499 : if (!orc) {
409 : : /*
410 : : * As a fallback, try to assume this code uses a frame pointer.
411 : : * This is useful for generated code, like BPF, which ORC
412 : : * doesn't know about. This is just a guess, so the rest of
413 : : * the unwind is no longer considered reliable.
414 : : */
415 : 0 : orc = &orc_fp_entry;
416 : 0 : state->error = true;
417 : : }
418 : :
419 : : /* End-of-stack check for kernel threads: */
420 [ + + ]: 774499 : if (orc->sp_reg == ORC_REG_UNDEFINED) {
421 [ - + ]: 21 : if (!orc->end)
422 : 0 : goto err;
423 : :
424 : 21 : goto the_end;
425 : : }
426 : :
427 : : /* Find the previous frame's stack: */
428 [ + + - - : 774478 : switch (orc->sp_reg) {
- - - -
- ]
429 : 677684 : case ORC_REG_SP:
430 : 677684 : sp = state->sp + orc->sp_offset;
431 : 677684 : break;
432 : :
433 : 96794 : case ORC_REG_BP:
434 : 96794 : sp = state->bp + orc->sp_offset;
435 : 96794 : break;
436 : :
437 : 0 : case ORC_REG_SP_INDIRECT:
438 : 0 : sp = state->sp + orc->sp_offset;
439 : 0 : indirect = true;
440 : 0 : break;
441 : :
442 : 0 : case ORC_REG_BP_INDIRECT:
443 : 0 : sp = state->bp + orc->sp_offset;
444 : 0 : indirect = true;
445 : 0 : break;
446 : :
447 : 0 : case ORC_REG_R10:
448 [ # # # # ]: 0 : if (!state->regs || !state->full_regs) {
449 [ # # ]: 0 : orc_warn("missing regs for base reg R10 at ip %pB\n",
450 : : (void *)state->ip);
451 : 0 : goto err;
452 : : }
453 : 0 : sp = state->regs->r10;
454 : 0 : break;
455 : :
456 : 0 : case ORC_REG_R13:
457 [ # # # # ]: 0 : if (!state->regs || !state->full_regs) {
458 [ # # ]: 0 : orc_warn("missing regs for base reg R13 at ip %pB\n",
459 : : (void *)state->ip);
460 : 0 : goto err;
461 : : }
462 : 0 : sp = state->regs->r13;
463 : 0 : break;
464 : :
465 : 0 : case ORC_REG_DI:
466 [ # # # # ]: 0 : if (!state->regs || !state->full_regs) {
467 [ # # ]: 0 : orc_warn("missing regs for base reg DI at ip %pB\n",
468 : : (void *)state->ip);
469 : 0 : goto err;
470 : : }
471 : 0 : sp = state->regs->di;
472 : 0 : break;
473 : :
474 : 0 : case ORC_REG_DX:
475 [ # # # # ]: 0 : if (!state->regs || !state->full_regs) {
476 [ # # ]: 0 : orc_warn("missing regs for base reg DX at ip %pB\n",
477 : : (void *)state->ip);
478 : 0 : goto err;
479 : : }
480 : 0 : sp = state->regs->dx;
481 : 0 : break;
482 : :
483 : 0 : default:
484 [ # # ]: 0 : orc_warn("unknown SP base reg %d for ip %pB\n",
485 : : orc->sp_reg, (void *)state->ip);
486 : 0 : goto err;
487 : : }
488 : :
489 : 774478 : if (indirect) {
490 [ # # ]: 0 : if (!deref_stack_reg(state, sp, &sp))
491 : 0 : goto err;
492 : : }
493 : :
494 : : /* Find IP, SP and possibly regs: */
495 [ + - - - ]: 774478 : switch (orc->type) {
496 : 774478 : case ORC_TYPE_CALL:
497 : 774478 : ip_p = sp - sizeof(long);
498 : :
499 [ - + ]: 774478 : if (!deref_stack_reg(state, ip_p, &state->ip))
500 : 0 : goto err;
501 : :
502 : 774478 : state->ip = ftrace_graph_ret_addr(state->task, &state->graph_idx,
503 : : state->ip, (void *)ip_p);
504 : :
505 : 774478 : state->sp = sp;
506 : 774478 : state->regs = NULL;
507 : 774478 : state->signal = false;
508 : 774478 : break;
509 : :
510 : 0 : case ORC_TYPE_REGS:
511 : 0 : if (!deref_stack_regs(state, sp, &state->ip, &state->sp)) {
512 [ # # ]: 0 : orc_warn("can't dereference registers at %p for ip %pB\n",
513 : : (void *)sp, (void *)orig_ip);
514 : 0 : goto err;
515 : : }
516 : :
517 : 0 : state->regs = (struct pt_regs *)sp;
518 : 0 : state->full_regs = true;
519 : 0 : state->signal = true;
520 : 0 : break;
521 : :
522 : 0 : case ORC_TYPE_REGS_IRET:
523 : 0 : if (!deref_stack_iret_regs(state, sp, &state->ip, &state->sp)) {
524 [ # # ]: 0 : orc_warn("can't dereference iret registers at %p for ip %pB\n",
525 : : (void *)sp, (void *)orig_ip);
526 : 0 : goto err;
527 : : }
528 : :
529 : 0 : state->regs = (void *)sp - IRET_FRAME_OFFSET;
530 : 0 : state->full_regs = false;
531 : 0 : state->signal = true;
532 : 0 : break;
533 : :
534 : 0 : default:
535 [ # # ]: 0 : orc_warn("unknown .orc_unwind entry type %d for ip %pB\n",
536 : : orc->type, (void *)orig_ip);
537 : 0 : break;
538 : : }
539 : :
540 : : /* Find BP: */
541 [ + + - - ]: 774478 : switch (orc->bp_reg) {
542 : 96857 : case ORC_REG_UNDEFINED:
543 [ - + - - ]: 96857 : if (state->regs && state->full_regs)
544 : 0 : state->bp = state->regs->bp;
545 : : break;
546 : :
547 : 677621 : case ORC_REG_PREV_SP:
548 [ - + ]: 677621 : if (!deref_stack_reg(state, sp + orc->bp_offset, &state->bp))
549 : 0 : goto err;
550 : : break;
551 : :
552 : 0 : case ORC_REG_BP:
553 [ # # ]: 0 : if (!deref_stack_reg(state, state->bp + orc->bp_offset, &state->bp))
554 : 0 : goto err;
555 : : break;
556 : :
557 : 0 : default:
558 [ # # ]: 0 : orc_warn("unknown BP base reg %d for ip %pB\n",
559 : : orc->bp_reg, (void *)orig_ip);
560 : 0 : goto err;
561 : : }
562 : :
563 : : /* Prevent a recursive loop due to bad ORC data: */
564 [ + - + - ]: 1548956 : if (state->stack_info.type == prev_type &&
565 [ + - - + ]: 1548956 : on_stack(&state->stack_info, (void *)state->sp, sizeof(long)) &&
566 : : state->sp <= prev_sp) {
567 [ # # ]: 0 : orc_warn("stack going in the wrong direction? ip=%pB\n",
568 : : (void *)orig_ip);
569 : 0 : goto err;
570 : : }
571 : :
572 : 774478 : preempt_enable();
573 : 774478 : return true;
574 : :
575 : 0 : err:
576 : 0 : state->error = true;
577 : :
578 : 21 : the_end:
579 : 21 : preempt_enable();
580 : 21 : state->stack_info.type = STACK_TYPE_UNKNOWN;
581 : 21 : return false;
582 : : }
583 : : EXPORT_SYMBOL_GPL(unwind_next_frame);
584 : :
585 : 96815 : void __unwind_start(struct unwind_state *state, struct task_struct *task,
586 : : struct pt_regs *regs, unsigned long *first_frame)
587 : : {
588 : 96815 : memset(state, 0, sizeof(*state));
589 : 96815 : state->task = task;
590 : :
591 : : /*
592 : : * Refuse to unwind the stack of a task while it's executing on another
593 : : * CPU. This check is racy, but that's ok: the unwinder has other
594 : : * checks to prevent it from going off the rails.
595 : : */
596 [ - + - + ]: 193630 : if (task_on_another_cpu(task))
597 : 0 : goto done;
598 : :
599 [ + + ]: 96815 : if (regs) {
600 [ - + ]: 21 : if (user_mode(regs))
601 : 0 : goto done;
602 : :
603 : 21 : state->ip = regs->ip;
604 : 21 : state->sp = regs->sp;
605 : 21 : state->bp = regs->bp;
606 : 21 : state->regs = regs;
607 : 21 : state->full_regs = true;
608 : 21 : state->signal = true;
609 : :
610 [ + - ]: 96794 : } else if (task == current) {
611 : 96794 : asm volatile("lea (%%rip), %0\n\t"
612 : : "mov %%rsp, %1\n\t"
613 : : "mov %%rbp, %2\n\t"
614 : : : "=r" (state->ip), "=r" (state->sp),
615 : : "=r" (state->bp));
616 : :
617 : : } else {
618 : 0 : struct inactive_task_frame *frame = (void *)task->thread.sp;
619 : :
620 : 0 : state->sp = task->thread.sp;
621 : 0 : state->bp = READ_ONCE_NOCHECK(frame->bp);
622 : 0 : state->ip = READ_ONCE_NOCHECK(frame->ret_addr);
623 : : }
624 : :
625 [ - + ]: 96815 : if (get_stack_info((unsigned long *)state->sp, state->task,
626 : : &state->stack_info, &state->stack_mask)) {
627 : : /*
628 : : * We weren't on a valid stack. It's possible that
629 : : * we overflowed a valid stack into a guard page.
630 : : * See if the next page up is valid so that we can
631 : : * generate some kind of backtrace if this happens.
632 : : */
633 : 0 : void *next_page = (void *)PAGE_ALIGN((unsigned long)state->sp);
634 [ # # ]: 0 : if (get_stack_info(next_page, state->task, &state->stack_info,
635 : : &state->stack_mask))
636 : : return;
637 : : }
638 : :
639 : : /*
640 : : * The caller can provide the address of the first frame directly
641 : : * (first_frame) or indirectly (regs->sp) to indicate which stack frame
642 : : * to start unwinding at. Skip ahead until we reach it.
643 : : */
644 : :
645 : : /* When starting from regs, skip the regs frame: */
646 [ + + ]: 96815 : if (regs) {
647 : 21 : unwind_next_frame(state);
648 : 21 : return;
649 : : }
650 : :
651 : : /* Otherwise, skip ahead to the user-specified starting frame: */
652 [ + - - + ]: 580764 : while (!unwind_done(state) &&
653 : 290382 : (!on_stack(&state->stack_info, first_frame, sizeof(long)) ||
654 [ + + ]: 290382 : state->sp <= (unsigned long)first_frame))
655 : 193588 : unwind_next_frame(state);
656 : :
657 : : return;
658 : :
659 : 0 : done:
660 : 0 : state->stack_info.type = STACK_TYPE_UNKNOWN;
661 : 0 : return;
662 : : }
663 : : EXPORT_SYMBOL_GPL(__unwind_start);
|