sh: tracing: Use the DWARF unwinder for CALLER_ADDRx
authorMatt Fleming <matt@console-pimps.org>
Sun, 11 Oct 2009 16:56:17 +0000 (17:56 +0100)
committerMatt Fleming <matt@console-pimps.org>
Sun, 11 Oct 2009 16:56:17 +0000 (17:56 +0100)
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>
arch/sh/include/asm/ftrace.h

index 12f3a31..5ea9030 100644 (file)
@@ -32,6 +32,53 @@ static inline unsigned long ftrace_call_adjust(unsigned long addr)
        return 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 */
 
 #endif /* __ASSEMBLY__ */
 #endif /* CONFIG_FUNCTION_TRACER */