Merge branch 'dev' of 106.109.8.71:/srv/git/dbi into new_dpf
authorVyacheslav Cherkashin <v.cherkashin@samsung.com>
Tue, 15 Jan 2013 09:29:54 +0000 (13:29 +0400)
committerVyacheslav Cherkashin <v.cherkashin@samsung.com>
Tue, 15 Jan 2013 09:29:54 +0000 (13:29 +0400)
14 files changed:
driver/device_driver.c
driver/module.c
driver/new_dpf.h [new file with mode: 0644]
driver/probes_manager.c
driver/storage.c
driver/storage.h
driver/us_proc_inst.c
driver/us_proc_inst.h
kprobe/arch/asm-arm/dbi_kprobes.c
kprobe/dbi_insn_slots.c
kprobe/dbi_kprobes.h
kprobe/dbi_kprobes_deps.c
kprobe/dbi_uprobes.c
kprobe/dbi_uprobes.h

index 2cbd4b0..258f84c 100644 (file)
@@ -8,7 +8,7 @@
 //      SEE ALSO:       device_driver.h
 //      AUTHOR:         L.Komkov, S.Dianov, S.Grekhov, A.Gerenkov
 //      COMPANY NAME:   Samsung Research Center in Moscow
-//      DEPT NAME:      Advanced Software Group 
+//      DEPT NAME:      Advanced Software Group
 //      CREATED:        2008.02.15
 //      VERSION:        1.0
 //      REVISION DATE:  2008.12.03
@@ -25,6 +25,11 @@ extern unsigned long swap_sum_time;
 extern unsigned long swap_sum_hit;
 #endif
 
+
+extern unsigned long imi_sum_time;
+extern unsigned long imi_sum_hit;
+
+
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 17)
 static BLOCKING_NOTIFIER_HEAD(swap_notifier_list);
 #endif
@@ -165,20 +170,20 @@ static int device_open(struct inode *inode, struct file *file)
        try_module_get(THIS_MODULE);
        return 0;
 }
+
 static int device_release(struct inode *inode, struct file *file)
 {
        gl_nDeviceOpened--;
        module_put(THIS_MODULE);
        return 0;
 }
+
 static ssize_t device_read(struct file *filp, char *buffer, size_t length, loff_t * offset)
 {
        EPRINTF("Operation <<read>> not supported!");
        return -1;
 }
