From 579fa505e9bfa7a30f2dc42f01c7895df5050097 Mon Sep 17 00:00:00 2001 From: Vyacheslav Cherkashin Date: Thu, 21 Mar 2013 15:59:28 +0400 Subject: [PATCH] [REFACTOR] redesign arch_prepare_uretprobe_hl() --- uprobe/arch/asm-arm/swap_uprobes.c | 28 +++++++--------------------- uprobe/arch/asm-arm/swap_uprobes.h | 2 +- uprobe/swap_uprobes.c | 22 ++++++++++++++++++++-- 3 files changed, 28 insertions(+), 24 deletions(-) diff --git a/uprobe/arch/asm-arm/swap_uprobes.c b/uprobe/arch/asm-arm/swap_uprobes.c index 3f2f53e..2af978e 100644 --- a/uprobe/arch/asm-arm/swap_uprobes.c +++ b/uprobe/arch/asm-arm/swap_uprobes.c @@ -595,30 +595,16 @@ int arch_prepare_uprobe(struct kprobe *p, struct task_struct *task, int atomic) return ret; } -void arch_prepare_uretprobe_hl(struct kretprobe *rp, struct pt_regs *regs) +void arch_prepare_uretprobe_hl(struct kretprobe_instance *ri, + struct pt_regs *regs) { - struct kretprobe_instance *ri; + /* Set flag of current mode */ + ri->sp = (kprobe_opcode_t *)((long)ri->sp | !!thumb_mode(regs)); - /* TODO: test - remove retprobe after func entry but before its exit */ - if ((ri = get_free_rp_inst(rp)) != NULL) { - ri->rp = rp; - ri->rp2 = NULL; - ri->task = current; - ri->ret_addr = (kprobe_opcode_t *)regs->ARM_lr; - ri->sp = (kprobe_opcode_t *)regs->ARM_sp; - - /* Set flag of current mode */ - ri->sp = (kprobe_opcode_t *)((long)ri->sp | !!thumb_mode(regs)); - - if (thumb_mode(regs)) { - regs->ARM_lr = (unsigned long)(rp->kp.ainsn.insn) + 0x1b; - } else { - regs->ARM_lr = (unsigned long)(rp->kp.ainsn.insn + UPROBES_TRAMP_RET_BREAK_IDX); - } - - add_rp_inst(ri); + if (thumb_mode(regs)) { + regs->ARM_lr = (unsigned long)(ri->rp->kp.ainsn.insn) + 0x1b; } else { - ++rp->nmissed; + regs->ARM_lr = (unsigned long)(ri->rp->kp.ainsn.insn + UPROBES_TRAMP_RET_BREAK_IDX); } } diff --git a/uprobe/arch/asm-arm/swap_uprobes.h b/uprobe/arch/asm-arm/swap_uprobes.h index da9a889..067c946 100644 --- a/uprobe/arch/asm-arm/swap_uprobes.h +++ b/uprobe/arch/asm-arm/swap_uprobes.h @@ -13,7 +13,7 @@ static inline int longjmp_break_uhandler(struct kprobe *p, struct pt_regs *regs) return 0; } -void arch_prepare_uretprobe_hl(struct kretprobe *rp, struct pt_regs *regs); +void arch_prepare_uretprobe_hl(struct kretprobe_instance *ri, struct pt_regs *regs); int swap_arch_init_uprobes(void); void swap_arch_exit_uprobes(void); diff --git a/uprobe/swap_uprobes.c b/uprobe/swap_uprobes.c index 39caaf6..0331c7b 100644 --- a/uprobe/swap_uprobes.c +++ b/uprobe/swap_uprobes.c @@ -320,13 +320,31 @@ void dbi_unregister_ujprobe(struct task_struct *task, struct jprobe *jp, int ato static int pre_handler_uretprobe(struct kprobe *p, struct pt_regs *regs) { struct kretprobe *rp = container_of(p, struct kretprobe, kp); + struct kretprobe_instance *ri; unsigned long flags; /* TODO: consider to only swap the RA after the last pre_handler fired */ spin_lock_irqsave(&kretprobe_lock, flags); - if (!rp->disarm) { - arch_prepare_uretprobe_hl(rp, regs); + if (rp->disarm) { + goto unlock; } + + /* TODO: test - remove retprobe after func entry but before its exit */ + if ((ri = get_free_rp_inst(rp)) != NULL) { + ri->rp = rp; + ri->rp2 = NULL; + ri->task = current; + ri->ret_addr = (kprobe_opcode_t *)regs->ARM_lr; + ri->sp = (kprobe_opcode_t *)regs->ARM_sp; + + arch_prepare_uretprobe_hl(ri, regs); + + add_rp_inst(ri); + } else { + ++rp->nmissed; + } + +unlock: spin_unlock_irqrestore(&kretprobe_lock, flags); return 0; -- 2.7.4