Merge branch 'dev' into kernel
[kernel/swap-modules.git] / driver / us_proc_inst.c
index 52adc71..75b5e0d 100644 (file)
 #include "us_proc_inst.h"
 
 #include "../kprobe/dbi_kprobes_deps.h"
-#include "../kprobe/dbi_uprobes.h"
+#include "../uprobe/swap_uprobes.h"
 
 #include "sspt/sspt.h"
-#include "java_inst.h"
+
+#include <dbi_insn_slots.h>
 
 #define mm_read_lock(task, mm, atomic, lock)                   \
        mm = atomic ? task->active_mm : get_task_mm(task);      \
                mmput(mm);                                      \
        }
 
-#if defined(CONFIG_MIPS)
-#      define ARCH_REG_VAL(regs, idx)  regs->regs[idx]
-#elif defined(CONFIG_ARM)
-#      define ARCH_REG_VAL(regs, idx)  regs->uregs[idx]
-#else
-#      define ARCH_REG_VAL(regs, idx)  0
-#      warning ARCH_REG_VAL is not implemented for this architecture. FBI will work improperly or even crash!!!
-#endif // ARCH
-
 unsigned long ujprobe_event_pre_handler (struct us_ip *ip, struct pt_regs *regs);
 void ujprobe_event_handler (unsigned long arg1, unsigned long arg2, unsigned long arg3, unsigned long arg4, unsigned long arg5, unsigned long arg6);
-int uretprobe_event_handler (struct kretprobe_instance *probe, struct pt_regs *regs, struct us_ip *ip);
+int uretprobe_event_handler(struct uretprobe_instance *probe, struct pt_regs *regs, struct us_ip *ip);
 
 
-int us_proc_probes;
-
 LIST_HEAD(proc_probes_list);
 
-
-#ifdef ANDROID_APP
-unsigned long android_app_vma_start = 0;
-unsigned long android_app_vma_end = 0;
-struct dentry *app_process_dentry = NULL;
-#endif /* ANDROID_APP */
-
-#ifdef SLP_APP
-static struct dentry *launchpad_daemon_dentry = NULL;
-EXPORT_SYMBOL_GPL(launchpad_daemon_dentry);
-#endif /* SLP_APP */
-
 #define print_event(fmt, args...)                                              \
 {                                                                              \
        char *buf[1024];                                                        \
@@ -95,6 +73,127 @@ static inline int is_us_instrumentation(void)
        return !!us_proc_info.path;
 }
 
