working, owerhead 60 -> 6
authorVyacheslav Cherkashin <v.cherkashin@samsung.com>
Mon, 8 Oct 2012 09:02:21 +0000 (13:02 +0400)
committerVyacheslav Cherkashin <v.cherkashin@samsung.com>
Mon, 8 Oct 2012 09:02:21 +0000 (13:02 +0400)
driver/new_dpf.h
driver/us_proc_inst.c
kprobe/arch/asm-arm/dbi_kprobes.c
kprobe/dbi_uprobes.c

index 2e8ecd2..a077d2d 100644 (file)
@@ -3,16 +3,7 @@
 
 #include <linux/list.h>
 
-
-//struct addr_probe {
-//     unsigned long addr;
-//
-//     struct hlist_node node; // for page_probes
-//};
-
 struct us_proc_ip {
-//     char *name;
-//     int installed;
        struct jprobe jprobe;
        struct kretprobe retprobe;
        unsigned long addr;
@@ -21,16 +12,16 @@ struct us_proc_ip {
 struct page_probes {
        unsigned long page;
        unsigned long offset;
-
-       struct hlist_node node; // for file_probes
-//     struct hlist_head head; // for addr_probe
-
        size_t cnt_ip;
        struct us_proc_ip *ip;
+
+       struct hlist_node node; // for file_probes
 };
 
 struct file_probes {
        struct dentry *dentry;
+       char *path;
+       int loaded;
 
        struct hlist_head head; // for page_probes
 };
@@ -40,24 +31,6 @@ struct proc_probes {
        struct file_probes **fp;
 };
 
-// addr_probe
-//static struct addr_probe *ap_new(unsigned long addr)
-//{
-//     struct addr_probe *obj = kmalloc(sizeof(*obj), GFP_ATOMIC);
-//
-//     if (obj) {
-//             obj->addr = addr;
-//             INIT_HLIST_NODE(&obj->node);
-//     }
-//
-//     return obj;
-//}
-//
-//static void ap_del(struct addr_probe *ap)
-//{
-//     // TODO: del
-//}
-// addr_probe
 
 // page_probes
 static struct page_probes *pp_new(unsigned long page, struct us_proc_ip *ip, size_t cnt)
@@ -89,7 +62,7 @@ static void pp_del(struct page_probes *pp)
 }
 // page_probes
 
-void pp_set_all_kp_addr(struct page_probes *pp)
+static void pp_set_all_kp_addr(struct page_probes *pp)
 {
        struct us_proc_ip *ip;
        unsigned long addr;
@@ -98,16 +71,19 @@ void pp_set_all_kp_addr(struct page_probes *pp)
                ip = &pp->ip[i];
                addr = ip->addr + pp->offset;
                ip->retprobe.kp.addr = ip->jprobe.kp.addr = addr;
+//             printk("###       pp_set_all_kp_addr: addr=%x\n", addr);
        }
 }
 
 // file_probes
