[REFACTOR] remove kprobe from uprobe 42/44042/4
authorAnatolii Nikulin <nikulin.a@samsung.com>
Mon, 22 Jun 2015 12:45:02 +0000 (15:45 +0300)
committerAnatolii Nikulin <nikulin.a@samsung.com>
Fri, 7 Aug 2015 09:31:18 +0000 (12:31 +0300)
Change-Id: I378b0d6af97b3bd342b7708ffad2122d7e54073c
Signed-off-by: Anatolii Nikulin <nikulin.a@samsung.com>
14 files changed:
fbiprobe/fbiprobe.c
nsp/nsp.c
preload/preload_module.c
uprobe/arch/arm/swap-asm/swap_uprobes.c
uprobe/arch/arm/swap-asm/swap_uprobes.h
uprobe/arch/x86/swap-asm/swap_uprobes.c
uprobe/arch/x86/swap-asm/swap_uprobes.h
uprobe/swap_uprobes.c
uprobe/swap_uprobes.h
us_manager/probes/probe_info_new.c
us_manager/probes/probe_info_new.h
us_manager/sspt/sspt.h
us_manager/sspt/sspt_debug.h
wsp/wsp.c

index d507502..96c2467 100644 (file)
@@ -255,10 +255,9 @@ exit:
        return 0;
 }
 