+static unsigned long alloc_user_pages(struct task_struct *task, unsigned long len, unsigned long prot, unsigned long flags)
+{
+       unsigned long ret = 0;
+       struct task_struct *otask = current;
+       struct mm_struct *mm;
+       int atomic = in_atomic();
+
+       mm = atomic ? task->active_mm : get_task_mm (task);
+       if (mm) {
+               if (!atomic) {
+                       if (!down_write_trylock(&mm->mmap_sem)) {
+                               rcu_read_lock();
+
+                               up_read(&mm->mmap_sem);
+                               down_write(&mm->mmap_sem);
+
+                               rcu_read_unlock();
+                       }
+               }
+               // FIXME: its seems to be bad decision to replace 'current' pointer temporarily
+               current_thread_info()->task = task;
+               ret = do_mmap_pgoff(NULL, 0, len, prot, flags, 0);
+               current_thread_info()->task = otask;
+               if (!atomic) {
+                       downgrade_write (&mm->mmap_sem);
+                       mmput(mm);
+               }
+       } else {
+               printk("proc %d has no mm", task->tgid);
+       }
+
+       return ret;
+}
+
+static void *sm_alloc_us(struct slot_manager *sm)
+{
+       struct task_struct *task = sm->data;
+
+       return (void *)alloc_user_pages(task, PAGE_SIZE,
+                                       PROT_EXEC|PROT_READ|PROT_WRITE,
+                                       MAP_ANONYMOUS|MAP_PRIVATE);
+}
+
+static void sm_free_us(struct slot_manager *sm, void *ptr)
+{
+       struct task_struct *task = sm->data;
+
+       /*
+        * E. G.: This code provides kernel dump because of rescheduling while atomic.
+        * As workaround, this code was commented. In this case we will have memory leaks
+        * for instrumented process, but instrumentation process should functionate correctly.
+        * Planned that good solution for this problem will be done during redesigning KProbe
+        * for improving supportability and performance.
+        */
+#if 0
+       mm = get_task_mm(task);
+       if (mm) {
+               down_write(&mm->mmap_sem);
+               do_munmap(mm, (unsigned long)(ptr), PAGE_SIZE);
+               up_write(&mm->mmap_sem);
+               mmput(mm);
+       }
+#endif
+       /* FIXME: implement the removal of memory for task */
+}
+
+struct slot_manager *create_sm_us(struct task_struct *task)
+{
+       struct slot_manager *sm = kmalloc(sizeof(*sm), GFP_ATOMIC);
+       sm->slot_size = UPROBES_TRAMP_LEN;
+       sm->alloc = sm_alloc_us;
+       sm->free = sm_free_us;
+       INIT_HLIST_NODE(&sm->page_list);
+       sm->data = task;
+}
+
+void free_sm_us(struct slot_manager *sm)
+{
+       /* FIXME: free */
+}
+
+struct pf_data {
+       unsigned long addr;
+};
+
+static int entry_handler_pf(struct kretprobe_instance *ri, struct pt_regs *regs);
+static int ret_handler_pf(struct kretprobe_instance *ri, struct pt_regs *regs);
+
+static struct kretprobe pf_kretprobe = {
+       .entry_handler = entry_handler_pf,
+       .handler = ret_handler_pf,
+       .data_size = sizeof(struct pf_data)
+};
+
+static void copy_process_ret_pre_code(struct task_struct *p);
+
+static int ret_handler_cp(struct kretprobe_instance *ri, struct pt_regs *regs)
+{
+       struct task_struct* task = (struct task_struct *)regs_return_value(regs);
+
+       copy_process_ret_pre_code(task);
+
+       return 0;
+}
+
+static struct kretprobe cp_kretprobe = {
+       .handler = ret_handler_cp,
+};
+
+static void jmm_release(struct task_struct *tsk, struct mm_struct *mm);
+
+static struct jprobe mr_jprobe = {
+       .entry = jmm_release
+};
+
+static int jdo_munmap(struct mm_struct *mm, unsigned long start, size_t len);
+
+static struct jprobe unmap_jprobe = {
+       .entry = jdo_munmap
+};
+
 static struct sspt_procs *get_proc_probes_by_task(struct task_struct *task)
 {
        struct sspt_procs *procs, *tmp;
@@ -127,59 +226,13 @@ static struct sspt_procs *get_proc_probes_by_task_or_new(struct task_struct *tas
        struct sspt_procs *procs = get_proc_probes_by_task(task);
        if (procs == NULL) {
                procs = sspt_procs_copy(us_proc_info.pp, task);
+               procs->sm = create_sm_us(task);
                add_proc_probes(task, procs);
        }
 
        return procs;
 }
 
-#ifdef SLP_APP
-static int is_slp_app_with_dentry(struct vm_area_struct *vma,
-                                                                 struct dentry *dentry)
-{
-       struct vm_area_struct *slp_app_vma = NULL;
-
-       if (vma->vm_file->f_dentry == launchpad_daemon_dentry) {
-               slp_app_vma = vma;
-               while (slp_app_vma) {
-                       if (slp_app_vma->vm_file) {
-                               if (slp_app_vma->vm_file->f_dentry == dentry &&
-                                       slp_app_vma->vm_pgoff == 0) {
-                                       return 1;
-                               }
-                       }
-                       slp_app_vma = slp_app_vma->vm_next;
-               }
-       }
-
-       return 0;
-}
-#endif /* SLP_APP */
-
-#ifdef ANDROID_APP
-static int is_android_app_with_dentry(struct vm_area_struct *vma,
-                                                                         struct dentry *dentry)
-{
-       struct vm_area_struct *android_app_vma = NULL;
-
-       if (vma->vm_file->f_dentry == app_process_dentry) {
-               android_app_vma = vma;
-               while (android_app_vma) {
-                       if (android_app_vma->vm_file) {
-                               if (android_app_vma->vm_file->f_dentry == dentry) {
-                                       android_app_vma_start = android_app_vma->vm_start;
-                                       android_app_vma_end = android_app_vma->vm_end;
-                                       return 1;
-                               }
-                       }
-                       android_app_vma = android_app_vma->vm_next;
-               }
-       }
-
-       return 0;
-}
-#endif /* ANDROID_APP */
-
 struct dentry *dentry_by_path(const char *path)
 {
        struct dentry *dentry;
@@ -209,13 +262,9 @@ struct dentry *dentry_by_path(const char *path)
 
 static int check_vma(struct vm_area_struct *vma)
 {
-#ifndef __ANDROID
        return vma->vm_file && !(vma->vm_pgoff != 0 || !(vma->vm_flags & VM_EXEC) || (vma->vm_flags & VM_ACCOUNT) ||
                        !(vma->vm_flags & (VM_WRITE | VM_MAYWRITE)) ||
                        !(vma->vm_flags & (VM_READ | VM_MAYREAD)));
-#else // __ANDROID
-       return vma->vm_file && !(vma->vm_pgoff != 0 || !(vma->vm_flags & VM_EXEC));
-#endif // __ANDROID
 }
 
 static int find_task_by_path (const char *path, struct task_struct **p_task, struct list_head *tids)
@@ -254,22 +303,6 @@ static int find_task_by_path (const char *path, struct task_struct **p_task, str
                                        }
                                                //break;
                                }
-#ifdef SLP_APP
-                               if (!*p_task) {
-                                       if (is_slp_app_with_dentry(vma, dentry)) {
-                                               *p_task = task;
-                                               get_task_struct(task);
-                                       }
-                               }
-#endif /* SLP_APP */
-#ifdef ANDROID_APP
-                               if (!*p_task) {
-                                       if (is_android_app_with_dentry(vma, dentry)) {
-                                               *p_task = task;
-                                               get_task_struct(task);
-                                       }
-                               }
-#endif /* ANDROID_APP */
                        }
                        vma = vma->vm_next;
                }
