linux/arch/powerpc/kernel/stacktrace.c
<<
>>
Prefs
   1/*
   2 * Stack trace utility
   3 *
   4 * Copyright 2008 Christoph Hellwig, IBM Corp.
   5 *
   6 *
   7 *      This program is free software; you can redistribute it and/or
   8 *      modify it under the terms of the GNU General Public License
   9 *      as published by the Free Software Foundation; either version
  10 *      2 of the License, or (at your option) any later version.
  11 */
  12
  13#include <linux/module.h>
  14#include <linux/sched.h>
  15#include <linux/stacktrace.h>
  16#include <asm/ptrace.h>
  17#include <asm/processor.h>
  18
  19/*
  20 * Save stack-backtrace addresses into a stack_trace buffer.
  21 */
  22static void save_context_stack(struct stack_trace *trace, unsigned long sp,
  23                        struct task_struct *tsk, int savesched)
  24{
  25        for (;;) {
  26                unsigned long *stack = (unsigned long *) sp;
  27                unsigned long newsp, ip;
  28
  29                if (!validate_sp(sp, tsk, STACK_FRAME_OVERHEAD))
  30                        return;
  31
  32                newsp = stack[0];
  33                ip = stack[STACK_FRAME_LR_SAVE];
  34
  35                if (savesched || !in_sched_functions(ip)) {
  36                        if (!trace->skip)
  37                                trace->entries[trace->nr_entries++] = ip;
  38                        else
  39                                trace->skip--;
  40                }
  41
  42                if (trace->nr_entries >= trace->max_entries)
  43                        return;
  44
  45                sp = newsp;
  46        }
  47}
  48
  49void save_stack_trace(struct stack_trace *trace)
  50{
  51        unsigned long sp;
  52
  53        asm("mr %0,1" : "=r" (sp));
  54
  55        save_context_stack(trace, sp, current, 1);
  56}
  57EXPORT_SYMBOL_GPL(save_stack_trace);
  58
  59void save_stack_trace_tsk(struct task_struct *tsk, struct stack_trace *trace)
  60{
  61        save_context_stack(trace, tsk->thread.ksp, tsk, 0);
  62}
  63EXPORT_SYMBOL_GPL(save_stack_trace_tsk);
  64