From: Matt Fleming Date: Sun, 11 Oct 2009 16:56:17 +0000 (+0100) Subject: sh: tracing: Use the DWARF unwinder for CALLER_ADDRx X-Git-Tag: v2.6.33-rc1~63^2~62^2~91^2 X-Git-Url: http://ftp.safe.ca/?p=safe%2Fjmp%2Flinux-2.6;a=commitdiff_plain;h=d26cddbbd23b81eac4fcf340b633e97b40b8d3a1 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 --- diff --git a/arch/sh/include/asm/ftrace.h b/arch/sh/include/asm/ftrace.h index 12f3a31..5ea9030 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 + +#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 */