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>
This commit is contained in:
committed by
Ingo Molnar
parent
f34bfb1bee
commit
395a59d0f8
@@ -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
|
||||
|
@@ -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}
|
||||
|
@@ -12,9 +12,10 @@
|
||||
*/
|
||||
|
||||
#include <linux/ftrace.h>
|
||||
#include <asm/cacheflush.h>
|
||||
|
||||
#define INSN_SIZE 4
|
||||
#include <asm/cacheflush.h>
|
||||
#include <asm/ftrace.h>
|
||||
|
||||
#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;
|
||||
|
Reference in New Issue
Block a user