linux/arch/sparc/kernel/stacktrace.c
<<
>>
Prefs
   1#include <linux/sched.h>
   2#include <linux/stacktrace.h>
   3#include <linux/thread_info.h>
   4#include <linux/module.h>
   5#include <asm/ptrace.h>
   6#include <asm/stacktrace.h>
   7
   8#include "kstack.h"
   9
  10static void __save_stack_trace(struct thread_info *tp,
  11                               struct stack_trace *trace,
  12                               bool skip_sched)
  13{
  14        unsigned long ksp, fp;
  15
  16        if (tp == current_thread_info()) {
  17                stack_trace_flush();
  18                __asm__ __volatile__("mov %%fp, %0" : "=r" (ksp));
  19        } else {
  20                ksp = tp->ksp;
  21        }
  22
  23        fp = ksp + STACK_BIAS;
  24        do {
  25                struct sparc_stackf *sf;
  26                struct pt_regs *regs;
  27                unsigned long pc;
  28
  29                if (!kstack_valid(tp, fp))
  30                        break;
  31
  32                sf = (struct sparc_stackf *) fp;
  33                regs = (struct pt_regs *) (sf + 1);
  34
  35                if (kstack_is_trap_frame(tp, regs)) {
  36                        if (!(regs->tstate & TSTATE_PRIV))
  37                                break;
  38                        pc = regs->tpc;
  39                        fp = regs->u_regs[UREG_I6] + STACK_BIAS;
  40                } else {
  41                        pc = sf->callers_pc;
  42                        fp = (unsigned long)sf->fp + STACK_BIAS;
  43                }
  44
  45                if (trace->skip > 0)
  46                        trace->skip--;
  47                else if (!skip_sched || !in_sched_functions(pc))
  48                        trace->entries[trace->nr_entries++] = pc;
  49        } while (trace->nr_entries < trace->max_entries);
  50}
  51
  52void save_stack_trace(struct stack_trace *trace)
  53{
  54        __save_stack_trace(current_thread_info(), trace, false);
  55}
  56EXPORT_SYMBOL_GPL(save_stack_trace);
  57
  58void save_stack_trace_tsk(struct task_struct *tsk, struct stack_trace *trace)
  59{
  60        struct thread_info *tp = task_thread_info(tsk);
  61
  62        __save_stack_trace(tp, trace, true);
  63}
  64EXPORT_SYMBOL_GPL(save_stack_trace_tsk);
  65