xref: /linux/arch/x86/kernel/unwind_guess.c (revision 59024954a1e7e26b62680e1f2b5725249a6c09f7)
1 #include <linux/sched.h>
2 #include <linux/ftrace.h>
3 #include <asm/ptrace.h>
4 #include <asm/bitops.h>
5 #include <asm/stacktrace.h>
6 #include <asm/unwind.h>
7 
8 bool unwind_next_frame(struct unwind_state *state)
9 {
10 	struct stack_info *info = &state->stack_info;
11 
12 	if (unwind_done(state))
13 		return false;
14 
15 	do {
16 		for (state->sp++; state->sp < info->end; state->sp++)
17 			if (__kernel_text_address(*state->sp))
18 				return true;
19 
20 		state->sp = info->next_sp;
21 
22 	} while (!get_stack_info(state->sp, state->task, info,
23 				 &state->stack_mask));
24 
25 	return false;
26 }
27 EXPORT_SYMBOL_GPL(unwind_next_frame);
28 
29 void __unwind_start(struct unwind_state *state, struct task_struct *task,
30 		    struct pt_regs *regs, unsigned long *first_frame)
31 {
32 	memset(state, 0, sizeof(*state));
33 
34 	state->task = task;
35 	state->sp   = first_frame;
36 
37 	get_stack_info(first_frame, state->task, &state->stack_info,
38 		       &state->stack_mask);
39 
40 	if (!__kernel_text_address(*first_frame))
41 		unwind_next_frame(state);
42 }
43 EXPORT_SYMBOL_GPL(__unwind_start);
44