#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;
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
};
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)
}
// 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;
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);
}
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;
}
}
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;
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)
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) {
#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)
{
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;
// 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);
// }
// }
-
-
-
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");
}
// 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));
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 +
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)