summaryrefslogtreecommitdiff
path: root/arch/blackfin/include/asm/ftrace.h
diff options
context:
space:
mode:
authorJiri Kosina <jkosina@suse.cz>2010-04-23 04:08:44 +0400
committerJiri Kosina <jkosina@suse.cz>2010-04-23 04:08:44 +0400
commit6c9468e9eb1252eaefd94ce7f06e1be9b0b641b1 (patch)
tree797676a336b050bfa1ef879377c07e541b9075d6 /arch/blackfin/include/asm/ftrace.h
parent4cb3ca7cd7e2cae8d1daf5345ec99a1e8502cf3f (diff)
parentc81eddb0e3728661d1585fbc564449c94165cc36 (diff)
downloadlinux-6c9468e9eb1252eaefd94ce7f06e1be9b0b641b1.tar.xz
Merge branch 'master' into for-next
Diffstat (limited to 'arch/blackfin/include/asm/ftrace.h')
-rw-r--r--arch/blackfin/include/asm/ftrace.h53
1 files changed, 53 insertions, 0 deletions
diff --git a/arch/blackfin/include/asm/ftrace.h b/arch/blackfin/include/asm/ftrace.h
index 90c9b400ba6d..4cfe2d9ba7e8 100644
--- a/arch/blackfin/include/asm/ftrace.h
+++ b/arch/blackfin/include/asm/ftrace.h
@@ -10,4 +10,57 @@
#define MCOUNT_INSN_SIZE 6 /* sizeof "[++sp] = rets; call __mcount;" */
+#ifndef __ASSEMBLY__
+
+#ifdef CONFIG_FRAME_POINTER
+#include <linux/mm.h>
+
+extern inline void *return_address(unsigned int level)
+{
+ unsigned long *endstack, *fp, *ret_addr;
+ unsigned int current_level = 0;
+
+ if (level == 0)
+ return __builtin_return_address(0);
+
+ fp = (unsigned long *)__builtin_frame_address(0);
+ endstack = (unsigned long *)PAGE_ALIGN((unsigned long)&level);
+
+ while (((unsigned long)fp & 0x3) == 0 && fp &&
+ (fp + 1) < endstack && current_level < level) {
+ fp = (unsigned long *)*fp;
+ current_level++;
+ }
+
+ if (((unsigned long)fp & 0x3) == 0 && fp &&
+ (fp + 1) < endstack)
+ ret_addr = (unsigned long *)*(fp + 1);
+ else
+ ret_addr = NULL;
+
+ return ret_addr;
+}
+
+#else
+
+extern inline void *return_address(unsigned int level)
+{
+ return NULL;
+}
+
+#endif /* CONFIG_FRAME_POINTER */
+
+#define HAVE_ARCH_CALLER_ADDR
+
+/* inline function or macro may lead to unexpected result */
+#define CALLER_ADDR0 ((unsigned long)__builtin_return_address(0))
+#define CALLER_ADDR1 ((unsigned long)return_address(1))
+#define CALLER_ADDR2 ((unsigned long)return_address(2))
+#define CALLER_ADDR3 ((unsigned long)return_address(3))
+#define CALLER_ADDR4 ((unsigned long)return_address(4))
+#define CALLER_ADDR5 ((unsigned long)return_address(5))
+#define CALLER_ADDR6 ((unsigned long)return_address(6))
+
+#endif /* __ASSEMBLY__ */
+
#endif