@@ -299,7 +332,7 @@ static void set_mapping_file(struct sspt_file *file,
 int install_otg_ip(unsigned long addr,
                        kprobe_pre_entry_handler_t pre_handler,
                        unsigned long jp_handler,
-                       kretprobe_handler_t rp_handler)
+                       uretprobe_handler_t rp_handler)
 {
        int ret = 0;
        struct task_struct *task = current->group_leader;
@@ -358,35 +391,104 @@ int install_otg_ip(unsigned long addr,
 }
 EXPORT_SYMBOL_GPL(install_otg_ip);
 
-static int uninstall_kernel_probe (unsigned long addr, int uflag, int kflag, kernel_probe_t ** pprobe)
+int init_helper(void)
 {
-       kernel_probe_t *probe = NULL;
-       int iRet = 0;
-       if (probes_flags & kflag) {
-               probe = find_probe(addr);
-               if (probe) {
-                       iRet = remove_probe_from_list (addr);
-                       if (iRet)
-                               EPRINTF ("remove_probe_from_list(0x%lx) result=%d!", addr, iRet);
-                       if (pprobe)
-                               *pprobe = NULL;
-               }
-               probes_flags &= ~kflag;
-       }
-       if (us_proc_probes & uflag) {
-               if (!(probes_flags & uflag)) {
-                       if (probe) {
-                               iRet = unregister_kernel_probe(probe);
-                               if (iRet) {
-                                       EPRINTF ("unregister_kernel_probe(0x%lx) result=%d!",
-                                                       addr, iRet);
-                                       return iRet;
-                               }
-                       }
-               }
-               us_proc_probes &= ~uflag;
+       unsigned long addr;
+       addr = swap_ksyms("do_page_fault");
+       if (addr == 0) {
+               EPRINTF("Cannot find address for page fault function!");
+               return -EINVAL;
        }
-       return iRet;
+       pf_kretprobe.kp.addr = (kprobe_opcode_t *)addr;
+
+       addr = swap_ksyms("copy_process");
+       if (addr == 0) {
+               EPRINTF("Cannot find address for copy_process function!");
+               return -EINVAL;
+       }
+       cp_kretprobe.kp.addr = (kprobe_opcode_t *)addr;
+
+       addr = swap_ksyms("mm_release");
+       if (addr == 0) {
+               EPRINTF("Cannot find address for mm_release function!");
+               return -EINVAL;
+       }
+       mr_jprobe.kp.addr = (kprobe_opcode_t *)addr;
+
+       addr = swap_ksyms("do_munmap");
+       if (addr == 0) {
+               EPRINTF("Cannot find address for do_munmap function!");
+               return -EINVAL;
+       }
+       unmap_jprobe.kp.addr = (kprobe_opcode_t *)addr;
+
+       return 0;
+}
+
+void uninit_helper(void)
+{
+}
+
+static int register_helper_ks_probes(void)
+{
+       int ret = 0;
+
+       /* install jprobe on 'do_munmap' to detect when for remove user space probes */
+       ret = dbi_register_jprobe(&unmap_jprobe);
+       if (ret) {
+               EPRINTF("dbi_register_jprobe(do_munmap) result=%d!", ret);
+               return ret;
+       }
+
+       /* install jprobe on 'mm_release' to detect when for remove user space probes */
+       ret = dbi_register_jprobe(&mr_jprobe);
+       if (ret != 0) {
+               EPRINTF("dbi_register_jprobe(mm_release) result=%d!", ret);
+               goto unregister_unmap;
+       }
+
+
+       /* install kretprobe on 'copy_process' */
+       ret = dbi_register_kretprobe(&cp_kretprobe);
+       if (ret) {
+               EPRINTF("dbi_register_kretprobe(copy_process) result=%d!", ret);
+               goto unregister_mr;
+       }
+
+       /* install kretprobe on 'do_page_fault' to detect when they will be loaded */
+       ret = dbi_register_kretprobe(&pf_kretprobe);
+       if (ret) {
+               EPRINTF("dbi_register_kretprobe(do_page_fault) result=%d!", ret);
+               goto unregister_cp;
+       }
+
+       return ret;
+
+unregister_cp:
+       dbi_unregister_kretprobe(&cp_kretprobe);
+
+unregister_mr:
+       dbi_unregister_jprobe(&mr_jprobe);
+
+unregister_unmap:
+       dbi_unregister_jprobe(&unmap_jprobe);
+
+       return ret;
+}
+
+static void unregister_helper_ks_probes(void)
+{
+       /* uninstall kretprobe with 'do_page_fault' */
+       dbi_unregister_kretprobe(&pf_kretprobe);
+
+       /* uninstall kretprobe with 'copy_process' */
+       dbi_unregister_kretprobe(&cp_kretprobe);
+
+       /* uninstall jprobe with 'mm_release' */
+       dbi_unregister_jprobe(&mr_jprobe);
+
+       /* uninstall jprobe with 'do_munmap' */
+       dbi_unregister_jprobe(&unmap_jprobe);
 }
 
 static int uninstall_us_proc_probes(struct task_struct *task, struct sspt_procs *procs, enum US_FLAGS flag);
@@ -400,28 +502,6 @@ int deinst_usr_space_proc (void)
                return 0;
        }
 
-       iRet = uninstall_kernel_probe (pf_addr, US_PROC_PF_INSTLD,
-                       0, &pf_probe);
-       if (iRet)
-               EPRINTF ("uninstall_kernel_probe(do_page_fault) result=%d!", iRet);
-
-       iRet = uninstall_kernel_probe (cp_addr, US_PROC_CP_INSTLD,
-                       0, &cp_probe);
-       if (iRet)
-               EPRINTF ("uninstall_kernel_probe(copy_process) result=%d!", iRet);
-
-        iRet = uninstall_kernel_probe (mr_addr, US_PROC_MR_INSTLD,
-                        0, &mr_probe);
-        if (iRet)
-                EPRINTF ("uninstall_kernel_probe(mm_release) result=%d!", iRet);
-
-       iRet = uninstall_kernel_probe (exit_addr, US_PROC_EXIT_INSTLD,
-                       0, &exit_probe);
-       if (iRet)
-               EPRINTF ("uninstall_kernel_probe(do_exit) result=%d!", iRet);
-
-       iRet = uninstall_kernel_probe (unmap_addr, US_PROC_UNMAP_INSTLD,
-                       0, &unmap_probe);
        if (iRet)
                EPRINTF ("uninstall_kernel_probe(do_munmap) result=%d!", iRet);
 
@@ -474,40 +554,9 @@ int deinst_usr_space_proc (void)
                }
        }
 
