summaryrefslogtreecommitdiffstats
path: root/arch/arm/kernel
diff options
context:
space:
mode:
authorAbhishek Sagar <sagar.abhishek@gmail.com>2008-06-21 23:47:27 +0530
committerIngo Molnar <mingo@elte.hu>2008-06-23 22:10:56 +0200
commit395a59d0f8e86bb39cd700c3d185d30c670bb958 (patch)
tree1558e635efcede901c5dbe9acd625d475db5b369 /arch/arm/kernel
parentf34bfb1beef8a17ba3d46b60f8fa19ffedc1ed8d (diff)
ftrace: store mcount address in rec->ip
Record the address of the mcount call-site. Currently all archs except sparc64 record the address of the instruction following the mcount call-site. Some general cleanups are entailed. Storing mcount addresses in rec->ip enables looking them up in the kprobe hash table later on to check if they're kprobe'd. Signed-off-by: Abhishek Sagar <sagar.abhishek@gmail.com> Cc: davem@davemloft.net Cc: Steven Rostedt <rostedt@goodmis.org> Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'arch/arm/kernel')
-rw-r--r--arch/arm/kernel/armksyms.c10
-rw-r--r--arch/arm/kernel/entry-common.S4
-rw-r--r--arch/arm/kernel/ftrace.c16
3 files changed, 16 insertions, 14 deletions
diff --git a/arch/arm/kernel/armksyms.c b/arch/arm/kernel/armksyms.c
index 3b132215cbf..cc7b246e965 100644
--- a/arch/arm/kernel/armksyms.c
+++ b/arch/arm/kernel/armksyms.c
@@ -18,6 +18,7 @@
#include <asm/io.h>
#include <asm/system.h>
#include <asm/uaccess.h>
+#include <asm/ftrace.h>
/*
* libgcc functions - functions that are used internally by the
@@ -48,11 +49,6 @@ extern void __aeabi_ulcmp(void);
extern void fpundefinstr(void);
extern void fp_enter(void);
-#ifdef CONFIG_FTRACE
-extern void mcount(void);
-EXPORT_SYMBOL(mcount);
-#endif
-
/*
* This has a special calling convention; it doesn't
* modify any of the usual registers, except for LR.
@@ -186,3 +182,7 @@ EXPORT_SYMBOL(_find_next_bit_be);
#endif
EXPORT_SYMBOL(copy_page);
+
+#ifdef CONFIG_FTRACE
+EXPORT_SYMBOL(mcount);
+#endif
diff --git a/arch/arm/kernel/entry-common.S b/arch/arm/kernel/entry-common.S
index 8f79a4789ed..84694e88b42 100644
--- a/arch/arm/kernel/entry-common.S
+++ b/arch/arm/kernel/entry-common.S
@@ -9,6 +9,7 @@
*/
#include <asm/unistd.h>
+#include <asm/ftrace.h>
#include <asm/arch/entry-macro.S>
#include "entry-header.S"
@@ -104,6 +105,7 @@ ENTRY(ret_from_fork)
ENTRY(mcount)
stmdb sp!, {r0-r3, lr}
mov r0, lr
+ sub r0, r0, #MCOUNT_INSN_SIZE
.globl mcount_call
mcount_call:
@@ -114,6 +116,7 @@ ENTRY(ftrace_caller)
stmdb sp!, {r0-r3, lr}
ldr r1, [fp, #-4]
mov r0, lr
+ sub r0, r0, #MCOUNT_INSN_SIZE
.globl ftrace_call
ftrace_call:
@@ -134,6 +137,7 @@ ENTRY(mcount)
trace:
ldr r1, [fp, #-4]
mov r0, lr
+ sub r0, r0, #MCOUNT_INSN_SIZE
mov lr, pc
mov pc, r2
ldmia sp!, {r0-r3, pc}
diff --git a/arch/arm/kernel/ftrace.c b/arch/arm/kernel/ftrace.c
index 22f3d6e309f..76d50e6091b 100644
--- a/arch/arm/kernel/ftrace.c
+++ b/arch/arm/kernel/ftrace.c
@@ -12,9 +12,10 @@
*/
#include <linux/ftrace.h>
+
#include <asm/cacheflush.h>
+#include <asm/ftrace.h>
-#define INSN_SIZE 4
#define PC_OFFSET 8
#define BL_OPCODE 0xeb000000
#define BL_OFFSET_MASK 0x00ffffff
@@ -32,10 +33,10 @@ unsigned char *ftrace_call_replace(unsigned long pc, unsigned long addr)
{
long offset;
- offset = (long)addr - (long)(pc - INSN_SIZE + PC_OFFSET);
+ offset = (long)addr - (long)(pc + PC_OFFSET);
if (unlikely(offset < -33554432 || offset > 33554428)) {
/* Can't generate branches that far (from ARM ARM). Ftrace
- * doesn't generate branches outside of core kernel text.
+ * doesn't generate branches outside of kernel text.
*/
WARN_ON_ONCE(1);
return NULL;
@@ -52,7 +53,6 @@ int ftrace_modify_code(unsigned long pc, unsigned char *old_code,
old = *(unsigned long *)old_code;
new = *(unsigned long *)new_code;
- pc -= INSN_SIZE;
__asm__ __volatile__ (
"1: ldr %1, [%2] \n"
@@ -77,7 +77,7 @@ int ftrace_modify_code(unsigned long pc, unsigned char *old_code,
: "memory");
if (!err && (replaced == old))
- flush_icache_range(pc, pc + INSN_SIZE);
+ flush_icache_range(pc, pc + MCOUNT_INSN_SIZE);
return err;
}
@@ -89,8 +89,7 @@ int ftrace_update_ftrace_func(ftrace_func_t func)
unsigned char *new;
pc = (unsigned long)&ftrace_call;
- pc += INSN_SIZE;
- memcpy(&old, &ftrace_call, INSN_SIZE);
+ memcpy(&old, &ftrace_call, MCOUNT_INSN_SIZE);
new = ftrace_call_replace(pc, (unsigned long)func);
ret = ftrace_modify_code(pc, (unsigned char *)&old, new);
return ret;
@@ -103,8 +102,7 @@ int ftrace_mcount_set(unsigned long *data)
unsigned char *new;
pc = (unsigned long)&mcount_call;
- pc += INSN_SIZE;
- memcpy(&old, &mcount_call, INSN_SIZE);
+ memcpy(&old, &mcount_call, MCOUNT_INSN_SIZE);
new = ftrace_call_replace(pc, *addr);
*addr = ftrace_modify_code(pc, (unsigned char *)&old, new);
return 0;