0001
0002
0003
0004
0005
0006
0007
0008 #include <linux/stacktrace.h>
0009 #include <asm/stacktrace.h>
0010 #include <asm/unwind.h>
0011 #include <asm/kprobes.h>
0012
0013 void arch_stack_walk(stack_trace_consume_fn consume_entry, void *cookie,
0014 struct task_struct *task, struct pt_regs *regs)
0015 {
0016 struct unwind_state state;
0017 unsigned long addr;
0018
0019 unwind_for_each_frame(&state, task, regs, 0) {
0020 addr = unwind_get_return_address(&state);
0021 if (!addr || !consume_entry(cookie, addr))
0022 break;
0023 }
0024 }
0025
0026 int arch_stack_walk_reliable(stack_trace_consume_fn consume_entry,
0027 void *cookie, struct task_struct *task)
0028 {
0029 struct unwind_state state;
0030 unsigned long addr;
0031
0032 unwind_for_each_frame(&state, task, NULL, 0) {
0033 if (state.stack_info.type != STACK_TYPE_TASK)
0034 return -EINVAL;
0035
0036 if (state.regs)
0037 return -EINVAL;
0038
0039 addr = unwind_get_return_address(&state);
0040 if (!addr)
0041 return -EINVAL;
0042
0043 #ifdef CONFIG_KPROBES
0044
0045
0046
0047
0048 if (state.ip == (unsigned long)__kretprobe_trampoline)
0049 return -EINVAL;
0050 #endif
0051
0052 if (!consume_entry(cookie, addr))
0053 return -EINVAL;
0054 }
0055
0056
0057 if (unwind_error(&state))
0058 return -EINVAL;
0059 return 0;
0060 }