-       return iRet;
-}
-static int install_kernel_probe (unsigned long addr, int uflag, int kflag, kernel_probe_t ** pprobe)
-{
-       kernel_probe_t *probe = NULL;
-       int iRet = 0;
-
-       DPRINTF("us_proc_probes = 0x%x, uflag = 0x%x, "
-                       "probes_flags = 0x%x, kflag = 0x%x",
-                       us_proc_probes, uflag, probes_flags, kflag);
-
-       if (!(probes_flags & kflag)) {
-               iRet = add_probe_to_list (addr, &probe);
-               if (iRet) {
-                       EPRINTF ("add_probe_to_list(0x%lx) result=%d!", addr, iRet);
-                       return iRet;
-               }
-               probes_flags |= kflag;
-       }
-       if (!(us_proc_probes & uflag)) {
-               if (!(probes_flags & uflag)) {
-                       iRet = register_kernel_probe (probe);
-                       if (iRet) {
-                               EPRINTF ("register_kernel_probe(0x%lx) result=%d!", addr, iRet);
-                               return iRet;
-                       }
-               }
-               us_proc_probes |= uflag;
-       }
-
-       if (probe)
-               *pprobe = probe;
+       unregister_helper_ks_probes();
 
-       return 0;
+       return iRet;
 }
 
 static void install_proc_probes(struct task_struct *task, struct sspt_procs *procs, int atomic);
@@ -523,24 +572,11 @@ int inst_usr_space_proc (void)
 
        DPRINTF("User space instr");
 
-#ifdef SLP_APP
-       launchpad_daemon_dentry = dentry_by_path("/usr/bin/launchpad_preloading_preinitializing_daemon");
-       if (launchpad_daemon_dentry == NULL) {
-               return -EINVAL;
-       }
-
-#endif /* SLP_APP */
-
-#ifdef ANDROID_APP
-       app_process_dentry = dentry_by_path("/system/bin/app_process");
-       if (app_process_dentry == NULL) {
-               return -EINVAL;
+       ret = register_helper_ks_probes();
+       if (ret) {
+               return ret;
        }
 
-       android_app_vma_start = 0;
-       android_app_vma_end = 0;
-#endif /* ANDROID_APP */
-
        for (i = 0; i < us_proc_info.libs_count; i++) {
                us_proc_info.p_libs[i].loaded = 0;
        }
@@ -577,69 +613,15 @@ int inst_usr_space_proc (void)
                {
                        DPRINTF("task found. installing probes");
                        us_proc_info.tgid = task->pid;
+                       us_proc_info.pp->sm = create_sm_us(task);
                        install_proc_probes(task, us_proc_info.pp, 0);
                        put_task_struct (task);
                }
        }
 
