summaryrefslogtreecommitdiff
path: root/kprobe
diff options
context:
space:
mode:
authorVyacheslav Cherkashin <v.cherkashin@samsung.com>2014-04-12 18:21:00 +0400
committerVyacheslav Cherkashin <v.cherkashin@samsung.com>2014-04-21 17:04:57 +0400
commitc4598a886ca8c6c208e3c35b647b56de2371616b (patch)
treeea2d8b083d517f3e1132f6782005c8151bd0232a /kprobe
parent4e6453d75e12abc9be72ca0e368579b89c20146c (diff)
downloadswap-modules-c4598a886ca8c6c208e3c35b647b56de2371616b.tar.gz
swap-modules-c4598a886ca8c6c208e3c35b647b56de2371616b.tar.bz2
swap-modules-c4598a886ca8c6c208e3c35b647b56de2371616b.zip
[IMPROVE] ARM: create jumper
Change-Id: I6db3078573ba35773ca78431d9c6b1d95679231b Signed-off-by: Vyacheslav Cherkashin <v.cherkashin@samsung.com>
Diffstat (limited to 'kprobe')
-rw-r--r--kprobe/arch/asm-arm/dbi_kprobes.c81
-rw-r--r--kprobe/arch/asm-arm/dbi_kprobes.h7
2 files changed, 88 insertions, 0 deletions
diff --git a/kprobe/arch/asm-arm/dbi_kprobes.c b/kprobe/arch/asm-arm/dbi_kprobes.c
index d4edf4fe..f63efca1 100644
--- a/kprobe/arch/asm-arm/dbi_kprobes.c
+++ b/kprobe/arch/asm-arm/dbi_kprobes.c
@@ -514,6 +514,87 @@ void arch_prepare_kretprobe(struct kretprobe_instance *ri, struct pt_regs *regs)
*ptr_ret_addr = (unsigned long)&kretprobe_trampoline;
}
+
+
+
+
+/*
+ ******************************************************************************
+ * jumper *
+ ******************************************************************************
+ */
+struct cb_data {
+ unsigned long ret_addr;
+ unsigned long r0;
+
+ jumper_cb_t cb;
+ char data[0];
+};
+
+static unsigned long __used get_r0(struct cb_data *data)
+{
+ return data->r0;
+}
+
+static unsigned long __used jump_handler(struct cb_data *data)
+{
+ unsigned long ret_addr = data->ret_addr;
+
+ /* call callback */
+ data->cb(data->data);
+
+ /* FIXME: potential memory leak, when process kill */
+ kfree(data);
+
+ return ret_addr;
+}
+
+/* FIXME: restore condition flags */
+void jump_trampoline(void);
+__asm(
+ "jump_trampoline: \n"
+
+ "push {r0 - r12} \n"
+ "mov r1, r0 \n" /* data --> r1 */
+ "bl get_r0 \n"
+ "str r0, [sp] \n" /* restore r0 */
+ "mov r0, r1 \n" /* data --> r0 */
+ "bl jump_handler \n"
+ "mov lr, r0 \n"
+ "pop {r0 - r12} \n"
+ "bx lr \n"
+);
+
+unsigned long get_jump_addr(void)
+{
+ return (unsigned long)&jump_trampoline;
+}
+EXPORT_SYMBOL_GPL(get_jump_addr);
+
+int set_jump_cb(unsigned long ret_addr, struct pt_regs *regs,
+ jumper_cb_t cb, void *data, size_t size)
+{
+ struct cb_data *cb_data;
+
+ cb_data = kmalloc(sizeof(*cb_data) + size, GFP_ATOMIC);
+
+ /* save data */
+ cb_data->ret_addr = ret_addr;
+ cb_data->cb = cb;
+ cb_data->r0 = regs->ARM_r0;
+ memcpy(cb_data->data, data, size);
+
+ /* save cb_data to r0 */
+ regs->ARM_r0 = (long)cb_data;
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(set_jump_cb);
+
+
+
+
+
void swap_register_undef_hook(struct undef_hook *hook)
{
__swap_register_undef_hook(hook);
diff --git a/kprobe/arch/asm-arm/dbi_kprobes.h b/kprobe/arch/asm-arm/dbi_kprobes.h
index 704ad045..cd7f23bb 100644
--- a/kprobe/arch/asm-arm/dbi_kprobes.h
+++ b/kprobe/arch/asm-arm/dbi_kprobes.h
@@ -530,6 +530,13 @@ static inline unsigned long swap_get_sarg(struct pt_regs *regs, unsigned long n)
return swap_get_karg(regs, n);
}
+/* jumper */
+typedef unsigned long (*jumper_cb_t)(void *);
+
+unsigned long get_jump_addr(void);
+int set_jump_cb(unsigned long ret_addr, struct pt_regs *regs,
+ jumper_cb_t cb, void *data, size_t size);
+
int arch_init_kprobes(void);
void arch_exit_kprobes(void);