summaryrefslogtreecommitdiffstats
path: root/arch/sh
diff options
context:
space:
mode:
authorPaul Mundt <lethal@linux-sh.org>2009-10-13 10:31:50 +0900
committerPaul Mundt <lethal@linux-sh.org>2009-10-13 10:31:50 +0900
commit7a0064d67215c53dce56839c82db504d0a066b79 (patch)
tree4fe288db70d5ab9f493669af9e3034efef172fb1 /arch/sh
parent8ec006c58775869175edee3d23f4525b6df2935a (diff)
parentd26cddbbd23b81eac4fcf340b633e97b40b8d3a1 (diff)
downloadlinux-7a0064d67215c53dce56839c82db504d0a066b79.tar.bz2
Merge branch 'sh/ftrace' of git://github.com/mfleming/linux-2.6
Diffstat (limited to 'arch/sh')
-rw-r--r--arch/sh/include/asm/ftrace.h47
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)
return addr;
}
+
+#ifdef CONFIG_DWARF_UNWINDER
+#include <asm/dwarf.h>
+
+#define HAVE_ARCH_CALLER_ADDR
+
+static inline unsigned long dwarf_return_address(int depth)
+{
+ struct dwarf_frame *frame;
+ unsigned long ra;
+ int i;
+
+ for (i = 0, frame = NULL, ra = 0; i <= depth; i++) {
+ struct dwarf_frame *tmp;
+
+ tmp = dwarf_unwind_stack(ra, frame);
+
+ if (frame)
+ dwarf_free_frame(frame);
+
+ frame = tmp;
+
+ if (!frame || !frame->return_addr)
+ break;
+
+ ra = frame->return_addr;
+ }
+
+ /* Failed to unwind the stack to the specified depth. */
+ WARN_ON(i != depth + 1);
+
+ if (frame)
+ dwarf_free_frame(frame);
+
+ return ra;
+}
+
+#define CALLER_ADDR0 ((unsigned long)__builtin_return_address(0))
+#define CALLER_ADDR1 dwarf_return_address(1)
+#define CALLER_ADDR2 dwarf_return_address(2)
+#define CALLER_ADDR3 dwarf_return_address(3)
+#define CALLER_ADDR4 dwarf_return_address(4)
+#define CALLER_ADDR5 dwarf_return_address(5)
+#define CALLER_ADDR6 dwarf_return_address(6)
+
+#endif /* CONFIG_DWARF_UNWINDER */
+
#endif /* __ASSEMBLY__ */
#endif /* CONFIG_FUNCTION_TRACER */