+
 static ssize_t device_write(struct file *filp, const char *buff, size_t len, loff_t * off)
 {
        EPRINTF("Operation <<write>> not supported!");
@@ -194,6 +199,9 @@ static long device_ioctl (struct file *file UNUSED, unsigned int cmd, unsigned l
        unsigned long spinlock_flags = 0L;
        int result = -1;
 //     DPRINTF("Command=%d", cmd);
+       printk("#1# Command=%d\n", cmd);
+       printk("#2# Command=%d\n", cmd);
+
        switch (cmd)
        {
        case EC_IOCTL_SET_EC_MODE:
@@ -511,6 +519,17 @@ static long device_ioctl (struct file *file UNUSED, unsigned int cmd, unsigned l
                swap_sum_time = 0;
                swap_sum_hit = 0;
 #endif
+
+               printk("\n### imi_sum_time = %ld in install_mapped_ips()\n", imi_sum_time);
+               printk("### imi_sum_hit = %ld in install_mapped_ips()\n", imi_sum_hit);
+
+               if (imi_sum_hit != 0) {
+                       printk("### time = %ld in install_mapped_ips()\n", imi_sum_time/imi_sum_hit);
+               }
+
+               imi_sum_time = 0;
+               imi_sum_hit = 0;
+
                local_mh = get_dbi_modules_handlers();
                if(ec_user_stop() != 0) {
                        result = -1;
@@ -615,13 +634,13 @@ sad_cleanup:
                        {
                                if(ioctl_args.len == 0){
                                        result = -EINVAL;
-                                       EPRINTF ("invalid event length!");                                      
+                                       EPRINTF ("invalid event length!");
                                }
                                else {
                                        char *buf = kmalloc(ioctl_args.len, GFP_KERNEL);
                                        if(!buf){
                                                result = -ENOMEM;
-                                               EPRINTF ("failed to alloc mem for event!");                                     
+                                               EPRINTF ("failed to alloc mem for event!");
                                        }
                                        else {
                                                result = copy_from_user (buf, (void *) ioctl_args.data, ioctl_args.len);
@@ -638,7 +657,7 @@ sad_cleanup:
 //                     DPRINTF("User Space Event"); // Frequent call
                        break;
                }
-               
+
        case EC_IOCTL_SET_EVENT_MASK:
                {
                        int mask;
@@ -677,6 +696,9 @@ sad_cleanup:
 
        case EC_IOCTL_SET_PREDEF_UPROBES:
                {
+                       result = -1;
+                       break;
+
                        ioctl_predef_uprobes_info_t data;
                        result = copy_from_user (&data, (void *) arg, sizeof (data));
                        if (result)
@@ -693,9 +715,12 @@ sad_cleanup:
                        DPRINTF("Set Predefined User Space Probes");
                        break;
                }
-               
+
        case EC_IOCTL_GET_PREDEF_UPROBES:
                {
+//                     result = 0;
+//                     break;
+
                        result = get_predef_uprobes((ioctl_predef_uprobes_info_t *)arg);
                        if (result)
                        {
@@ -704,7 +729,7 @@ sad_cleanup:
                        DPRINTF("Get Predefined User Space Probes");
                        break;
                }
-               
+
        case EC_IOCTL_GET_PREDEF_UPROBES_SIZE:
                {
                        int size = 0;
@@ -721,7 +746,7 @@ sad_cleanup:
                        DPRINTF("Get Size of Predefined User Space Probes");
                        break;
                }
-       
+
        default:
                EPRINTF ("Unknown driver command = %u", cmd);
                result = -EINVAL;
index 00e2472..e667a60 100644 (file)
@@ -8,7 +8,7 @@
 //      SEE ALSO:       module.h
 //      AUTHOR:         L.Komkov, A.Gerenkov
 //      COMPANY NAME:   Samsung Research Center in Moscow
-//      DEPT NAME:      Advanced Software Group 
+//      DEPT NAME:      Advanced Software Group
 //      CREATED:        2008.02.15
 //      VERSION:        1.0
 //      REVISION DATE:  2008.12.03
@@ -62,6 +62,10 @@ void __put_task_struct(struct task_struct *tsk)
 void (*flush_cache_page) (struct vm_area_struct * vma, unsigned long page);
 #endif
 
+#include "../../tools/gpmu/probes/entry_data.h"
+
+storage_arg_t sa_dpf;
+
 static int __init InitializeModule(void)
 {
        if(lookup_name == NULL) {
@@ -105,11 +109,14 @@ static int __init InitializeModule(void)
        INIT_LIST_HEAD(&cond_list.list);
 
        DPRINTF ("is successfully initialized.");
+
+       swap_init_storage_arg(&sa_dpf);
        return 0;
 }
 
 static void __exit UninitializeModule (void)
 {
+       swap_uninit_storage_arg(&sa_dpf);
        ec_user_stop ();
        device_down ();
        probes_manager_down ();
diff --git a/driver/new_dpf.h b/driver/new_dpf.h
new file mode 100644 (file)
index 0000000..8d6a3ce
--- /dev/null
@@ -0,0 +1,641 @@
+#ifndef __NEW_DPF__
+#define __NEW_DPF__
+
+#include <linux/hash.h>
+#include "storage.h"
+
+enum US_FLAGS {
+       US_UNREGS_PROBE,
+       US_NOT_RP2,
+       US_DISARM
+};
+
+struct ip_data {
+       unsigned long offset;
+       unsigned long got_addr;
+
+       kprobe_pre_entry_handler_t pre_handler;
+       unsigned long jp_handler;
+       kretprobe_handler_t rp_handler;
+
+       unsigned flag_retprobe:1;
+};
+
+struct page_probes {
+       struct list_head ip_list;
+       unsigned long offset;
+       int install;
+       spinlock_t lock;
+
+       struct hlist_node hlist; // for file_probes
+};
+
+struct file_probes {
+       struct list_head list;                  // for proc_probes
+       struct dentry *dentry;
+       char *path;
+       int loaded;
+       unsigned long vm_start;
+       unsigned long vm_end;
+
+       unsigned long page_probes_hash_bits;
+       struct hlist_head *page_probes_table; // for page_probes
+};
+
+struct proc_probes {
+       struct list_head list;
+       pid_t tgid;
+       struct dentry *dentry;
+       struct list_head file_list;
+};
+
+
+// ==================== us_ip ====================
+
+static struct us_ip *create_ip(unsigned long offset)
+{
+       struct us_ip *ip = kmalloc(sizeof(*ip), GFP_ATOMIC);
+       memset(ip, 0, sizeof(*ip));
+
+       INIT_LIST_HEAD(&ip->list);
+       ip->offset = offset;
+
+       return ip;
+}
+
+static void free_ip(struct us_ip *ip)
+{
+       kfree(ip);
+}
+
+static void set_ip_jp_handler(struct us_ip *ip, kprobe_pre_entry_handler_t per_entry, void *entry)
+{
+       ip->jprobe.pre_entry = per_entry;
+       ip->jprobe.entry = entry;
+}
+
+static void set_ip_rp_handler(struct us_ip *ip, kretprobe_handler_t handler)
+{
+       ip->flag_retprobe = 1;
+       ip->retprobe.handler = handler;
+}
+
+static void set_ip_got_addr(struct us_ip *ip, unsigned long got_addr)
+{
+       ip->got_addr = got_addr;
+}
+
+struct us_ip *us_proc_ip_copy(const struct us_ip *ip)
+{
+       // FIXME: one malloc us_ip
+       struct us_ip *ip_out = kmalloc(sizeof(*ip_out), GFP_ATOMIC);
+       if (ip_out == NULL) {
+               DPRINTF ("us_proc_ip_copy: No enough memory");
+               return NULL;
+       }
+
+       memcpy(ip_out, ip, sizeof(*ip_out));
+
+       // jprobe
+       memset(&ip_out->jprobe, 0, sizeof(struct jprobe));
+       ip_out->jprobe.entry = ip->jprobe.entry;
+       ip_out->jprobe.pre_entry = ip->jprobe.pre_entry;
+
+       // retprobe
+       retprobe_init(&ip_out->retprobe, ip->retprobe.handler);
+
+       ip_out->flag_got = 0;
+
+       INIT_LIST_HEAD(&ip_out->list);
+
+       return ip_out;
+}
+
+static struct us_ip *create_ip_by_ip_data(struct ip_data *ip_d)
+{
+       struct us_ip *ip = create_ip(ip_d->offset);
+       set_ip_jp_handler(ip, ip_d->pre_handler, ip_d->jp_handler);
+
+       if (ip_d->flag_retprobe) {
+               set_ip_rp_handler(ip, ip_d->rp_handler);
+       }
+
+       set_ip_got_addr(ip, ip_d->got_addr);
+
+       return ip;
+}
+
+// ==================== us_ip ====================
+
+
+// page_probes
+static struct page_probes *page_p_new(unsigned long offset)
+{
+       struct page_probes *obj = kmalloc(sizeof(*obj), GFP_ATOMIC);
+       if (obj) {
+               INIT_LIST_HEAD(&obj->ip_list);
+               obj->offset = offset;
+               obj->install = 0;
+               spin_lock_init(&obj->lock);
+               INIT_HLIST_NODE(&obj->hlist);
+       }
+
+       return obj;
+}
+
+static void page_p_del(struct page_probes *page_p)
+{
+       // TODO: del
+}
+
+static struct page_probes *page_p_copy(const struct page_probes *page_p)
+{
+       struct us_ip *ip_in, *ip_out;
+       struct page_probes *page_p_out = kmalloc(sizeof(*page_p), GFP_ATOMIC);
+
+       if (page_p_out) {
+               INIT_LIST_HEAD(&page_p_out->ip_list);
+               list_for_each_entry(ip_in, &page_p->ip_list, list) {
+                       ip_out = us_proc_ip_copy(ip_in);
+                       if (ip_out == NULL) {
+                               // FIXME: free ip_list in page_p_out
+                               kfree(page_p_out);
+                               return NULL;
+                       }
+
+                       list_add(&ip_out->list, &page_p_out->ip_list);
+               }
+
+               page_p_out->offset = page_p->offset;
+               page_p_out->install = 0;
+               spin_lock_init(&page_p_out->lock);
+               INIT_HLIST_NODE(&page_p_out->hlist);
+       }
+
+       return page_p_out;
+}
+
+static void page_p_add_ip(struct page_probes *page_p, struct us_ip *ip)
+{
+       ip->offset &= ~PAGE_MASK;
+       INIT_LIST_HEAD(&ip->list);
+       list_add(&ip->list, &page_p->ip_list);
+}
+
+static struct us_ip *page_p_find_ip(struct page_probes *page_p, unsigned long offset)
+{
+       struct us_ip *ip;
+
+       list_for_each_entry(ip, &page_p->ip_list, list) {
+               if (ip->offset == offset) {
+                       return ip;
+               }
+       }
+
+       return NULL;
+}
+
+static void page_p_assert_install(const struct page_probes *page_p)
+{
+       if (page_p->install != 0) {
+               panic("already installed page %x\n", page_p->offset);
+       }
+}
+
+static int page_p_is_install(struct page_probes *page_p)
+{
+       return page_p->install;
+}
+
+static void page_p_installed(struct page_probes *page_p)
+{
+       page_p->install = 1;
+}
+
+static void page_p_uninstalled(struct page_probes *page_p)
+{
+       page_p->install = 0;
+}
+// page_probes
+
+static void set_ip_kp_addr(struct us_ip *ip, struct page_probes *page_p, const struct file_probes *file_p)
+{
+       unsigned long addr = file_p->vm_start + page_p->offset + ip->offset;
+       ip->retprobe.kp.addr = ip->jprobe.kp.addr = addr;
+}
+
+static void page_p_set_all_kp_addr(struct page_probes *page_p, const struct file_probes *file_p)
+{
+       struct us_ip *ip;
+       unsigned long addr;
+
+       list_for_each_entry(ip, &page_p->ip_list, list) {
+               addr = file_p->vm_start + page_p->offset + ip->offset;
+               ip->retprobe.kp.addr = ip->jprobe.kp.addr = addr;
+//             printk("###       pp_set_all_kp_addr: start=%x, page_offset=%x, ip_offset=%x, addr=%x\n",
+//                             file_p->vm_start, page_p->offset, ip->offset, addr);
+       }
+}
+
+static int calculation_hash_bits(int cnt)
+{
+       int bits;
+       for (bits = 1; cnt >>= 1; ++bits);
+
+       return bits;
+}
+
+// file_probes
+static struct file_probes *file_p_new(const char *path, struct dentry *dentry, int page_cnt)
+{
+       struct file_probes *obj = kmalloc(sizeof(*obj), GFP_ATOMIC);
+
+       if (obj) {
+               int i, table_size;
+               obj->path = path;
+               obj->dentry = dentry;
+               obj->loaded = 0;
+               obj->vm_start = 0;
+               obj->vm_end = 0;
+
+               obj->page_probes_hash_bits = calculation_hash_bits(page_cnt);//PAGE_PROBES_HASH_BITS;
+               table_size = (1 << obj->page_probes_hash_bits);
+
+               obj->page_probes_table = kmalloc(sizeof(*obj->page_probes_table)*table_size, GFP_ATOMIC);
+
+               for (i = 0; i < table_size; ++i) {
+                       INIT_HLIST_HEAD(&obj->page_probes_table[i]);
+               }
+       }
+
+       return obj;
+}
+
+static void file_p_del(struct file_probes *file_p)
+{
+       // TODO: del
+}
+
+static void file_p_add_page_p(struct file_probes *file_p, struct page_probes *page_p)
+{
+       hlist_add_head_rcu(&page_p->hlist, &file_p->page_probes_table[hash_ptr(page_p->offset, file_p->page_probes_hash_bits)]);
+}
+
+static struct file_probes *file_p_copy(const struct file_probes *file_p)
+{
+       struct file_probes *file_p_out;
+
+       if (file_p == NULL) {
+               printk("### WARNING: file_p == NULL\n");
+               return NULL;
+       }
+
+       file_p_out = kmalloc(sizeof(*file_p_out), GFP_ATOMIC);
+       if (file_p_out) {
+               struct page_probes *page_p = NULL;
+               struct hlist_node *node = NULL;
+               struct hlist_head *head = NULL;
+               int i, table_size;
+               INIT_LIST_HEAD(&file_p_out->list);
+               file_p_out->dentry = file_p->dentry;
+               file_p_out->path = file_p->path;
+               file_p_out->loaded = 0;
+               file_p_out->vm_start = 0;
+               file_p_out->vm_end = 0;
+
+               file_p_out->page_probes_hash_bits = file_p->page_probes_hash_bits;
+               table_size = (1 << file_p_out->page_probes_hash_bits);
+
+               file_p_out->page_probes_table =
+                               kmalloc(sizeof(*file_p_out->page_probes_table)*table_size, GFP_ATOMIC);
+
+               for (i = 0; i < table_size; ++i) {
+                       INIT_HLIST_HEAD(&file_p_out->page_probes_table[i]);
+               }
+
+               // copy pages
+               for (i = 0; i < table_size; ++i) {
+                       head = &file_p->page_probes_table[i];
+                       hlist_for_each_entry_rcu(page_p, node, head, hlist) {
+                               file_p_add_page_p(file_p_out, page_p_copy(page_p));
+                       }
+               }
+       }
+
+       return file_p_out;
+}
+
+static struct page_probes *file_p_find_page_p(struct file_probes *file_p, unsigned long offset)
+{
+       struct hlist_node *node;
+       struct hlist_head *head;
+       struct page_probes *page_p;
+
+       head = &file_p->page_probes_table[hash_ptr(offset, file_p->page_probes_hash_bits)];
+       hlist_for_each_entry_rcu(page_p, node, head, hlist) {
+               if (page_p->offset == offset) {
+                       return page_p;
+               }
+       }
+
+       return NULL;
+}
+
+static struct page_probes *file_p_find_page_p_or_new(struct file_probes *file_p, unsigned long offset)
+{
+       struct page_probes *page_p = file_p_find_page_p(file_p, offset);
+
+       if (page_p == NULL) {
+               page_p = page_p_new(offset);
+               file_p_add_page_p(file_p, page_p);
+       }
+
+       return page_p;
+}
+
+static struct page_probes *file_p_find_page_p_mapped(struct file_probes *file_p, unsigned long page)
+{
+       unsigned long offset;
+
+       if (file_p->vm_start > page || file_p->vm_end < page) {
+               // TODO: or panic?!
+               printk("ERROR: file_p[vm_start..vm_end] <> page: file_p[vm_start=%x, vm_end=%x, path=%s, d_iname=%s] page=%x\n",
+                               file_p->vm_start, file_p->vm_end, file_p->path, file_p->dentry->d_iname, page);
+               return NULL;
+       }
+
+       offset = page - file_p->vm_start;
+
+       return file_p_find_page_p(file_p, offset);
+}
+
+static void file_p_add_probe(struct file_probes *file_p, struct ip_data *ip_d)
+{
+       unsigned long offset = ip_d->offset & PAGE_MASK;
+       struct page_probes *page_p = file_p_find_page_p_or_new(file_p, offset);
+
+       // FIXME: delete ip
+       struct us_ip *ip = create_ip_by_ip_data(ip_d);
+
+       page_p_add_ip(page_p, ip);
+}
+
+static struct page_probes *get_page_p(struct file_probes *file_p, unsigned long offset_addr)
+{
+       unsigned long offset = offset_addr & PAGE_MASK;
+       struct page_probes *page_p = file_p_find_page_p_or_new(file_p, offset);
+
+       spin_lock(&page_p->lock);
+
+       return page_p;
+}
+
+static void put_page_p(struct page_probes *page_p)
+{
+       spin_unlock(&page_p->lock);
+}
+// file_probes
+
+// proc_probes
+static void proc_p_init(struct proc_probes *proc_p, struct dentry* dentry, pid_t tgid)
+{
+       INIT_LIST_HEAD(&proc_p->list);
+       proc_p->tgid = tgid;
+       proc_p->dentry = dentry;
+       INIT_LIST_HEAD(&proc_p->file_list);
+}
+
+static void proc_p_add_file_p(struct proc_probes *proc_p, struct file_probes *file_p)
+{
+       list_add(&file_p->list, &proc_p->file_list);
+}
+
+static struct file_probes *proc_p_find_file_p_by_dentry(struct proc_probes *proc_p,
+               const char *pach, struct dentry *dentry)
+{
+       struct file_probes *file_p;
+
+       list_for_each_entry(file_p, &proc_p->file_list, list) {
+               if (file_p->dentry == dentry) {
+                       return file_p;
+               }
+       }
+
+       file_p = file_p_new(pach, dentry, 10);
+       proc_p_add_file_p(proc_p, file_p);
+
+       return file_p;
+}
+
+static void proc_p_add_dentry_probes(struct proc_probes *proc_p, const char *pach,
+               struct dentry* dentry, struct ip_data *ip_d, int cnt)
+{
+       int i;
+       struct file_probes *file_p = proc_p_find_file_p_by_dentry(proc_p, pach, dentry);
+
+       for (i = 0; i < cnt; ++i) {
+               file_p_add_probe(file_p, &ip_d[i]);
+       }
+}
+
+static struct proc_probes *proc_p_copy(struct proc_probes *proc_p, struct task_struct *task)
+{
+       struct file_probes *file_p;
+       struct proc_probes *proc_p_out = kmalloc(sizeof(*proc_p_out), GFP_ATOMIC);
+
+       proc_p_init(proc_p_out, proc_p->dentry, task->tgid);
+
+       list_for_each_entry(file_p, &proc_p->file_list, list) {
+               proc_p_add_file_p(proc_p_out, file_p_copy(file_p));
+       }
+
+       return proc_p_out;
+}
+
+static struct file_probes *proc_p_find_file_p(struct proc_probes *proc_p, struct vm_area_struct *vma)
+{
+       struct file_probes *file_p;
+
+       list_for_each_entry(file_p, &proc_p->file_list, list) {
+               if (vma->vm_file->f_dentry == file_p->dentry) {
+                       return file_p;
+               }
+       }
+
+       return NULL;
+}
+// proc_probes
+
+#include "storage.h"
+
+static void print_proc_probes(const struct proc_probes *proc_p);
+
+struct proc_probes *get_file_probes(const inst_us_proc_t *task_inst_info)
+{
+       struct proc_probes *proc_p = kmalloc(sizeof(*proc_p), GFP_ATOMIC);
+
+       printk("####### get START #######\n");
+
+       if (proc_p) {
+               int i;
+               proc_p_init(proc_p, task_inst_info->m_f_dentry, 0);
+
+               printk("#2# get_file_probes: proc_p[dentry=%p]\n", proc_p->dentry);
+
+               for (i = 0; i < task_inst_info->libs_count; ++i) {
+                       int k, j;
+                       us_proc_lib_t *p_libs = &task_inst_info->p_libs[i];
+                       struct dentry *dentry = p_libs->m_f_dentry;
+                       const char *pach = p_libs->path;
+
+                       for (k = 0; k < p_libs->ips_count; ++k) {
+                               struct ip_data pd;
+                               us_proc_ip_t *ip = &p_libs->p_ips[k];
+                               unsigned long got_addr = 0;
+
+                               for (j = 0; j < p_libs->plt_count; ++j) {
+                                       if (ip->offset == p_libs->p_plt[j].func_addr) {
+                                               got_addr = p_libs->p_plt[j].got_addr;
+                                               break;
+                                       }
+                               }
+
+                               pd.flag_retprobe = 1;
+                               pd.offset = ip->offset;
+                               pd.got_addr = got_addr;
+                               pd.pre_handler = ip->jprobe.pre_entry;
+                               pd.jp_handler = ip->jprobe.entry;
+                               pd.rp_handler = ip->retprobe.handler;
+
+                               proc_p_add_dentry_probes(proc_p, pach, dentry, &pd, 1);
+                       }
+               }
+       }
+
+       print_proc_probes(proc_p);
+
+       printk("####### get  END  #######\n");
+
+       return proc_p;
+}
+
+static int register_usprobe_my(struct task_struct *task, struct us_ip *ip)
+{
+       return register_usprobe(task, ip, 1);
+}
+
+static int unregister_usprobe_my(struct task_struct *task, struct us_ip *ip, enum US_FLAGS flag)
+{
+       int err = 0;
+
+       switch (flag) {
+       case US_UNREGS_PROBE:
+               err = unregister_usprobe(task, ip, 1, 0);
+               break;
+       case US_NOT_RP2:
+               err = unregister_usprobe(task, ip, 1, 1);
+               break;
+       case US_DISARM:
+               arch_disarm_uprobe(&ip->jprobe.kp, task);
+               break;
+       default:
+               panic("incorrect value flag=%d", flag);
+       }
+
+       return err;
+}
+
+// debug
+static void print_jprobe(struct jprobe *jp)
+{
+       printk("###         JP: entry=%x, pre_entry=%x\n",
+                       jp->entry, jp->pre_entry);
+}
+
+static void print_retprobe(struct kretprobe *rp)
+{
+       printk("###         RP: handler=%x\n",
+                       rp->handler);
+}
+
+static void print_page_probes(const struct page_probes *page_p)
+{
+       int i = 0;
+       struct us_ip *ip;
+
+       printk("###     offset=%x\n", page_p->offset);
+       list_for_each_entry(ip, &page_p->ip_list, list) {
+
+               printk("###       addr[%2d]=%x, J_addr=%x, R_addr=%x\n",
+                               i, ip->offset, ip->jprobe.kp.addr, ip->retprobe.kp.addr);
+               print_jprobe(&ip->jprobe);
+               print_retprobe(&ip->retprobe);
+               ++i;
+       }
+}
+
+static const char *NA = "N/A";
+
+static void print_file_probes(const struct file_probes *file_p)
+{
+       int i, table_size;
+       struct page_probes *page_p = NULL;
+       struct hlist_node *node = NULL;
+       struct hlist_head *head = NULL;
+
+       if (file_p == NULL) {
+               printk("### file_p == NULL\n");
+               return;
+       }
+
+       table_size = (1 << file_p->page_probes_hash_bits);
+       const char *name = (file_p->dentry) ? file_p->dentry->d_iname : NA;
+
+       printk("### print_file_probes: path=%s, d_iname=%s, table_size=%d, vm_start=%x\n",
+                       file_p->path, name, table_size, file_p->vm_start);
+
+       for (i = 0; i < table_size; ++i) {
+               head = &file_p->page_probes_table[i];
+               hlist_for_each_entry_rcu(page_p, node, head, hlist) {
+                       print_page_probes(page_p);
+               }
+       }
+}
+
+static void print_proc_probes(const struct proc_probes *proc_p)
+{
+       struct file_probes *file_p;
+
+       printk("### print_proc_probes\n");
+       list_for_each_entry(file_p, &proc_p->file_list, list) {
+               print_file_probes(file_p);
+       }
+       printk("### print_proc_probes\n");
+}
+
+void print_inst_us_proc(const inst_us_proc_t *task_inst_info)
+{
+       int i;
+       int cnt = task_inst_info->libs_count;
+       printk(  "### BUNDLE PRINT START ###\n");
+       printk("\n### BUNDLE PRINT START ###\n");
+       printk("### task_inst_info.libs_count=%d\n", cnt);
+
+       for (i = 0; i < cnt; ++i) {
+               int j;
+
+               us_proc_lib_t *lib = &task_inst_info->p_libs[i];
+               int cnt_j = lib->ips_count;
+               char *path = lib->path;
+               printk("###     path=%s, cnt_j=%d\n", path, cnt_j);
+
+               for (j = 0; j < cnt_j; ++j) {
+                       struct us_ip *ips = &lib->p_ips[j];
+                       unsigned long offset = ips->offset;
+                       printk("###         offset=%x\n", offset);
+               }
+       }
+       printk("### BUNDLE PRINT  END  ###\n");
+}
+
+#endif /* __NEW_DPF__ */
index 3c748c0..09b1b8f 100644 (file)
@@ -418,6 +418,8 @@ def_jprobe_event_handler (unsigned long arg1, unsigned long arg2, unsigned long
 
        if (pf_probe == probe)
        {
+               if (us_proc_probes & US_PROC_PF_INSTLD)
+                       do_page_fault_j_pre_code(arg1, arg2, arg3);
 #ifdef CONFIG_X86
                /* FIXME on x86 targets do_page_fault instrumentation may lead to
                 * abnormal termination of some applications (in most cases GUI apps).
index 92699c5..f032ef3 100644 (file)
@@ -31,7 +31,6 @@
 
 char *p_buffer = NULL;
 inst_us_proc_t us_proc_info;
-struct list_head otg_us_proc_info;
 inst_dex_proc_t dex_proc_info;
 char *deps;
 char *bundle;
@@ -539,7 +538,6 @@ void unlink_bundle(void)
        us_proc_lib_t *d_lib;
        char *path;
        struct list_head *pos;  //, *tmp;
-       us_proc_otg_ip_t *p;
 
        path = us_proc_info.path;
        us_proc_info.path = 0;
@@ -596,13 +594,11 @@ void unlink_bundle(void)
        /* } */
 
        us_proc_info.tgid = 0;
-
-       /* OTG probes list cleaning */
-       list_for_each_entry_rcu (p, &otg_us_proc_info, list) {
-               list_del_rcu(&p->list);
-       }
 }
 
+struct proc_probes *get_file_probes(const inst_us_proc_t *task_inst_info);
+void print_inst_us_proc(const inst_us_proc_t *task_inst_info);
+
 extern struct dentry *dentry_by_path(const char *path);
 
 int link_bundle()
@@ -1057,6 +1053,11 @@ int link_bundle()
 
        p += sizeof(u_int32_t);
 
+       // print
+//     print_inst_us_proc(&us_proc_info);
+
+       us_proc_info.pp = get_file_probes(&us_proc_info);
+
        return 0;
 }
 
@@ -1076,7 +1077,7 @@ int storage_init (void)
 
        INIT_HLIST_HEAD(&kernel_probes);
        INIT_HLIST_HEAD(&otg_kernel_probes);
-       INIT_LIST_HEAD(&otg_us_proc_info);
+
        spin_lock_init(&dbi_mh.lock);
        INIT_LIST_HEAD(&dbi_mh.modules_handlers);
        return 0;
index baa8fb9..9bf1684 100644 (file)
@@ -135,8 +135,6 @@ extern int dbi_unregister_handlers_module(struct dbi_modules_handlers_info *dbi_
 /* list of on-the-go installed kernel probes */
 extern struct hlist_head otg_kernel_probes;
 
-extern struct list_head otg_us_proc_info;
-
 // event mask
 extern int event_mask;
 
@@ -145,19 +143,30 @@ extern unsigned int inst_pid;
 
 typedef struct
 {
+       struct list_head list;
        char *name;
        int installed;
        struct jprobe jprobe;
        struct kretprobe retprobe;
        unsigned long offset;
+       unsigned long got_addr;
+
+       unsigned flag_retprobe:1;
+       unsigned flag_got:1;
 } us_proc_ip_t;
 
-typedef struct
-{
-       us_proc_ip_t ip;
-       pid_t tgid;
+struct us_ip {
        struct list_head list;
-} us_proc_otg_ip_t;
+
+       struct jprobe jprobe;
+       struct kretprobe retprobe;
+
+       unsigned long offset;
+       unsigned long got_addr;
+
+       unsigned flag_retprobe:1;
+       unsigned flag_got:1;
+};
 
 typedef struct
 {
@@ -209,7 +218,6 @@ typedef struct
        pid_t tgid;
        unsigned unres_ips_count;
        unsigned unres_vtps_count;
-       unsigned unres_otg_ips_count;
        //kprobe_opcode_t *mapped_codelets;
        int is_plt;
        unsigned libs_count;
@@ -220,6 +228,9 @@ typedef struct
        us_proc_ip_t libdvm_entry_ip;
        us_proc_ip_t libdvm_return_ip;
 #endif /* __ANDROID */
+
+       // new_dpf
+       struct proc_probes *pp;
 } inst_us_proc_t;
 
 typedef struct
index ad9f2b0..6964812 100644 (file)
 #include "../kprobe/dbi_kprobes_deps.h"
 #include "../kprobe/dbi_uprobes.h"
 
+#define mm_read_lock(task, mm, atomic, lock)                   \
+       mm = atomic ? task->active_mm : get_task_mm(task);      \
+       if (mm == NULL) {                                       \
+               /* FIXME: */                                    \
+               panic("ERRR mm_read_lock: mm == NULL\n");       \
+       }                                                       \
+                                                               \
+       if (atomic) {                                           \
+               lock = down_read_trylock(&mm->mmap_sem);        \
+       } else {                                                \
+               lock = 1;                                       \
+               down_read(&mm->mmap_sem);                       \
+       }
+
+#define mm_read_unlock(mm, atomic, lock)                       \
+       if (lock) {                                             \
+               up_read(&mm->mmap_sem);                         \
+       }                                                       \
+                                                               \
+       if (!atomic) {                                          \
+               mmput(mm);                                      \
+       }
+
 DEFINE_PER_CPU (us_proc_vtp_t *, gpVtp) = NULL;
 DEFINE_PER_CPU (struct pt_regs *, gpCurVtpRegs) = NULL;
 
@@ -33,30 +56,18 @@ DEFINE_PER_CPU (struct pt_regs *, gpCurVtpRegs) = NULL;
 #      warning ARCH_REG_VAL is not implemented for this architecture. FBI will work improperly or even crash!!!
 #endif // ARCH
 
-unsigned long (*dbi_ujprobe_event_pre_handler_custom_p)
-(us_proc_ip_t *, struct pt_regs *) = NULL;
-EXPORT_SYMBOL(dbi_ujprobe_event_pre_handler_custom_p);
-void (*dbi_ujprobe_event_handler_custom_p)(void) = NULL;
-EXPORT_SYMBOL(dbi_ujprobe_event_handler_custom_p);
-int (*dbi_uretprobe_event_handler_custom_p)
-(struct kretprobe_instance *, struct pt_regs *, us_proc_ip_t *) = NULL;
-EXPORT_SYMBOL(dbi_uretprobe_event_handler_custom_p);
-
-unsigned long ujprobe_event_pre_handler (us_proc_ip_t * ip, struct pt_regs *regs);
+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, us_proc_ip_t * ip);
+int uretprobe_event_handler (struct kretprobe_instance *probe, struct pt_regs *regs, struct us_ip *ip);
+
+static int register_usprobe(struct task_struct *task, struct us_ip *ip, int atomic);
+static int unregister_usprobe(struct task_struct *task, struct us_ip *ip, int atomic, int no_rp2);
 
-static int register_usprobe (struct task_struct *task, struct mm_struct *mm, us_proc_ip_t * ip, int atomic, kprobe_opcode_t * islot);
-static int unregister_usprobe (struct task_struct *task, us_proc_ip_t * ip, int atomic);
+#include "new_dpf.h"
 
 int us_proc_probes;
 
-struct task_inst_info_node {
-       struct list_head      plist;
-       inst_us_proc_t *      task_inst_info;
-       int                   tgid;
-};
-LIST_HEAD(task_inst_info_list);
+LIST_HEAD(proc_probes_list);
 
 #ifdef SLP_APP
 struct dentry *launchpad_daemon_dentry = NULL;
@@ -77,209 +88,62 @@ struct dentry *libdvm_dentry = NULL;
 #define LIBDVM_RETURN 0x30bdc
 #endif /* __ANDROID */
 
-us_proc_otg_ip_t *find_otg_probe(unsigned long addr)
-{
-       us_proc_otg_ip_t *p;
 
-       list_for_each_entry_rcu (p, &otg_us_proc_info, list) {
-               if (p->ip.offset == addr) {
-                       return p;
-               }
-       }
 
-       return NULL;
+#define print_event(fmt, args...)                                              \
+{                                                                              \
+       char *buf[1024];                                                        \
+       sprintf(buf, fmt, ##args);                                              \
+       pack_event_info(US_PROBE_ID, RECORD_ENTRY, "ds", 0x0badc0de, buf);      \
 }
 
-int add_otg_probe_to_list(unsigned long addr, us_proc_otg_ip_t **pprobe)
+static inline int is_libonly(void)
 {
-       us_proc_otg_ip_t *new_probe;
-       us_proc_otg_ip_t *probe;
-
-       if (pprobe) {
-               *pprobe = NULL;
-       }
-       /* check if such probe does already exist */
-       probe = find_otg_probe(addr);
-       if (probe) {
-               return 1;
-       }
-
-       new_probe = kmalloc(sizeof(us_proc_otg_ip_t), GFP_KERNEL);
-       if (!new_probe) {
-               EPRINTF ("no memory for new probe!");
-               return -ENOMEM;
-       }
-       memset(new_probe,0, sizeof(us_proc_otg_ip_t));
-
-       new_probe->ip.offset = addr;
-       new_probe->ip.jprobe.kp.addr =
-               new_probe->ip.retprobe.kp.addr = (kprobe_opcode_t *)addr;
-       new_probe->ip.jprobe.priv_arg =
-               new_probe->ip.retprobe.priv_arg = new_probe;
-
-       INIT_LIST_HEAD(&new_probe->list);
-       list_add_rcu(&new_probe->list, &otg_us_proc_info);
-
-       if (pprobe) {
-               *pprobe = new_probe;
-       }
-       return 0;
+       return !strcmp(us_proc_info.path,"*");
 }
 
-int remove_otg_probe_from_list(unsigned long addr)
+// is user-space instrumentation
+static inline int is_us_instrumentation(void)
 {
-       us_proc_otg_ip_t *p;
-
-       //check if such probe does exist
-       p = find_otg_probe(addr);
-       if (!p) {
-               /* We do not care about it. Nothing bad. */
-               return 0;
-       }
-
-       list_del_rcu(&p->list);
-
-       kfree (p);
-
-       return 0;
+       return !!us_proc_info.path;
 }
 
-/**
- * Prepare copy of instrumentation data for task
- * in case of library only instrumentation
- */
-
-inst_us_proc_t* copy_task_inst_info (struct task_struct *task, inst_us_proc_t * task_inst_info)
+struct proc_probes *get_proc_probes_by_task(struct task_struct *task)
 {
-       int i, j;
-       kprobe_opcode_t *entry_save;
-       kprobe_pre_entry_handler_t pre_entry_save;
-       kretprobe_handler_t handler_save;
-
-       inst_us_proc_t* copy_info = 0;
-
-       int unres_ips_count = 0, unres_vtps_count = 0;
-
-       copy_info = kmalloc (sizeof (inst_us_proc_t), GFP_ATOMIC);
-       memset ((void *) copy_info, 0, sizeof (inst_us_proc_t));
+       struct proc_probes *proc_p, *tmp;
 
-       copy_info->path = task_inst_info->path;
-       copy_info->m_f_dentry = NULL;
-
-       copy_info->libs_count = task_inst_info->libs_count;
-       copy_info->p_libs =
-               kmalloc (task_inst_info->libs_count * sizeof (us_proc_lib_t), GFP_ATOMIC);
-
-       if (!copy_info->p_libs) {
-               DPRINTF ("No enough memory for copy_info->p_libs");
-               return NULL;
-       }
-       memcpy (copy_info->p_libs, task_inst_info->p_libs,
-                       copy_info->libs_count * sizeof (us_proc_lib_t));
-
-       for (i = 0; i < copy_info->libs_count; i++) {
-               if (copy_info->p_libs[i].ips_count > 0)
-               {
-                       unres_ips_count += copy_info->p_libs[i].ips_count;
-
-                       copy_info->p_libs[i].p_ips =
-                               kmalloc (copy_info->p_libs[i].ips_count * sizeof (us_proc_ip_t), GFP_ATOMIC);
-
-                       if (!copy_info->p_libs[i].p_ips) {
-                               DPRINTF ("No enough memory for copy_info->p_libs[i].p_ips");
-                               return NULL;
-                       }
-
-                       memcpy (copy_info->p_libs[i].p_ips, task_inst_info->p_libs[i].p_ips,
-                                       copy_info->p_libs[i].ips_count * sizeof (us_proc_ip_t));
-                       for (j = 0; j < copy_info->p_libs[i].ips_count; j++) {
-                               // save handlers
-                               entry_save = copy_info->p_libs[i].p_ips[j].jprobe.entry;
-                               pre_entry_save = copy_info->p_libs[i].p_ips[j].jprobe.pre_entry;
-                               handler_save = copy_info->p_libs[i].p_ips[j].retprobe.handler;
-
-                               copy_info->p_libs[i].p_ips[j].installed = 0;
-                               memset(&copy_info->p_libs[i].p_ips[j].jprobe, 0, sizeof(struct jprobe));
-                               memset(&copy_info->p_libs[i].p_ips[j].retprobe, 0, sizeof(struct kretprobe));
-
-                               // restore handlers
-                               copy_info->p_libs[i].p_ips[j].jprobe.entry = entry_save;
-                               copy_info->p_libs[i].p_ips[j].jprobe.pre_entry = pre_entry_save;
-                               copy_info->p_libs[i].p_ips[j].retprobe.handler = handler_save;
-                       }
-
-                       unres_ips_count += copy_info->p_libs[i].ips_count;
-               }
-
-               for (j = 0; j < copy_info->p_libs[i].plt_count; j++)
-               {
-                       copy_info->p_libs[i].p_plt[j].real_func_addr = 0;
+       if (!is_libonly()) {
+               if (task != current) {
+                       printk("ERROR get_proc_probes_by_task: \'task != current\'\n");
+                       return NULL;
                }
 
-               if (copy_info->p_libs[i].vtps_count > 0) {
-                       unres_vtps_count += copy_info->p_libs[i].vtps_count;
-
-                       copy_info->p_libs[i].p_vtps =
-                               kmalloc (copy_info->p_libs[i].vtps_count * sizeof (us_proc_vtp_t), GFP_ATOMIC);
-
-                       if (!copy_info->p_libs[i].p_vtps) {
-                               DPRINTF ("No enough memory for copy_info->p_libs[i].p_vtps");
-                               return NULL;
-                       }
-
-                       memcpy (copy_info->p_libs[i].p_vtps, task_inst_info->p_libs[i].p_vtps,
-                                       copy_info->p_libs[i].vtps_count * sizeof (us_proc_vtp_t));
-                       for (j = 0; j < copy_info->p_libs[i].vtps_count; j++) {
-                               copy_info->p_libs[i].p_vtps[j].installed = 0;
-                               memset (&copy_info->p_libs[i].p_vtps[j].jprobe, 0, sizeof(struct jprobe));
-                       }
-                       unres_vtps_count = copy_info->p_libs[i].vtps_count;
-               }
-
-               copy_info->p_libs[i].m_f_dentry = task_inst_info->p_libs[i].m_f_dentry;
-               copy_info->p_libs[i].loaded = 0;
-
-               copy_info->p_libs[i].vma_start = 0;
-               copy_info->p_libs[i].vma_end = 0;
+               return us_proc_info.pp;
        }
-       copy_info->unres_ips_count = unres_ips_count;
-       copy_info->unres_vtps_count = unres_vtps_count;
-
-       return copy_info;
-}
 
-inst_us_proc_t* get_task_inst_node(struct task_struct *task)
-{
-       struct task_inst_info_node *node, *tnode;
-
-       list_for_each_entry_safe(node, tnode, &task_inst_info_list, plist)
-       {
-               if (node && task && node->tgid == task->tgid) {
-                       return node->task_inst_info;
+       list_for_each_entry_safe(proc_p, tmp, &proc_probes_list, list) {
+               if (proc_p->tgid == task->tgid) {
+                       return proc_p;
                }
        }
+
        return NULL;
 }
 
-void put_task_inst_node(struct task_struct *task, inst_us_proc_t *task_inst_info)
+void add_proc_probes(struct task_struct *task, struct proc_probes *proc_p)
 {
-       struct task_inst_info_node * node;
-
-       node = kmalloc (sizeof(struct task_inst_info_node), GFP_ATOMIC);
-
-       node->tgid = task->tgid;
-       node->task_inst_info = task_inst_info;
-
-       list_add_tail (&(node->plist), &task_inst_info_list);
+       list_add_tail(&proc_p->list, &proc_probes_list);
 }
 
-
-void clear_task_inst_info(void)
+struct proc_probes *get_proc_probes_by_task_or_new(struct task_struct *task)
 {
-       struct list_head *node, *tmp;
+       struct proc_probes *proc_p = get_proc_probes_by_task(task);
+       if (proc_p == NULL) {
+               proc_p = proc_p_copy(us_proc_info.pp, task);
+               add_proc_probes(task, proc_p);
+       }
 
-       list_for_each_safe(node, tmp, &task_inst_info_list)
-               list_del(node);
+       return proc_p;
 }
 
 #ifdef SLP_APP
@@ -545,7 +409,6 @@ static int install_mapped_ips (struct task_struct *task, inst_us_proc_t* task_in
        int i, k, err;
        unsigned long addr;
        unsigned int old_ips_count, old_vtps_count;
-       us_proc_otg_ip_t *p;
        struct task_struct *t;
        struct mm_struct *mm;
 
@@ -617,9 +480,8 @@ static int install_mapped_ips (struct task_struct *task, inst_us_proc_t* task_in
                                                                task_inst_info->p_libs[i].p_ips[k].offset, addr);
                                                        task_inst_info->p_libs[i].p_ips[k].jprobe.kp.addr = (kprobe_opcode_t *) addr;
                                                        task_inst_info->p_libs[i].p_ips[k].retprobe.kp.addr = (kprobe_opcode_t *) addr;
-                                                       task_inst_info->p_libs[i].p_ips[k].installed = 1;
                                                        task_inst_info->unres_ips_count--;
-                                                       err = register_usprobe (task, mm, &task_inst_info->p_libs[i].p_ips[k], atomic, 0);
+                                                       err = register_usprobe(task, &task_inst_info->p_libs[i].p_ips[k], atomic);
                                                        if (err != 0) {
                                                                DPRINTF ("failed to install IP at %lx/%p. Error %d!",
                                                                        task_inst_info->p_libs[i].p_ips[k].offset,
@@ -646,7 +508,7 @@ static int install_mapped_ips (struct task_struct *task, inst_us_proc_t* task_in
                                                        task_inst_info->p_libs[i].p_vtps[k].jprobe.priv_arg = &task_inst_info->p_libs[i].p_vtps[k];
                                                        task_inst_info->p_libs[i].p_vtps[k].installed = 1;
                                                        task_inst_info->unres_vtps_count--;
-                                                       err = dbi_register_ujprobe (task, mm, &task_inst_info->p_libs[i].p_vtps[k].jprobe, atomic);
+                                                       err = dbi_register_ujprobe(task, &task_inst_info->p_libs[i].p_vtps[k].jprobe, atomic);
                                                        if ( err != 0 ) {
                                                                EPRINTF ("failed to install VTP at %p. Error %d!",
                                                                                task_inst_info->p_libs[i].p_vtps[k].jprobe.kp.addr, err);
@@ -705,26 +567,7 @@ static int install_mapped_ips (struct task_struct *task, inst_us_proc_t* task_in
 #endif /* __ANDROID */
                vma = vma->vm_next;
        }
-       list_for_each_entry_rcu (p, &otg_us_proc_info, list) {
-               if (p->ip.installed) {
-                       continue;
-               }
 
-               if (!page_present(mm, p->ip.offset)) {
-                       DPRINTF("Page isn't present for %p.",
-                               p->ip.offset);
-                       continue;
-               }
-               p->ip.installed = 1;
-               err = register_usprobe(task, mm, &p->ip, atomic, 0);
-               if (err != 0) {
-                       DPRINTF("failed to install IP at %lx/%p. Error %d!",
-                               p->ip.offset,
-                               p->ip.jprobe.kp.addr, err);
-                       continue;
-               }
-               task_inst_info->unres_otg_ips_count--;
-       }
        if (!atomic) {
                up_read (&mm->mmap_sem);
                mmput (mm);
@@ -732,72 +575,69 @@ static int install_mapped_ips (struct task_struct *task, inst_us_proc_t* task_in
        return task_inst_info->unres_ips_count + task_inst_info->unres_vtps_count;
 }
 
-static int install_otg_ip(unsigned long addr,
-                     unsigned long pre_handler,
-                     unsigned long jp_handler,
-                     unsigned long rp_handler)
+static void set_mapping_file(struct file_probes *file_p,
+               const struct proc_probes *proc_p,
+               const struct task_struct *task,
+               const struct vm_area_struct *vma);
+
+int install_otg_ip(unsigned long addr,
+                       kprobe_pre_entry_handler_t pre_handler,
+                       unsigned long jp_handler,
+                       kretprobe_handler_t rp_handler)
 {
-       int err;
-       us_proc_otg_ip_t *pprobe;
+       int ret = 0;
        struct task_struct *task = current->group_leader;
        struct mm_struct *mm = task->mm;
 
-       /* Probe preparing */
-       err = add_otg_probe_to_list(addr, &pprobe);
-       if (err) {
-               if (err == 1) {
-                       DPRINTF("OTG probe %p already installed.", addr);
-                       return 0;
-               } else {
-                       DPRINTF("Failed to add new OTG probe, err=%d",err);
-                       return err;
-               }
-       }
-       if (pre_handler) {
-               pprobe->ip.jprobe.pre_entry =
-                       (kprobe_pre_entry_handler_t)pre_handler;
-       } else {
-               pprobe->ip.jprobe.pre_entry =
-                       (kprobe_pre_entry_handler_t)
-                       dbi_ujprobe_event_pre_handler_custom_p;
+       if (mm) {
+               struct vm_area_struct *vma = find_vma(mm, addr);
+               if (vma && (vma->vm_flags & VM_EXEC) &&
+                   vma->vm_file && vma->vm_file->f_dentry) {
+                       unsigned long offset_addr = addr - vma->vm_start;
+                       struct dentry *dentry = vma->vm_file->f_dentry;
+                       char *name = dentry->d_iname;
+                       struct proc_probes *proc_p = get_proc_probes_by_task(task);
+                       struct ip_data pd = {
+                                       .offset = offset_addr,
+                                       .pre_handler = pre_handler,
+                                       .jp_handler = jp_handler,
+                                       .rp_handler = rp_handler,
+                                       .flag_retprobe = 1
+                       };
+
+                       struct file_probes *file_p = proc_p_find_file_p_by_dentry(proc_p, name, dentry);
+                       struct page_probes *page_p = get_page_p(file_p, offset_addr);
+                       struct us_ip *ip = page_p_find_ip(page_p, offset_addr & ~PAGE_MASK);
+
+                       if (!file_p->loaded) {
+                               set_mapping_file(file_p, proc_p, task, vma);
+                               file_p->loaded = 1;
+                       }
 
-       }
-       if (jp_handler) {
-               pprobe->ip.jprobe.entry =
-                       (kprobe_opcode_t *)jp_handler;
-       } else {
-               pprobe->ip.jprobe.entry =
-                       (kprobe_opcode_t *)
-                       dbi_ujprobe_event_handler_custom_p;
-       }
-       if (rp_handler) {
-               pprobe->ip.retprobe.handler =
-                       (kretprobe_handler_t)rp_handler;
-       } else {
-               pprobe->ip.retprobe.handler =
-                       (kretprobe_handler_t)
-                       dbi_uretprobe_event_handler_custom_p;
-       }
+                       if (ip == NULL) {
+                               struct file_probes *file_p = proc_p_find_file_p_by_dentry(proc_p, name, dentry);
+                               file_p_add_probe(file_p, &pd);
 
-       pprobe->tgid = task->tgid;
-       if (!page_present(mm, addr)) {
-               DPRINTF("Page isn't present for %p.", addr);
+                               /* if addr mapping, that probe install, else it be installed in do_page_fault handler */
+                               if (page_present(mm, addr)) {
+                                       ip = page_p_find_ip(page_p, offset_addr & ~PAGE_MASK);
+                                       set_ip_kp_addr(ip, page_p, file_p);
 
-               us_proc_info.unres_otg_ips_count++;
-               /* Probe will be installed in do_page_fault handler */
-               return 0;
-       }
-       DPRINTF("Page present for %p.", addr);
+                                       // TODO: error
+                                       ret = register_usprobe_my(task, ip);
+                                       if (ret == 0) {
+                                               page_p_installed(page_p);
+                                       } else {
+                                               printk("ERROR install_otg_ip: ret=%d\n", ret);
+                                       }
+                               }
+                       }
 
-       /* Probe installing */
-       pprobe->ip.installed = 1;
-       err = register_usprobe(current, mm, &pprobe->ip, 1, 0);
-       if (err != 0) {
-               DPRINTF("failed to install IP at %lx/%p. Error %d!",
-                        addr, pprobe->ip.jprobe.kp.addr, err);
-               return err;
+                       put_page_p(page_p);
+               }
        }
-       return 0;
+
+       return ret;
 }
 EXPORT_SYMBOL_GPL(install_otg_ip);
 
@@ -805,7 +645,6 @@ EXPORT_SYMBOL_GPL(install_otg_ip);
 static int uninstall_mapped_ips (struct task_struct *task,  inst_us_proc_t* task_inst_info, int atomic)
 {
        int i, k, err;
-       us_proc_otg_ip_t *p;
 
        for (i = 0; i < task_inst_info->libs_count; i++)
        {
@@ -815,14 +654,13 @@ static int uninstall_mapped_ips (struct task_struct *task,  inst_us_proc_t* task
                        if (task_inst_info->p_libs[i].p_ips[k].installed)
                        {
                                DPRINTF ("remove IP at %p.", task_inst_info->p_libs[i].p_ips[k].jprobe.kp.addr);
-                               err = unregister_usprobe (task, &task_inst_info->p_libs[i].p_ips[k], atomic);
+                               err = unregister_usprobe (task, &task_inst_info->p_libs[i].p_ips[k], atomic, 0);
                                if (err != 0)
                                {
                                        EPRINTF ("failed to uninstall IP at %p. Error %d!", task_inst_info->p_libs[i].p_ips[k].jprobe.kp.addr, err);
                                        continue;
                                }
                                task_inst_info->unres_ips_count++;
-                               task_inst_info->p_libs[i].p_ips[k].installed = 0;
                        }
                }
                for (k = 0; k < task_inst_info->p_libs[i].vtps_count; k++)
@@ -850,77 +688,12 @@ static int uninstall_mapped_ips (struct task_struct *task,  inst_us_proc_t* task
                }
        }
 #endif /* __ANDROID */
-       list_for_each_entry_rcu (p, &otg_us_proc_info, list) {
-               if (!p->ip.installed) {
-                       continue;
-               }
-               DPRINTF("remove OTG IP at %p.", p->ip.offset);
-               err = unregister_usprobe(task, &p->ip, atomic);
-               if (err != 0) {
-                       EPRINTF("failed to uninstall IP at %p. Error %d!",
-                                p->ip.jprobe.kp.addr, err);
-                       continue;
-               }
-               p->ip.installed = 0;
-       }
 
        DPRINTF ("Ures IPs  %d.", task_inst_info->unres_ips_count);
        DPRINTF ("Ures VTPs %d.", task_inst_info->unres_vtps_count);
        return 0;
 }
 
-void send_sig_jprobe_event_handler (int sig, struct siginfo *info, struct task_struct *t, struct sigpending *signals)
-{
-       int iRet, del = 0;
-       struct task_struct *task;
-       inst_us_proc_t *task_inst_info = NULL;
-
-       //if user-space instrumentation is not set
-       if (!us_proc_info.path)
-           return;
-
-       if (sig != SIGKILL)
-               return;
-
-       if (!strcmp(us_proc_info.path,"*"))
-       {
-               task_inst_info = get_task_inst_node(t);
-               if (task_inst_info)
-               {
-                       iRet = uninstall_mapped_ips (t, task_inst_info, 1);
-                       if (iRet != 0)
-                               EPRINTF ("failed to uninstall IPs (%d)!", iRet);
-                       dbi_unregister_all_uprobes(t, 1);
-                       return;
-               }
-       }
-       else
-       {
-               if (current->tgid != us_proc_info.tgid)
-                       return;
-                       del = 1;
-
-               // look for another process with the same tgid
-               rcu_read_lock ();
-               for_each_process (task)
-               {
-                       if ((task->pid != t->pid) && (task->tgid == us_proc_info.tgid))
-                       {
-                               del = 0;
-                               break;
-                       }
-               }
-               rcu_read_unlock ();
-               if (del)
-               {
-                       DPRINTF ("%s(%d) send_signal SIGKILL for the last target proc %s(%d)",
-                                       current->comm, current->pid, t->comm, t->pid);
-                       iRet = uninstall_mapped_ips (t, &us_proc_info, 1);
-                       if (iRet != 0)
-                               EPRINTF ("failed to uninstall IPs (%d)!", iRet);
-               }
-       }
-}
 static int uninstall_kernel_probe (unsigned long addr, int uflag, int kflag, kernel_probe_t ** pprobe)
 {
        kernel_probe_t *probe = NULL;
@@ -952,15 +725,17 @@ static int uninstall_kernel_probe (unsigned long addr, int uflag, int kflag, ker
        return iRet;
 }
 
+static int uninstall_us_proc_probes(struct task_struct *task, struct proc_probes *proc_p, enum US_FLAGS flag);
+
 int deinst_usr_space_proc (void)
 {
        int iRet = 0, found = 0;
        struct task_struct *task = 0;
        inst_us_proc_t *task_inst_info = NULL;
 
-       //if user-space instrumentation is not set
-       if (!us_proc_info.path)
+       if (!is_us_instrumentation()) {
                return 0;
+       }
 
        iRet = uninstall_kernel_probe (pf_addr, US_PROC_PF_INSTLD,
                        0, &pf_probe);
@@ -987,16 +762,17 @@ int deinst_usr_space_proc (void)
        if (iRet)
                EPRINTF ("uninstall_kernel_probe(do_munmap) result=%d!", iRet);
 
-       if (!strcmp(us_proc_info.path,"*"))
-       {
-               for_each_process (task)
-               {
-                       task_inst_info = get_task_inst_node(task);
-                       if (task_inst_info)
-                       {
-                               iRet = uninstall_mapped_ips (task, task_inst_info, 1);
-                               if (iRet != 0)
-                                       EPRINTF ("failed to uninstall IPs (%d)!", iRet);
+       if (is_libonly()) {
+               struct proc_probes *proc_p;
+
+               for_each_process(task)  {
+                       proc_p = get_proc_probes_by_task(task);
+                       if (proc_p) {
+                               int ret = uninstall_us_proc_probes(task, proc_p, US_UNREGS_PROBE);
+                               if (ret) {
+                                       EPRINTF ("failed to uninstall IPs (%d)!", ret);
+                               }
+
                                dbi_unregister_all_uprobes(task, 1);
                        }
                }
@@ -1018,12 +794,16 @@ int deinst_usr_space_proc (void)
                rcu_read_unlock ();
                if (found)
                {
-                       int i;
+                       int i, ret;
                        // uninstall IPs
-                       iRet = uninstall_mapped_ips (task, &us_proc_info, 0);
-                       if (iRet != 0)
-                       EPRINTF ("failed to uninstall IPs %d!", iRet);
+                       ret = uninstall_us_proc_probes(task, us_proc_info.pp, US_UNREGS_PROBE);
+                       if (ret != 0) {
+                               EPRINTF ("failed to uninstall IPs %d!", ret);
+                       }
+
                        put_task_struct (task);
+
+                       printk("### 1 ### dbi_unregister_all_uprobes:\n");
                        dbi_unregister_all_uprobes(task, 1);
                        us_proc_info.tgid = 0;
                        for(i = 0; i < us_proc_info.libs_count; i++)
@@ -1067,15 +847,16 @@ static int install_kernel_probe (unsigned long addr, int uflag, int kflag, kerne
        return 0;
 }
 
+static void install_proc_probes(struct task_struct *task, struct proc_probes *proc_p, int atomic);
+
 int inst_usr_space_proc (void)
 {
        int ret, i;
        struct task_struct *task = 0;
-       inst_us_proc_t *task_inst_info = NULL;
 
-       //if user-space instrumentation is not set
-       if (!us_proc_info.path)
+       if (!is_us_instrumentation()) {
                return 0;
+       }
 
        DPRINTF("User space instr");
 
@@ -1122,32 +903,27 @@ int inst_usr_space_proc (void)
         * 2) if process is not running - make sure that do_page_fault handler is installed
         * */
 
-       if (!strcmp(us_proc_info.path,"*"))
+       if (is_libonly())
        {
-               clear_task_inst_info();
+               // FIXME: clear_task_inst_info();
                for_each_process (task) {
+                       struct proc_probes *proc_p;
+
                        if (task->flags & PF_KTHREAD){
                                DPRINTF("ignored kernel thread %d\n",
                                        task->pid);
                                continue;
                        }
 
-                       task_inst_info = get_task_inst_node(task);
-                       if (!task_inst_info) {
-                               task_inst_info =
-                                       copy_task_inst_info(task,
-                                                           &us_proc_info);
-                               put_task_inst_node(task, task_inst_info);
-                       }
+                       proc_p = get_proc_probes_by_task_or_new(task);
                        DPRINTF("trying process");
 #ifdef __ANDROID
                        if (is_java_inst_enabled()) {
                                find_libdvm_for_task(task, task_inst_info);
                        }
 #endif /* __ANDROID */
-                       install_mapped_ips (task, task_inst_info, 1);
+                       install_proc_probes(task, proc_p, 1);
                        //put_task_struct (task);
-                       task_inst_info = NULL;
                }
        }
        else
@@ -1162,7 +938,7 @@ int inst_usr_space_proc (void)
                                find_libdvm_for_task(task, &us_proc_info);
                        }
 #endif /* __ANDROID */
-                       install_mapped_ips (task, &us_proc_info, 0);
+                       install_proc_probes(task, us_proc_info.pp, 0);
                        put_task_struct (task);
                }
        }
@@ -1207,106 +983,366 @@ int inst_usr_space_proc (void)
        return 0;
 }
 
-void do_page_fault_ret_pre_code (void)
+#include "../../tools/gpmu/probes/entry_data.h"
+
+extern storage_arg_t sa_dpf;
+
+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;
+EXPORT_SYMBOL_GPL (imi_sum_time);
+EXPORT_SYMBOL_GPL (imi_sum_hit);
+
+static void set_mapping_file(struct file_probes *file_p,
+               const struct proc_probes *proc_p,
+               const struct task_struct *task,
+               const struct vm_area_struct *vma)
+{
+       int app_flag = (vma->vm_file->f_dentry == proc_p->dentry);
+       char *p;
+       // if we installed something, post library info for those IPs
+       p = strrchr(file_p->path, '/');
+       if(!p) {
+               p = file_p->path;
+       } else {
+               p++;
+       }
+
+       file_p->vm_start = vma->vm_start;
+       file_p->vm_end = vma->vm_end;
+
+       pack_event_info(DYN_LIB_PROBE_ID, RECORD_ENTRY, "dspdd",
+                       task->tgid, p, vma->vm_start,
+                       vma->vm_end - vma->vm_start, app_flag);
+}
+
+void print_vma(struct mm_struct *mm);
+
+static int register_us_page_probe(struct page_probes *page_p,
+               const struct file_probes *file_p,
+               const struct task_struct *task)
+{
+       int err = 0;
+       struct us_ip *ip;
+
+       spin_lock(&page_p->lock);
+
+       if (page_p_is_install(page_p)) {
+               printk("page %x in %s task[tgid=%u, pid=%u] already installed\n",
+                               page_p->offset, file_p->dentry->d_iname, task->tgid, task->pid);
+               print_vma(task->mm);
+               return 0;
+       }
+
+       page_p_assert_install(page_p);
+       page_p_set_all_kp_addr(page_p, file_p);
+
+       list_for_each_entry(ip, &page_p->ip_list, list) {
+               err = register_usprobe_my(task, ip);
+               if (err != 0) {
+                       //TODO: ERROR
+                       return err;
+               }
+       }
+
+       page_p_installed(page_p);
+
+       spin_unlock(&page_p->lock);
+
+       return 0;
+}
+
+static int unregister_us_page_probe(const struct task_struct *task,
+               struct page_probes *page_p, enum US_FLAGS flag)
+{
+       int err = 0;
+       struct us_ip *ip;
+
+       spin_lock(&page_p->lock);
+       if (!page_p_is_install(page_p)) {
+               spin_unlock(&page_p->lock);
+               return 0;
+       }
+
+       list_for_each_entry(ip, &page_p->ip_list, list) {
+               err = unregister_usprobe_my(task, ip, flag);
+               if (err != 0) {
+                       //TODO: ERROR
+                       break;
+               }
+       }
+
+       if (flag != US_DISARM) {
+               page_p_uninstalled(page_p);
+       }
+       spin_unlock(&page_p->lock);
+
+       return err;
+}
+
+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 void install_page_probes(unsigned long page, struct task_struct *task, struct proc_probes *proc_p, int atomic)
+{
+       int lock;
        struct mm_struct *mm;
+       struct vm_area_struct *vma;
+
+       mm_read_lock(task, mm, atomic, lock);
+
+       vma = find_vma(mm, page);
+       if (vma && check_vma(vma)) {
+               struct file_probes *file_p = proc_p_find_file_p(proc_p, vma);
+               if (file_p) {
+                       struct page_probes *page_p;
+                       if (!file_p->loaded) {
+                               set_mapping_file(file_p, proc_p, task, vma);
+                               file_p->loaded = 1;
+                       }
+
+                       page_p = file_p_find_page_p_mapped(file_p, page);
+                       if (page_p) {
+                               register_us_page_probe(page_p, file_p, task);
+                       }
+               }
+       }
+
+       mm_read_unlock(mm, atomic, lock);
+}
+
+static void install_file_probes(struct task_struct *task, struct mm_struct *mm, struct file_probes *file_p)
+{
+       struct page_probes *page_p = NULL;
+       struct hlist_node *node = NULL;
+       struct hlist_head *head = NULL;
+       int i, table_size = (1 << file_p->page_probes_hash_bits);
+
+       for (i = 0; i < table_size; ++i) {
+               head = &file_p->page_probes_table[i];
+               hlist_for_each_entry_rcu(page_p, node, head, hlist) {
+                       if (page_present(mm, page_p->offset)) {
+                               register_us_page_probe(page_p, file_p, task);
+                       }
+               }
+       }
+}
+
+static void install_proc_probes(struct task_struct *task, struct proc_probes *proc_p, int atomic)
+{
+       int lock;
+       struct vm_area_struct *vma;
+       struct mm_struct *mm;
+
+       mm_read_lock(task, mm, atomic, lock);
+
+       for (vma = mm->mmap; vma; vma = vma->vm_next) {
+               if (check_vma(vma)) {
+                       struct file_probes *file_p = proc_p_find_file_p(proc_p, vma);
+                       if (file_p) {
+                               if (!file_p->loaded) {
+                                       set_mapping_file(file_p, proc_p, task, vma);
+                                       file_p->loaded = 1;
+                               }
+
+                               install_file_probes(task, mm, file_p);
+                       }
+               }
+       }
+
+       mm_read_unlock(mm, atomic, lock);
+}
+
+static int check_install_pages_in_file(struct task_struct *task, struct file_probes *file_p)
+{
+       int i;
+       int table_size = (1 << file_p->page_probes_hash_bits);
+       struct page_probes *page_p;
+       struct hlist_node *node, *tmp;
+       struct hlist_head *head;
+
+       for (i = 0; i < table_size; ++i) {
+               head = &file_p->page_probes_table[i];
+               hlist_for_each_entry_safe (page_p, node, tmp, head, hlist) {
+                       if (page_p->install) {
+                               return 1;
+                       }
+               }
+       }
+
+       return 0;
+}
+
+static int unregister_us_file_probes(struct task_struct *task, struct file_probes *file_p, enum US_FLAGS flag)
+{
+       int i, err = 0;
+       int table_size = (1 << file_p->page_probes_hash_bits);
+       struct page_probes *page_p;
+       struct hlist_node *node, *tmp;
+       struct hlist_head *head;
+
+       for (i = 0; i < table_size; ++i) {
+               head = &file_p->page_probes_table[i];
+               hlist_for_each_entry_safe (page_p, node, tmp, head, hlist) {
+                       err = unregister_us_page_probe(task, page_p, flag);
+                       if (err != 0) {
+                               // TODO: ERROR
+                               return err;
+                       }
+               }
+       }
+
+       if (flag != US_DISARM) {
+               file_p->loaded = 0;
+       }
+
+       return err;
+}
+
+static int uninstall_us_proc_probes(struct task_struct *task, struct proc_probes *proc_p, enum US_FLAGS flag)
+{
+       int err;
+       struct file_probes *file_p;
+
+       list_for_each_entry_rcu(file_p, &proc_p->file_list, list) {
+               err = unregister_us_file_probes(task, file_p, flag);
+               if (err != 0) {
+                       // TODO:
+                       return err;
+               }
+       }
+
+       return err;
+}
+
+static pid_t find_proc_by_task(const struct task_struct *task, const struct dentry *dentry)
+{
+       struct vm_area_struct *vma;
+       struct mm_struct *mm = task->active_mm;
+       if (mm == NULL) {
+               return 0;
+       }
+
+       for (vma = mm->mmap; vma; vma = vma->vm_next) {
+               if ((vma->vm_flags & VM_EXECUTABLE) && vma->vm_file) {
+                       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)
+{
+       struct task_struct *task = current->group_leader;
+       struct mm_struct *mm = task->mm;
        struct vm_area_struct *vma = 0;
-       inst_us_proc_t *task_inst_info = NULL;
+       struct proc_probes *proc_p = NULL;
        /*
         * Because process threads have same address space
         * we instrument only group_leader of all this threads
         */
-       struct task_struct *task = current->group_leader;
+       unsigned long addr = 0;
+       int valid_addr;
 
-       //if user-space instrumentation is not set
-       if (!us_proc_info.path)
-               return;
+       // overhead
+       struct timeval imi_tv1;
+       struct timeval imi_tv2;
+#define USEC_IN_SEC_NUM                                1000000
 
        if (task->flags & PF_KTHREAD) {
                DPRINTF("ignored kernel thread %d\n", task->pid);
                return;
        }
 
+       if (!is_us_instrumentation()) {
+               return;
+       }
 
-       if (!strcmp(us_proc_info.path,"*"))
-       {
-               task_inst_info = get_task_inst_node(task);
-               if (!task_inst_info)
-               {
-                       task_inst_info = copy_task_inst_info(task,
-                                                            &us_proc_info);
-                       put_task_inst_node(task, task_inst_info);
-#ifdef __ANDROID
-                       if (is_java_inst_enabled()) {
-                               find_libdvm_for_task(task, task_inst_info);
-                       }
-#endif /* __ANDROID */
-               }
-               install_mapped_ips (task, task_inst_info, 1);
+       addr = (unsigned long)swap_get_entry_data(&sa_dpf);
+
+       if (addr == 0) {
+               printk("WARNING: do_page_fault_ret_pre_code addr = 0\n");
                return;
        }
 
-       task_inst_info = &us_proc_info;
-       //DPRINTF("do_page_fault from proc %d-%d-%d", current->pid, task_inst_info->tgid, task_inst_info->unres_ips_count);
-       if (!is_java_inst_enabled()
-           && (task_inst_info->unres_ips_count + task_inst_info->unres_vtps_count
-               + task_inst_info->unres_otg_ips_count) == 0)
-       {
-               //DPRINTF("do_page_fault: there no unresolved IPs");
+
+
+
+       valid_addr = mm && page_present(mm, addr);
+       if (!valid_addr) {
                return;
        }
 
-       if (task_inst_info->tgid == 0)
-       {
-               mm = task->active_mm;
-               if (mm)
-               {
-//                     down_read (&mm->mmap_sem);
-                       vma = mm->mmap;
-                       while (vma)
-                       {
-                               if ((vma->vm_flags & VM_EXECUTABLE) && vma->vm_file)
-                               {
-                                       if (vma->vm_file->f_dentry == task_inst_info->m_f_dentry)
-                                       {
-                                               break;
-                                       }
-#ifdef SLP_APP
-                                       if (is_slp_app_with_dentry(vma, task_inst_info->m_f_dentry)) {
-                                               break;
-                                       }
-#endif /* SLP_APP */
-#ifdef ANDROID_APP
-                                       if (is_android_app_with_dentry(vma, task_inst_info->m_f_dentry)) {
-                                               break;
-                                       }
-#endif /* ANDROID_APP */
-                               }
-                               vma = vma->vm_next;
+       if (is_libonly()) {
+               proc_p = get_proc_probes_by_task_or_new(task);
+       } else {
+               // find task
+               if (us_proc_info.tgid == 0) {
+                       pid_t tgid = find_proc_by_task(task, us_proc_info.m_f_dentry);
+                       if (tgid) {
+                               us_proc_info.tgid = gl_nNotifyTgid = tgid;
                        }
-//                     up_read (&mm->mmap_sem);
-//                     mmput (mm);
-               } else {
-                       //                      DPRINTF ("proc %s/%d has no mm", current->comm, current->pid);
                }
-               if (vma)
-               {
-                    DPRINTF ("do_page_fault found target proc %s(%d)", task->comm, task->pid);
-                    task_inst_info->tgid = task->pid;
-                    gl_nNotifyTgid = task->tgid;
+
+               if (us_proc_info.tgid == task->tgid) {
+                       proc_p = us_proc_info.pp;
                }
        }
-       if (task_inst_info->tgid == task->tgid)
-       {
-               //DPRINTF("do_page_fault from target proc %d", task_inst_info->tgid);
+
+       if (proc_p) {
+               unsigned long page = addr & PAGE_MASK;
+
 #ifdef __ANDROID
                if (is_java_inst_enabled()) {
                        find_libdvm_for_task(task, &us_proc_info);
                }
 #endif /* __ANDROID */
-               install_mapped_ips (task, &us_proc_info, 1);
+
+               // overhead
+               do_gettimeofday(&imi_tv1);
+               install_page_probes(page, task, proc_p, 1);
+               do_gettimeofday(&imi_tv2);
+               imi_sum_hit++;
+               imi_sum_time += ((imi_tv2.tv_sec - imi_tv1.tv_sec) *  USEC_IN_SEC_NUM +
+                               (imi_tv2.tv_usec - imi_tv1.tv_usec));
        }
-       //DPRINTF("do_page_fault from proc %d-%d exit", task->pid, task_inst_info->pid);
 }
 
 EXPORT_SYMBOL_GPL(do_page_fault_ret_pre_code);
@@ -1318,88 +1354,69 @@ void do_exit_probe_pre_code (void)
 }
 EXPORT_SYMBOL_GPL(do_exit_probe_pre_code);
 
-static int check_addr(unsigned long addr, unsigned long start, size_t len)
+int check_vma_area(struct vm_area_struct *vma, unsigned long start, unsigned long end)
 {
-       if ((addr >= start) && (addr < start + (unsigned long)len)) {
-               return 1;
-       }
-
-       return 0;
+       return (vma->vm_start >= start && vma->vm_end <= end);
 }
 
-static int remove_unmap_probes(struct task_struct *task, inst_us_proc_t* task_inst_info, unsigned long start, size_t len)
+void print_vma(struct mm_struct *mm)
 {
-       int i, k, err;
-       us_proc_otg_ip_t *p;
-       unsigned long addr;
-       const int atomic = 1;
-
-       for (i = 0; i < task_inst_info->libs_count; ++i) {
-               for (k = 0; k < task_inst_info->p_libs[i].ips_count; ++k) {
-                       if (task_inst_info->p_libs[i].p_ips[k].installed) {
-                               addr = task_inst_info->p_libs[i].p_ips[k].jprobe.kp.addr;
-                               if (check_addr(addr, start, len)) {
-                                       err = unregister_usprobe(task, &task_inst_info->p_libs[i].p_ips[k], atomic);
-                                       if (err != 0) {
-                                               EPRINTF("failed to uninstall IP at %p. Error %d!", task_inst_info->p_libs[i].p_ips[k].jprobe.kp.addr, err);
-                                               continue;
-                                       }
-                                       task_inst_info->unres_ips_count++;
-                                       task_inst_info->p_libs[i].p_ips[k].installed = 0;
-                               }
-                       }
-               }
-               for (k = 0; k < task_inst_info->p_libs[i].vtps_count; ++k) {
-                       if (task_inst_info->p_libs[i].p_vtps[k].installed) {
-                               addr = task_inst_info->p_libs[i].p_vtps[k].jprobe.kp.addr;
-                               if (check_addr(addr, start, len)) {
-                                       dbi_unregister_ujprobe(task, &task_inst_info->p_libs[i].p_vtps[k].jprobe, atomic);
-                                       task_inst_info->unres_vtps_count++;
-                                       task_inst_info->p_libs[i].p_vtps[k].installed = 0;
-                               }
-                       }
-               }
+       struct vm_area_struct *vma;
+       printk("### print_vma: START\n");\
+       printk("### print_vma: START\n");
+
+       for (vma = mm->mmap; vma; vma = vma->vm_next) {
+               char *x = vma->vm_flags & VM_EXEC ? "x" : "-";
+               char *r = vma->vm_flags & VM_READ ? "r" : "-";
+               char *w = vma->vm_flags & VM_WRITE ? "w" : "-";
+               char *name = vma->vm_file ? vma->vm_file->f_dentry->d_iname : "N/A";
+
+               printk("### [%8x..%8x] %s%s%s pgoff=\'%8u\' %s\n",
+                               vma->vm_start, vma->vm_end, x, r, w, vma->vm_pgoff, name);
        }
-#ifdef __ANDROID
-       if (is_java_inst_enabled()) {
-               us_proc_ip_t *entp = &task_inst_info->libdvm_entry_ip;
-               if (entp->installed) {
-                       addr = entp->jprobe.kp.addr;
-                       if (check_addr(addr, start, len)) {
-                               unregister_usprobe(task, entp, atomic);
-                               entp->installed = 0;
-                       }
-               }
-               us_proc_ip_t *retp = &task_inst_info->libdvm_return_ip;
-               if (retp->installed) {
-                       addr = retp->jprobe.kp.addr;
-                       if (check_addr(addr, start, len)) {
-                               unregister_usprobe(task, retp, atomic);
-                               retp->installed = 0;
-                       }
-               }
+       printk("### print_vma:  END\n");
+}
+
+static int remove_unmap_probes(struct task_struct *task, struct proc_probes *proc_p, unsigned long start, size_t len)
+{
+       struct mm_struct *mm = task->mm;
+       struct vm_area_struct *vma;
+       unsigned long end, pointer, step;
+
+       if ((start & ~PAGE_MASK) || start > TASK_SIZE || len > TASK_SIZE - start) {
+               return -EINVAL;
        }
-#endif /* __ANDROID */
 
-       // remove OTG-probes
-       list_for_each_entry_rcu (p, &otg_us_proc_info, list) {
-               if (!p->ip.installed) {
-                       continue;
-               }
+       if ((len = PAGE_ALIGN(len)) == 0) {
+               return -EINVAL;
+       }
 
-               addr = p->ip.jprobe.kp.addr;
-               if (check_addr(addr, start, len) == 0) {
-                       continue;
-               }
+       vma = find_vma(mm, start);
+       if (vma && check_vma(vma)) {
+               struct file_probes *file_p;
+               unsigned long end = start + len;
+
+               file_p = proc_p_find_file_p(proc_p, vma);
+               if (file_p) {
+                       if (vma->vm_start == start || vma->vm_end == end) {
+                               unregister_us_file_probes(task, file_p, US_NOT_RP2);
+                               file_p->loaded = 0;
+                       } else {
+                               unsigned long page;
+                               struct page_probes *page_p;
+
+                               for (page = vma->vm_start; page < vma->vm_end; page += PAGE_SIZE) {
+                                       page_p = file_p_find_page_p_mapped(file_p, page);
+                                       if (page_p) {
+                                               unregister_us_page_probe(task, page_p, US_NOT_RP2);
+                                       }
+                               }
 
-               err = unregister_usprobe(task, &p->ip, atomic);
-               if (err != 0) {
-                       EPRINTF("failed to uninstall IP at %p. Error %d!",
-                                p->ip.jprobe.kp.addr, err);
-                       continue;
+                               if (check_install_pages_in_file(task, file_p)) {
+                                       file_p->loaded = 0;
+                               }
+                       }
                }
-               p->ip.installed = 0;
-               remove_otg_probe_from_list(p->ip.offset);
        }
 
        return 0;
@@ -1407,104 +1424,75 @@ static int remove_unmap_probes(struct task_struct *task, inst_us_proc_t* task_in
 
 void do_munmap_probe_pre_code(struct mm_struct *mm, unsigned long start, size_t len)
 {
-       inst_us_proc_t *task_inst_info = NULL;
+       struct proc_probes *proc_p = NULL;
        struct task_struct *task = current;
 
        //if user-space instrumentation is not set
-       if (!us_proc_info.path || task->tgid != task->pid)
+       if (!is_us_instrumentation()) {
                return;
+       }
 
-       if (!strcmp(us_proc_info.path,"*")) {
-               task_inst_info = get_task_inst_node(task);
+       if (is_libonly()) {
+               proc_p = get_proc_probes_by_task(task);
        } else {
                if (task->tgid == us_proc_info.tgid) {
-                       task_inst_info = &us_proc_info;
+                       proc_p = us_proc_info.pp;
                }
        }
 
-       if (task_inst_info) {
-               remove_unmap_probes(task, task_inst_info, start, len);
+       if (proc_p) {
+               if (remove_unmap_probes(task, proc_p, start, len)) {
+                       printk("ERROR do_munmap: start=%x, len=%x\n", start, len);
+               }
        }
 }
 EXPORT_SYMBOL_GPL(do_munmap_probe_pre_code);
 
 void mm_release_probe_pre_code(void)
 {
-       int iRet, del = 0;
-       struct task_struct *task;
-       inst_us_proc_t *task_inst_info = NULL;
+       struct task_struct *task = current;
+       struct proc_probes *proc_p = NULL;
 
-       //if user-space instrumentation is not set
-       if (!us_proc_info.path || current->tgid != current->pid)
+       if (!is_us_instrumentation() || task->tgid != task->pid) {
                return;
+       }
 
-       if (!strcmp(us_proc_info.path,"*"))
-       {
-               task_inst_info = get_task_inst_node(current);
-               if (task_inst_info)
-               {
-                       iRet = uninstall_mapped_ips (current, task_inst_info, 1);
-                       if (iRet != 0)
-                               EPRINTF ("failed to uninstall IPs (%d)!", iRet);
-                       dbi_unregister_all_uprobes(current, 1);
+       if (is_libonly()) {
+               proc_p = get_proc_probes_by_task(task);
+       } else {
+               if (task->tgid == us_proc_info.tgid) {
+                       proc_p = get_proc_probes_by_task(task);
+                       us_proc_info.tgid = 0;
                }
        }
-       else
-       {
-               if (current->tgid != us_proc_info.tgid)
-                       return;
-                       del = 1;
-               // look for another process with the same tgid
-               rcu_read_lock ();
-               for_each_process (task)
-               {
-                       if ((task->pid != current->pid) && (task->tgid == us_proc_info.tgid))
-                       {
-                               del = 0;
-                               break;
-                       }
-               }
-               rcu_read_unlock ();
-               if (del)
-               {
-                       int i;
-                       iRet = uninstall_mapped_ips (current, &us_proc_info, 1);
-                       if (iRet != 0)
-                               EPRINTF ("failed to uninstall IPs (%d)!", iRet);
-                       dbi_unregister_all_uprobes(current, 1);
-                       us_proc_info.tgid = 0;
-                       for(i = 0; i < us_proc_info.libs_count; i++)
-                               us_proc_info.p_libs[i].loaded = 0;
+
+       if (proc_p) {
+               int ret = uninstall_us_proc_probes(task, proc_p, US_NOT_RP2);
+               if (ret != 0) {
+                       EPRINTF ("failed to uninstall IPs (%d)!", ret);
                }
+
+               dbi_unregister_all_uprobes(task, 1);
        }
 }
 EXPORT_SYMBOL_GPL(mm_release_probe_pre_code);
 
 
-static void recover_child(struct task_struct *child_task, inst_us_proc_t *parent_iup)
+static void recover_child(struct task_struct *child_task, struct proc_probes *proc_p)
 {
-       int i, k;
-       for(i = 0; i < parent_iup->libs_count; ++i)
-       {
-               for(k = 0; k < parent_iup->p_libs[i].ips_count; ++k)
-                       if(parent_iup->p_libs[i].p_ips[k].installed)
-                               arch_disarm_uprobe(&parent_iup->p_libs[i].p_ips[k].jprobe.kp, child_task);
-
-               for(k = 0; k < parent_iup->p_libs[i].vtps_count; ++k)
-                       if(parent_iup->p_libs[i].p_vtps[k].installed)
-                               arch_disarm_uprobe(&parent_iup->p_libs[i].p_vtps[k].jprobe.kp, child_task);
-       }
+       uninstall_us_proc_probes(child_task, proc_p, US_DISARM);
 }
 
 static void rm_uprobes_child(struct task_struct *new_task)
 {
-       if(!strcmp(us_proc_info.path, "*")) {
-               inst_us_proc_t *task_inst_info = get_task_inst_node(current);
-               if(task_inst_info)
-                       recover_child(new_task, task_inst_info);
+       if (is_libonly()) {
+               struct proc_probes *proc_p = get_proc_probes_by_task(current);
+               if(proc_p) {
+                       recover_child(new_task, proc_p);
+               }
        } else {
                if(us_proc_info.tgid == current->tgid) {
-                       recover_child(new_task, &us_proc_info);
+                       recover_child(new_task, us_proc_info.pp);
                }
        }
 }
@@ -1519,13 +1507,13 @@ void copy_process_ret_pre_code(struct task_struct *p)
 }
 
 
-DEFINE_PER_CPU (us_proc_ip_t *, gpCurIp) = NULL;
+DEFINE_PER_CPU(struct us_ip *, gpCurIp) = NULL;
 EXPORT_PER_CPU_SYMBOL_GPL(gpCurIp);
 DEFINE_PER_CPU(struct pt_regs *, gpUserRegs) = NULL;
 EXPORT_PER_CPU_SYMBOL_GPL(gpUserRegs);
 
 
-unsigned long ujprobe_event_pre_handler (us_proc_ip_t * ip, struct pt_regs *regs)
+unsigned long ujprobe_event_pre_handler(struct us_ip *ip, struct pt_regs *regs)
 {
        __get_cpu_var (gpCurIp) = ip;
        __get_cpu_var (gpUserRegs) = regs;
@@ -1538,7 +1526,7 @@ int handle_java_event(unsigned long addr)
        unsigned long start = 0;
        struct pt_regs *regs = __get_cpu_var(gpUserRegs);
 
-       if (!strcmp(us_proc_info.path, "*")) {
+       if (is_libonly()) {
                /* TODO: some stuff here */
        } else {
                start = us_proc_info.libdvm_start;
@@ -1581,7 +1569,7 @@ int handle_java_event(unsigned long addr)
 
 void ujprobe_event_handler (unsigned long arg1, unsigned long arg2, unsigned long arg3, unsigned long arg4, unsigned long arg5, unsigned long arg6)
 {
-       us_proc_ip_t *ip = __get_cpu_var (gpCurIp);
+       struct us_ip *ip = __get_cpu_var(gpCurIp);
        unsigned long addr = (unsigned long)ip->jprobe.kp.addr;
 
 #ifdef __ANDROID
@@ -1606,82 +1594,48 @@ void ujprobe_event_handler (unsigned long arg1, unsigned long arg2, unsigned lon
        dbi_uprobe_return ();
 }
 
-void find_plt_address(unsigned long addr)
+void send_plt(struct us_ip *ip)
 {
-       inst_us_proc_t *task_inst_info = NULL;
-       int i;
-       unsigned real_addr;
-       struct vm_area_struct *vma;
-       us_proc_lib_t *p_lib = NULL;
-       char *szLibPath = NULL;
+       unsigned long addr = (unsigned long)ip->jprobe.kp.addr;
+       struct vm_area_struct *vma = find_vma(current->mm, addr);
 
-       // Search for library structure to check whether this function plt or not
-       if (strcmp(us_proc_info.path, "*")){
-       // If app lib instrumentation
-               task_inst_info = &us_proc_info;
-       } else {
-       // If lib only instrumentation
-               task_inst_info = get_task_inst_node(current);
-       }
-       if ((task_inst_info != NULL) && (task_inst_info->is_plt != 0)) {
-               for (i = 0; i < task_inst_info->libs_count; i++)
-               {
-                       if ((task_inst_info->p_libs[i].loaded)
-                               && (task_inst_info->p_libs[i].plt_count > 0)
-                               && (addr > task_inst_info->p_libs[i].vma_start)
-                               && (addr < task_inst_info->p_libs[i].vma_end))
-                       {
-                               p_lib = &(task_inst_info->p_libs[i]);
-                               break;
-                       }
+       if (vma && check_vma(vma)) {
+               char *name = NULL;
+               unsigned long real_addr;
+               unsigned long real_got = vma->vm_flags & VM_EXECUTABLE ?
+                               ip->got_addr :
+                               ip->got_addr + vma->vm_start;
+
+               if (!read_proc_vm_atomic(current, real_got, &real_addr, sizeof(real_addr))) {
+                       printk("Failed to read got %p at memory address %p!\n", ip->got_addr, real_got);
+                       return;
                }
-               if (p_lib != NULL) {
-                       for (i = 0; i < p_lib->plt_count; i++)
-                       {
-                               if (addr == p_lib->p_plt[i].func_addr + p_lib->vma_start) {
-                                       unsigned long real_got;
-                                       if (p_lib->vma_flag & VM_EXECUTABLE) {
-                                               real_got = p_lib->p_plt[i].got_addr;
-                                       } else {
-                                               real_got = p_lib->p_plt[i].got_addr + p_lib->vma_start;
-                                       }
-                                       if (!read_proc_vm_atomic(current, (unsigned long)(real_got), &real_addr, sizeof(unsigned long))) {
-                                               printk("Failed to read got %p at memory address %p!\n", p_lib->p_plt[i].got_addr, real_got);
-                                               return;
-                                       }
-                                       if (real_addr != p_lib->p_plt[i].real_func_addr) {
-                                               p_lib->p_plt[i].real_func_addr =  real_addr;
-                                               vma = find_vma(current->mm, real_addr);
-                                               if ((vma != NULL) && (vma->vm_start <= real_addr) && (vma->vm_end > real_addr)) {
-                                                       if (vma->vm_file != NULL) {
-                                                               szLibPath = &(vma->vm_file->f_dentry->d_iname);
-                                                       }
-                                               } else {
-                                                       printk("Failed to get vma, includes %x address\n", real_addr);
-                                                       return;
-                                               }
-                                               if (szLibPath) {
-                                                       pack_event_info(PLT_ADDR_PROBE_ID, RECORD_RET, "ppsp", addr, real_addr, szLibPath, real_addr - vma->vm_start);
-                                                       return;
-                                               } else {
-                                                       pack_event_info(PLT_ADDR_PROBE_ID, RECORD_RET, "ppp", addr, real_addr, real_addr - vma->vm_start);
-                                                       return;
-                                               }
-                                       } else {
-                                               return;
-                                       }
-                               }
-                       }
+
+               vma = find_vma(current->mm, real_addr);
+               if (vma && (vma->vm_start <= real_addr) && (vma->vm_end > real_addr)) {
+                       name = vma->vm_file ? vma->vm_file->f_dentry->d_iname : NULL;
+               } else {
+                       printk("Failed to get vma, includes %x address\n", real_addr);
+                       return;
+               }
+
+               if (name) {
+                       pack_event_info(PLT_ADDR_PROBE_ID, RECORD_RET, "ppsp", addr, real_addr, name, real_addr - vma->vm_start);
+               } else {
+                       pack_event_info(PLT_ADDR_PROBE_ID, RECORD_RET, "ppp", addr, real_addr, real_addr - vma->vm_start);
                }
        }
 }
 
-int uretprobe_event_handler (struct kretprobe_instance *probe, struct pt_regs *regs, us_proc_ip_t * ip)
+int uretprobe_event_handler(struct kretprobe_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;
 
-       find_plt_address(addr);
+       if (ip->got_addr && ip->flag_got == 0) {
+               send_plt(ip);
+               ip->flag_got = 1;
+       }
 
 #if defined(CONFIG_ARM)
        if (ip->offset & 0x01)
@@ -1698,68 +1652,55 @@ int uretprobe_event_handler (struct kretprobe_instance *probe, struct pt_regs *r
        return 0;
 }
 
-static int register_usprobe (struct task_struct *task, struct mm_struct *mm, us_proc_ip_t * ip, int atomic, kprobe_opcode_t * islot)
+static int register_usprobe(struct task_struct *task, struct us_ip *ip, int atomic)
 {
        int ret = 0;
        ip->jprobe.kp.tgid = task->tgid;
-       //ip->jprobe.kp.addr = (kprobe_opcode_t *) addr;
-       if(!ip->jprobe.entry) {
-               if (dbi_ujprobe_event_handler_custom_p != NULL)
-               {
-                       ip->jprobe.entry = (kprobe_opcode_t *) dbi_ujprobe_event_handler_custom_p;
-                       DPRINTF("Set custom event handler for %x\n", ip->offset);
-               }
-               else
-               {
-                       ip->jprobe.entry = (kprobe_opcode_t *) ujprobe_event_handler;
-                       DPRINTF("Set default event handler for %x\n", ip->offset);
-               }
+
+       if (ip->jprobe.entry == NULL) {
+               ip->jprobe.entry = (kprobe_opcode_t *)ujprobe_event_handler;
+               DPRINTF("Set default event handler for %x\n", ip->offset);
        }
-       if(!ip->jprobe.pre_entry) {
-               if (dbi_ujprobe_event_pre_handler_custom_p != NULL)
-               {
-                       ip->jprobe.pre_entry = (kprobe_pre_entry_handler_t) dbi_ujprobe_event_pre_handler_custom_p;
-                       DPRINTF("Set custom pre handler for %x\n", ip->offset);
-               }
-               else
-               {
-                       ip->jprobe.pre_entry = (kprobe_pre_entry_handler_t) ujprobe_event_pre_handler;
-                       DPRINTF("Set default pre 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;
+               DPRINTF("Set default pre handler for %x\n", ip->offset);
        }
+
        ip->jprobe.priv_arg = ip;
-       ret = dbi_register_ujprobe (task, mm, &ip->jprobe, atomic);
-       if (ret)
-       {
+       ret = dbi_register_ujprobe(task, &ip->jprobe, atomic);
+       if (ret) {
                DPRINTF ("dbi_register_ujprobe() failure %d", ret);
                return ret;
        }
 
-       // Mr_Nobody: comment for valencia
-       ip->retprobe.kp.tgid = task->tgid;
-       //ip->retprobe.kp.addr = (kprobe_opcode_t *) addr;
-       if(!ip->retprobe.handler) {
-               if (dbi_uretprobe_event_handler_custom_p != NULL)
-                       ip->retprobe.handler = (kretprobe_handler_t) dbi_uretprobe_event_handler_custom_p;
-               else {
-                       ip->retprobe.handler = (kretprobe_handler_t) uretprobe_event_handler;
-                       //DPRINTF("Failed custom dbi_uretprobe_event_handler_custom_p");
+       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;
+                       DPRINTF("Set default ret event handler for %x\n", ip->offset);
+               }
+
+               ip->retprobe.priv_arg = ip;
+               ret = dbi_register_uretprobe(task, &ip->retprobe, atomic);
+               if (ret) {
+                       EPRINTF ("dbi_register_uretprobe() failure %d", ret);
+                       return ret;
                }
        }
-       ip->retprobe.priv_arg = ip;
-       ret = dbi_register_uretprobe (task, mm, &ip->retprobe, atomic);
-       if (ret)
-       {
-               EPRINTF ("dbi_register_uretprobe() failure %d", ret);
-               return ret;
-       }
+
        return 0;
 }
 
-static int unregister_usprobe (struct task_struct *task, us_proc_ip_t * ip, int atomic)
+static int unregister_usprobe(struct task_struct *task, struct us_ip *ip, int atomic, int not_rp2)
 {
-       dbi_unregister_ujprobe (task, &ip->jprobe, atomic);
-       dbi_unregister_uretprobe (task, &ip->retprobe, atomic);
+       dbi_unregister_ujprobe(task, &ip->jprobe, atomic);
+
+       if (ip->flag_retprobe) {
+               dbi_unregister_uretprobe(task, &ip->retprobe, atomic, not_rp2);
+       }
+
        return 0;
 }
 
@@ -1848,7 +1789,7 @@ int dump_backtrace(probe_id_t probe_id, struct task_struct *task,
 }
 EXPORT_SYMBOL_GPL(dump_backtrace);
 
-unsigned long get_ret_addr(struct task_struct *task, us_proc_ip_t *ip)
+unsigned long get_ret_addr(struct task_struct *task, struct us_ip *ip)
 {
        unsigned long retaddr = 0;
        struct hlist_node *item, *tmp_node;
index 75b7da4..4243201 100644 (file)
@@ -28,6 +28,7 @@ extern int inst_usr_space_proc (void);
 extern int deinst_usr_space_proc (void);
 
 /* Detects when IPs are really loaded into phy mem and installs probes. */
+extern void do_page_fault_j_pre_code(unsigned long addr, unsigned int fsr, struct pt_regs *regs);
 extern void do_page_fault_ret_pre_code (void);
 
 /* Detects when target process exits. */
@@ -75,7 +76,7 @@ extern int dump_backtrace(probe_id_t probe_id, struct task_struct *task,
                void *addr, struct pt_regs *regs, unsigned long sz);
 
 /* Gets current function return address */
-extern unsigned long get_ret_addr(struct task_struct *task, us_proc_ip_t *ip);
+extern unsigned long get_ret_addr(struct task_struct *task, struct us_ip *ip);
 
 #define user_backtrace(size) \
        do { \
index 152fc86..99fc4bc 100644 (file)
@@ -651,7 +651,7 @@ int arch_prepare_uprobe (struct kprobe *p, struct task_struct *task, int atomic)
                return -EINVAL;
        }
        if (!read_proc_vm_atomic (task, (unsigned long) p->addr, &insn, MAX_INSN_SIZE * sizeof(kprobe_opcode_t)))
-               panic ("Failed to read memory %p!\n", p->addr);
+               panic ("Failed to read memory task[tgid=%u, comm=%s] %p!\n", task->tgid, task->comm, p->addr);
        p->opcode = insn[0];
        p->ainsn.insn_arm = get_insn_slot(task, atomic);
        if (!p->ainsn.insn_arm) {
@@ -675,8 +675,8 @@ int arch_prepare_uprobe (struct kprobe *p, struct task_struct *task, int atomic)
                return -EFAULT;
        }
        if ((p->safe_arm == -1) && (p->safe_thumb == -1)) {
-               printk("Error in %s at %d: failed arch_copy_trampoline_*_uprobe() (both) addr=%p, inst=%x\n",
-                       __FILE__, __LINE__, p->addr, p->opcode);
+               printk("Error in %s at %d: failed arch_copy_trampoline_*_uprobe() (both) [tgid=%u, addr=%x, data=%x]\n",
+                               __FILE__, __LINE__, task->tgid, p->addr, p->opcode);
                if (!write_proc_vm_atomic (task, (unsigned long) p->addr, &p->opcode, sizeof (p->opcode)))
                        panic ("Failed to write memory %p!\n", p->addr);
                free_insn_slot(&uprobe_insn_pages, task, p->ainsn.insn_arm);
@@ -1078,6 +1078,7 @@ int kprobe_handler(struct pt_regs *regs)
 #endif
        preempt_disable();
 
+//     printk("### kprobe_handler: task[tgid=%u (%s)] addr=%p\n", tgid, current->comm, addr);
        p = get_kprobe(addr, tgid);
 
        if (user_m && p && (check_validity_insn(p, regs, current) != 0)) {
index 629db58..b98672a 100644 (file)
@@ -189,7 +189,7 @@ static void *page_new(struct task_struct *task, int atomic)
        if (task) {
                return (void *)alloc_user_pages(task, PAGE_SIZE,
                                PROT_EXEC|PROT_READ|PROT_WRITE,
-                               MAP_ANONYMOUS|MAP_SHARED, atomic);
+                               MAP_ANONYMOUS|MAP_PRIVATE/*MAP_SHARED*/, atomic);
        } else {
                return kmalloc(PAGE_SIZE, GFP_ATOMIC);
        }
index 84e14a5..6f79b22 100644 (file)
@@ -194,6 +194,20 @@ struct kretprobe
        struct hlist_head used_instances;
 };
 
+static void retprobe_init(struct kretprobe *rp, kretprobe_handler_t handler)
+{
+       memset(rp, 0, sizeof(*rp));
+       rp->handler = handler;
+}
+
+static struct kretprobe *retprobe_create(kretprobe_handler_t handler)
+{
+       struct kretprobe *rp = kmalloc(sizeof(rp), GFP_ATOMIC);
+       retprobe_init(rp, handler);
+
+       return rp;
+}
+
 struct kretprobe_instance
 {
        // either on free list or used list
index 53af180..3a9a533 100644 (file)
@@ -737,6 +737,70 @@ int get_user_pages_uprobe(struct task_struct *tsk, struct mm_struct *mm,
 #endif
 }
 
+#define ACCESS_PROCESS_OPTIMIZATION 0
+
+#if ACCESS_PROCESS_OPTIMIZATION
+
+#define GET_STEP_X(LEN, STEP) (((LEN) >= (STEP)) ? (STEP) : (LEN) % (STEP))
+#define GET_STEP_4(LEN) GET_STEP_X((LEN), 4)
+
+static void read_data_current(unsigned long addr, void *buf, int len)
+{
+       int step;
+       int pos = 0;
+
+       for (step = GET_STEP_4(len); len; len -= step) {
+               switch (GET_STEP_4(len)) {
+               case 1:
+                       get_user(*(u8 *)(buf + pos), (unsigned long *)(addr + pos));
+                       step = 1;
+                       break;
+
+               case 2:
+               case 3:
+                       get_user(*(u16 *)(buf + pos), (unsigned long *)(addr + pos));
+                       step = 2;
+                       break;
+
+               case 4:
+                       get_user(*(u32 *)(buf + pos), (unsigned long *)(addr + pos));
+                       step = 4;
+                       break;
+               }
+
+               pos += step;
+       }
+}
+
+// not working
+static void write_data_current(unsigned long addr, void *buf, int len)
+{
+       int step;
+       int pos = 0;
+
+       for (step = GET_STEP_4(len); len; len -= step) {
+               switch (GET_STEP_4(len)) {
+               case 1:
+                       put_user(*(u8 *)(buf + pos), (unsigned long *)(addr + pos));
+                       step = 1;
+                       break;
+
+               case 2:
+               case 3:
+                       put_user(*(u16 *)(buf + pos), (unsigned long *)(addr + pos));
+                       step = 2;
+                       break;
+
+               case 4:
+                       put_user(*(u32 *)(buf + pos), (unsigned long *)(addr + pos));
+                       step = 4;
+                       break;
+               }
+
+               pos += step;
+       }
+}
+#endif
 
 int access_process_vm_atomic(struct task_struct *tsk, unsigned long addr, void *buf, int len, int write)
 {
@@ -744,11 +808,21 @@ int access_process_vm_atomic(struct task_struct *tsk, unsigned long addr, void *
        struct vm_area_struct *vma;
        void *old_buf = buf;
 
-       mm = get_task_mm(tsk);
+       if (len <= 0) {
+               return -1;
+       }
+
+#if ACCESS_PROCESS_OPTIMIZATION
+       if (write == 0 && tsk == current) {
+               read_data_current(addr, buf, len);
+               return len;
+       }
+#endif
+
+       mm = tsk->mm; /* function 'get_task_mm' is to be called */
        if (!mm)
                return 0;
 
-       /* down_read(&mm->mmap_sem); */
        /* ignore errors, just check how much was successfully transferred */
        while (len) {
                int bytes, ret, offset;
@@ -780,7 +854,8 @@ int access_process_vm_atomic(struct task_struct *tsk, unsigned long addr, void *
                        if (bytes > PAGE_SIZE-offset)
                                bytes = PAGE_SIZE-offset;
 
-                       maddr = kmap(page);
+                       maddr = kmap_atomic(page);
+
                        if (write) {
                                copy_to_user_page(vma, page, addr,
                                                  maddr + offset, buf, bytes);
@@ -789,15 +864,14 @@ int access_process_vm_atomic(struct task_struct *tsk, unsigned long addr, void *
                                copy_from_user_page(vma, page, addr,
                                                    buf, maddr + offset, bytes);
                        }
-                       kunmap(page);
+
+                       kunmap_atomic(maddr);
                        page_cache_release(page);
                }
                len -= bytes;
                buf += bytes;
                addr += bytes;
        }
-       /* up_read(&mm->mmap_sem); */
-       mmput(mm);
 
        return buf - old_buf;
 }
index 6494ebb..1843ada 100644 (file)
@@ -43,23 +43,92 @@ extern struct kretprobe *sched_rp;
 
 struct hlist_head uprobe_insn_slot_table[KPROBE_TABLE_SIZE];
 
-static
-int __register_uprobe (struct kprobe *p, struct task_struct *task, int atomic, unsigned long called_from)
+
+#define DEBUG_PRINT_HASH_TABLE 0
+
+#if DEBUG_PRINT_HASH_TABLE
+void print_kprobe_hash_table(void)
+{
+       int i;
+       struct hlist_head *head;
+       struct hlist_node *node;
+       struct kprobe *p;
+
+       // print uprobe table
+       for (i = 0; i < KPROBE_TABLE_SIZE; ++i) {
+               head = &kprobe_table[i];
+               hlist_for_each_entry_rcu (p, node, head, is_hlist_arm) {
+                       printk("####### find K tgid=%u, addr=%x\n",
+                                       p->tgid, p->addr);
+               }
+       }
+}
+
+void print_kretprobe_hash_table(void)
+{
+       int i;
+       struct hlist_head *head;
+       struct hlist_node *node;
+       struct kprobe *p;
+
+       // print uprobe table
+       for (i = 0; i < KPROBE_TABLE_SIZE; ++i) {
+               head = &kretprobe_inst_table[i];
+               hlist_for_each_entry_rcu (p, node, head, is_hlist_arm) {
+                       printk("####### find KR tgid=%u, addr=%x\n",
+                                       p->tgid, p->addr);
+               }
+       }
+}
+
+void print_uprobe_hash_table(void)
+{
+       int i;
+       struct hlist_head *head;
+       struct hlist_node *node;
+       struct kprobe *p;
+
+       // print uprobe table
+       for (i = 0; i < KPROBE_TABLE_SIZE; ++i) {
+               head = &uprobe_insn_slot_table[i];
+               hlist_for_each_entry_rcu (p, node, head, is_hlist_arm) {
+                       printk("####### find U tgid=%u, addr=%x\n",
+                                       p->tgid, p->addr);
+               }
+       }
+}
+#endif
+
+
+static void add_uprobe_table(struct kprobe *p)
+{
+#ifdef CONFIG_ARM
+       INIT_HLIST_NODE(&p->is_hlist_arm);
+       hlist_add_head_rcu(&p->is_hlist_arm, &uprobe_insn_slot_table[hash_ptr (p->ainsn.insn_arm, KPROBE_HASH_BITS)]);
+       INIT_HLIST_NODE(&p->is_hlist_thumb);
+       hlist_add_head_rcu(&p->is_hlist_thumb, &uprobe_insn_slot_table[hash_ptr (p->ainsn.insn_thumb, KPROBE_HASH_BITS)]);
+#else /* CONFIG_ARM */
+       INIT_HLIST_NODE(&p->is_hlist);
+       hlist_add_head_rcu(&p->is_hlist, &uprobe_insn_slot_table[hash_ptr (p->ainsn.insn, KPROBE_HASH_BITS)]);
+#endif /* CONFIG_ARM */
+}
+
+
+static int __register_uprobe(struct kprobe *p, struct task_struct *task, int atomic)
 {
        int ret = 0;
        struct kprobe *old_p;
 
-//     printk (">>>>>>>>>>>>>>>>>>>>>>>>>>>>>> %s %d\n", __FUNCTION__, __LINE__);
-
-       if (!p->addr)
+       if (!p->addr) {
                return -EINVAL;
+       }
 
-       DBPRINTF ("p->addr = 0x%p p = 0x%p\n", p->addr, p);
+       DBPRINTF("p->addr = 0x%p p = 0x%p\n", p->addr, p);
 
 // thumb address = address-1;
 #if defined(CONFIG_ARM)
-       if ((unsigned long) p->addr & 0x01)
-       {
+       // TODO: must be corrected in 'bundle'
+       if ((unsigned long) p->addr & 0x01) {
                p->addr = (kprobe_opcode_t *)((unsigned long)p->addr & 0xfffffffe);
        }
 #endif
@@ -75,74 +144,46 @@ int __register_uprobe (struct kprobe *p, struct task_struct *task, int atomic, u
 
        // get the first item
        old_p = get_kprobe(p->addr, p->tgid);
-       if (old_p)
-       {
+       if (old_p) {
 #ifdef CONFIG_ARM
                p->safe_arm = old_p->safe_arm;
                p->safe_thumb = old_p->safe_thumb;
 #endif
-               ret = register_aggr_kprobe (old_p, p);
+               ret = register_aggr_kprobe(old_p, p);
                if (!ret) {
-                       atomic_inc (&kprobe_count);
-#ifdef CONFIG_ARM
-                       INIT_HLIST_NODE (&p->is_hlist_arm);
-                       hlist_add_head_rcu (&p->is_hlist_arm, &uprobe_insn_slot_table[hash_ptr (p->ainsn.insn_arm, KPROBE_HASH_BITS)]);
-                       INIT_HLIST_NODE (&p->is_hlist_thumb);
-                       hlist_add_head_rcu (&p->is_hlist_thumb, &uprobe_insn_slot_table[hash_ptr (p->ainsn.insn_thumb, KPROBE_HASH_BITS)]);
-#else /* CONFIG_ARM */
-                       INIT_HLIST_NODE (&p->is_hlist);
-                       hlist_add_head_rcu (&p->is_hlist, &uprobe_insn_slot_table[hash_ptr (p->ainsn.insn, KPROBE_HASH_BITS)]);
-#endif /* CONFIG_ARM */
+                       atomic_inc(&kprobe_count);
+                       add_uprobe_table(p);
                }
-               DBPRINTF ("goto out\n", ret);
+               DBPRINTF("goto out\n", ret);
                goto out;
        }
 
-//     printk ("================================ %s %d\n", __FUNCTION__, __LINE__);
-       if ((ret = arch_prepare_uprobe (p, task, atomic)) != 0)
-       {
-//             printk ("================================ %s %d\n", __FUNCTION__, __LINE__);
-               DBPRINTF ("goto out\n", ret);
+       ret = arch_prepare_uprobe(p, task, atomic);
+       if (ret) {
+               DBPRINTF("goto out\n", ret);
                goto out;
        }
 
-//     printk ("================================ %s %d\n", __FUNCTION__, __LINE__);
        DBPRINTF ("before out ret = 0x%x\n", ret);
 
-       INIT_HLIST_NODE (&p->hlist);
-//     printk ("================================ %s %d\n", __FUNCTION__, __LINE__);
-       hlist_add_head_rcu (&p->hlist, &kprobe_table[hash_ptr (p->addr, KPROBE_HASH_BITS)]);
-
-#ifdef CONFIG_ARM
-       INIT_HLIST_NODE (&p->is_hlist_arm);
-       INIT_HLIST_NODE (&p->is_hlist_thumb);
-//     printk ("================================ %s %d\n", __FUNCTION__, __LINE__);
-       hlist_add_head_rcu (&p->is_hlist_arm, &uprobe_insn_slot_table[hash_ptr (p->ainsn.insn_arm, KPROBE_HASH_BITS)]);
-       hlist_add_head_rcu (&p->is_hlist_thumb, &uprobe_insn_slot_table[hash_ptr (p->ainsn.insn_thumb, KPROBE_HASH_BITS)]);
-#else /* CONFIG_ARM */
-       INIT_HLIST_NODE (&p->is_hlist);
-       //      printk ("================================ %s %d\n", __FUNCTION__, __LINE__);
-       hlist_add_head_rcu (&p->is_hlist, &uprobe_insn_slot_table[hash_ptr (p->ainsn.insn, KPROBE_HASH_BITS)]);
-#endif /* CONFIG_ARM */
-
-//     printk ("================================ %s %d\n", __FUNCTION__, __LINE__);
-       arch_arm_uprobe (p, task);
-//     printk ("================================ %s %d\n", __FUNCTION__, __LINE__);
+       // TODO: add uprobe (must be in function)
+       INIT_HLIST_NODE(&p->hlist);
+       hlist_add_head_rcu(&p->hlist, &kprobe_table[hash_ptr (p->addr, KPROBE_HASH_BITS)]);
+       add_uprobe_table(p);
+       arch_arm_uprobe(p, task);
 
 out:
-       DBPRINTF ("out ret = 0x%x\n", ret);
-
-//     printk ("<<<<<<<<<<<<<<<<<<<<<<<<<<<<< %s %d\n", __FUNCTION__, __LINE__);
+       DBPRINTF("out ret = 0x%x\n", ret);
        return ret;
 }
 
-void unregister_uprobe (struct kprobe *p, struct task_struct *task, int atomic)
+void unregister_uprobe(struct kprobe *p, struct task_struct *task, int atomic)
 {
        dbi_unregister_kprobe (p, task);
 }
 
 
-int dbi_register_ujprobe (struct task_struct *task, struct mm_struct *mm, struct jprobe *jp, int atomic)
+int dbi_register_ujprobe(struct task_struct *task, struct jprobe *jp, int atomic)
 {
        int ret = 0;
 
@@ -150,15 +191,14 @@ int dbi_register_ujprobe (struct task_struct *task, struct mm_struct *mm, struct
        jp->kp.pre_handler = setjmp_pre_handler;
        jp->kp.break_handler = longjmp_break_handler;
 
-       ret = __register_uprobe (&jp->kp, task, atomic,
-                       (unsigned long) __builtin_return_address (0));
+       ret = __register_uprobe(&jp->kp, task, atomic);
 
        return ret;
 }
 
-void dbi_unregister_ujprobe (struct task_struct *task, struct jprobe *jp, int atomic)
+void dbi_unregister_ujprobe(struct task_struct *task, struct jprobe *jp, int atomic)
 {
-       unregister_uprobe (&jp->kp, task, atomic);
+       unregister_uprobe(&jp->kp, task, atomic);
        /*
         * Here is an attempt to unregister even those probes that have not been
         * installed (hence not added to the hlist).
@@ -180,11 +220,10 @@ void dbi_unregister_ujprobe (struct task_struct *task, struct jprobe *jp, int at
 #endif /* CONFIG_ARM */
 }
 
-int dbi_register_uretprobe (struct task_struct *task, struct mm_struct *mm, struct kretprobe *rp, int atomic)
+int dbi_register_uretprobe(struct task_struct *task, struct kretprobe *rp, int atomic)
 {
-       int ret = 0;
+       int i, ret = 0;
        struct kretprobe_instance *inst;
-       int i;
 
        DBPRINTF ("START\n");
 
@@ -196,64 +235,67 @@ int dbi_register_uretprobe (struct task_struct *task, struct mm_struct *mm, stru
        rp->disarm = 0;
 
        /* Pre-allocate memory for max kretprobe instances */
-       if (rp->maxactive <= 0)
-       {
+       if (rp->maxactive <= 0) {
 #if 1//def CONFIG_PREEMPT
-               rp->maxactive = max (10, 2 * NR_CPUS);
+               rp->maxactive = max(10, 2 * NR_CPUS);
 #else
                rp->maxactive = NR_CPUS;
 #endif
        }
-       INIT_HLIST_HEAD (&rp->used_instances);
-       INIT_HLIST_HEAD (&rp->free_instances);
-       for (i = 0; i < rp->maxactive; i++)
-       {
-               inst = kmalloc (sizeof (struct kretprobe_instance), GFP_KERNEL);
-               if (inst == NULL)
-               {
+
+       INIT_HLIST_HEAD(&rp->used_instances);
+       INIT_HLIST_HEAD(&rp->free_instances);
+
+       for (i = 0; i < rp->maxactive; i++) {
+               inst = kmalloc(sizeof(*inst), GFP_KERNEL);
+               if (inst == NULL) {
                        free_rp_inst (rp);
                        ret = -ENOMEM;
                        goto out;
                }
-               INIT_HLIST_NODE (&inst->uflist);
-               hlist_add_head (&inst->uflist, &rp->free_instances);
+
+               INIT_HLIST_NODE(&inst->uflist);
+               hlist_add_head(&inst->uflist, &rp->free_instances);
        }
 
        rp->nmissed = 0;
 
        /* Establish function exit probe point */
-       if ((ret = arch_prepare_uretprobe (rp, task)) != 0)
+       ret = arch_prepare_uretprobe(rp, task);
+       if (ret) {
                goto out;
+       }
+
        /* Establish function entry probe point */
-       if ((ret = __register_uprobe (&rp->kp, task, atomic,
-                                       (unsigned long) __builtin_return_address (0))) != 0)
-       {
-               free_rp_inst (rp);
+       ret = __register_uprobe(&rp->kp, task, atomic);
+       if (ret) {
+               free_rp_inst(rp);
                goto out;
        }
 
-       arch_arm_uretprobe (rp, task);//vmas[1], pages[1], kaddrs[1]);
+       arch_arm_uretprobe(rp, task);
 out:
        return ret;
 }
 
 
-void dbi_unregister_uretprobe (struct task_struct *task, struct kretprobe *rp, int atomic)
+void dbi_unregister_uretprobe(struct task_struct *task, struct kretprobe *rp, int atomic, int not_rp2)
 {
        unsigned long flags;
        struct kretprobe_instance *ri;
        struct kretprobe *rp2 = NULL;
 
        spin_lock_irqsave (&kretprobe_lock, flags);
-       if (hlist_empty (&rp->used_instances))
-       {
+
+       if (hlist_empty(&rp->used_instances) || not_rp2) {
                struct kprobe *p = &rp->kp;
                // if there are no used retprobe instances (i.e. function is not entered) - disarm retprobe
-               arch_disarm_uretprobe (rp, task);//vmas[1], pages[1], kaddrs[1]);
+               arch_disarm_uretprobe(rp, task);//vmas[1], pages[1], kaddrs[1]);
 #ifdef CONFIG_ARM
                if (!(hlist_unhashed(&p->is_hlist_arm))) {
                        hlist_del_rcu(&p->is_hlist_arm);
                }
+
                if (!(hlist_unhashed(&p->is_hlist_thumb))) {
                        hlist_del_rcu(&p->is_hlist_thumb);
                }
@@ -262,16 +304,13 @@ void dbi_unregister_uretprobe (struct task_struct *task, struct kretprobe *rp, i
                        hlist_del_rcu(&p->is_hlist);
                }
 #endif /* CONFIG_ARM */
-       }
-       else
-       {
+       } else {
                struct kprobe *new_p = NULL;
                struct kprobe *p = &rp->kp;
-               rp2 = clone_kretprobe (rp);
-               if (!rp2)
+               rp2 = clone_kretprobe(rp);
+               if (!rp2) {
                        DBPRINTF ("dbi_unregister_uretprobe addr %p: failed to clone retprobe!", rp->kp.addr);
-               else
-               {
+               } else {
                        DBPRINTF ("initiating deferred retprobe deletion addr %p", rp->kp.addr);
                        printk ("initiating deferred retprobe deletion addr %p\n", rp->kp.addr);
                        arch_disarm_uprobe(&rp->kp, task);
@@ -294,42 +333,35 @@ void dbi_unregister_uretprobe (struct task_struct *task, struct kretprobe *rp, i
                }
 #endif /* CONFIG_ARM */
                new_p = &rp2->kp;
-#ifdef CONFIG_ARM
-               INIT_HLIST_NODE (&new_p->is_hlist_arm);
-               INIT_HLIST_NODE (&new_p->is_hlist_thumb);
-               hlist_add_head_rcu (&new_p->is_hlist_arm, &uprobe_insn_slot_table[hash_ptr (new_p->ainsn.insn_arm, KPROBE_HASH_BITS)]);
-               hlist_add_head_rcu (&new_p->is_hlist_thumb, &uprobe_insn_slot_table[hash_ptr (new_p->ainsn.insn_thumb, KPROBE_HASH_BITS)]);
-#else /* CONFIG_ARM */
-               INIT_HLIST_NODE (&new_p->is_hlist);
-               hlist_add_head_rcu (&new_p->is_hlist, &uprobe_insn_slot_table[hash_ptr (new_p->ainsn.insn, KPROBE_HASH_BITS)]);
-#endif /* CONFIG_ARM */
+               add_uprobe_table(new_p);
        }
 
-       while ((ri = get_used_rp_inst (rp)) != NULL)
-       {
+       while ((ri = get_used_rp_inst(rp)) != NULL) {
                ri->rp = NULL;
                ri->rp2 = rp2;
-               hlist_del (&ri->uflist);
+               hlist_del(&ri->uflist);
        }
-       spin_unlock_irqrestore (&kretprobe_lock, flags);
-       free_rp_inst (rp);
 
-       unregister_uprobe (&rp->kp, task, atomic);
+       spin_unlock_irqrestore(&kretprobe_lock, flags);
+       free_rp_inst(rp);
+
+       unregister_uprobe(&rp->kp, task, atomic);
 }
 
-void dbi_unregister_all_uprobes (struct task_struct *task, int atomic)
+void dbi_unregister_all_uprobes(struct task_struct *task, int atomic)
 {
        struct hlist_head *head;
        struct hlist_node *node, *tnode;
        struct kprobe *p;
        int i;
 
-       for(i = 0; i < KPROBE_TABLE_SIZE; i++){
+       for (i = 0; i < KPROBE_TABLE_SIZE; ++i) {
                head = &kprobe_table[i];
-               hlist_for_each_entry_safe (p, node, tnode, head, hlist){
-                       if(p->tgid == task->tgid){
-                               printk("dbi_unregister_all_uprobes: delete uprobe at %pf for %s/%d\n", p->addr, task->comm, task->pid);
-                               unregister_uprobe (p, task, atomic);
+               hlist_for_each_entry_safe(p, node, tnode, head, hlist) {
+                       if (p->tgid == task->tgid) {
+                               printk("dbi_unregister_all_uprobes: delete uprobe at %p[%x] for %s/%d\n",
+                                               p->addr, p->opcode, task->comm, task->pid);
+                               unregister_uprobe(p, task, atomic);
                        }
                }
        }
@@ -337,19 +369,18 @@ void dbi_unregister_all_uprobes (struct task_struct *task, int atomic)
 
 void init_uprobes_insn_slots(int i)
 {
-       INIT_HLIST_HEAD (&uprobe_insn_slot_table[i]);
+       INIT_HLIST_HEAD(&uprobe_insn_slot_table[i]);
 }
 
-void dbi_uprobe_return (void)
+void dbi_uprobe_return(void)
 {
        dbi_arch_uprobe_return();
 }
 
 
-EXPORT_SYMBOL_GPL (dbi_uprobe_return);
-EXPORT_SYMBOL_GPL (dbi_register_ujprobe);
-EXPORT_SYMBOL_GPL (dbi_unregister_ujprobe);
-EXPORT_SYMBOL_GPL (dbi_register_uretprobe);
-EXPORT_SYMBOL_GPL (dbi_unregister_uretprobe);
-EXPORT_SYMBOL_GPL (dbi_unregister_all_uprobes);
-
+EXPORT_SYMBOL_GPL(dbi_uprobe_return);
+EXPORT_SYMBOL_GPL(dbi_register_ujprobe);
+EXPORT_SYMBOL_GPL(dbi_unregister_ujprobe);
+EXPORT_SYMBOL_GPL(dbi_register_uretprobe);
+EXPORT_SYMBOL_GPL(dbi_unregister_uretprobe);
+EXPORT_SYMBOL_GPL(dbi_unregister_all_uprobes);
index 211cd88..5a8d2c6 100644 (file)
  *
  * 2008-2009    Alexey Gerenkov <a.gerenkov@samsung.com> User-Space
  *              Probes initial implementation; Support x86/ARM/MIPS for both user and kernel spaces.
- * 2010         Ekaterina Gorelkina <e.gorelkina@samsung.com>: redesign module for separating core and arch parts 
+ * 2010         Ekaterina Gorelkina <e.gorelkina@samsung.com>: redesign module for separating core and arch parts
  *
-
  */
 
 #include "dbi_kprobes.h"
 
 
-int dbi_register_ujprobe (struct task_struct *task, struct mm_struct *mm, struct jprobe *jp, int atomic);
-void dbi_unregister_ujprobe (struct task_struct *task, struct jprobe *jp, int atomic);
+int dbi_register_ujprobe(struct task_struct *task, struct jprobe *jp, int atomic);
+void dbi_unregister_ujprobe(struct task_struct *task, struct jprobe *jp, int atomic);
 
-void unregister_uprobe (struct kprobe *p, struct task_struct *task, int atomic);
+void unregister_uprobe(struct kprobe *p, struct task_struct *task, int atomic);
 
-int dbi_register_uretprobe (struct task_struct *task, struct mm_struct *mm, struct kretprobe *rp, int atomic);
-void dbi_unregister_uretprobe (struct task_struct *task, struct kretprobe *rp, int atomic);
+int dbi_register_uretprobe(struct task_struct *task, struct kretprobe *rp, int atomic);
+void dbi_unregister_uretprobe(struct task_struct *task, struct kretprobe *rp, int atomic, int not_rp2);
 
-void dbi_unregister_all_uprobes (struct task_struct *task, int atomic);
+void dbi_unregister_all_uprobes(struct task_struct *task, int atomic);
 
 void init_uprobes_insn_slots(int i) ;
 
-void dbi_uprobe_return (void);
+void dbi_uprobe_return(void);
 
 
 
-#endif /*  _DBI_UPROBES_H */ 
+#endif /*  _DBI_UPROBES_H */