-       // enable 'do_page_fault' probe to detect when they will be loaded
-       ret = install_kernel_probe (pf_addr, US_PROC_PF_INSTLD, 0, &pf_probe);
-       if (ret != 0)
-       {
-               EPRINTF ("install_kernel_probe(do_page_fault) result=%d!", ret);
-               return ret;
-       }
-       // enable 'do_exit' probe to detect for remove task_struct
-       ret = install_kernel_probe (exit_addr, US_PROC_EXIT_INSTLD, 0, &exit_probe);
-       if (ret != 0)
-       {
-               EPRINTF ("install_kernel_probe(do_exit) result=%d!", ret);
-               return ret;
-       }
-       /* enable 'copy_process' */
-       ret = install_kernel_probe (cp_addr, US_PROC_CP_INSTLD, 0, &cp_probe);
-       if (ret != 0)
-       {
-               EPRINTF ("instpall_kernel_probe(copy_process) result=%d!", ret);
-               return ret;
-       }
-
-       // enable 'mm_release' probe to detect when for remove user space probes
-       ret = install_kernel_probe (mr_addr, US_PROC_MR_INSTLD, 0, &mr_probe);
-       if (ret != 0)
-       {
-               EPRINTF ("install_kernel_probe(mm_release) result=%d!", ret);
-               return ret;
-       }
-
-       // enable 'do_munmap' probe to detect when for remove user space probes
-       ret = install_kernel_probe (unmap_addr, US_PROC_UNMAP_INSTLD, 0, &unmap_probe);
-       if (ret != 0)
-       {
-               EPRINTF ("install_kernel_probe(do_munmap) result=%d!", ret);
-               return ret;
-       }
        return 0;
 }
 
-#include "../../tools/gpmu/probes/entry_data.h"
-
-void do_page_fault_j_pre_code(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
-{
-       struct task_struct *task = current->group_leader;
-
-       if (task->flags & PF_KTHREAD) {
-               DPRINTF("ignored kernel thread %d\n", task->pid);
-               return;
-       }
-
-       if (is_us_instrumentation()) {
-               swap_put_entry_data((void *)addr, &sa_dpf);
-       }
-}
-EXPORT_SYMBOL_GPL(do_page_fault_j_pre_code);
-
-
 unsigned long imi_sum_time = 0;
 unsigned long imi_sum_hit = 0;
 
@@ -869,23 +851,23 @@ static pid_t find_proc_by_task(const struct task_struct *task, struct dentry *de
                        if (vma->vm_file->f_dentry == dentry) {
                                return task->tgid;
                        }
-#ifdef SLP_APP
-                       if (is_slp_app_with_dentry(vma, dentry)) {
-                               return task->tgid;
-                       }
-#endif /* SLP_APP */
-#ifdef ANDROID_APP
-                       if (is_android_app_with_dentry(vma, dentry)) {
-                               return task->tgid;
-                       }
-#endif /* ANDROID_APP */
                }
        }
 
        return 0;
 }
 
-void do_page_fault_ret_pre_code (void)
+static int entry_handler_pf(struct kretprobe_instance *ri, struct pt_regs *regs)
+{
+       struct pf_data *data = (struct pf_data *)ri->data;
+
+       /* for ARM arch*/
+       data->addr = regs->ARM_r0;
+       return 0;
+}
+
+/* Detects when IPs are really loaded into phy mem and installs probes. */
+static int ret_handler_pf(struct kretprobe_instance *ri, struct pt_regs *regs)
 {
        struct task_struct *task = current->group_leader;
        struct mm_struct *mm = task->mm;
@@ -894,6 +876,7 @@ void do_page_fault_ret_pre_code (void)
         * Because process threads have same address space
         * we instrument only group_leader of all this threads
         */
+       struct pf_data *data;
        unsigned long addr = 0;
        int valid_addr;
 
@@ -903,27 +886,19 @@ void do_page_fault_ret_pre_code (void)
 #define USEC_IN_SEC_NUM                                1000000
 
        if (task->flags & PF_KTHREAD) {
-               DPRINTF("ignored kernel thread %d\n", task->pid);
-               return;
+               goto out;
        }
 
        if (!is_us_instrumentation()) {
-               return;
+               goto out;
        }
 
-       addr = (unsigned long)swap_get_entry_data(&sa_dpf);
-
-       if (addr == 0) {
-               printk("WARNING: do_page_fault_ret_pre_code addr = 0\n");
-               return;
-       }
-
-
-
+       data = (struct pf_data *)ri->data;
+       addr = data->addr;
 
        valid_addr = mm && page_present(mm, addr);
        if (!valid_addr) {
-               return;
+               goto out;
        }
 
        if (is_libonly()) {
@@ -935,6 +910,7 @@ void do_page_fault_ret_pre_code (void)
                        if (tgid) {
                                us_proc_info.tgid = gl_nNotifyTgid = tgid;
 
+                               us_proc_info.pp->sm = create_sm_us(task);
                                /* install probes in already mapped memory */
                                install_proc_probes(task, us_proc_info.pp, 1);
                        }
@@ -956,16 +932,10 @@ void do_page_fault_ret_pre_code (void)
                imi_sum_time += ((imi_tv2.tv_sec - imi_tv1.tv_sec) *  USEC_IN_SEC_NUM +
                                (imi_tv2.tv_usec - imi_tv1.tv_usec));
        }
-}
-
-EXPORT_SYMBOL_GPL(do_page_fault_ret_pre_code);
-
 
