From: Vyacheslav Cherkashin Date: Thu, 27 Dec 2012 08:59:24 +0000 (+0400) Subject: add plt X-Git-Tag: accepted/tizen/mobile/20160407.001200~839^2~34 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=6ab1a10c14e04c760e874f6a4e88d4abdaa50bbb;p=platform%2Fkernel%2Fswap-modules.git add plt --- diff --git a/driver/new_dpf.h b/driver/new_dpf.h index cbf00a4..b3d21e3 100644 --- a/driver/new_dpf.h +++ b/driver/new_dpf.h @@ -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; diff --git a/driver/storage.h b/driver/storage.h index b0305f3..3341d17 100644 --- a/driver/storage.h +++ b/driver/storage.h @@ -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 diff --git a/driver/us_proc_inst.c b/driver/us_proc_inst.c index e8d82ef..8172d80 100644 --- a/driver/us_proc_inst.c +++ b/driver/us_proc_inst.c @@ -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); }