diff options
author | David S. Miller <davem@davemloft.net> | 2010-04-07 10:53:30 +0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2010-04-07 10:53:30 +0400 |
commit | 4a35ecf8bf1c4b039503fa554100fe85c761de76 (patch) | |
tree | 9b75f5d5636004d9a9aa496924377379be09aa1f /arch/blackfin/include/asm/ftrace.h | |
parent | b4d562e3c3553ac58c7120555c4e4aefbb090a2a (diff) | |
parent | fb9e2d887243499b8d28efcf80821c4f6a092395 (diff) | |
download | linux-4a35ecf8bf1c4b039503fa554100fe85c761de76.tar.xz |
Merge branch 'master' of master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6
Conflicts:
drivers/net/bonding/bond_main.c
drivers/net/via-velocity.c
drivers/net/wireless/iwlwifi/iwl-agn.c
Diffstat (limited to 'arch/blackfin/include/asm/ftrace.h')
-rw-r--r-- | arch/blackfin/include/asm/ftrace.h | 53 |
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 |