Commit 2f0260371f428fd78ffc2287a5c5768ea8eeab97
1 parent
58bd2bfebd
Exists in
master
and in
7 other branches
[AVR32] Implement stacktrace support
Signed-off-by: Haavard Skinnemoen <hskinnemoen@atmel.com>
Showing 3 changed files with 57 additions and 0 deletions Side-by-side Diff
arch/avr32/Kconfig
arch/avr32/kernel/Makefile
arch/avr32/kernel/stacktrace.c
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 | + | |
14 | +register unsigned long current_frame_pointer asm("r7"); | |
15 | + | |
16 | +struct stackframe { | |
17 | + unsigned long lr; | |
18 | + unsigned long fp; | |
19 | +}; | |
20 | + | |
21 | +/* | |
22 | + * Save stack-backtrace addresses into a stack_trace buffer. | |
23 | + */ | |
24 | +void 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 - 8)) { | |
36 | + frame = (struct stackframe *)fp; | |
37 | + | |
38 | + if (skip) { | |
39 | + skip--; | |
40 | + } else { | |
41 | + trace->entries[trace->nr_entries++] = frame->lr; | |
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 + 8; | |
51 | + fp = frame->fp; | |
52 | + } | |
53 | +} |