diff options
author | Matt Fleming <matt@console-pimps.org> | 2009-10-11 18:56:17 +0200 |
---|---|---|
committer | Matt Fleming <matt@console-pimps.org> | 2009-10-11 18:56:17 +0200 |
commit | d26cddbbd23b81eac4fcf340b633e97b40b8d3a1 (patch) | |
tree | c8c169df4b33500edd0183ce5f03baf006c6bc5f /arch/sh/include | |
parent | Merge branch 'sh/cachetlb' (diff) | |
download | linux-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.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) 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 */ |