summaryrefslogtreecommitdiffstats
path: root/arch/sh/include
diff options
context:
space:
mode:
authorMatt Fleming <matt@console-pimps.org>2009-10-11 18:56:17 +0200
committerMatt Fleming <matt@console-pimps.org>2009-10-11 18:56:17 +0200
commitd26cddbbd23b81eac4fcf340b633e97b40b8d3a1 (patch)
treec8c169df4b33500edd0183ce5f03baf006c6bc5f /arch/sh/include
parentMerge branch 'sh/cachetlb' (diff)
downloadlinux-d26cddbbd23b81eac4fcf340b633e97b40b8d3a1.tar.xz
linux-d26cddbbd23b81eac4fcf340b633e97b40b8d3a1.zip
sh: tracing: Use the DWARF unwinder for CALLER_ADDRx
The major reason for implementing the DWARF unwinder in the first place was so that we could stop using __builtin_return_address(n), which doesn't work on SH for n > 0. Signed-off-by: Matt Fleming <matt@console-pimps.org>
Diffstat (limited to 'arch/sh/include')
-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 */