-static struct file_probes *fp_new(struct dentry *dentry)
+static struct file_probes *fp_new(us_proc_lib_t *lib)
 {
        struct file_probes *obj = kmalloc(sizeof(*obj), GFP_ATOMIC);
 
        if (obj) {
-               obj->dentry = dentry;
+               obj->dentry = lib->m_f_dentry;
+               obj->path = lib->path;
+               obj->loaded = 0;
                INIT_HLIST_HEAD(&obj->head);
        }
 
@@ -135,7 +111,6 @@ static struct page_probes *fp_find_pp(struct file_probes *fp, unsigned long page
                pp_page = start_addr > pp->page ? start_addr + pp->page : pp->page;
                if (pp_page == page) {
                        pp->offset = start_addr > pp->page ? start_addr : 0;
-//                     pp->
                        return pp;
                }
        }
@@ -213,7 +188,7 @@ struct proc_probes *get_file_probes(const inst_us_proc_t *task_inst_info)
 
                for (i = 0; i < task_inst_info->libs_count; ++i) {
                        us_proc_lib_t *p_libs = &task_inst_info->p_libs[i];
-                       struct file_probes *fp = fp_new(p_libs->m_f_dentry);
+                       struct file_probes *fp = fp_new(p_libs);
                        unsigned long page = 0, min_index = 0, max_index = 0, cnt = 0, idx = 0;
                        struct page_probes *pp = NULL;
                        int k;
@@ -252,28 +227,102 @@ struct proc_probes *get_file_probes(const inst_us_proc_t *task_inst_info)
        return proc_p;
 }
 
-// debug
-//static void print_addr_probe(const struct addr_probe *ap)
-//{
-//     printk("###       addr=%x\n", ap->addr);
-//}
+static int register_usprobe_my(struct task_struct *task, struct mm_struct *mm, struct us_proc_ip *ip)
+{
+//     us_proc_ip_t ip_t;
+//     ip_t.installed = 0;
+//     ip_t.name = 0;
+//     ip_t.jprobe = ip->jprobe;
+//     ip_t.retprobe = ip->retprobe;
+//     ip_t.offset = ip->addr;
+
+
+       us_proc_ip_t *ip_t = kmalloc(sizeof(*ip_t), GFP_ATOMIC);
+       ip_t->installed = 0;
+       ip_t->name = 0;
+       ip_t->jprobe = ip->jprobe;
+       ip_t->retprobe = ip->retprobe;
+       ip_t->offset = ip->addr;
+
+
+       return register_usprobe(task, mm, ip_t, 1, NULL);
+
+
+       int atomic = 1;
+
+       int ret = 0;
+       ip->jprobe.kp.tgid = task->tgid;
+       //ip->jprobe.kp.addr = (kprobe_opcode_t *) addr;
+
+//     printk("### register_usprobe: offset=%x, j_addr=%x, ret_addr=%x\n",
+//                     ip->offset, ip->jprobe.kp.addr, ip->retprobe.kp.addr);
+
+//     return 0;
 
+       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.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);
+               }
+       }
+       ip->jprobe.priv_arg = ip;
+       ret = dbi_register_ujprobe (task, mm, &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");
+               }
+       }
+       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;
+}
+
+// debug
 static void print_page_probes(const struct page_probes *pp)
 {
-//     struct addr_probe *ap = NULL;
-//     struct hlist_node *node = NULL;
-//     struct hlist_head *head = &pp->head;
        int i;
 
        printk("###     page=%x, offset=%x\n", pp->page, pp->offset);
        for (i = 0; i < pp->cnt_ip; ++i) {
-               printk("###       addr[%2d]=%x\n", i, pp->ip[i].addr);
+               printk("###       addr[%2d]=%x, J_addr=%x, R_addr=%x\n",
+                               i, pp->ip[i].addr,
+                               pp->ip[i].jprobe.kp.addr, pp->ip[i].retprobe.kp.addr);
        }
-
-
-//     hlist_for_each_entry(ap, node, head, node) {
-//             print_addr_probe(ap);
-//     }
 }
 
 static void print_file_probes(const struct file_probes *fp)
