diff options
author | Paul Mundt <lethal@linux-sh.org> | 2009-10-13 01:31:50 (GMT) |
---|---|---|
committer | Paul Mundt <lethal@linux-sh.org> | 2009-10-13 01:31:50 (GMT) |
commit | 7a0064d67215c53dce56839c82db504d0a066b79 (patch) | |
tree | 4fe288db70d5ab9f493669af9e3034efef172fb1 /arch/sh | |
parent | 8ec006c58775869175edee3d23f4525b6df2935a (diff) | |
parent | d26cddbbd23b81eac4fcf340b633e97b40b8d3a1 (diff) | |
download | linux-7a0064d67215c53dce56839c82db504d0a066b79.tar.xz |
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.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 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 <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 */ |