[REFACTOR] redesign arch_prepare_uretprobe_hl()
authorVyacheslav Cherkashin <v.cherkashin@samsung.com>
Thu, 21 Mar 2013 11:59:28 +0000 (15:59 +0400)
committerVyacheslav Cherkashin <v.cherkashin@samsung.com>
Thu, 21 Mar 2013 11:59:28 +0000 (15:59 +0400)
uprobe/arch/asm-arm/swap_uprobes.c
uprobe/arch/asm-arm/swap_uprobes.h
uprobe/swap_uprobes.c

index 3f2f53e..2af978e 100644 (file)
@@ -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);
        }
 }
 
index da9a889..067c946 100644 (file)
@@ -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);
index 39caaf6..0331c7b 100644 (file)
@@ -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;