index c3e3b8d..d04c9d8 100644 (file)
@@ -566,7 +566,7 @@ static int install_mapped_ips (struct task_struct *task, inst_us_proc_t* task_in
        struct mm_struct *mm;
 //     char path_buffer[256];
 
-       printk("### install_mapped_ips:\n");
+//     printk("### install_mapped_ips:\n");
 
        mm = atomic ? task->active_mm : get_task_mm (task);
        if (!mm) {
@@ -1350,6 +1350,61 @@ EXPORT_SYMBOL_GPL (imi_sum_hit);
 
 #include "new_dpf.h"
 
+static void register_us_page_probe(const struct page_probes *page_p,
+               struct file_probes *fp,
+               const struct task_struct *task,
+               const struct mm_struct *mm,
+               const struct vm_area_struct *vma)
+{
+       int err;
+       size_t ii;
+
+//     // overhead
+//     struct timeval imi_tv1;
+//     struct timeval imi_tv2;
+//#define USEC_IN_SEC_NUM                              1000000
+
+       if (!(vma->vm_flags & VM_EXECUTABLE) && !fp->loaded) {
+               char *p;
+               // if we installed something, post library info for those IPs
+               p = strrchr(fp->path, '/');
+               if(!p) {
+                       p = fp->path;
+               } else {
+                       p++;
+               }
+               fp->loaded = 1;
+               pack_event_info (DYN_LIB_PROBE_ID, RECORD_ENTRY, "dspd",
+                               task->tgid, p, vma->vm_start, vma->vm_end-vma->vm_start);
+       }
+
+//     print_page_probes(page_p);
+       pp_set_all_kp_addr(page_p);
+
+       for (ii = 0; ii < page_p->cnt_ip; ++ii) {
+//             do_gettimeofday(&imi_tv1);
+               err = register_usprobe_my(task, mm, &page_p->ip[ii]);
+//             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));
+               if (err != 0) {
+                       //TODO: ERROR
+               }
+       }
+}
+
+static int check_vma(struct vm_area_struct *vma)
+{
+#ifndef __ANDROID
+       return vma->vm_file && !(!(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 *pp, unsigned long addr)
 {
@@ -1357,7 +1412,14 @@ static void install_page_probes(unsigned long page, struct task_struct *task, st
        struct vm_area_struct *vma;
        struct mm_struct *mm = get_task_mm(task);
 
-       printk("### install_page_probes: addr=%x\n", addr);
+
+       // overhead
+       struct timeval imi_tv1;
+       struct timeval imi_tv2;
+#define USEC_IN_SEC_NUM                                1000000
+
+
+//     printk("### install_page_probes: addr=%x\n", addr);
        if (mm == NULL) {
                printk("#### ERRR install_page_probes\n");
                return;
@@ -1365,6 +1427,46 @@ static void install_page_probes(unsigned long page, struct task_struct *task, st
 
 //     printk("### for 1\n");
        down_read(&mm->mmap_sem);
+
+//     do_gettimeofday(&imi_tv1);
+       vma = find_vma(mm, page);
+//     printk("### vma=%p\n", vma);
+
+
+
+       if (vma && check_vma(vma)) {
+               for (i = 0; i < pp->cnt; ++i) {
+                       struct page_probes *page_p;
+                       struct file_probes *fp = pp->fp[i];
+
+                       //TODO: test - try to instrument non-existing libs
+                       if (vma->vm_file->f_dentry != fp->dentry) {
+                               continue;
+                       }
+
+                       page_p = fp_find_pp(fp, page, vma->vm_start);
+
+                       if (page_p) {
+                               register_us_page_probe(page_p, fp, task, mm, vma);
+                       }
+               }
+       }
+
+//     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));
+
+       goto out;
+
+
+
+
+
+
+
+
+
        for (vma = mm->mmap; vma; vma = vma->vm_next) {
 //             printk("### vma: start=%x, end=%x\n", vma->vm_start, vma->vm_end);
 
@@ -1402,75 +1504,24 @@ static void install_page_probes(unsigned long page, struct task_struct *task, st
 //                     }
 //             }
 
-
-
-
                for (i = 0; i < pp->cnt; ++i) {
-                       struct page_probes *page_p = NULL;
+                       struct page_probes *page_p;
+                       struct file_probes *fp = pp->fp[i];
 
                        //TODO: test - try to instrument non-existing libs
-//                     printk("vma: start=%x, name=%s, name_2=%s\n",
-//                                     vma->vm_start,
-//                                     vma->vm_file->f_dentry->d_iname,
-//                                     vma->vm_file->f_dentry->d_name.name);
-                       if (vma->vm_file->f_dentry != pp->fp[i]->dentry) {
+                       if (vma->vm_file->f_dentry != fp->dentry) {
                                continue;
                        }
 
-//                     if (!(vma->vm_flags & VM_EXECUTABLE) {
-//                     }
-//                     if (page >= vma->vm_start) {
-//                             page -= vma->vm_start;
-//                     }
-
-                       page_p = fp_find_pp(pp->fp[i], page, vma->vm_start);
+                       page_p = fp_find_pp(fp, page, vma->vm_start);
 
                        if (page_p) {
-                               printk("### vma: start=%x, addr=%x, name=%s, name_2=%s\n",
-                                               vma->vm_start, addr,
-                                               vma->vm_file->f_dentry->d_iname,
-                                               vma->vm_file->f_dentry->d_name.name);
-                               print_page_probes(page_p);
+                               register_us_page_probe(page_p, fp, task, mm, vma);
                        }
-
-
-//                     for (k = 0; k < task_inst_info->p_libs[i].ips_count; k++) {
-//                             DPRINTF("ips_count current:%d", k);
-//                             if (!task_inst_info->p_libs[i].p_ips[k].installed) {
-//                                     DPRINTF("!installed");
-//                                     addr = task_inst_info->p_libs[i].p_ips[k].offset;
-//                                     if (!(vma->vm_flags & VM_EXECUTABLE)) {
-//                                             /* In the case of prelinking addr is already an
-//                                              * absolute address so we do not need to add
-//                                              * library base address to it.  We use a rule of
-//                                              * thumb here: if addr is greater than library base
-//                                              * address than there is prelinking.
-//                                              */
-//                                             if (addr < vma->vm_start)
-//                                                     addr += vma->vm_start;
-//                                     }
-//                                     if (page_present (mm, addr)) {
-//                                             DPRINTF ("pid %d, %s sym is loaded at %lx/%lx.",
-//                                                     task->pid, task_inst_info->p_libs[i].path,
-//                                                     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);
-//                                             if (err != 0) {
-//                                                     DPRINTF ("failed to install IP at %lx/%p. Error %d!",
-//                                                             task_inst_info->p_libs[i].p_ips[k].offset,
-//                                                             task_inst_info->p_libs[i].p_ips[k].jprobe.kp.addr, err);
-//                                             }
-//                                     }
-//                             }
-//                     }
-
-
                }
        }
 
+out:
        up_read(&mm->mmap_sem);
        mmput(mm);
 //     printk("### for 2\n");
@@ -1530,10 +1581,12 @@ void do_page_fault_ret_pre_code (void)
                }
 
                // overhead
+               printk("####### T_0\n");
                do_gettimeofday(&imi_tv1);
                install_page_probes(page, task, us_proc_info.pp, addr);
-               install_mapped_ips (task, task_inst_info, 1);
+//             install_mapped_ips (task, task_inst_info, 1);
                do_gettimeofday(&imi_tv2);
+               printk("####### T_1\n");
                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));
@@ -1601,7 +1654,7 @@ void do_page_fault_ret_pre_code (void)
 
                do_gettimeofday(&imi_tv1);
                install_page_probes(page, task, us_proc_info.pp, addr);
-               install_mapped_ips (task, &us_proc_info, 1);
+//             install_mapped_ips (task, &us_proc_info, 1);
                do_gettimeofday(&imi_tv2);
                imi_sum_hit++;
                imi_sum_time += ((imi_tv2.tv_sec - imi_tv1.tv_sec) *  USEC_IN_SEC_NUM +
@@ -1837,8 +1890,10 @@ static int register_usprobe (struct task_struct *task, struct mm_struct *mm, us_
        ip->jprobe.kp.tgid = task->tgid;
        //ip->jprobe.kp.addr = (kprobe_opcode_t *) addr;
 
-       printk("### register_usprobe: offset=%x, j_addr=%x, ret_addr=%x\n",
-                       ip->offset, ip->jprobe.kp.addr, ip->retprobe.kp.addr);
+//     printk("### register_usprobe: offset=%x, j_addr=%x, ret_addr=%x\n",
+//                     ip->offset, ip->jprobe.kp.addr, ip->retprobe.kp.addr);
+
+//     return 0;
 
        if(!ip->jprobe.entry) {
                if (dbi_ujprobe_event_handler_custom_p != NULL)
index d33e3a2..769201d 100644 (file)
@@ -1068,6 +1068,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 bf3e517..b84fbc5 100644 (file)
@@ -48,6 +48,7 @@ int __register_uprobe (struct kprobe *p, struct task_struct *task, int atomic, u
 {
        int ret = 0;
        struct kprobe *old_p;
+//     printk("### __register_uprobe: p->addr = 0x%p\n", p->addr);
 
 //     printk (">>>>>>>>>>>>>>>>>>>>>>>>>>>>>> %s %d\n", __FUNCTION__, __LINE__);