From 0187b0fe95e533eded9f46919bbe8a49d3bf8fd2 Mon Sep 17 00:00:00 2001 From: Vyacheslav Cherkashin Date: Wed, 10 Apr 2013 13:15:34 +0400 Subject: [PATCH] [REFACTOR] redesign arch_prepare_kretprobe() -void arch_prepare_kretprobe(struct kretprobe *rp, struct pt_regs *regs) +void arch_prepare_kretprobe(struct kretprobe_instance *ri, struct pt_regs *regs) --- kprobe/arch/asm-arm/dbi_kprobes.c | 32 +++++--------------------------- kprobe/arch/asm-arm/dbi_kprobes.h | 3 ++- kprobe/dbi_kprobes.c | 25 +++++++++++++++++++------ kprobe/dbi_kprobes.h | 1 - 4 files changed, 26 insertions(+), 35 deletions(-) diff --git a/kprobe/arch/asm-arm/dbi_kprobes.c b/kprobe/arch/asm-arm/dbi_kprobes.c index 3acaf77..eb994ad 100644 --- a/kprobe/arch/asm-arm/dbi_kprobes.c +++ b/kprobe/arch/asm-arm/dbi_kprobes.c @@ -479,35 +479,13 @@ int trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs) } EXPORT_SYMBOL_GPL(trampoline_probe_handler); -void arch_prepare_kretprobe(struct kretprobe *rp, struct pt_regs *regs) +void arch_prepare_kretprobe(struct kretprobe_instance *ri, struct pt_regs *regs) { - struct kretprobe_instance *ri; + ri->ret_addr = (kprobe_opcode_t *)regs->ARM_lr; + ri->sp = (kprobe_opcode_t *)regs->ARM_sp; - DBPRINTF ("start\n"); - //TODO: test - remove retprobe after func entry but before its exit - if ((ri = get_free_rp_inst(rp)) != NULL) { - ri->rp = rp; - ri->task = current; - - if (rp->entry_handler) { - rp->entry_handler(ri, regs, ri->rp->priv_arg); - } - - ri->ret_addr = (kprobe_opcode_t *)regs->uregs[14]; - ri->sp = (kprobe_opcode_t *)regs->ARM_sp; //uregs[13]; - - /* Set flag of current mode */ - ri->sp = (kprobe_opcode_t *)((long)ri->sp | !!thumb_mode(regs)); - - /* Replace the return addr with trampoline addr */ - regs->uregs[14] = (unsigned long)&kretprobe_trampoline; - -// DBPRINTF ("ret addr set to %p->%lx\n", ri->ret_addr, regs->uregs[14]); - add_rp_inst(ri); - } else { - DBPRINTF ("WARNING: missed retprobe %p\n", rp->kp.addr); - rp->nmissed++; - } + /* Replace the return addr with trampoline addr */ + regs->ARM_lr = (unsigned long)&kretprobe_trampoline; } void swap_register_undef_hook(struct undef_hook *hook) diff --git a/kprobe/arch/asm-arm/dbi_kprobes.h b/kprobe/arch/asm-arm/dbi_kprobes.h index 99eff47..a98f37b 100644 --- a/kprobe/arch/asm-arm/dbi_kprobes.h +++ b/kprobe/arch/asm-arm/dbi_kprobes.h @@ -488,8 +488,9 @@ int prep_pc_dep_insn_execbuf(kprobe_opcode_t *insns, kprobe_opcode_t insn, int u struct slot_manager; struct kretprobe; +struct kretprobe_instance; int arch_prepare_kprobe(struct kprobe *p, struct slot_manager *sm); -void arch_prepare_kretprobe(struct kretprobe *rp, struct pt_regs *regs); +void arch_prepare_kretprobe(struct kretprobe_instance *ri, struct pt_regs *regs); void arch_arm_kprobe(struct kprobe *p); void arch_disarm_kprobe(struct kprobe *p); diff --git a/kprobe/dbi_kprobes.c b/kprobe/dbi_kprobes.c index 16183c1..c737575 100644 --- a/kprobe/dbi_kprobes.c +++ b/kprobe/dbi_kprobes.c @@ -603,22 +603,35 @@ void dbi_unregister_jprobe(struct jprobe *jp) * This kprobe pre_handler is registered with every kretprobe. When probe * hits it will set up the return probe. */ -int pre_handler_kretprobe(struct kprobe *p, struct pt_regs *regs) +static int pre_handler_kretprobe(struct kprobe *p, struct pt_regs *regs) { struct kretprobe *rp = container_of(p, struct kretprobe, kp); + struct kretprobe_instance *ri; unsigned long flags = 0; - DBPRINTF ("START\n"); - /*TODO: consider to only swap the RA after the last pre_handler fired */ + /* TODO: consider to only swap the RA after the last pre_handler fired */ spin_lock_irqsave(&kretprobe_lock, flags); - arch_prepare_kretprobe(rp, regs); + /* TODO: test - remove retprobe after func entry but before its exit */ + if ((ri = get_free_rp_inst(rp)) != NULL) { + ri->rp = rp; + ri->task = current; + + if (rp->entry_handler) { + rp->entry_handler(ri, regs, ri->rp->priv_arg); + } + + arch_prepare_kretprobe(ri, regs); + + add_rp_inst(ri); + } else { + ++rp->nmissed; + } spin_unlock_irqrestore(&kretprobe_lock, flags); - DBPRINTF ("END\n"); + return 0; } -EXPORT_SYMBOL_GPL(pre_handler_kretprobe); struct kretprobe *sched_rp; diff --git a/kprobe/dbi_kprobes.h b/kprobe/dbi_kprobes.h index bfd4340..4458f6f 100644 --- a/kprobe/dbi_kprobes.h +++ b/kprobe/dbi_kprobes.h @@ -229,7 +229,6 @@ int dbi_register_kprobe (struct kprobe *p); void dbi_unregister_kprobe (struct kprobe *p, struct task_struct *task); int register_aggr_kprobe (struct kprobe *old_p, struct kprobe *p); -int pre_handler_kretprobe (struct kprobe *p, struct pt_regs *regs); int setjmp_pre_handler (struct kprobe *, struct pt_regs *); int longjmp_break_handler (struct kprobe *, struct pt_regs *); -- 2.7.4