]>
Commit | Line | Data |
---|---|---|
ac4fac8c PM |
1 | /* |
2 | * arch/sh/kernel/return_address.c | |
3 | * | |
4 | * Copyright (C) 2009 Matt Fleming | |
5 | * Copyright (C) 2009 Paul Mundt | |
6 | * | |
7 | * This file is subject to the terms and conditions of the GNU General Public | |
8 | * License. See the file "COPYING" in the main directory of this archive | |
9 | * for more details. | |
10 | */ | |
11 | #include <linux/kernel.h> | |
5dd6ef50 | 12 | #include <linux/module.h> |
ac4fac8c PM |
13 | #include <asm/dwarf.h> |
14 | ||
15 | #ifdef CONFIG_DWARF_UNWINDER | |
16 | ||
17 | void *return_address(unsigned int depth) | |
18 | { | |
19 | struct dwarf_frame *frame; | |
20 | unsigned long ra; | |
21 | int i; | |
22 | ||
23 | for (i = 0, frame = NULL, ra = 0; i <= depth; i++) { | |
24 | struct dwarf_frame *tmp; | |
25 | ||
26 | tmp = dwarf_unwind_stack(ra, frame); | |
8a37f520 PM |
27 | if (!tmp) |
28 | return NULL; | |
ac4fac8c PM |
29 | |
30 | if (frame) | |
31 | dwarf_free_frame(frame); | |
32 | ||
33 | frame = tmp; | |
34 | ||
35 | if (!frame || !frame->return_addr) | |
36 | break; | |
37 | ||
38 | ra = frame->return_addr; | |
39 | } | |
40 | ||
41 | /* Failed to unwind the stack to the specified depth. */ | |
42 | WARN_ON(i != depth + 1); | |
43 | ||
44 | if (frame) | |
45 | dwarf_free_frame(frame); | |
46 | ||
47 | return (void *)ra; | |
48 | } | |
49 | ||
50 | #else | |
51 | ||
52 | void *return_address(unsigned int depth) | |
53 | { | |
54 | return NULL; | |
55 | } | |
56 | ||
57 | #endif | |
5dd6ef50 PM |
58 | |
59 | EXPORT_SYMBOL_GPL(return_address); |