From 2a6769248704e411f72f8c53037af8fb84ec186a Mon Sep 17 00:00:00 2001 From: Helge Deller Date: Sun, 25 Oct 2009 21:48:36 +0000 Subject: [PATCH] --- yaml --- r: 176900 b: refs/heads/master c: 11e178091f6a9c5ca479f8a276b9dd0dfacf8fc4 h: refs/heads/master v: v3 --- [refs] | 2 +- trunk/arch/parisc/include/asm/ftrace.h | 14 +++++++++++++ trunk/arch/parisc/kernel/unwind.c | 27 ++++++++++++++++++++++++++ 3 files changed, 42 insertions(+), 1 deletion(-) diff --git a/[refs] b/[refs] index 4b5682aaa361..6ab75f78b5d7 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: b29f90379eb5def21ca3fdf576079c285b815e6a +refs/heads/master: 11e178091f6a9c5ca479f8a276b9dd0dfacf8fc4 diff --git a/trunk/arch/parisc/include/asm/ftrace.h b/trunk/arch/parisc/include/asm/ftrace.h index 2fa05dd6aeee..72c0fafaa039 100644 --- a/trunk/arch/parisc/include/asm/ftrace.h +++ b/trunk/arch/parisc/include/asm/ftrace.h @@ -20,6 +20,20 @@ struct ftrace_ret_stack { * Defined in entry.S */ extern void return_to_handler(void); + + +extern unsigned long return_address(unsigned int); + +#define HAVE_ARCH_CALLER_ADDR + +#define CALLER_ADDR0 ((unsigned long)__builtin_return_address(0)) +#define CALLER_ADDR1 return_address(1) +#define CALLER_ADDR2 return_address(2) +#define CALLER_ADDR3 return_address(3) +#define CALLER_ADDR4 return_address(4) +#define CALLER_ADDR5 return_address(5) +#define CALLER_ADDR6 return_address(6) + #endif /* __ASSEMBLY__ */ #endif /* _ASM_PARISC_FTRACE_H */ diff --git a/trunk/arch/parisc/kernel/unwind.c b/trunk/arch/parisc/kernel/unwind.c index a36799e85693..f03f6fb0ec83 100644 --- a/trunk/arch/parisc/kernel/unwind.c +++ b/trunk/arch/parisc/kernel/unwind.c @@ -417,3 +417,30 @@ int unwind_to_user(struct unwind_frame_info *info) return ret; } + +unsigned long return_address(unsigned int level) +{ + struct unwind_frame_info info; + struct pt_regs r; + unsigned long sp; + + /* initialize unwind info */ + asm volatile ("copy %%r30, %0" : "=r"(sp)); + memset(&r, 0, sizeof(struct pt_regs)); + r.iaoq[0] = (unsigned long) current_text_addr(); + r.gr[2] = (unsigned long) __builtin_return_address(0); + r.gr[30] = sp; + unwind_frame_init(&info, current, &r); + + /* unwind stack */ + ++level; + do { + if (unwind_once(&info) < 0 || info.ip == 0) + return 0; + if (!__kernel_text_address(info.ip)) { + return 0; + } + } while (info.ip && level--); + + return info.ip; +}