-static int fbi_probe_handler(struct kprobe *p, struct pt_regs *regs)
+static int fbi_probe_handler(struct uprobe *p, struct pt_regs *regs)
 {
-       struct uprobe *up = container_of(p, struct uprobe, kp);
-       struct us_ip *ip = container_of(up, struct us_ip, uprobe);
+       struct us_ip *ip = container_of(p, struct us_ip, uprobe);
        struct fbi_info *fbi_i = &ip->info->fbi_i;
        struct fbi_var_data *fbi_d = NULL;
        uint8_t i;
@@ -308,7 +307,7 @@ void fbi_probe_cleanup(struct probe_info *probe_i)
 
 void fbi_probe_init(struct us_ip *ip)
 {
-       ip->uprobe.kp.pre_handler = (kprobe_pre_handler_t)fbi_probe_handler;
+       ip->uprobe.pre_handler = (uprobe_pre_handler_t)fbi_probe_handler;
 }
 
 void fbi_probe_uninit(struct us_ip *ip)
index 3a0fc6f..07482fa 100644 (file)
--- a/nsp/nsp.c
+++ b/nsp/nsp.c
@@ -60,7 +60,7 @@ static int main_rh(struct uretprobe_instance *ri, struct pt_regs *regs);
 static struct probe_info_new pin_main = MAKE_URPROBE(main_eh, main_rh, 0);
 
 /* appcore_efl_main */
-static int ac_efl_main_h(struct kprobe *p, struct pt_regs *regs);
+static int ac_efl_main_h(struct uprobe *p, struct pt_regs *regs);
 static struct probe_info_new pin_ac_efl_main = MAKE_UPROBE(ac_efl_main_h);
 static struct probe_new p_ac_efl_main = {
        .info = &pin_ac_efl_main
@@ -74,7 +74,7 @@ static struct probe_new p_ac_init = {
 };
 
 /* elm_run@plt */
-static int elm_run_h(struct kprobe *p, struct pt_regs *regs);
+static int elm_run_h(struct uprobe *p, struct pt_regs *regs);
 static struct probe_info_new pin_elm_run = MAKE_UPROBE(elm_run_h);
 static struct probe_new p_elm_run = {
        .info = &pin_elm_run
@@ -673,7 +673,7 @@ static void stage_end(enum nsp_proc_stat priv, enum nsp_proc_stat cur,
        }
 }
 
-static int main_h(struct kprobe *p, struct pt_regs *regs)
+static int main_h(struct uprobe *p, struct pt_regs *regs)
 {
        struct tdata *tdata;
        u64 time_start;
@@ -708,7 +708,7 @@ static int main_eh(struct uretprobe_instance *ri, struct pt_regs *regs)
        struct uretprobe *rp = ri->rp;
 
        if (rp) {
-               main_h(&rp->up.kp, regs);
+               main_h(&rp->up, regs);
 
                if (get_quiet() == QT_OFF) {
                        struct us_ip *ip;
@@ -743,7 +743,7 @@ static int main_rh(struct uretprobe_instance *ri, struct pt_regs *regs)
        return 0;
 }
 
-static int ac_efl_main_h(struct kprobe *p, struct pt_regs *regs)
+static int ac_efl_main_h(struct uprobe *p, struct pt_regs *regs)
 {
        stage_end(NPS_MAIN_E, NPS_AC_EFL_MAIN_E, NMS_MAIN);
        return 0;
@@ -755,7 +755,7 @@ static int ac_init_rh(struct uretprobe_instance *ri, struct pt_regs *regs)
        return 0;
 }
 
-static int elm_run_h(struct kprobe *p, struct pt_regs *regs)
+static int elm_run_h(struct uprobe *p, struct pt_regs *regs)
 {
        stage_end(NPS_AC_INIT_R, NPS_ELM_RUN_E, NMS_CREATE);
        return 0;
index 87575f8..f7cb11e 100644 (file)
@@ -140,7 +140,7 @@ static inline void __prepare_ujump(struct uretprobe_instance *ri,
                                   struct pt_regs *regs,
                                   unsigned long vaddr)
 {
-       ri->rp->up.kp.ss_addr[smp_processor_id()] = (kprobe_opcode_t *)vaddr;
+       ri->rp->up.ss_addr[smp_processor_id()] = (kprobe_opcode_t *)vaddr;
 
 #ifdef CONFIG_ARM
        if (thumb_mode(regs)) {
@@ -201,7 +201,7 @@ static inline void print_regs(const char *prefix, struct pt_regs *regs,
               "sp(%08lx), lr(%08lx), pc(%08lx)\n",
               current->comm, current->tgid, current->pid,
               (int)preload_pd_get_state(__get_process_data(ri->rp)),
-              prefix, (unsigned long)ri->rp->up.kp.addr,
+              prefix, (unsigned long)ri->rp->up.addr,
               regs->ARM_r0, regs->ARM_r1, regs->ARM_r2, regs->ARM_r3,
               regs->ARM_r4, regs->ARM_r5, regs->ARM_r6, regs->ARM_r7,
               regs->ARM_sp, regs->ARM_lr, regs->ARM_pc);
@@ -210,7 +210,7 @@ static inline void print_regs(const char *prefix, struct pt_regs *regs,
               "ip(%08lx), arg0(%08lx), arg1(%08lx), raddr(%08lx)\n",
               current->comm, current->tgid, current->pid,
               (int)preload_pd_get_state(__get_process_data(ri->rp)),
-              prefix, (unsigned long)ri->rp->up.kp.addr,
+              prefix, (unsigned long)ri->rp->up.addr,
               regs->EREG(ip), swap_get_arg(regs, 0), swap_get_arg(regs, 1),
               swap_get_ret_addr(regs));
 #endif /* CONFIG_ARM */
@@ -715,7 +715,7 @@ static int preload_us_ret(struct uretprobe_instance *ri, struct pt_regs *regs)
 
 
 
-static int get_caller_handler(struct kprobe *p, struct pt_regs *regs)
+static int get_caller_handler(struct uprobe *p, struct pt_regs *regs)
 {
        unsigned long caller;
        int ret;
@@ -732,7 +732,7 @@ static int get_caller_handler(struct kprobe *p, struct pt_regs *regs)
        return 0;
 }
 
-static int get_call_type_handler(struct kprobe *p, struct pt_regs *regs)
+static int get_call_type_handler(struct uprobe *p, struct pt_regs *regs)
 {
        unsigned char call_type;
        int ret;
@@ -749,7 +749,7 @@ static int get_call_type_handler(struct kprobe *p, struct pt_regs *regs)
        return 0;
 }
 
-static int write_msg_handler(struct kprobe *p, struct pt_regs *regs)
+static int write_msg_handler(struct uprobe *p, struct pt_regs *regs)
 {
        char *user_buf;
        char *buf;
@@ -819,7 +819,7 @@ int preload_module_get_caller_init(struct us_ip *ip)
 {
        struct uprobe *up = &ip->uprobe;
 
-       up->kp.pre_handler = get_caller_handler;
+       up->pre_handler = get_caller_handler;
 
        return 0;
 }
@@ -832,7 +832,7 @@ int preload_module_get_call_type_init(struct us_ip *ip)
 {
        struct uprobe *up = &ip->uprobe;
 
-       up->kp.pre_handler = get_call_type_handler;
+       up->pre_handler = get_call_type_handler;
 
        return 0;
 }
@@ -845,7 +845,7 @@ int preload_module_write_msg_init(struct us_ip *ip)
 {
        struct uprobe *up = &ip->uprobe;
 
-       up->kp.pre_handler = write_msg_handler;
+       up->pre_handler = write_msg_handler;
 
        return 0;
 }
index af1ccf5..56a4a20 100644 (file)
@@ -100,13 +100,12 @@ static int is_thumb2(kprobe_opcode_t insn)
                (insn & 0xf800) == 0xf800);
 }
 
-static int arch_copy_trampoline_arm_uprobe(struct uprobe *up)
+static int arch_copy_trampoline_arm_uprobe(struct uprobe *p)
 {
        int ret;
-       struct kprobe *p = up2kp(up);
        unsigned long insn = p->opcode;
        unsigned long vaddr = (unsigned long)p->addr;
-       unsigned long *tramp = up->atramp.tramp_arm;
+       unsigned long *tramp = p->atramp.tramp_arm;
 
        ret = arch_make_trampoline_arm(vaddr, insn, tramp);
        p->safe_arm = !!ret;
@@ -394,20 +393,19 @@ static int prep_pc_dep_insn_execbuf_thumb(kprobe_opcode_t *insns,
        return 0;
 }
 
-static int arch_copy_trampoline_thumb_uprobe(struct uprobe *up)
+static int arch_copy_trampoline_thumb_uprobe(struct uprobe *p)
 {
        int uregs, pc_dep;
-       struct kprobe *p = up2kp(up);
        unsigned int addr;
        unsigned long vaddr = (unsigned long)p->addr;
        unsigned long insn = p->opcode;
-       unsigned long *tramp = up->atramp.tramp_thumb;
-       enum { tramp_len = sizeof(up->atramp.tramp_thumb) };
+       unsigned long *tramp = p->atramp.tramp_thumb;
+       enum { tramp_len = sizeof(p->atramp.tramp_thumb) };
 
        p->safe_thumb = 1;
        if (vaddr & 0x01) {
                printk(KERN_INFO "Error in %s at %d: attempt to register "
-                      "kprobe at an unaligned address\n", __FILE__, __LINE__);
+                      "uprobe at an unaligned address\n", __FILE__, __LINE__);
                return -EINVAL;
        }
 
@@ -610,10 +608,9 @@ static int arch_copy_trampoline_thumb_uprobe(struct uprobe *up)
  * @return 0 on success,\n
  * negative error code on error.
  */
-int arch_prepare_uprobe(struct uprobe *up)
+int arch_prepare_uprobe(struct uprobe *p)
 {
-       struct kprobe *p = up2kp(up);
-       struct task_struct *task = up->task;
+       struct task_struct *task = p->task;
        unsigned long vaddr = (unsigned long)p->addr;
        unsigned long insn;
 
@@ -631,8 +628,8 @@ int arch_prepare_uprobe(struct uprobe *up)
 
        p->opcode = insn;
 
-       arch_copy_trampoline_arm_uprobe(up);
-       arch_copy_trampoline_thumb_uprobe(up);
+       arch_copy_trampoline_arm_uprobe(p);
+       arch_copy_trampoline_thumb_uprobe(p);
 
        if ((p->safe_arm) && (p->safe_thumb)) {
                printk(KERN_INFO "Error in %s at %d: failed "
@@ -642,8 +639,8 @@ int arch_prepare_uprobe(struct uprobe *up)
                return -EFAULT;
        }
 
-       up->atramp.utramp = swap_slot_alloc(up->sm);
-       if (up->atramp.utramp == NULL) {
+       p->atramp.utramp = swap_slot_alloc(p->sm);
+       if (p->atramp.utramp == NULL) {
                printk(KERN_INFO "Error: swap_slot_alloc failed (%08lx)\n",
                       vaddr);
                return -ENOMEM;
@@ -661,13 +658,13 @@ int arch_prepare_uprobe(struct uprobe *up)
 void arch_opcode_analysis_uretprobe(struct uretprobe *rp)
 {
        /* Remove retprobe if first insn overwrites lr */
-       rp->thumb_noret = !!(THUMB2_INSN_MATCH(BL, rp->up.kp.opcode) ||
-                            THUMB2_INSN_MATCH(BLX1, rp->up.kp.opcode) ||
-                            THUMB_INSN_MATCH(BLX2, rp->up.kp.opcode));
+       rp->thumb_noret = !!(THUMB2_INSN_MATCH(BL, rp->up.opcode) ||
+                            THUMB2_INSN_MATCH(BLX1, rp->up.opcode) ||
+                            THUMB_INSN_MATCH(BLX2, rp->up.opcode));
 
-       rp->arm_noret = !!(ARM_INSN_MATCH(BL, rp->up.kp.opcode) ||
-                          ARM_INSN_MATCH(BLX1, rp->up.kp.opcode) ||
-                          ARM_INSN_MATCH(BLX2, rp->up.kp.opcode));
+       rp->arm_noret = !!(ARM_INSN_MATCH(BL, rp->up.opcode) ||
+                          ARM_INSN_MATCH(BLX1, rp->up.opcode) ||
+                          ARM_INSN_MATCH(BLX2, rp->up.opcode));
 }
 
 /**
@@ -686,12 +683,12 @@ int arch_prepare_uretprobe(struct uretprobe_instance *ri, struct pt_regs *regs)
        ri->sp = (kprobe_opcode_t *)((long)ri->sp | !!thumb_mode(regs));
 
        if (ri->preload_thumb) {
-               regs->ARM_lr = (unsigned long)(ri->rp->up.kp.ainsn.insn) + 0x1b;
+               regs->ARM_lr = (unsigned long)(ri->rp->up.ainsn.insn) + 0x1b;
        } else {
                if (thumb_mode(regs))
-                       regs->ARM_lr = (unsigned long)(ri->rp->up.kp.ainsn.insn) + 0x1b;
+                       regs->ARM_lr = (unsigned long)(ri->rp->up.ainsn.insn) + 0x1b;
                else
-                       regs->ARM_lr = (unsigned long)(ri->rp->up.kp.ainsn.insn +
+                       regs->ARM_lr = (unsigned long)(ri->rp->up.ainsn.insn +
                                                       UPROBES_TRAMP_RET_BREAK_IDX);
        }
 
@@ -721,9 +718,9 @@ int arch_disarm_urp_inst(struct uretprobe_instance *ri,
        /* Understand function mode */
        if ((long)ri->sp & 1) {
                tramp = (unsigned long *)
-                       ((unsigned long)ri->rp->up.kp.ainsn.insn + 0x1b);
+                       ((unsigned long)ri->rp->up.ainsn.insn + 0x1b);
        } else {
-               tramp = (unsigned long *)(ri->rp->up.kp.ainsn.insn +
+               tramp = (unsigned long *)(ri->rp->up.ainsn.insn +
                                          UPROBES_TRAMP_RET_BREAK_IDX);
        }
 
@@ -755,7 +752,7 @@ int arch_disarm_urp_inst(struct uretprobe_instance *ri,
               "%08lx (%08lx /%+d) - %p\n",
               task->comm, task->tgid, task->pid,
               (unsigned long)found, (unsigned long)sp,
-              found - sp, ri->rp->up.kp.addr);
+              found - sp, ri->rp->up.addr);
        retval = write_proc_vm_atomic(task, (unsigned long)found,
                                      &ri->ret_addr,
                                      sizeof(ri->ret_addr));
@@ -773,14 +770,14 @@ check_lr: /* check lr anyway */
                printk(KERN_INFO "---> %s (%d/%d): trampoline found at "
                       "lr = %08lx - %p\n",
                       task->comm, task->tgid, task->pid,
-                      ra, ri->rp->up.kp.addr);
+                      ra, ri->rp->up.addr);
                swap_set_ret_addr(uregs, (unsigned long)ri->ret_addr);
                retval = 0;
        } else if (retval) {
                printk(KERN_INFO "---> %s (%d/%d): trampoline NOT found at "
                       "sp = %08lx, lr = %08lx - %p\n",
                       task->comm, task->tgid, task->pid,
-                      (unsigned long)sp, ra, ri->rp->up.kp.addr);
+                      (unsigned long)sp, ra, ri->rp->up.addr);
        }
 
        return retval;
@@ -789,17 +786,16 @@ check_lr: /* check lr anyway */
 /**
  * @brief Jump pre-handler.
  *
- * @param p Pointer to the kprobe.
+ * @param p Pointer to the uprobe.
  * @param regs Pointer to CPU register data.
  * @return 0.
  */
-int setjmp_upre_handler(struct kprobe *p, struct pt_regs *regs)
+int setjmp_upre_handler(struct uprobe *p, struct pt_regs *regs)
 {
-       struct uprobe *up = container_of(p, struct uprobe, kp);
-       struct ujprobe *jp = container_of(up, struct ujprobe, up);
+       struct ujprobe *jp = container_of(p, struct ujprobe, up);
 
-       kprobe_pre_entry_handler_t pre_entry =
-               (kprobe_pre_entry_handler_t)jp->pre_entry;
+       uprobe_pre_entry_handler_t pre_entry =
+               (uprobe_pre_entry_handler_t)jp->pre_entry;
        entry_point_t entry = (entry_point_t)jp->entry;
 
        if (pre_entry) {
@@ -820,11 +816,11 @@ int setjmp_upre_handler(struct kprobe *p, struct pt_regs *regs)
 /**
  * @brief Gets trampoline address.
  *
- * @param p Pointer to the kprobe.
+ * @param p Pointer to the uprobe.
  * @param regs Pointer to CPU register data.
  * @return Trampoline address.
  */
-unsigned long arch_get_trampoline_addr(struct kprobe *p, struct pt_regs *regs)
+unsigned long arch_get_trampoline_addr(struct uprobe *p, struct pt_regs *regs)
 {
        return thumb_mode(regs) ?
                        (unsigned long)(p->ainsn.insn) + 0x1b :
@@ -861,7 +857,7 @@ void arch_remove_uprobe(struct uprobe *up)
        swap_slot_free(up->sm, up->atramp.utramp);
 }
 
-static void restore_opcode_for_thumb(struct kprobe *p, struct pt_regs *regs)
+static void restore_opcode_for_thumb(struct uprobe *p, struct pt_regs *regs)
 {
        if (thumb_mode(regs) && !is_thumb2(p->opcode)) {
                u16 tmp = p->opcode >> 16;
@@ -871,10 +867,9 @@ static void restore_opcode_for_thumb(struct kprobe *p, struct pt_regs *regs)
        }
 }
 
-static int make_trampoline(struct uprobe *up, struct pt_regs *regs)
+static int make_trampoline(struct uprobe *p, struct pt_regs *regs)
 {
        unsigned long *tramp, *utramp;
-       struct kprobe *p = up2kp(up);
        int sw;
 
        /*
@@ -890,13 +885,13 @@ static int make_trampoline(struct uprobe *up, struct pt_regs *regs)
        /* ARM */
        case 0b110:
        case 0b010:
-               tramp = up->atramp.tramp_arm;
+               tramp = p->atramp.tramp_arm;
                break;
        /* THUMB */
        case 0b111:
        case 0b101:
                restore_opcode_for_thumb(p, regs);
-               tramp = up->atramp.tramp_thumb;
+               tramp = p->atramp.tramp_thumb;
                break;
        default:
                printk(KERN_INFO "Error in %s at %d: we are in arm mode "
@@ -904,14 +899,14 @@ static int make_trampoline(struct uprobe *up, struct pt_regs *regs)
                       "(%0lX instruction at %p address)!\n",
                       __FILE__, __LINE__, p->opcode, p->addr);
 
-               disarm_uprobe(p, up->task);
+               disarm_uprobe(p, p->task);
 
                return 1;
        }
 
-       utramp = up->atramp.utramp;
+       utramp = p->atramp.utramp;
 
-       if (!write_proc_vm_atomic(up->task, (unsigned long)utramp, tramp,
+       if (!write_proc_vm_atomic(p->task, (unsigned long)utramp, tramp,
                                  UPROBES_TRAMP_LEN * sizeof(*tramp))) {
                printk(KERN_ERR "failed to write memory %p!\n", utramp);
                return -EINVAL;
@@ -923,21 +918,41 @@ static int make_trampoline(struct uprobe *up, struct pt_regs *regs)
        return 0;
 }
 
+/**
+ * @brief Prepares singlestep for current CPU.
+ *
+ * @param p Pointer to uprobe.
+ * @param regs Pointer to CPU registers data.
+ * @return Void.
+ */
+
+static void uprobe_prepare_singlestep(struct uprobe *p, struct pt_regs *regs)
+{
+       int cpu = smp_processor_id();
+
+       if (p->ss_addr[cpu]) {
+               regs->ARM_pc = (unsigned long)p->ss_addr[cpu];
+               p->ss_addr[cpu] = NULL;
+       } else {
+               regs->ARM_pc = (unsigned long)p->ainsn.insn;
+       }
+}
+
 static int uprobe_handler(struct pt_regs *regs)
 {
        kprobe_opcode_t *addr = (kprobe_opcode_t *)(regs->ARM_pc);
        struct task_struct *task = current;
        pid_t tgid = task->tgid;
-       struct kprobe *p;
+       struct uprobe *p;
 
-       p = get_ukprobe(addr, tgid);
+       p = get_uprobe(addr, tgid);
        if (p == NULL) {
                unsigned long offset_bp = thumb_mode(regs) ?
                                          0x1a :
                                          4 * UPROBES_TRAMP_RET_BREAK_IDX;
                void *tramp_addr = (void *)addr - offset_bp;
 
-               p = get_ukprobe_by_insn_slot(tramp_addr, tgid, regs);
+               p = get_uprobe_by_insn_slot(tramp_addr, tgid, regs);
                if (p == NULL) {
                        printk(KERN_INFO "no_uprobe: Not one of ours: let "
                               "kernel handle it %p\n", addr);
@@ -947,9 +962,8 @@ static int uprobe_handler(struct pt_regs *regs)
                trampoline_uprobe_handler(p, regs);
        } else {
                if (p->ainsn.insn == NULL) {
-                       struct uprobe *up = kp2up(p);
 
-                       if (make_trampoline(up, regs)) {
+                       if (make_trampoline(p, regs)) {
                                printk(KERN_INFO "no_uprobe live\n");
                                return 0;
                        }
@@ -959,7 +973,7 @@ static int uprobe_handler(struct pt_regs *regs)
                }
 
                if (!p->pre_handler || !p->pre_handler(p, regs))
-                       prepare_singlestep(p, regs);
+                       uprobe_prepare_singlestep(p, regs);
        }
 
        return 0;
index 51342af..ee21d13 100644 (file)
@@ -39,7 +39,6 @@
 #include <swap-asm/swap_kprobes.h>     /* FIXME: for UPROBES_TRAMP_LEN */
 
 
-struct kprobe;
 struct task_struct;
 struct uprobe;
 struct uretprobe;
@@ -73,8 +72,8 @@ static inline void arch_ujprobe_return(void)
 
 int arch_prepare_uprobe(struct uprobe *up);
 
-int setjmp_upre_handler(struct kprobe *p, struct pt_regs *regs);
-static inline int longjmp_break_uhandler(struct kprobe *p, struct pt_regs *regs)
+int setjmp_upre_handler(struct uprobe *p, struct pt_regs *regs);
+static inline int longjmp_break_uhandler(struct uprobe *p, struct pt_regs *regs)
 {
        return 0;
 }
@@ -84,7 +83,7 @@ int arch_prepare_uretprobe(struct uretprobe_instance *ri, struct pt_regs *regs);
 int arch_disarm_urp_inst(struct uretprobe_instance *ri,
                         struct task_struct *task);
 
-unsigned long arch_get_trampoline_addr(struct kprobe *p, struct pt_regs *regs);
+unsigned long arch_get_trampoline_addr(struct uprobe *p, struct pt_regs *regs);
 void arch_set_orig_ret_addr(unsigned long orig_ret_addr, struct pt_regs *regs);
 void arch_remove_uprobe(struct uprobe *up);
 
index 84de6e4..0d6053a 100644 (file)
  */
 struct uprobe_ctlblk {
        unsigned long flags;            /**< Flags */
-       struct kprobe *p;               /**< Pointer to the uprobe's kprobe */
+       struct uprobe *p;               /**< Pointer to the uprobe */
 };
 
 static unsigned long trampoline_addr(struct uprobe *up)
 {
-       return (unsigned long)(up->kp.ainsn.insn +
+       return (unsigned long)(up->ainsn.insn +
                               UPROBES_TRAMP_RET_BREAK_IDX);
 }
 
@@ -60,12 +60,12 @@ static struct uprobe_ctlblk *current_ucb(void)
        return (struct uprobe_ctlblk *)(end_of_stack(current) + 20);
 }
 
-static struct kprobe *get_current_probe(void)
+static struct uprobe *get_current_probe(void)
 {
        return current_ucb()->p;
 }
 
-static void set_current_probe(struct kprobe *p)
+static void set_current_probe(struct uprobe *p)
 {
        current_ucb()->p = p;
 }
@@ -88,11 +88,10 @@ static void restore_current_flags(struct pt_regs *regs, unsigned long flags)
  * @return 0 on success,\n
  * -1 on error.
  */
-int arch_prepare_uprobe(struct uprobe *up)
+int arch_prepare_uprobe(struct uprobe *p)
 {
-       struct kprobe *p = up2kp(up);
-       struct task_struct *task = up->task;
-       u8 *tramp = up->atramp.tramp;
+       struct task_struct *task = p->task;
+       u8 *tramp = p->atramp.tramp;
        enum { call_relative_opcode = 0xe8 };
 
        if (!read_proc_vm_atomic(task, (unsigned long)p->addr,
@@ -113,15 +112,15 @@ int arch_prepare_uprobe(struct uprobe *up)
 
        p->ainsn.boostable = swap_can_boost(tramp) ? 0 : -1;
 
-       p->ainsn.insn = swap_slot_alloc(up->sm);
+       p->ainsn.insn = swap_slot_alloc(p->sm);
        if (p->ainsn.insn == NULL) {
                printk(KERN_ERR "trampoline out of memory\n");
                return -ENOMEM;
        }
 
        if (!write_proc_vm_atomic(task, (unsigned long)p->ainsn.insn,
-                                 tramp, sizeof(up->atramp.tramp))) {
-               swap_slot_free(up->sm, p->ainsn.insn);
+                                 tramp, sizeof(p->atramp.tramp))) {
+               swap_slot_free(p->sm, p->ainsn.insn);
                printk(KERN_INFO "failed to write memory %p!\n", tramp);
                return -EINVAL;
        }
@@ -135,16 +134,15 @@ int arch_prepare_uprobe(struct uprobe *up)
 /**
  * @brief Jump pre-handler.
  *
- * @param p Pointer to the uprobe's kprobe.
+ * @param p Pointer to the uprobe.
  * @param regs Pointer to CPU register data.
  * @return 0.
  */
-int setjmp_upre_handler(struct kprobe *p, struct pt_regs *regs)
+int setjmp_upre_handler(struct uprobe *p, struct pt_regs *regs)
 {
-       struct uprobe *up = container_of(p, struct uprobe, kp);
-       struct ujprobe *jp = container_of(up, struct ujprobe, up);
-       kprobe_pre_entry_handler_t pre_entry =
-               (kprobe_pre_entry_handler_t)jp->pre_entry;
+       struct ujprobe *jp = container_of(p, struct ujprobe, up);
+       uprobe_pre_entry_handler_t pre_entry =
+               (uprobe_pre_entry_handler_t)jp->pre_entry;
        entry_point_t entry = (entry_point_t)jp->entry;
        unsigned long args[6];
 
@@ -189,7 +187,7 @@ int arch_prepare_uretprobe(struct uretprobe_instance *ri, struct pt_regs *regs)
        if (!read_proc_vm_atomic(current, regs->EREG(sp), &(ri->ret_addr),
                                 sizeof(ri->ret_addr))) {
                printk(KERN_ERR "failed to read user space func ra %lx addr=%p!\n",
-                               regs->EREG(sp), ri->rp->up.kp.addr);
+                               regs->EREG(sp), ri->rp->up.addr);
                return -EINVAL;
        }
 
@@ -245,13 +243,13 @@ int arch_disarm_urp_inst(struct uretprobe_instance *ri,
 /**
  * @brief Gets trampoline address.
  *
- * @param p Pointer to the uprobe's kprobe.
+ * @param p Pointer to the uprobe.
  * @param regs Pointer to CPU register data.
  * @return Trampoline address.
  */
-unsigned long arch_get_trampoline_addr(struct kprobe *p, struct pt_regs *regs)
+unsigned long arch_get_trampoline_addr(struct uprobe *p, struct pt_regs *regs)
 {
-       return trampoline_addr(kp2up(p));
+       return trampoline_addr(p);
 }
 
 /**
@@ -272,11 +270,9 @@ void arch_set_orig_ret_addr(unsigned long orig_ret_addr, struct pt_regs *regs)
  * @param up Pointer to the target uprobe.
  * @return Void.
  */
-void arch_remove_uprobe(struct uprobe *up)
+void arch_remove_uprobe(struct uprobe *p)
 {
-       struct kprobe *p = up2kp(up);
-
-       swap_slot_free(up->sm, p->ainsn.insn);
+       swap_slot_free(p->sm, p->ainsn.insn);
 }
 
 static void set_user_jmp_op(void *from, void *to)
@@ -295,7 +291,7 @@ static void set_user_jmp_op(void *from, void *to)
                       "failed to write jump opcode to user space %p\n", from);
 }
 
-static void resume_execution(struct kprobe *p,
+static void resume_execution(struct uprobe *p,
                             struct pt_regs *regs,
                             unsigned long flags)
 {
@@ -420,7 +416,7 @@ no_change:
        return;
 }
 
-static bool prepare_ss_addr(struct kprobe *p, struct pt_regs *regs)
+static bool prepare_ss_addr(struct uprobe *p, struct pt_regs *regs)
 {
        unsigned long *ss_addr = (long *)&p->ss_addr[smp_processor_id()];
 
@@ -441,9 +437,35 @@ static void prepare_ss(struct pt_regs *regs)
        regs->flags &= ~IF_MASK;
 }
 
+/**
+ * @brief Prepares singlestep for current CPU.
+ *
+ * @param p Pointer to uprobe.
+ * @param regs Pointer to CPU registers data.
+ * @return Void.
+ */
+static void uprobe_prepare_singlestep(struct uprobe *p, struct pt_regs *regs)
+{
+       int cpu = smp_processor_id();
+
+       if (p->ss_addr[cpu]) {
+               regs->EREG(ip) = (unsigned long)p->ss_addr[cpu];
+               p->ss_addr[cpu] = NULL;
+       } else {
+               regs->EREG(flags) |= TF_MASK;
+               regs->EREG(flags) &= ~IF_MASK;
+               /* single step inline if the instruction is an int3 */
+               if (p->opcode == BREAKPOINT_INSTRUCTION) {
+                       regs->EREG(ip) = (unsigned long) p->addr;
+                       /* printk(KERN_INFO "break_insn!!!\n"); */
+               } else
+                       regs->EREG(ip) = (unsigned long) p->ainsn.insn;
+       }
+}
+
 static int uprobe_handler(struct pt_regs *regs)
 {
-       struct kprobe *p;
+       struct uprobe *p;
        kprobe_opcode_t *addr;
        struct task_struct *task = current;
        pid_t tgid = task->tgid;
@@ -451,12 +473,12 @@ static int uprobe_handler(struct pt_regs *regs)
        save_current_flags(regs);
 
        addr = (kprobe_opcode_t *)(regs->EREG(ip) - sizeof(kprobe_opcode_t));
-       p = get_ukprobe(addr, tgid);
+       p = get_uprobe(addr, tgid);
 
        if (p == NULL) {
                void *tramp_addr = (void *)addr - UPROBES_TRAMP_RET_BREAK_IDX;
 
-               p = get_ukprobe_by_insn_slot(tramp_addr, tgid, regs);
+               p = get_uprobe_by_insn_slot(tramp_addr, tgid, regs);
                if (p == NULL) {
                        printk(KERN_INFO "no_uprobe\n");
                        return 0;
@@ -475,6 +497,8 @@ static int uprobe_handler(struct pt_regs *regs)
                                set_current_probe(p);
                                prepare_ss(regs);
                        }
+
+                       uprobe_prepare_singlestep(p, regs);
                }
        }
 
@@ -483,7 +507,7 @@ static int uprobe_handler(struct pt_regs *regs)
 
 static int post_uprobe_handler(struct pt_regs *regs)
 {
-       struct kprobe *p = get_current_probe();
+       struct uprobe *p = get_current_probe();
        unsigned long flags = current_ucb()->flags;
 
        if (p == NULL) {
index faef033..038f65c 100644 (file)
@@ -73,8 +73,8 @@ static inline void arch_ujprobe_return(void)
 }
 
 int arch_prepare_uprobe(struct uprobe *up);
-int setjmp_upre_handler(struct kprobe *p, struct pt_regs *regs);
-static inline int longjmp_break_uhandler(struct kprobe *p, struct pt_regs *regs)
+int setjmp_upre_handler(struct uprobe *p, struct pt_regs *regs);
+static inline int longjmp_break_uhandler(struct uprobe *p, struct pt_regs *regs)
 {
        return 0;
 }
@@ -87,7 +87,7 @@ static inline int arch_opcode_analysis_uretprobe(struct uretprobe *rp)
 int arch_prepare_uretprobe(struct uretprobe_instance *ri, struct pt_regs *regs);
 int arch_disarm_urp_inst(struct uretprobe_instance *ri,
                         struct task_struct *task);
-unsigned long arch_get_trampoline_addr(struct kprobe *p, struct pt_regs *regs);
+unsigned long arch_get_trampoline_addr(struct uprobe *p, struct pt_regs *regs);
 void arch_set_orig_ret_addr(unsigned long orig_ret_addr, struct pt_regs *regs);
 void arch_remove_uprobe(struct uprobe *up);
 
index 82e64c8..2f6d3c3 100644 (file)
@@ -64,15 +64,15 @@ void print_uprobe_hash_table(void)
 {
        int i;
        struct hlist_head *head;
-       struct kprobe *p;
+       struct uprobe *p;
        DECLARE_NODE_PTR_FOR_HLIST(node);
 
        /* print uprobe table */
        for (i = 0; i < UPROBE_TABLE_SIZE; ++i) {
                head = &uprobe_insn_slot_table[i];
-               swap_hlist_for_each_entry_rcu(p, node, head, is_hlist_arm) {
-                       printk(KERN_INFO "####### find U tgid=%u, addr=%x\n",
-                                       p->tgid, p->addr);
+               swap_hlist_for_each_entry_rcu(p, node, head, is_hlist) {
+                       printk(KERN_INFO "####### find U tgid=%u, addr=0x%lx\n",
+                                       p->task->tgid, (unsigned long)p->addr);
                }
        }
 }
@@ -81,7 +81,7 @@ void print_uprobe_hash_table(void)
 /*
  * Keep all fields in the uprobe consistent
  */
-static inline void copy_uprobe(struct kprobe *old_p, struct kprobe *p)
+static inline void copy_uprobe(struct uprobe *old_p, struct uprobe *p)
 {
        memcpy(&p->opcode, &old_p->opcode, sizeof(kprobe_opcode_t));
        memcpy(&p->ainsn, &old_p->ainsn, sizeof(struct arch_specific_insn));
@@ -95,14 +95,14 @@ static inline void copy_uprobe(struct kprobe *old_p, struct kprobe *p)
  * Aggregate handlers for multiple uprobes support - these handlers
  * take care of invoking the individual uprobe handlers on p->list
  */
-static int aggr_pre_uhandler(struct kprobe *p, struct pt_regs *regs)
+static int aggr_pre_uhandler(struct uprobe *p, struct pt_regs *regs)
 {
-       struct kprobe *kp;
+       struct uprobe *up;
        int ret;
 
-       list_for_each_entry_rcu(kp, &p->list, list) {
-               if (kp->pre_handler) {
-                       ret = kp->pre_handler(kp, regs);
+       list_for_each_entry_rcu(up, &p->list, list) {
+               if (up->pre_handler) {
+                       ret = up->pre_handler(up, regs);
                        if (ret)
                                return ret;
                }
@@ -111,25 +111,25 @@ static int aggr_pre_uhandler(struct kprobe *p, struct pt_regs *regs)
        return 0;
 }
 
-static void aggr_post_uhandler(struct kprobe *p, struct pt_regs *regs,
+static void aggr_post_uhandler(struct uprobe *p, struct pt_regs *regs,
                               unsigned long flags)
 {
-       struct kprobe *kp;
+       struct uprobe *up;
 
-       list_for_each_entry_rcu(kp, &p->list, list) {
-               if (kp->post_handler)
-                       kp->post_handler(kp, regs, flags);
+       list_for_each_entry_rcu(up, &p->list, list) {
+               if (up->post_handler)
+                       up->post_handler(up, regs, flags);
        }
 }
 
-static int aggr_fault_uhandler(struct kprobe *p,
+static int aggr_fault_uhandler(struct uprobe *p,
                               struct pt_regs *regs,
                               int trapnr)
 {
        return 0;
 }
 
-static int aggr_break_uhandler(struct kprobe *p, struct pt_regs *regs)
+static int aggr_break_uhandler(struct uprobe *p, struct pt_regs *regs)
 {
        return 0;
 }
@@ -138,7 +138,7 @@ static int aggr_break_uhandler(struct kprobe *p, struct pt_regs *regs)
  * Add the new probe to old_p->list. Fail if this is the
  * second ujprobe at the address - two ujprobes can't coexist
  */
-static int add_new_uprobe(struct kprobe *old_p, struct kprobe *p)
+static int add_new_uprobe(struct uprobe *old_p, struct uprobe *p)
 {
        if (p->break_handler) {
                if (old_p->break_handler)
@@ -160,7 +160,7 @@ static int add_new_uprobe(struct kprobe *old_p, struct kprobe *p)
  * Fill in the required fields of the "manager uprobe". Replace the
  * earlier uprobe in the hlist with the manager uprobe
  */
-static inline void add_aggr_uprobe(struct kprobe *ap, struct kprobe *p)
+static inline void add_aggr_uprobe(struct uprobe *ap, struct uprobe *p)
 {
        copy_uprobe(p, ap);
 
@@ -184,10 +184,9 @@ static inline void add_aggr_uprobe(struct kprobe *ap, struct kprobe *p)
  * This is the second or subsequent uprobe at the address - handle
  * the intricacies
  */
-static int register_aggr_uprobe(struct kprobe *old_p, struct kprobe *p)
+static int register_aggr_uprobe(struct uprobe *old_p, struct uprobe *p)
 {
        int ret = 0;
-       struct kprobe *ap;
 
        if (old_p->pre_handler == aggr_pre_uhandler) {
                copy_uprobe(old_p, p);
@@ -197,11 +196,10 @@ static int register_aggr_uprobe(struct kprobe *old_p, struct kprobe *p)
                if (!uap)
                        return -ENOMEM;
 
-               uap->task = kp2up(p)->task;
-               ap = up2kp(uap);
-               add_aggr_uprobe(ap, old_p);
-               copy_uprobe(ap, p);
-               ret = add_new_uprobe(ap, p);
+               uap->task = p->task;
+               add_aggr_uprobe(uap, old_p);
+               copy_uprobe(uap, p);
+               ret = add_new_uprobe(uap, p);
        }
 
        return ret;
@@ -210,11 +208,11 @@ static int register_aggr_uprobe(struct kprobe *old_p, struct kprobe *p)
 static int arm_uprobe(struct uprobe *p)
 {
        kprobe_opcode_t insn = BREAKPOINT_INSTRUCTION;
-       int ret = write_proc_vm_atomic(p->task, (unsigned long)p->kp.addr,
+       int ret = write_proc_vm_atomic(p->task, (unsigned long)p->addr,
                                       &insn, sizeof(insn));
        if (!ret) {
                printk("arm_uprobe: failed to write memory "
-                      "tgid=%u addr=%p!\n", p->task->tgid, p->kp.addr);
+                      "tgid=%u addr=%p!\n", p->task->tgid, p->addr);
 
                return -EACCES;
        }
@@ -225,11 +223,11 @@ static int arm_uprobe(struct uprobe *p)
 /**
  * @brief Disarms uprobe.
  *
- * @param p Pointer to the uprobe's kprobe.
+ * @param p Pointer to the uprobe.
  * @param task Pointer to the target task.
  * @return Void.
  */
-void disarm_uprobe(struct kprobe *p, struct task_struct *task)
+void disarm_uprobe(struct uprobe *p, struct task_struct *task)
 {
        int ret = write_proc_vm_atomic(task, (unsigned long)p->addr,
                                       &p->opcode, sizeof(p->opcode));
@@ -262,22 +260,22 @@ static void init_uretprobe_inst_table(void)
 }
 
 /**
- * @brief Gets uprobe's kprobe.
+ * @brief Gets uprobe.
  *
  * @param addr Probe's address.
  * @param tgid Probes's thread group ID.
- * @return Pointer to the kprobe on success,\n
+ * @return Pointer to the uprobe on success,\n
  * NULL otherwise.
  */
-struct kprobe *get_ukprobe(void *addr, pid_t tgid)
+struct uprobe *get_uprobe(void *addr, pid_t tgid)
 {
        struct hlist_head *head;
-       struct kprobe *p;
+       struct uprobe *p;
        DECLARE_NODE_PTR_FOR_HLIST(node);
 
        head = &uprobe_table[hash_ptr(addr, UPROBE_HASH_BITS)];
        swap_hlist_for_each_entry_rcu(p, node, head, hlist) {
-               if (p->addr == addr && kp2up(p)->task->tgid == tgid)
+               if (p->addr == addr && p->task->tgid == tgid)
                        return p;
        }
 
@@ -287,10 +285,10 @@ struct kprobe *get_ukprobe(void *addr, pid_t tgid)
 /**
  * @brief Adds uprobe to hlist when trampoline have been made.
  *
- * @param p Pointer to the uprobe's kprobe.
+ * @param p Pointer to the uprobe.
  * @return Void.
  */
-void add_uprobe_table(struct kprobe *p)
+void add_uprobe_table(struct uprobe *p)
 {
        write_lock(&st_lock);
        hlist_add_head(&p->is_hlist,
@@ -298,7 +296,7 @@ void add_uprobe_table(struct kprobe *p)
        write_unlock(&st_lock);
 }
 
-static void del_uprobe_table(struct kprobe *p)
+static void del_uprobe_table(struct uprobe *p)
 {
        write_lock(&st_lock);
        if (!hlist_unhashed(&p->is_hlist))
@@ -307,26 +305,26 @@ static void del_uprobe_table(struct kprobe *p)
 }
 
 /**
- * @brief Gets kprobe by insn slot.
+ * @brief Gets uprobe by insn slot.
  *
  * @param addr Probe's address.
  * @param tgit Probe's thread group ID.
  * @param regs Pointer to CPU registers data.
- * @return Pointer to the kprobe on success,\n
+ * @return Pointer to the uprobe on success,\n
  * NULL otherwise.
  */
-struct kprobe *get_ukprobe_by_insn_slot(void *addr,
-                                       pid_t tgid,
-                                       struct pt_regs *regs)
+struct uprobe *get_uprobe_by_insn_slot(void *addr,
+                                      pid_t tgid,
+                                      struct pt_regs *regs)
 {
        struct hlist_head *head;
-       struct kprobe *p;
+       struct uprobe *p;
        DECLARE_NODE_PTR_FOR_HLIST(node);
 
        read_lock(&st_lock);
        head = &slot_table[hash_ptr(addr, UPROBE_HASH_BITS)];
        swap_hlist_for_each_entry(p, node, head, is_hlist) {
-               if (p->ainsn.insn == addr && kp2up(p)->task->tgid == tgid) {
+               if (p->ainsn.insn == addr && p->task->tgid == tgid) {
                        read_unlock(&st_lock);
                        return p;
                }
@@ -339,7 +337,7 @@ struct kprobe *get_ukprobe_by_insn_slot(void *addr,
 
 static void remove_uprobe(struct uprobe *up)
 {
-       del_uprobe_table(&up->kp);
+       del_uprobe_table(up);
        arch_remove_uprobe(up);
 }
 
@@ -478,12 +476,11 @@ static struct uretprobe_instance *get_free_urp_inst(struct uretprobe *rp)
  * @return 0 on success,\n
  * negative error code on error.
  */
-int swap_register_uprobe(struct uprobe *up)
+int swap_register_uprobe(struct uprobe *p)
 {
        int ret = 0;
-       struct kprobe *p, *old_p;
+       struct uprobe *old_p;
 
-       p = &up->kp;
        if (!p->addr)
                return -EINVAL;
 
@@ -498,8 +495,6 @@ int swap_register_uprobe(struct uprobe *up)
 #endif
 
        p->ainsn.insn = NULL;
-       p->mod_refcounted = 0;
-       p->nmissed = 0;
        INIT_LIST_HEAD(&p->list);
 #ifdef KPROBES_PROFILE
        p->start_tm.tv_sec = p->start_tm.tv_usec = 0;
@@ -508,9 +503,9 @@ int swap_register_uprobe(struct uprobe *up)
 #endif
 
        /* get the first item */
-       old_p = get_ukprobe(p->addr, kp2up(p)->task->tgid);
+       old_p = get_uprobe(p->addr, p->task->tgid);
        if (old_p) {
-               struct task_struct *task = up->task;
+               struct task_struct *task = p->task;
 
                /* TODO: add support many uprobes on address */
                printk(KERN_INFO "uprobe on task[%u %u %s] vaddr=%p is there\n",
@@ -528,7 +523,7 @@ int swap_register_uprobe(struct uprobe *up)
 
        INIT_HLIST_NODE(&p->is_hlist);
 
-       ret = arch_prepare_uprobe(up);
+       ret = arch_prepare_uprobe(p);
        if (ret) {
                DBPRINTF("goto out\n", ret);
                goto out;
@@ -541,11 +536,11 @@ int swap_register_uprobe(struct uprobe *up)
        hlist_add_head_rcu(&p->hlist,
                           &uprobe_table[hash_ptr(p->addr, UPROBE_HASH_BITS)]);
 
-       ret = arm_uprobe(up);
+       ret = arm_uprobe(p);
        if (ret) {
                hlist_del_rcu(&p->hlist);
                synchronize_rcu();
-               remove_uprobe(up);
+               remove_uprobe(p);
        }
 
 out:
@@ -561,13 +556,12 @@ EXPORT_SYMBOL_GPL(swap_register_uprobe);
  * @param disarm Disarm flag. When true uprobe is disarmed.
  * @return Void.
  */
-void __swap_unregister_uprobe(struct uprobe *up, int disarm)
+void __swap_unregister_uprobe(struct uprobe *p, int disarm)
 {
-       struct kprobe *p, *old_p, *list_p;
+       struct uprobe *old_p, *list_p;
        int cleanup_p;
 
-       p = &up->kp;
-       old_p = get_ukprobe(p->addr, kp2up(p)->task->tgid);
+       old_p = get_uprobe(p->addr, p->task->tgid);
        if (unlikely(!old_p))
                return;
 
@@ -587,7 +581,7 @@ valid_p:
            (p->list.next == &old_p->list) && (p->list.prev == &old_p->list))) {
                /* Only probe on the hash list */
                if (disarm)
-                       disarm_uprobe(&up->kp, up->task);
+                       disarm_uprobe(p, p->task);
 
                hlist_del_rcu(&old_p->hlist);
                cleanup_p = 1;
@@ -605,7 +599,7 @@ valid_p:
                if (!in_atomic())
                        synchronize_sched();
 
-               remove_uprobe(up);
+               remove_uprobe(p);
        } else {
                if (p->break_handler)
                        old_p->break_handler = NULL;
@@ -649,8 +643,8 @@ int swap_register_ujprobe(struct ujprobe *jp)
        int ret = 0;
 
        /* Todo: Verify probepoint is a function entry point */
-       jp->up.kp.pre_handler = setjmp_upre_handler;
-       jp->up.kp.break_handler = longjmp_break_uhandler;
+       jp->up.pre_handler = setjmp_upre_handler;
+       jp->up.break_handler = longjmp_break_uhandler;
 
        ret = swap_register_uprobe(&jp->up);
 
@@ -687,14 +681,14 @@ EXPORT_SYMBOL_GPL(swap_unregister_ujprobe);
 /**
  * @brief Trampoline uprobe handler.
  *
- * @param p Pointer to the uprobe's kprobe.
+ * @param p Pointer to the uprobe.
  * @param regs Pointer to CPU register data.
  * @return 1
  */
-int trampoline_uprobe_handler(struct kprobe *p, struct pt_regs *regs)
+int trampoline_uprobe_handler(struct uprobe *p, struct pt_regs *regs)
 {
        struct uretprobe_instance *ri = NULL;
-       struct kprobe *kp;
+       struct uprobe *up;
        struct hlist_head *head;
        unsigned long flags, tramp_addr, orig_ret_addr = 0;
        struct hlist_node *tmp;
@@ -724,9 +718,9 @@ int trampoline_uprobe_handler(struct kprobe *p, struct pt_regs *regs)
                        continue;
                }
 
-               kp = NULL;
+               up = NULL;
                if (ri->rp) {
-                       kp = up2kp(&ri->rp->up);
+                       up = &ri->rp->up;
 
                        if (ri->rp->handler)
                                ri->rp->handler(ri, regs);
@@ -735,7 +729,7 @@ int trampoline_uprobe_handler(struct kprobe *p, struct pt_regs *regs)
                orig_ret_addr = (unsigned long)ri->ret_addr;
                recycle_urp_inst(ri);
 
-               if ((orig_ret_addr != tramp_addr && kp == p) || kp == NULL) {
+               if ((orig_ret_addr != tramp_addr && up == p) || up == NULL) {
                        /*
                         * This is the real return address. Any other
                         * instances associated with this task are for
@@ -754,10 +748,9 @@ int trampoline_uprobe_handler(struct kprobe *p, struct pt_regs *regs)
        return 1;
 }
 
-static int pre_handler_uretprobe(struct kprobe *p, struct pt_regs *regs)
+static int pre_handler_uretprobe(struct uprobe *p, struct pt_regs *regs)
 {
-       struct uprobe *up = container_of(p, struct uprobe, kp);
-       struct uretprobe *rp = container_of(up, struct uretprobe, up);
+       struct uretprobe *rp = container_of(p, struct uretprobe, up);
 #ifdef CONFIG_ARM
        int noret = thumb_mode(regs) ? rp->thumb_noret : rp->arm_noret;
 #endif
@@ -816,10 +809,10 @@ int swap_register_uretprobe(struct uretprobe *rp)
 
        DBPRINTF("START\n");
 
-       rp->up.kp.pre_handler = pre_handler_uretprobe;
-       rp->up.kp.post_handler = NULL;
-       rp->up.kp.fault_handler = NULL;
-       rp->up.kp.break_handler = NULL;
+       rp->up.pre_handler = pre_handler_uretprobe;
+       rp->up.post_handler = NULL;
+       rp->up.fault_handler = NULL;
+       rp->up.break_handler = NULL;
 
        /* Pre-allocate memory for max kretprobe instances */
        if (rp->maxactive <= 0) {
@@ -908,7 +901,7 @@ void swap_discard_pending_uretprobes(struct task_struct *task)
                if (ri->task == task) {
                        printk(KERN_INFO "%s (%d/%d): pending urp inst: %08lx\n",
                               task->comm, task->tgid, task->pid,
-                              (unsigned long)ri->rp->up.kp.addr);
+                              (unsigned long)ri->rp->up.addr);
                        arch_disarm_urp_inst(ri, task);
                        recycle_urp_inst(ri);
                }
@@ -938,7 +931,7 @@ void __swap_unregister_uretprobe(struct uretprobe *rp, int disarm)
                        printk(KERN_INFO "%s (%d/%d): "
                               "cannot disarm urp instance (%08lx)\n",
                               ri->task->comm, ri->task->tgid, ri->task->pid,
-                              (unsigned long)rp->up.kp.addr);
+                              (unsigned long)rp->up.addr);
                recycle_urp_inst(ri);
        }
 
@@ -974,7 +967,7 @@ EXPORT_SYMBOL_GPL(swap_unregister_uretprobe);
 void swap_unregister_all_uprobes(struct task_struct *task)
 {
        struct hlist_head *head;
-       struct kprobe *p;
+       struct uprobe *p;
        int i;
        struct hlist_node *tnode;
        DECLARE_NODE_PTR_FOR_HLIST(node);
@@ -982,14 +975,12 @@ void swap_unregister_all_uprobes(struct task_struct *task)
        for (i = 0; i < UPROBE_TABLE_SIZE; ++i) {
                head = &uprobe_table[i];
                swap_hlist_for_each_entry_safe(p, node, tnode, head, hlist) {
-                       if (kp2up(p)->task->tgid == task->tgid) {
-                               struct uprobe *up =
-                                       container_of(p, struct uprobe, kp);
+                       if (p->task->tgid == task->tgid) {
                                printk(KERN_INFO "%s: delete uprobe at %p[%lx]"
                                       " for %s/%d\n", __func__, p->addr,
                                       (unsigned long)p->opcode,
                                       task->comm, task->pid);
-                               swap_unregister_uprobe(up);
+                               swap_unregister_uprobe(p);
                        }
                }
        }
index 1e3a9fd..9578cf8 100644 (file)
 
 #include <swap-asm/swap_uprobes.h>
 
+/**
+ * @brief Uprobe pre-handler pointer.
+ */
+typedef int (*uprobe_pre_handler_t) (struct uprobe *, struct pt_regs *);
+
+/**
+ * @brief Uprobe break handler pointer.
+ */
+typedef int (*uprobe_break_handler_t) (struct uprobe *, struct pt_regs *);
+
+/**
+ * @brief Uprobe post handler pointer.
+ */
+typedef void (*uprobe_post_handler_t) (struct uprobe *,
+                                      struct pt_regs *,
+                                      unsigned long flags);
+
+/**
+ * @brief Uprobe fault handler pointer.
+ */
+typedef int (*uprobe_fault_handler_t) (struct uprobe *,
+                                      struct pt_regs *,
+                                      int trapnr);
 
 /**
  * @struct uprobe
- * @brief Stores uprobe data, based on kprobe.
+ * @brief Stores uprobe data.
  */
 struct uprobe {
-       struct kprobe kp;                   /**< Kprobe for this uprobe */
-       struct task_struct *task;           /**< Pointer to the task struct */
-       struct slot_manager *sm;            /**< Pointer to slot manager */
-       struct arch_specific_tramp atramp;  /**< Stores trampoline */
+       struct hlist_node hlist; /**< Hash list.*/
+       /** List of probes to search by instruction slot.*/
+       struct hlist_node is_hlist;
+       /** List of uprobes for multi-handler support.*/
+       struct list_head list;
+       /** Location of the probe point. */
+       kprobe_opcode_t *addr;
+       /** Called before addr is executed.*/
+       uprobe_pre_handler_t pre_handler;
+       /** Called after addr is executed, unless...*/
+       uprobe_post_handler_t post_handler;
+       /** ... called if executing addr causes a fault (eg. page fault).*/
+       uprobe_fault_handler_t fault_handler;
+       /** Return 1 if it handled fault, otherwise kernel will see it.*/
+       uprobe_break_handler_t break_handler;
+       /** Saved opcode (which has been replaced with breakpoint).*/
+       kprobe_opcode_t opcode;
+       /** Copy of the original instruction.*/
+       struct arch_specific_insn ainsn;
+       /** Override single-step target address, may be used to redirect
+        * control-flow to arbitrary address after probe point without
+        * invocation of original instruction; useful for functions
+        * replacement. If jprobe.entry should return address of function or
+        * NULL if original function should be called.
+        * Not supported for X86, not tested for MIPS. */
+       kprobe_opcode_t *ss_addr[NR_CPUS];
+#ifdef CONFIG_ARM
+       /** Safe/unsafe to use probe on ARM.*/
+       unsigned safe_arm:1;
+       /** Safe/unsafe to use probe on Thumb.*/
+       unsigned safe_thumb:1;
+#endif
+
+       struct task_struct *task;            /**< Pointer to the task struct */
+       struct slot_manager *sm;             /**< Pointer to slot manager */
+       struct arch_specific_tramp atramp;   /**< Stores trampoline */
 };
 
 /**
@@ -143,25 +198,15 @@ void swap_unregister_all_uprobes(struct task_struct *task);
 void swap_discard_pending_uretprobes(struct task_struct *task);
 
 void swap_ujprobe_return(void);
-struct kprobe *get_ukprobe(void *addr, pid_t tgid);
-struct kprobe *get_ukprobe_by_insn_slot(void *addr,
+struct uprobe *get_uprobe(void *addr, pid_t tgid);
+struct uprobe *get_uprobe_by_insn_slot(void *addr,
                                        pid_t tgid,
                                        struct pt_regs *regs);
 
-static inline struct uprobe *kp2up(struct kprobe *p)
-{
-       return container_of(p, struct uprobe, kp);
-}
-
-static inline struct kprobe *up2kp(struct uprobe *p)
-{
-       return &p->kp;
-}
-
-void disarm_uprobe(struct kprobe *p, struct task_struct *task);
+void disarm_uprobe(struct uprobe *p, struct task_struct *task);
 
-int trampoline_uprobe_handler(struct kprobe *p, struct pt_regs *regs);
+int trampoline_uprobe_handler(struct uprobe *p, struct pt_regs *regs);
 
-void add_uprobe_table(struct kprobe *p);
+void add_uprobe_table(struct uprobe *p);
 
 #endif /*  _SWAP_UPROBES_H */
index 5c764e8..22c49b0 100644 (file)
@@ -65,10 +65,9 @@ static int urp_ret_handler(struct uretprobe_instance *ri, struct pt_regs *regs)
        return 0;
 }
 
-static int uprobe_handler(struct kprobe *p, struct pt_regs *regs)
+static int uprobe_handler(struct uprobe *p, struct pt_regs *regs)
 {
-       struct uprobe *up = container_of(p, struct uprobe, kp);
-       struct us_ip *ip = container_of(up, struct us_ip, uprobe);
+       struct us_ip *ip = container_of(p, struct us_ip, uprobe);
        struct probe_info_new *info_new;
 
        info_new = probe_info_get_val(ip->info, struct probe_info_new *);
@@ -178,7 +177,7 @@ static void up_unregister_probe(struct us_ip *ip, int disarm)
 
 static void up_init(struct us_ip *ip)
 {
-       ip->uprobe.kp.pre_handler = uprobe_handler;
+       ip->uprobe.pre_handler = uprobe_handler;
 }
 
 static void up_uninit(struct us_ip *ip)
index 62ddaec..b176522 100644 (file)
@@ -36,7 +36,7 @@ struct probe_info_new {
        enum probe_t type;
        union {
                struct {
-                       kprobe_pre_handler_t handler;
+                       uprobe_pre_handler_t handler;
                } p;
 
                struct {
index 3199ae7..cd54010 100644 (file)
@@ -58,7 +58,7 @@ static inline int sspt_register_usprobe(struct us_ip *ip)
                return -EINVAL;
        }
 
-       up->kp.addr = (kprobe_opcode_t *)ip->orig_addr;
+       up->addr = (kprobe_opcode_t *)ip->orig_addr;
        up->task = ip->page->file->proc->task;
        up->sm = ip->page->file->proc->sm;
 
@@ -66,12 +66,12 @@ static inline int sspt_register_usprobe(struct us_ip *ip)
        if (ret) {
                struct sspt_file *file = ip->page->file;
                char *name = file->dentry->d_iname;
-               unsigned long addr = (unsigned long)up->kp.addr;
+               unsigned long addr = (unsigned long)up->addr;
                unsigned long offset = addr - file->vm_start;
 
                printk(KERN_INFO "swap_register_uretprobe() failure %d "
                       "(%s:%lx|%lx)\n", ret, name, offset,
-                      (unsigned long)ip->retprobe.up.kp.opcode);
+                      (unsigned long)ip->retprobe.up.opcode);
        }
 
        return ret;
@@ -89,7 +89,7 @@ static inline int sspt_unregister_usprobe(struct task_struct *task,
                break;
        case US_DISARM:
                up = probe_info_get_uprobe(ip->info, ip);
-               disarm_uprobe(&up->kp, task);
+               disarm_uprobe(up, task);
                break;
        case US_UNINSTALL:
                probe_info_unregister(ip->info, ip, 0);
index 0b3dc79..7d7e212 100644 (file)
@@ -47,7 +47,7 @@ static inline void print_ip(struct us_ip *ip, int i)
 
                printk(KERN_INFO "###       addr[%2d]=%lx, R_addr=%lx\n",
                       i, (unsigned long)ip->offset,
-                      (unsigned long)rp->up.kp.addr);
+                      (unsigned long)rp->up.addr);
                print_retprobe(rp);
        }
 }
index ccfa7d5..8f40a17 100644 (file)
--- a/wsp/wsp.c
+++ b/wsp/wsp.c
@@ -83,7 +83,7 @@ static void do_res_finish(struct wsp_res *res)
 /*
  * soup_req
  */
-static int soup_req_handle(struct kprobe *p, struct pt_regs *regs)
+static int soup_req_handle(struct uprobe *p, struct pt_regs *regs)
 {
        enum { max_str_len = 512 };
        const char __user *user_s;
@@ -116,7 +116,7 @@ static struct probe_info_new soup_req = MAKE_UPROBE(soup_req_handle);
 /*
  * main_res_req
  */
-static int mres_req_handle(struct kprobe *p, struct pt_regs *regs)
+static int mres_req_handle(struct uprobe *p, struct pt_regs *regs)
 {
        void *ptr = (void *)swap_get_uarg(regs, 0);
        struct wsp_res *res;
@@ -162,7 +162,7 @@ static struct probe_info_new mres_adata =
 /*
  * main_res_finish
  */
-static int mres_finish_handle(struct kprobe *p, struct pt_regs *regs)
+static int mres_finish_handle(struct uprobe *p, struct pt_regs *regs)
 {
        void *ptr = (void *)swap_get_uarg(regs, 0);
        struct wsp_res *res;
@@ -182,7 +182,7 @@ static struct probe_info_new mres_finish = MAKE_UPROBE(mres_finish_handle);
 /*
  * res_request
  */
-static int res_request_handle(struct kprobe *p, struct pt_regs *regs)
+static int res_request_handle(struct uprobe *p, struct pt_regs *regs)
 {
        void *ptr = (void *)swap_get_uarg(regs, 0);
        struct wsp_res *res;