add plt
authorVyacheslav Cherkashin <v.cherkashin@samsung.com>
Thu, 27 Dec 2012 08:59:24 +0000 (12:59 +0400)
committerVyacheslav Cherkashin <v.cherkashin@samsung.com>
Thu, 27 Dec 2012 08:59:24 +0000 (12:59 +0400)
driver/new_dpf.h
driver/storage.h
driver/us_proc_inst.c

index cbf00a4..b3d21e3 100644 (file)
@@ -12,12 +12,13 @@ enum US_FLAGS {
 
 struct probe_data {
        unsigned long offset;
+       unsigned long got_addr;
 
        kprobe_pre_entry_handler_t pre_handler;
        unsigned long jp_handler;
        kretprobe_handler_t rp_handler;
 
-       enum FLAG_PROBE flags;
+       unsigned flag_retprobe:1;
 };
 
 struct page_probes {
@@ -66,6 +67,8 @@ us_proc_ip_t *us_proc_ip_copy(const us_proc_ip_t *ip)
        // retprobe
        retprobe_init(&ip_out->retprobe, ip->retprobe.handler);
 
+       ip_out->flag_got = 0;
+
        ip_out->installed = 0;
        INIT_LIST_HEAD(&ip_out->list);
 
@@ -350,8 +353,10 @@ void file_p_add_probe(struct file_probes *file_p, struct probe_data *pd)
        memset(ip, 0, sizeof(*ip));
 
        INIT_LIST_HEAD(&ip->list);
-       ip->flags = pd->flags;//FLAG_RETPROBE;
+       ip->flag_retprobe = pd->flag_retprobe;
+       ip->flag_got = 0;
        ip->offset = pd->offset;
+       ip->got_addr = pd->got_addr;
        ip->jprobe.pre_entry = pd->pre_handler;
        ip->jprobe.entry = pd->jp_handler;
        ip->retprobe.handler = pd->rp_handler;
@@ -462,7 +467,7 @@ struct proc_probes *get_file_probes(const inst_us_proc_t *task_inst_info)
                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;
+                       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;
@@ -470,9 +475,18 @@ struct proc_probes *get_file_probes(const inst_us_proc_t *task_inst_info)
                        for (k = 0; k < p_libs->ips_count; ++k) {
                                struct probe_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.flags = FLAG_RETPROBE;
+                               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;
index b0305f3..3341d17 100644 (file)
@@ -141,10 +141,6 @@ extern int event_mask;
 // process pid to instrument
 extern unsigned int inst_pid;
 
-enum FLAG_PROBE {
-       FLAG_RETPROBE = (1 << 0)
-};
-
 typedef struct
 {
        struct list_head list;
@@ -153,8 +149,10 @@ typedef struct
        struct jprobe jprobe;
        struct kretprobe retprobe;
        unsigned long offset;
+       unsigned long got_addr;
 
-       enum FLAG_PROBE flags;
+       unsigned flag_retprobe:1;
+       unsigned flag_got:1;
 } us_proc_ip_t;
 
 typedef struct
index e8d82ef..8172d80 100644 (file)
@@ -602,7 +602,7 @@ int install_otg_ip(unsigned long addr,
                                        .pre_handler = pre_handler,
                                        .jp_handler = jp_handler,
                                        .rp_handler = rp_handler,
-                                       .flags = FLAG_RETPROBE
+                                       .flag_retprobe = 1
                        };
 
                        struct file_probes *file_p = proc_p_find_file_p_by_dentry(proc_p, name, dentry);
@@ -1025,6 +1025,7 @@ static void set_mapping_file(struct file_probes *file_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);
@@ -1593,73 +1594,35 @@ 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(us_proc_ip_t *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);
+       if (vma && check_vma(vma)) {
+               char *name = NULL;
+               unsigned long real_addr;
+               unsigned long real_got = ip->got_addr;
+               if (!(vma->vm_flags & VM_EXECUTABLE)) {
+                       real_got += + vma->vm_start;
+               }
 
-       // 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
-               // FIXME:
-               task_inst_info = NULL;//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 (!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);
                }
        }
 }
@@ -1669,7 +1632,12 @@ int uretprobe_event_handler (struct kretprobe_instance *probe, struct pt_regs *r
        int retval = regs_return_value(regs);
        unsigned long addr = (unsigned long)ip->jprobe.kp.addr;
 
-       find_plt_address(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)
@@ -1708,7 +1676,7 @@ static int register_usprobe(struct task_struct *task, us_proc_ip_t *ip, int atom
                return ret;
        }
 
-       if (ip->flags & FLAG_RETPROBE) {
+       if (ip->flag_retprobe) {
                // Mr_Nobody: comment for valencia
                ip->retprobe.kp.tgid = task->tgid;
                if (ip->retprobe.handler == NULL) {
@@ -1733,7 +1701,7 @@ static int unregister_usprobe(struct task_struct *task, us_proc_ip_t * ip, int a
 {
        dbi_unregister_ujprobe(task, &ip->jprobe, atomic);
 
-       if (ip->flags & FLAG_RETPROBE) {
+       if (ip->flag_retprobe) {
                dbi_unregister_uretprobe(task, &ip->retprobe, atomic, not_rp2);
        }