1 /* 2 * Stack trace management functions 3 * 4 * Copyright (C) 2007 Atmel Corporation 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License version 2 as 8 * published by the Free Software Foundation. 9 */ 10 #include <linux/sched.h> 11 #include <linux/stacktrace.h> 12 #include <linux/thread_info.h> 13 #include <linux/module.h> 14 15 register unsigned long current_frame_pointer asm("r7"); 16 17 struct stackframe { 18 unsigned long lr; 19 unsigned long fp; 20 }; 21 22 /* 23 * Save stack-backtrace addresses into a stack_trace buffer. 24 */ save_stack_trace(struct stack_trace * trace)25void save_stack_trace(struct stack_trace *trace) 26 { 27 unsigned long low, high; 28 unsigned long fp; 29 struct stackframe *frame; 30 int skip = trace->skip; 31 32 low = (unsigned long)task_stack_page(current); 33 high = low + THREAD_SIZE; 34 fp = current_frame_pointer; 35 36 while (fp >= low && fp <= (high - 8)) { 37 frame = (struct stackframe *)fp; 38 39 if (skip) { 40 skip--; 41 } else { 42 trace->entries[trace->nr_entries++] = frame->lr; 43 if (trace->nr_entries >= trace->max_entries) 44 break; 45 } 46 47 /* 48 * The next frame must be at a higher address than the 49 * current frame. 50 */ 51 low = fp + 8; 52 fp = frame->fp; 53 } 54 } 55 EXPORT_SYMBOL_GPL(save_stack_trace); 56