-void do_exit_probe_pre_code (void)
-{
-       // TODO: remove task
+out:
+       return 0;
 }
-EXPORT_SYMBOL_GPL(do_exit_probe_pre_code);
 
 void print_vma(struct mm_struct *mm)
 {
@@ -1007,7 +977,7 @@ static int remove_unmap_probes(struct task_struct *task, struct sspt_procs *proc
                file = sspt_procs_find_file(procs, dentry);
                if (file) {
                        if (vma->vm_start == start || vma->vm_end == end) {
-                               unregister_us_file_probes(task, file, US_NOT_RP2);
+                               unregister_us_file_probes(task, file, US_UNREGS_PROBE);
                                file->loaded = 0;
                        } else {
                                unsigned long page_addr;
@@ -1016,7 +986,7 @@ static int remove_unmap_probes(struct task_struct *task, struct sspt_procs *proc
                                for (page_addr = vma->vm_start; page_addr < vma->vm_end; page_addr += PAGE_SIZE) {
                                        page = sspt_find_page_mapped(file, page_addr);
                                        if (page) {
-                                               unregister_us_page_probe(task, page, US_NOT_RP2);
+                                               unregister_us_page_probe(task, page, US_UNREGS_PROBE);
                                        }
                                }
 
@@ -1030,14 +1000,15 @@ static int remove_unmap_probes(struct task_struct *task, struct sspt_procs *proc
        return 0;
 }
 
-void do_munmap_probe_pre_code(struct mm_struct *mm, unsigned long start, size_t len)
+/* Detects when target removes IPs. */
+static int jdo_munmap(struct mm_struct *mm, unsigned long start, size_t len)
 {
        struct sspt_procs *procs = NULL;
        struct task_struct *task = current;
 
        //if user-space instrumentation is not set
        if (!is_us_instrumentation()) {
-               return;
+               goto out;
        }
 
        if (is_libonly()) {
@@ -1053,16 +1024,19 @@ void do_munmap_probe_pre_code(struct mm_struct *mm, unsigned long start, size_t
                        printk("ERROR do_munmap: start=%lx, len=%x\n", start, len);
                }
        }
+
+out:
+       dbi_jprobe_return();
+       return 0;
 }
-EXPORT_SYMBOL_GPL(do_munmap_probe_pre_code);
 
-void mm_release_probe_pre_code(void)
+/* Detects when target process removes IPs. */
+static void jmm_release(struct task_struct *task, struct mm_struct *mm)
 {
-       struct task_struct *task = current;
        struct sspt_procs *procs = NULL;
 
        if (!is_us_instrumentation() || task->tgid != task->pid) {
-               return;
+               goto out;
        }
 
        if (is_libonly()) {
@@ -1075,16 +1049,17 @@ void mm_release_probe_pre_code(void)
        }
 
        if (procs) {
-               int ret = uninstall_us_proc_probes(task, procs, US_NOT_RP2);
+               int ret = uninstall_us_proc_probes(task, procs, US_UNREGS_PROBE);
                if (ret != 0) {
                        EPRINTF ("failed to uninstall IPs (%d)!", ret);
                }
 
                dbi_unregister_all_uprobes(task, 1);
        }
-}
-EXPORT_SYMBOL_GPL(mm_release_probe_pre_code);
 
+out:
+       dbi_jprobe_return();
+}
 
 static void recover_child(struct task_struct *child_task, struct sspt_procs *procs)
 {
@@ -1106,7 +1081,8 @@ static void rm_uprobes_child(struct task_struct *new_task)
        }
 }
 
-void copy_process_ret_pre_code(struct task_struct *p)
+/* Delete uprobs in children at fork */
+static void copy_process_ret_pre_code(struct task_struct *p)
 {
        if(!p || IS_ERR(p))
                return;
@@ -1130,15 +1106,7 @@ unsigned long ujprobe_event_pre_handler(struct us_ip *ip, struct pt_regs *regs)
 void ujprobe_event_handler (unsigned long arg1, unsigned long arg2, unsigned long arg3, unsigned long arg4, unsigned long arg5, unsigned long arg6)
 {
        struct us_ip *ip = __get_cpu_var(gpCurIp);
-       unsigned long addr = (unsigned long)ip->jprobe.kp.addr;
-
-#ifdef __ANDROID
-       struct pt_regs *regs = __get_cpu_var(gpUserRegs);
-       if (is_java_inst_enabled() && handle_java_event(regs)) {
-               return;
-       }
-#endif /* __ANDROID */
-
+       unsigned long addr = (unsigned long)ip->jprobe.up.kp.addr;
 
 #if defined(CONFIG_ARM)
        if (ip->offset & 0x01)
@@ -1157,7 +1125,7 @@ void ujprobe_event_handler (unsigned long arg1, unsigned long arg2, unsigned lon
 
 static void send_plt(struct us_ip *ip)
 {
-       unsigned long addr = (unsigned long)ip->jprobe.kp.addr;
+       unsigned long addr = (unsigned long)ip->jprobe.up.kp.addr;
        struct vm_area_struct *vma = find_vma(current->mm, addr);
 
        if (vma && check_vma(vma)) {
@@ -1188,10 +1156,10 @@ static void send_plt(struct us_ip *ip)
        }
 }
 
-int uretprobe_event_handler(struct kretprobe_instance *probe, struct pt_regs *regs, struct us_ip *ip)
+int uretprobe_event_handler(struct uretprobe_instance *probe, struct pt_regs *regs, struct us_ip *ip)
 {
        int retval = regs_return_value(regs);
-       unsigned long addr = (unsigned long)ip->jprobe.kp.addr;
+       unsigned long addr = (unsigned long)ip->jprobe.up.kp.addr;
 
        if (ip->got_addr && ip->flag_got == 0) {
                send_plt(ip);
@@ -1216,25 +1184,26 @@ int uretprobe_event_handler(struct kretprobe_instance *probe, struct pt_regs *re
 int register_usprobe(struct task_struct *task, struct us_ip *ip, int atomic)
 {
        int ret = 0;
-       ip->jprobe.kp.tgid = task->tgid;
 
        if (ip->jprobe.entry == NULL) {
-               ip->jprobe.entry = (kprobe_opcode_t *)ujprobe_event_handler;
+               ip->jprobe.entry = (void *)ujprobe_event_handler;
                DPRINTF("Set default event handler for %x\n", ip->offset);
        }
 
        if (ip->jprobe.pre_entry == NULL) {
-               ip->jprobe.pre_entry = (kprobe_pre_entry_handler_t)ujprobe_event_pre_handler;
+               ip->jprobe.pre_entry = (uprobe_pre_entry_handler_t)ujprobe_event_pre_handler;
                DPRINTF("Set default pre handler for %x\n", ip->offset);
        }
 
        ip->jprobe.priv_arg = ip;
-       ret = dbi_register_ujprobe(task, &ip->jprobe, atomic);
+       ip->jprobe.up.task = task;
+       ip->jprobe.up.sm = ip->page->file->procs->sm;
+       ret = dbi_register_ujprobe(&ip->jprobe, atomic);
        if (ret) {
                if (ret == -ENOEXEC) {
                        pack_event_info(ERR_MSG_ID, RECORD_ENTRY, "dp",
                                        0x1,
-                                       ip->jprobe.kp.addr);
+                                       ip->jprobe.up.kp.addr);
                }
                DPRINTF ("dbi_register_ujprobe() failure %d", ret);
                return ret;
@@ -1242,14 +1211,15 @@ int register_usprobe(struct task_struct *task, struct us_ip *ip, int atomic)
 
        if (ip->flag_retprobe) {
                // Mr_Nobody: comment for valencia
-               ip->retprobe.kp.tgid = task->tgid;
                if (ip->retprobe.handler == NULL) {
-                       ip->retprobe.handler = (kretprobe_handler_t)uretprobe_event_handler;
+                       ip->retprobe.handler = (uretprobe_handler_t)uretprobe_event_handler;
                        DPRINTF("Set default ret event handler for %x\n", ip->offset);
                }
 
                ip->retprobe.priv_arg = ip;
-               ret = dbi_register_uretprobe(task, &ip->retprobe, atomic);
+               ip->retprobe.up.task = task;
+               ip->retprobe.up.sm = ip->page->file->procs->sm;
+               ret = dbi_register_uretprobe(&ip->retprobe, atomic);
                if (ret) {
                        EPRINTF ("dbi_register_uretprobe() failure %d", ret);
                        return ret;
@@ -1259,138 +1229,13 @@ int register_usprobe(struct task_struct *task, struct us_ip *ip, int atomic)
        return 0;
 }
 
-int unregister_usprobe(struct task_struct *task, struct us_ip *ip, int atomic, int not_rp2)
+int unregister_usprobe(struct task_struct *task, struct us_ip *ip, int atomic)
 {
-       dbi_unregister_ujprobe(task, &ip->jprobe, atomic);
+       dbi_unregister_ujprobe(&ip->jprobe, atomic);
 
        if (ip->flag_retprobe) {
-               dbi_unregister_uretprobe(task, &ip->retprobe, atomic, not_rp2);
+               dbi_unregister_uretprobe(&ip->retprobe, atomic);
        }
 
        return 0;
 }
-
-unsigned long get_stack_size(struct task_struct *task,
-               struct pt_regs *regs)
-{
-#ifdef CONFIG_ADD_THREAD_STACK_INFO
-       return (task->stack_start - dbi_get_stack_ptr(regs));
-#else
-       struct vm_area_struct *vma = NULL;
-       struct mm_struct *mm = NULL;
-       unsigned long result = 0;
-    int atomic = in_atomic();
-
-       mm = (atomic ? task->active_mm: get_task_mm(task));
-
-       if (mm) {
-               if (!atomic)
-                       down_read(&mm->mmap_sem);
-
-               vma = find_vma(mm, dbi_get_stack_ptr(regs));
-
-               if (vma)
-                       result = vma->vm_end - dbi_get_stack_ptr(regs);
-               else
-                       result = 0;
-
-               if (!atomic) {
-                       up_read(&mm->mmap_sem);
-                       mmput(mm);
-               }
-       }
-
-       return result;
-#endif
-}
-EXPORT_SYMBOL_GPL(get_stack_size);
-
-unsigned long get_stack(struct task_struct *task, struct pt_regs *regs,
-               char *buf, unsigned long sz)
-{
-       unsigned long stack_sz = get_stack_size(task, regs);
-       unsigned long real_sz = (stack_sz > sz ? sz: stack_sz);
-       int res = read_proc_vm_atomic(task, dbi_get_stack_ptr(regs), buf, real_sz);
-       return res;
-}
-EXPORT_SYMBOL_GPL(get_stack);
-
-int dump_to_trace(probe_id_t probe_id, void *addr, const char *buf,
-               unsigned long sz)
-{
-       unsigned long rest_sz = sz;
-       const char *data = buf;
-
-       while (rest_sz >= EVENT_MAX_SIZE) {
-               pack_event_info(probe_id, RECORD_ENTRY, "pa",
-                               addr, EVENT_MAX_SIZE, data);
-               rest_sz -= EVENT_MAX_SIZE;
-               data += EVENT_MAX_SIZE;
-       }
-
-       if (rest_sz > 0)
-               pack_event_info(probe_id, RECORD_ENTRY, "pa", addr, rest_sz, data);
-
-       return 0;
-}
-EXPORT_SYMBOL_GPL(dump_to_trace);
-
-int dump_backtrace(probe_id_t probe_id, struct task_struct *task,
-               void *addr, struct pt_regs *regs, unsigned long sz)
-{
-       unsigned long real_sz = 0;
-       char *buf = NULL;
-
-       buf = (char *)kmalloc(sz, GFP_ATOMIC);
-
-       if (buf != NULL) {
-               real_sz = get_stack(task, regs, buf, sz);
-               if (real_sz > 0)
-                       dump_to_trace(probe_id, addr, buf, real_sz);
-               kfree(buf);
-               return 0;
-       } else {
-               return -1;
-       }
-}
-EXPORT_SYMBOL_GPL(dump_backtrace);
-
-struct kretprobe_instance *find_ri(struct task_struct *task, struct us_ip *ip)
-{
-       struct hlist_node *item, *tmp_node;
-       struct kretprobe_instance *ri;
-
-       if (ip == NULL)
-               return NULL;
-
-       hlist_for_each_safe (item, tmp_node, &ip->retprobe.used_instances) {
-               ri = hlist_entry (item, struct kretprobe_instance, uflist);
-
-               if (ri->task && ri->task->pid == task->pid &&
-                               ri->task->tgid == task->tgid)
-                       return ri;
-       }
-
-       return NULL;
-}
-EXPORT_SYMBOL_GPL(find_ri);
-
-unsigned long get_ret_addr(struct task_struct *task, struct us_ip *ip)
-{
-       struct kretprobe_instance *ri = find_ri(task, ip);;
-       if (ri)
-               return (unsigned long)ri->ret_addr;
-       else
-               return dbi_get_ret_addr(task_pt_regs(task));
-}
-EXPORT_SYMBOL_GPL(get_ret_addr);
-
-unsigned long get_entry_sp(struct task_struct *task, struct us_ip *ip)
-{
-       struct kretprobe_instance *ri = find_ri(task, ip);
-       if (ri)
-               return (unsigned long)ri->sp;
-       else
-               return dbi_get_stack_ptr(task_pt_regs(task));
-}
-EXPORT_SYMBOL_GPL(get_entry_sp);