linux/arch/x86/kernel/unwind_guess.c
<<
>>
Prefs
   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
   8unsigned long unwind_get_return_address(struct unwind_state *state)
   9{
  10        if (unwind_done(state))
  11                return 0;
  12
  13        return ftrace_graph_ret_addr(state->task, &state->graph_idx,
  14                                     *state->sp, state->sp);
  15}
  16EXPORT_SYMBOL_GPL(unwind_get_return_address);
  17
  18bool unwind_next_frame(struct unwind_state *state)
  19{
  20        struct stack_info *info = &state->stack_info;
  21
  22        if (unwind_done(state))
  23                return false;
  24
  25        do {
  26                for (state->sp++; state->sp < info->end; state->sp++)
  27                        if (__kernel_text_address(*state->sp))
  28                                return true;
  29
  30                state->sp = info->next_sp;
  31
  32        } while (!get_stack_info(state->sp, state->task, info,
  33                                 &state->stack_mask));
  34
  35        return false;
  36}
  37EXPORT_SYMBOL_GPL(unwind_next_frame);
  38
  39void __unwind_start(struct unwind_state *state, struct task_struct *task,
  40                    struct pt_regs *regs, unsigned long *first_frame)
  41{
  42        memset(state, 0, sizeof(*state));
  43
  44        state->task = task;
  45        state->sp   = first_frame;
  46
  47        get_stack_info(first_frame, state->task, &state->stack_info,
  48                       &state->stack_mask);
  49
  50        if (!__kernel_text_address(*first_frame))
  51                unwind_next_frame(state);
  52}
  53EXPORT_SYMBOL_GPL(__unwind_start);
  54