[FIX] Fix wrong functions w/o returns determination (bl,blx)
authorDmitry Kovalenko <d.kovalenko@samsung.com>
Tue, 18 Jun 2013 07:36:09 +0000 (11:36 +0400)
committerDmitry Kovalenko <d.kovalenko@samsung.com>
Tue, 18 Jun 2013 07:36:09 +0000 (11:36 +0400)
kprobe/arch/asm-arm/dbi_kprobes.c
kprobe/dbi_kprobes.c
kprobe/dbi_kprobes.h

index bc6d44d..36b9e41 100644 (file)
@@ -707,9 +707,17 @@ int arch_prepare_uretprobe (struct kretprobe *p, struct task_struct *task)
        /* Remove retprobe if first insn overwrites lr */
        if (THUMB_INSN_MATCH(BLX2, p->kp.opcode) ||
            THUMB2_INSN_MATCH(BL, p->kp.opcode) ||
-           THUMB2_INSN_MATCH(BLX1, p->kp.opcode)){
-               p->kp.pre_handler = NULL;
-       }
+           THUMB2_INSN_MATCH(BLX1, p->kp.opcode))
+               p->thumb_noret = 0;
+       else
+               p->thumb_noret = 1;
+
+       if (ARM_INSN_MATCH(BLX1, p->kp.opcode) ||
+           ARM_INSN_MATCH(BLX2, p->kp.opcode) ||
+           ARM_INSN_MATCH(BL, p->kp.opcode))
+               p->arm_noret = 0;
+       else
+               p->arm_noret = 1;
 
        return 0;
 }
index 9d66ac1..e5855bd 100644 (file)
@@ -633,6 +633,14 @@ int pre_handler_kretprobe (struct kprobe *p, struct pt_regs *regs)
        unsigned long flags = 0;
        DBPRINTF ("START\n");
 
+       if (p && p->tgid) {     /* Userspace */
+               if (unlikely(thumb_mode(regs))) {
+                       if (!rp->thumb_noret)
+                               return 0;
+               } else if (!rp->arm_noret)
+                       return 0;
+       }
+
        /*TODO: consider to only swap the RA after the last pre_handler fired */
        spin_lock_irqsave (&kretprobe_lock, flags);
        if (!rp->disarm)
index 2f28744..b5892f5 100644 (file)
@@ -194,6 +194,13 @@ struct kretprobe
        int disarm;
        struct hlist_head free_instances;
        struct hlist_head used_instances;
+
+#ifdef CONFIG_ARM
+       // probe with noreturn (bl,blx)
+       unsigned                                        arm_noret:1;
+       unsigned                                        thumb_noret:1;
+#endif
+
 };
 
 struct kretprobe_instance