diff options
Diffstat (limited to 'arch')
-rw-r--r-- | arch/sh/include/asm/ftrace.h | 47 |
1 files changed, 47 insertions, 0 deletions
diff --git a/arch/sh/include/asm/ftrace.h b/arch/sh/include/asm/ftrace.h index 12f3a31f20af..5ea9030725c0 100644 --- a/arch/sh/include/asm/ftrace.h +++ b/arch/sh/include/asm/ftrace.h | |||
@@ -32,6 +32,53 @@ static inline unsigned long ftrace_call_adjust(unsigned long addr) | |||
32 | return addr; | 32 | return addr; |
33 | } | 33 | } |
34 | 34 | ||
35 | |||
36 | #ifdef CONFIG_DWARF_UNWINDER | ||
37 | #include <asm/dwarf.h> | ||
38 | |||
39 | #define HAVE_ARCH_CALLER_ADDR | ||
40 | |||
41 | static inline unsigned long dwarf_return_address(int depth) | ||
42 | { | ||
43 | struct dwarf_frame *frame; | ||
44 | unsigned long ra; | ||
45 | int i; | ||
46 | |||
47 | for (i = 0, frame = NULL, ra = 0; i <= depth; i++) { | ||
48 | struct dwarf_frame *tmp; | ||
49 | |||
50 | tmp = dwarf_unwind_stack(ra, frame); | ||
51 | |||
52 | if (frame) | ||
53 | dwarf_free_frame(frame); | ||
54 | |||
55 | frame = tmp; | ||
56 | |||
57 | if (!frame || !frame->return_addr) | ||
58 | break; | ||
59 | |||
60 | ra = frame->return_addr; | ||
61 | } | ||
62 | |||
63 | /* Failed to unwind the stack to the specified depth. */ | ||
64 | WARN_ON(i != depth + 1); | ||
65 | |||
66 | if (frame) | ||
67 | dwarf_free_frame(frame); | ||
68 | |||
69 | return ra; | ||
70 | } | ||
71 | |||
72 | #define CALLER_ADDR0 ((unsigned long)__builtin_return_address(0)) | ||
73 | #define CALLER_ADDR1 dwarf_return_address(1) | ||
74 | #define CALLER_ADDR2 dwarf_return_address(2) | ||
75 | #define CALLER_ADDR3 dwarf_return_address(3) | ||
76 | #define CALLER_ADDR4 dwarf_return_address(4) | ||
77 | #define CALLER_ADDR5 dwarf_return_address(5) | ||
78 | #define CALLER_ADDR6 dwarf_return_address(6) | ||
79 | |||
80 | #endif /* CONFIG_DWARF_UNWINDER */ | ||
81 | |||
35 | #endif /* __ASSEMBLY__ */ | 82 | #endif /* __ASSEMBLY__ */ |
36 | #endif /* CONFIG_FUNCTION_TRACER */ | 83 | #endif /* CONFIG_FUNCTION_TRACER */ |
37 | 84 | ||