linux/arch/blackfin/kernel/stacktrace.c
<<
>>
Prefs
   1/*
   2 * Blackfin stacktrace code (mostly copied from avr32)
   3 *
   4 * Copyright 2009 Analog Devices Inc.
   5 * Licensed under the GPL-2 or later.
   6 */
   7
   8#include <linux/sched.h>
   9#include <linux/sched/task_stack.h>
  10#include <linux/stacktrace.h>
  11#include <linux/thread_info.h>
  12#include <linux/module.h>
  13
  14register unsigned long current_frame_pointer asm("FP");
  15
  16struct stackframe {
  17        unsigned long fp;
  18        unsigned long rets;
  19};
  20
  21/*
  22 * Save stack-backtrace addresses into a stack_trace buffer.
  23 */
  24void save_stack_trace(struct stack_trace *trace)
  25{
  26        unsigned long low, high;
  27        unsigned long fp;
  28        struct stackframe *frame;
  29        int skip = trace->skip;
  30
  31        low = (unsigned long)task_stack_page(current);
  32        high = low + THREAD_SIZE;
  33        fp = current_frame_pointer;
  34
  35        while (fp >= low && fp <= (high - sizeof(*frame))) {
  36                frame = (struct stackframe *)fp;
  37
  38                if (skip) {
  39                        skip--;
  40                } else {
  41                        trace->entries[trace->nr_entries++] = frame->rets;
  42                        if (trace->nr_entries >= trace->max_entries)
  43                                break;
  44                }
  45
  46                /*
  47                 * The next frame must be at a higher address than the
  48                 * current frame.
  49                 */
  50                low = fp + sizeof(*frame);
  51                fp = frame->fp;
  52        }
  53}
  54EXPORT_SYMBOL_GPL(save_stack_trace);
  55