us_proc_ip_t --> struct us_ip
[kernel/swap-modules.git] / driver / us_proc_inst.c
1 ////////////////////////////////////////////////////////////////////////////////////
2 //
3 //      FILE:           us_proc_inst.c
4 //
5 //      DESCRIPTION:
6 //      This file is C source for SWAP driver.
7 //
8 //      SEE ALSO:       us_proc_inst.h
9 //      AUTHOR:         A.Gerenkov, E. Gorelkina
10 //      COMPANY NAME:   Samsung Research Center in Moscow
11 //      DEPT NAME:      Advanced Software Group
12 //      CREATED:        2008.06.02
13 //      VERSION:        1.0
14 //      REVISION DATE:  2008.12.02
15 //
16 ////////////////////////////////////////////////////////////////////////////////////
17
18 #include "module.h"
19 #include "us_proc_inst.h"
20
21 #include "../kprobe/dbi_kprobes_deps.h"
22 #include "../kprobe/dbi_uprobes.h"
23
24 #define mm_read_lock(task, mm, atomic, lock)                    \
25         mm = atomic ? task->active_mm : get_task_mm(task);      \
26         if (mm == NULL) {                                       \
27                 /* FIXME: */                                    \
28                 panic("ERRR mm_read_lock: mm == NULL\n");       \
29         }                                                       \
30                                                                 \
31         if (atomic) {                                           \
32                 lock = down_read_trylock(&mm->mmap_sem);        \
33         } else {                                                \
34                 lock = 1;                                       \
35                 down_read(&mm->mmap_sem);                       \
36         }
37
38 #define mm_read_unlock(mm, atomic, lock)                        \
39         if (lock) {                                             \
40                 up_read(&mm->mmap_sem);                         \
41         }                                                       \
42                                                                 \
43         if (!atomic) {                                          \
44                 mmput(mm);                                      \
45         }
46
47 DEFINE_PER_CPU (us_proc_vtp_t *, gpVtp) = NULL;
48 DEFINE_PER_CPU (struct pt_regs *, gpCurVtpRegs) = NULL;
49
50 #if defined(CONFIG_MIPS)
51 #       define ARCH_REG_VAL(regs, idx)  regs->regs[idx]
52 #elif defined(CONFIG_ARM)
53 #       define ARCH_REG_VAL(regs, idx)  regs->uregs[idx]
54 #else
55 #       define ARCH_REG_VAL(regs, idx)  0
56 #       warning ARCH_REG_VAL is not implemented for this architecture. FBI will work improperly or even crash!!!
57 #endif // ARCH
58
59 unsigned long ujprobe_event_pre_handler (struct us_ip *ip, struct pt_regs *regs);
60 void ujprobe_event_handler (unsigned long arg1, unsigned long arg2, unsigned long arg3, unsigned long arg4, unsigned long arg5, unsigned long arg6);
61 int uretprobe_event_handler (struct kretprobe_instance *probe, struct pt_regs *regs, struct us_ip *ip);
62
63 static int register_usprobe(struct task_struct *task, struct us_ip *ip, int atomic);
64 static int unregister_usprobe(struct task_struct *task, struct us_ip *ip, int atomic, int no_rp2);
65
66 #include "new_dpf.h"
67
68 int us_proc_probes;
69
70 LIST_HEAD(proc_probes_list);
71
72 #ifdef SLP_APP
73 struct dentry *launchpad_daemon_dentry = NULL;
74 EXPORT_SYMBOL_GPL(launchpad_daemon_dentry);
75 #endif /* SLP_APP */
76
77 #ifdef ANDROID_APP
78 unsigned long android_app_vma_start = 0;
79 unsigned long android_app_vma_end = 0;
80 struct dentry *app_process_dentry = NULL;
81 #endif /* ANDROID_APP */
82
83 #ifdef __ANDROID
84 struct dentry *libdvm_dentry = NULL;
85 /* Defines below are for libdvm.so with md5sum:
86  * 5941c87b49198368e7db726c2977bf1d */
87 #define LIBDVM_ENTRY 0x30a64
88 #define LIBDVM_RETURN 0x30bdc
89 #endif /* __ANDROID */
90
91
92
93 #define print_event(fmt, args...)                                               \
94 {                                                                               \
95         char *buf[1024];                                                        \
96         sprintf(buf, fmt, ##args);                                              \
97         pack_event_info(US_PROBE_ID, RECORD_ENTRY, "ds", 0x0badc0de, buf);      \
98 }
99
100 static inline int is_libonly(void)
101 {
102         return !strcmp(us_proc_info.path,"*");
103 }
104
105 // is user-space instrumentation
106 static inline int is_us_instrumentation(void)
107 {
108         return !!us_proc_info.path;
109 }
110
111 struct proc_probes *get_proc_probes_by_task(struct task_struct *task)
112 {
113         struct proc_probes *proc_p, *tmp;
114
115         if (!is_libonly()) {
116                 if (task != current) {
117                         printk("ERROR get_proc_probes_by_task: \'task != current\'\n");
118                         return NULL;
119                 }
120
121                 return us_proc_info.pp;
122         }
123
124         list_for_each_entry_safe(proc_p, tmp, &proc_probes_list, list) {
125                 if (proc_p->tgid == task->tgid) {
126                         return proc_p;
127                 }
128         }
129
130         return NULL;
131 }
132
133 void add_proc_probes(struct task_struct *task, struct proc_probes *proc_p)
134 {
135         list_add_tail(&proc_p->list, &proc_probes_list);
136 }
137
138 struct proc_probes *get_proc_probes_by_task_or_new(struct task_struct *task)
139 {
140         struct proc_probes *proc_p = get_proc_probes_by_task(task);
141         if (proc_p == NULL) {
142                 proc_p = proc_p_copy(us_proc_info.pp, task);
143                 add_proc_probes(task, proc_p);
144         }
145
146         return proc_p;
147 }
148
149 #ifdef SLP_APP
150 static int is_slp_app_with_dentry(struct vm_area_struct *vma,
151                                                                   struct dentry *dentry)
152 {
153         struct vm_area_struct *slp_app_vma = NULL;
154
155         if (vma->vm_file->f_dentry == launchpad_daemon_dentry) {
156                 slp_app_vma = vma;
157                 while (slp_app_vma) {
158                         if (slp_app_vma->vm_file) {
159                                 if (slp_app_vma->vm_file->f_dentry == dentry &&
160                                         slp_app_vma->vm_pgoff == 0) {
161                                         return 1;
162                                 }
163                         }
164                         slp_app_vma = slp_app_vma->vm_next;
165                 }
166         }
167
168         return 0;
169 }
170 #endif /* SLP_APP */
171
172 #ifdef ANDROID_APP
173 static int is_android_app_with_dentry(struct vm_area_struct *vma,
174                                                                           struct dentry *dentry)
175 {
176         struct vm_area_struct *android_app_vma = NULL;
177
178         if (vma->vm_file->f_dentry == app_process_dentry) {
179                 android_app_vma = vma;
180                 while (android_app_vma) {
181                         if (android_app_vma->vm_file) {
182                                 if (android_app_vma->vm_file->f_dentry == dentry) {
183                                         android_app_vma_start = android_app_vma->vm_start;
184                                         android_app_vma_end = android_app_vma->vm_end;
185                                         return 1;
186                                 }
187                         }
188                         android_app_vma = android_app_vma->vm_next;
189                 }
190         }
191
192         return 0;
193 }
194 #endif /* ANDROID_APP */
195
196 #ifdef __ANDROID
197 void find_libdvm_for_task(struct task_struct *task, inst_us_proc_t *info)
198 {
199         struct vm_area_struct *vma = NULL;
200         struct mm_struct *mm = NULL;
201
202         mm = get_task_mm(task);
203         if (mm) {
204                 vma = mm->mmap;
205                 while (vma) {
206                         if (vma->vm_file) {
207                                 if (vma->vm_file->f_dentry == libdvm_dentry) {
208                                         info->libdvm_start = vma->vm_start;
209                                         info->libdvm_end = vma->vm_end;
210                                         break;
211                                 }
212                         }
213                         vma = vma->vm_next;
214                 }
215                 mmput(mm);
216         }
217 }
218 #endif /* __ANDROID */
219
220 struct dentry *dentry_by_path(const char *path)
221 {
222         struct dentry *dentry;
223 #if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 38)
224         struct path st_path;
225         if (kern_path(path, LOOKUP_FOLLOW, &st_path) != 0) {
226 #else /* LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 38) */
227         struct nameidata nd;
228         if (path_lookup(path, LOOKUP_FOLLOW, &nd) != 0) {
229 #endif /* LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 38) */
230                 EPRINTF("failed to lookup dentry for path %s!", path);
231                 return NULL;
232         }
233
234 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 25)
235         dentry = nd.dentry;
236         path_release(&nd);
237 #elif LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 38)
238         dentry = nd.path.dentry;
239         path_put(&nd.path);
240 #else /* LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 38) */
241         dentry = st_path.dentry;
242         path_put(&st_path);
243 #endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 25) */
244         return dentry;
245 }
246
247 static int find_task_by_path (const char *path, struct task_struct **p_task, struct list_head *tids)
248 {
249         int found = 0;
250         struct task_struct *task;
251         struct vm_area_struct *vma;
252         struct mm_struct *mm;
253         struct dentry *dentry = dentry_by_path(path);
254
255         *p_task = 0;
256
257         /* find corresponding dir entry, this is also check for valid path */
258         // TODO: test - try to instrument process with non-existing path
259         // TODO: test - try to instrument process  with existing path and delete file just after start
260         if (dentry == NULL) {
261                 return -EINVAL;
262         }
263
264         rcu_read_lock();
265         for_each_process (task) {
266
267                 if  ( 0 != inst_pid && ( inst_pid != task->pid ) )
268                         continue;
269
270                 mm = get_task_mm(task);
271                 if (!mm)
272                         continue;
273                 vma = mm->mmap;
274                 while (vma) {
275                         if ((vma->vm_flags & VM_EXECUTABLE) && vma->vm_file) {
276                                 if (vma->vm_file->f_dentry == dentry) {
277                                         if (!*p_task) {
278                                                 *p_task = task;
279                                                 get_task_struct (task);
280                                         }
281                                                 //break;
282                                 }
283 #ifdef SLP_APP
284                                 if (!*p_task) {
285                                         if (is_slp_app_with_dentry(vma, dentry)) {
286                                                 *p_task = task;
287                                                 get_task_struct(task);
288                                         }
289                                 }
290 #endif /* SLP_APP */
291 #ifdef ANDROID_APP
292                                 if (!*p_task) {
293                                         if (is_android_app_with_dentry(vma, dentry)) {
294                                                 *p_task = task;
295                                                 get_task_struct(task);
296                                         }
297                                 }
298 #endif /* ANDROID_APP */
299                         }
300                         vma = vma->vm_next;
301                 }
302                 // only decrement usage count on mm since we cannot sleep here
303                 atomic_dec(&mm->mm_users);
304                 if (found)
305                         break;
306         }
307         rcu_read_unlock();
308
309         if (*p_task) {
310                 DPRINTF ("found pid %d for %s.", (*p_task)->pid, path);
311                 *p_task = (*p_task)->group_leader;
312                 gl_nNotifyTgid = (*p_task)->tgid;
313         } else {
314                 DPRINTF ("pid for %s not found!", path);
315         }
316
317         return 0;
318 }
319
320
321 static void us_vtp_event_pre_handler (us_proc_vtp_t * vtp, struct pt_regs *regs)
322 {
323         __get_cpu_var(gpVtp) = vtp;
324         __get_cpu_var(gpCurVtpRegs) = regs;
325 }
326
327 static void us_vtp_event_handler (unsigned long arg1, unsigned long arg2, unsigned long arg3, unsigned long arg4, unsigned long arg5, unsigned long arg6)
328 {
329         us_proc_vtp_t *vtp = __get_cpu_var(gpVtp);
330 #if !defined(CONFIG_X86)
331         struct pt_regs *regs = __get_cpu_var(gpCurVtpRegs);
332 #endif
333         char fmt[4];
334         unsigned long vaddr;
335         long ival;
336         char cval, *sval;
337         us_proc_vtp_data_t *vtp_data;
338 unsigned long ll;
339         fmt[0] = 'p';
340         fmt[3] = 0;
341         fmt[2] = 's';
342
343         list_for_each_entry_rcu (vtp_data, &vtp->list, list) {
344                 //              DPRINTF ("[%d]proc %s(%d): %lx", nCount++, current->comm, current->pid, vtp->addr);
345                 fmt[1] = vtp_data->type;
346                 if (vtp_data->reg == -1)
347                         vaddr = vtp_data->off;
348                 else
349                         vaddr = ARCH_REG_VAL (regs, vtp_data->reg) + vtp_data->off;
350                 //              DPRINTF ("VTP type '%c'", vtp_data->type);
351                 switch (vtp_data->type)
352                 {
353                         case 'd':
354                         case 'x':
355                         case 'p':
356                                 if (read_proc_vm_atomic (current, vaddr, &ival, sizeof (ival)) < sizeof (ival))
357                                         EPRINTF ("failed to read vm of proc %s/%u addr %lu!", current->comm, current->pid, vaddr);
358                                 else
359                                         pack_event_info (VTP_PROBE_ID, RECORD_ENTRY, fmt, vtp->jprobe.kp.addr, ival, vtp_data->name);
360                                 break;
361                         case 'f':
362                                 if (read_proc_vm_atomic (current, vaddr, &ival, sizeof (ival)) < sizeof (ival))
363                                         EPRINTF ("failed to read vm of proc %s/%u addr %lu!", current->comm, current->pid, vaddr);
364                                 else
365                                         pack_event_info (VTP_PROBE_ID, RECORD_ENTRY, fmt, vtp->jprobe.kp.addr, ival, vtp_data->name);
366                                 break;
367                         case 'c':
368                                 if (read_proc_vm_atomic (current, vaddr, &cval, sizeof (cval)) < sizeof (cval))
369                                         EPRINTF ("failed to read vm of proc %s/%u addr %lu!", current->comm, current->pid, vaddr);
370                                 else
371                                         pack_event_info (VTP_PROBE_ID, RECORD_ENTRY, fmt, vtp->jprobe.kp.addr, cval, vtp_data->name);
372                                 break;
373                         case 's':
374                                 if (current->active_mm) {
375                                         struct page *page;
376                                         struct vm_area_struct *vma;
377                                         void *maddr;
378                                         int len;
379                                         if (get_user_pages_atomic (current, current->active_mm, vaddr, 1, 0, 1, &page, &vma) <= 0) {
380                                                 EPRINTF ("get_user_pages_atomic failed for proc %s/%u addr %lu!", current->comm, current->pid, vaddr);
381                                                 break;
382                                         }
383                                         maddr = kmap_atomic (page, KM_USER0);
384                                         len = strlen (maddr + (vaddr & ~PAGE_MASK));
385                                         sval = kmalloc (len + 1, GFP_KERNEL);
386                                         if (!sval)
387                                                 EPRINTF ("failed to alloc memory for string in proc %s/%u addr %lu!", current->comm, current->pid, vaddr);
388                                         else {
389                                                 copy_from_user_page (vma, page, vaddr, sval, maddr + (vaddr & ~PAGE_MASK), len + 1);
390                                                 pack_event_info (VTP_PROBE_ID, RECORD_ENTRY, fmt, vtp->jprobe.kp.addr, sval,  vtp_data->name);
391                                                 kfree (sval);
392                                         }
393                                         kunmap_atomic (maddr, KM_USER0);
394                                         page_cache_release (page);
395                                 }
396                                 else
397                                         EPRINTF ("task %s/%u has no mm!", current->comm, current->pid);
398                                 break;
399                         default:
400                                 EPRINTF ("unknown variable type '%c'", vtp_data->type);
401                 }
402         }
403         dbi_uprobe_return ();
404 }
405
406 static int install_mapped_ips (struct task_struct *task, inst_us_proc_t* task_inst_info, int atomic)
407 {
408         struct vm_area_struct *vma;
409         int i, k, err;
410         unsigned long addr;
411         unsigned int old_ips_count, old_vtps_count;
412         struct task_struct *t;
413         struct mm_struct *mm;
414
415         mm = atomic ? task->active_mm : get_task_mm (task);
416         if (!mm) {
417                 return task_inst_info->unres_ips_count + task_inst_info->unres_vtps_count;
418         }
419         old_ips_count = task_inst_info->unres_ips_count;
420         old_vtps_count = task_inst_info->unres_vtps_count;
421         if(!atomic)
422                 down_read (&mm->mmap_sem);
423         vma = mm->mmap;
424         while (vma) {
425                 // skip non-text section
426 #ifndef __ANDROID
427                 if (vma->vm_pgoff != 0 || !(vma->vm_flags & VM_EXEC) || !vma->vm_file || (vma->vm_flags & VM_ACCOUNT) ||
428                         !(vma->vm_flags & (VM_WRITE | VM_MAYWRITE)) ||
429                         !(vma->vm_flags & (VM_READ | VM_MAYREAD))) {
430 #else // __ANDROID
431                 if (vma->vm_pgoff != 0 || !(vma->vm_flags & VM_EXEC) || !vma->vm_file) {
432 #endif // __ANDROID
433                         vma = vma->vm_next;
434                         continue;
435                 }
436                 /**
437                  * After process was forked, some time it inherits parent process environment.
438                  * We need to renew instrumentation when we detect that process gets own environment.
439                  */
440                 for (i = 0; i < task_inst_info->libs_count; i++) {
441 //                      struct path tmp_path;
442 //                      tmp_path.dentry = task_inst_info->p_libs[i].m_f_dentry;
443 //                      tmp_path.mnt = task_inst_info->p_libs[i].m_vfs_mount;
444 //                      char* p_path = d_path ( &tmp_path, path_buffer, 255 );
445 //                      DPRINTF("f_dentry:%x m_f_dentry:%x path:%s", vma->vm_file->f_dentry,
446 //                              task_inst_info->p_libs[i].m_f_dentry, p_path );
447
448                         //TODO: test - try to instrument non-existing libs
449                         if (vma->vm_file->f_dentry == task_inst_info->p_libs[i].m_f_dentry) {
450 //                              DPRINTF("vm_flags:%x loaded:%x ips_count:%d vtps_count:%d",
451 //                                              vma->vm_flags, task_inst_info->p_libs[i].loaded,
452 //                                              task_inst_info->p_libs[i].ips_count, task_inst_info->p_libs[i].vtps_count );
453                                 if (!task_inst_info->p_libs[i].loaded) {
454 //                                      DPRINTF("!VM_EXECUTABLE && !loaded");
455                                         char *p;
456                                         int app_flag = (vma->vm_file->f_dentry == task_inst_info->m_f_dentry);
457                                         DPRINTF ("post dyn lib event %s/%s", current->comm, task_inst_info->p_libs[i].path);
458                                         // if we installed something, post library info for those IPs
459                                         p = strrchr(task_inst_info->p_libs[i].path, '/');
460                                         if(!p)
461                                                 p = task_inst_info->p_libs[i].path;
462                                         else
463                                                 p++;
464                                         task_inst_info->p_libs[i].loaded = 1;
465                                         task_inst_info->p_libs[i].vma_start = vma->vm_start;
466                                         task_inst_info->p_libs[i].vma_end = vma->vm_end;
467                                         task_inst_info->p_libs[i].vma_flag = vma->vm_flags;
468                                         pack_event_info (DYN_LIB_PROBE_ID, RECORD_ENTRY, "dspdd",
469                                                         task->tgid, p, vma->vm_start, vma->vm_end-vma->vm_start, app_flag);
470                                 }
471                                 for (k = 0; k < task_inst_info->p_libs[i].ips_count; k++) {
472                                         DPRINTF("ips_count current:%d", k);
473                                         if (!task_inst_info->p_libs[i].p_ips[k].installed) {
474                                                 DPRINTF("!installed");
475                                                 addr = task_inst_info->p_libs[i].p_ips[k].offset;
476                                                 addr += vma->vm_start;
477                                                 if (page_present (mm, addr)) {
478                                                         DPRINTF ("pid %d, %s sym is loaded at %lx/%lx.",
479                                                                 task->pid, task_inst_info->p_libs[i].path,
480                                                                 task_inst_info->p_libs[i].p_ips[k].offset, addr);
481                                                         task_inst_info->p_libs[i].p_ips[k].jprobe.kp.addr = (kprobe_opcode_t *) addr;
482                                                         task_inst_info->p_libs[i].p_ips[k].retprobe.kp.addr = (kprobe_opcode_t *) addr;
483                                                         task_inst_info->unres_ips_count--;
484                                                         err = register_usprobe(task, &task_inst_info->p_libs[i].p_ips[k], atomic);
485                                                         if (err != 0) {
486                                                                 DPRINTF ("failed to install IP at %lx/%p. Error %d!",
487                                                                         task_inst_info->p_libs[i].p_ips[k].offset,
488                                                                         task_inst_info->p_libs[i].p_ips[k].jprobe.kp.addr, err);
489                                                         }
490                                                 }
491                                         }
492                                 }
493                                 for (k = 0; k < task_inst_info->p_libs[i].vtps_count; k++) {
494                                         DPRINTF("vtps_count current:%d", k);
495                                         if (!task_inst_info->p_libs[i].p_vtps[k].installed) {
496                                                 DPRINTF("!installed");
497                                                 addr = task_inst_info->p_libs[i].p_vtps[k].addr;
498                                                 if (!(vma->vm_flags & VM_EXECUTABLE))
499                                                         addr += vma->vm_start;
500                                                 if (page_present (mm, addr)) {
501                                                         DPRINTF ("pid %d, %s sym is loaded at %lx/%lx.",
502                                                                 task->pid, task_inst_info->p_libs[i].path,
503                                                                 task_inst_info->p_libs[i].p_ips[k].offset, addr);
504                                                         task_inst_info->p_libs[i].p_vtps[k].jprobe.kp.tgid = task_inst_info->tgid;
505                                                         task_inst_info->p_libs[i].p_vtps[k].jprobe.kp.addr = (kprobe_opcode_t *) addr;
506                                                         task_inst_info->p_libs[i].p_vtps[k].jprobe.entry = (kprobe_opcode_t *) us_vtp_event_handler;
507                                                         task_inst_info->p_libs[i].p_vtps[k].jprobe.pre_entry = (kprobe_pre_entry_handler_t) us_vtp_event_pre_handler;
508                                                         task_inst_info->p_libs[i].p_vtps[k].jprobe.priv_arg = &task_inst_info->p_libs[i].p_vtps[k];
509                                                         task_inst_info->p_libs[i].p_vtps[k].installed = 1;
510                                                         task_inst_info->unres_vtps_count--;
511                                                         err = dbi_register_ujprobe(task, &task_inst_info->p_libs[i].p_vtps[k].jprobe, atomic);
512                                                         if ( err != 0 ) {
513                                                                 EPRINTF ("failed to install VTP at %p. Error %d!",
514                                                                                 task_inst_info->p_libs[i].p_vtps[k].jprobe.kp.addr, err);
515                                                         }
516                                                 }
517                                         }
518                                 }
519                         }
520                 }
521 #ifdef __ANDROID
522                 if (is_java_inst_enabled()
523                     && vma->vm_file->f_dentry == libdvm_dentry) {
524                         us_proc_ip_t *entp = &task_inst_info->libdvm_entry_ip;
525                         if (!entp->installed
526                             && task_inst_info->libdvm_start) {
527                                 unsigned long addr = LIBDVM_ENTRY + task_inst_info->libdvm_start;
528                                 if (page_present(mm, addr)) {
529                                         entp->jprobe.kp.tgid = task->tgid;
530                                         entp->jprobe.pre_entry = ujprobe_event_pre_handler;
531                                         entp->jprobe.entry = ujprobe_event_handler;
532                                         entp->jprobe.priv_arg = entp;
533                                         entp->jprobe.kp.addr = addr;
534                                         entp->retprobe.kp.tgid = task->tgid;
535                                         entp->retprobe.handler = uretprobe_event_handler;
536                                         entp->retprobe.priv_arg = entp;
537                                         entp->retprobe.kp.addr = addr;
538                                         err = register_usprobe(task, mm, entp, atomic, 0);
539                                         if (err != 0) {
540                                                 DPRINTF("failed to install IP at %p", addr);
541                                         }
542                                 }
543                                 entp->installed = 1;
544                         }
545                         us_proc_ip_t *retp = &task_inst_info->libdvm_return_ip;
546                         if (!retp->installed
547                             && task_inst_info->libdvm_start) {
548                                 unsigned long addr = LIBDVM_RETURN + task_inst_info->libdvm_start;
549                                 if (page_present(mm, addr)) {
550                                         retp->jprobe.kp.tgid = task->tgid;
551                                         retp->jprobe.pre_entry = ujprobe_event_pre_handler;
552                                         retp->jprobe.entry = ujprobe_event_handler;
553                                         retp->jprobe.priv_arg = retp;
554                                         retp->jprobe.kp.addr = addr;
555                                         retp->retprobe.kp.tgid = task->tgid;
556                                         retp->retprobe.handler = uretprobe_event_handler;
557                                         retp->retprobe.priv_arg = retp;
558                                         retp->retprobe.kp.addr = addr;
559                                         err = register_usprobe(task, mm, retp, atomic, 0);
560                                         if (err != 0) {
561                                                 DPRINTF("failed to install IP at %p", addr);
562                                         }
563                                 }
564                                 retp->installed = 1;
565                         }
566                 }
567 #endif /* __ANDROID */
568                 vma = vma->vm_next;
569         }
570
571         if (!atomic) {
572                 up_read (&mm->mmap_sem);
573                 mmput (mm);
574         }
575         return task_inst_info->unres_ips_count + task_inst_info->unres_vtps_count;
576 }
577
578 static void set_mapping_file(struct file_probes *file_p,
579                 const struct proc_probes *proc_p,
580                 const struct task_struct *task,
581                 const struct vm_area_struct *vma);
582
583 int install_otg_ip(unsigned long addr,
584                         kprobe_pre_entry_handler_t pre_handler,
585                         unsigned long jp_handler,
586                         kretprobe_handler_t rp_handler)
587 {
588         int ret = 0;
589         struct task_struct *task = current->group_leader;
590         struct mm_struct *mm = task->mm;
591
592         if (mm) {
593                 struct vm_area_struct *vma = find_vma(mm, addr);
594                 if (vma && (vma->vm_flags & VM_EXEC) &&
595                     vma->vm_file && vma->vm_file->f_dentry) {
596                         unsigned long offset_addr = addr - vma->vm_start;
597                         struct dentry *dentry = vma->vm_file->f_dentry;
598                         char *name = dentry->d_iname;
599                         struct proc_probes *proc_p = get_proc_probes_by_task(task);
600                         struct probe_data pd = {
601                                         .offset = offset_addr,
602                                         .pre_handler = pre_handler,
603                                         .jp_handler = jp_handler,
604                                         .rp_handler = rp_handler,
605                                         .flag_retprobe = 1
606                         };
607
608                         struct file_probes *file_p = proc_p_find_file_p_by_dentry(proc_p, name, dentry);
609                         struct page_probes *page_p = get_page_p(file_p, offset_addr);
610                         struct us_ip *ip = page_p_find_ip(page_p, offset_addr & ~PAGE_MASK);
611
612                         if (!file_p->loaded) {
613                                 set_mapping_file(file_p, proc_p, task, vma);
614                                 file_p->loaded = 1;
615                         }
616
617                         if (ip == NULL) {
618                                 struct file_probes *file_p = proc_p_find_file_p_by_dentry(proc_p, name, dentry);
619                                 file_p_add_probe(file_p, &pd);
620
621                                 /* if addr mapping, that probe install, else it be installed in do_page_fault handler */
622                                 if (page_present(mm, addr)) {
623                                         ip = page_p_find_ip(page_p, offset_addr & ~PAGE_MASK);
624                                         set_ip_kp_addr(ip, page_p, file_p);
625
626                                         // TODO: error
627                                         ret = register_usprobe_my(task, ip);
628                                         if (ret == 0) {
629                                                 page_p_installed(page_p);
630                                         } else {
631                                                 printk("ERROR install_otg_ip: ret=%d\n", ret);
632                                         }
633                                 }
634                         }
635
636                         put_page_p(page_p);
637                 }
638         }
639
640         return ret;
641 }
642 EXPORT_SYMBOL_GPL(install_otg_ip);
643
644
645 static int uninstall_mapped_ips (struct task_struct *task,  inst_us_proc_t* task_inst_info, int atomic)
646 {
647         int i, k, err;
648
649         for (i = 0; i < task_inst_info->libs_count; i++)
650         {
651                 DPRINTF ("clear lib %s.", task_inst_info->p_libs[i].path);
652                 for (k = 0; k < task_inst_info->p_libs[i].ips_count; k++)
653                 {
654                         if (task_inst_info->p_libs[i].p_ips[k].installed)
655                         {
656                                 DPRINTF ("remove IP at %p.", task_inst_info->p_libs[i].p_ips[k].jprobe.kp.addr);
657                                 err = unregister_usprobe (task, &task_inst_info->p_libs[i].p_ips[k], atomic, 0);
658                                 if (err != 0)
659                                 {
660                                         EPRINTF ("failed to uninstall IP at %p. Error %d!", task_inst_info->p_libs[i].p_ips[k].jprobe.kp.addr, err);
661                                         continue;
662                                 }
663                                 task_inst_info->unres_ips_count++;
664                         }
665                 }
666                 for (k = 0; k < task_inst_info->p_libs[i].vtps_count; k++)
667                 {
668                         if (task_inst_info->p_libs[i].p_vtps[k].installed)
669                         {
670                                 dbi_unregister_ujprobe (task, &task_inst_info->p_libs[i].p_vtps[k].jprobe, atomic);
671                                 task_inst_info->unres_vtps_count++;
672                                 task_inst_info->p_libs[i].p_vtps[k].installed = 0;
673                         }
674                 }
675                 task_inst_info->p_libs[i].loaded = 0;
676         }
677 #ifdef __ANDROID
678         if (is_java_inst_enabled()) {
679                 us_proc_ip_t *entp = &task_inst_info->libdvm_entry_ip;
680                 if (entp->installed) {
681                         unregister_usprobe(task, entp, atomic);
682                         entp->installed = 0;
683                 }
684                 us_proc_ip_t *retp = &task_inst_info->libdvm_return_ip;
685                 if (retp->installed) {
686                         unregister_usprobe(task, retp, atomic);
687                         retp->installed = 0;
688                 }
689         }
690 #endif /* __ANDROID */
691
692         DPRINTF ("Ures IPs  %d.", task_inst_info->unres_ips_count);
693         DPRINTF ("Ures VTPs %d.", task_inst_info->unres_vtps_count);
694         return 0;
695 }
696
697 static int uninstall_kernel_probe (unsigned long addr, int uflag, int kflag, kernel_probe_t ** pprobe)
698 {
699         kernel_probe_t *probe = NULL;
700         int iRet = 0;
701         if (probes_flags & kflag) {
702                 probe = find_probe(addr);
703                 if (probe) {
704                         iRet = remove_probe_from_list (addr);
705                         if (iRet)
706                                 EPRINTF ("remove_probe_from_list(0x%lx) result=%d!", addr, iRet);
707                         if (pprobe)
708                                 *pprobe = NULL;
709                 }
710                 probes_flags &= ~kflag;
711         }
712         if (us_proc_probes & uflag) {
713                 if (!(probes_flags & uflag)) {
714                         if (probe) {
715                                 iRet = unregister_kernel_probe(probe);
716                                 if (iRet) {
717                                         EPRINTF ("unregister_kernel_probe(0x%lx) result=%d!",
718                                                         addr, iRet);
719                                         return iRet;
720                                 }
721                         }
722                 }
723                 us_proc_probes &= ~uflag;
724         }
725         return iRet;
726 }
727
728 static int uninstall_us_proc_probes(struct task_struct *task, struct proc_probes *proc_p, enum US_FLAGS flag);
729
730 int deinst_usr_space_proc (void)
731 {
732         int iRet = 0, found = 0;
733         struct task_struct *task = 0;
734         inst_us_proc_t *task_inst_info = NULL;
735
736         if (!is_us_instrumentation()) {
737                 return 0;
738         }
739
740         iRet = uninstall_kernel_probe (pf_addr, US_PROC_PF_INSTLD,
741                         0, &pf_probe);
742         if (iRet)
743                 EPRINTF ("uninstall_kernel_probe(do_page_fault) result=%d!", iRet);
744
745         iRet = uninstall_kernel_probe (cp_addr, US_PROC_CP_INSTLD,
746                         0, &cp_probe);
747         if (iRet)
748                 EPRINTF ("uninstall_kernel_probe(copy_process) result=%d!", iRet);
749
750         iRet = uninstall_kernel_probe (mr_addr, US_PROC_MR_INSTLD,
751                         0, &mr_probe);
752         if (iRet)
753                 EPRINTF ("uninstall_kernel_probe(mm_release) result=%d!", iRet);
754
755         iRet = uninstall_kernel_probe (exit_addr, US_PROC_EXIT_INSTLD,
756                         0, &exit_probe);
757         if (iRet)
758                 EPRINTF ("uninstall_kernel_probe(do_exit) result=%d!", iRet);
759
760         iRet = uninstall_kernel_probe (unmap_addr, US_PROC_UNMAP_INSTLD,
761                         0, &unmap_probe);
762         if (iRet)
763                 EPRINTF ("uninstall_kernel_probe(do_munmap) result=%d!", iRet);
764
765         if (is_libonly()) {
766                 struct proc_probes *proc_p;
767
768                 for_each_process(task)  {
769                         proc_p = get_proc_probes_by_task(task);
770                         if (proc_p) {
771                                 int ret = uninstall_us_proc_probes(task, proc_p, US_UNREGS_PROBE);
772                                 if (ret) {
773                                         EPRINTF ("failed to uninstall IPs (%d)!", ret);
774                                 }
775
776                                 dbi_unregister_all_uprobes(task, 1);
777                         }
778                 }
779         }
780         else
781         {
782                 if (us_proc_info.tgid == 0)
783                         return 0;
784                         rcu_read_lock ();
785                 for_each_process (task)
786                 {
787                         if (task->tgid == us_proc_info.tgid)
788                         {
789                                 found = 1;
790                                 get_task_struct (task);
791                                 break;
792                         }
793                 }
794                 rcu_read_unlock ();
795                 if (found)
796                 {
797                         int i, ret;
798                         // uninstall IPs
799                         ret = uninstall_us_proc_probes(task, us_proc_info.pp, US_UNREGS_PROBE);
800                         if (ret != 0) {
801                                 EPRINTF ("failed to uninstall IPs %d!", ret);
802                         }
803
804                         put_task_struct (task);
805
806                         printk("### 1 ### dbi_unregister_all_uprobes:\n");
807                         dbi_unregister_all_uprobes(task, 1);
808                         us_proc_info.tgid = 0;
809                         for(i = 0; i < us_proc_info.libs_count; i++)
810                                 us_proc_info.p_libs[i].loaded = 0;
811                 }
812         }
813
814         return iRet;
815 }
816 static int install_kernel_probe (unsigned long addr, int uflag, int kflag, kernel_probe_t ** pprobe)
817 {
818         kernel_probe_t *probe = NULL;
819         int iRet = 0;
820
821         DPRINTF("us_proc_probes = 0x%x, uflag = 0x%x, "
822                         "probes_flags = 0x%x, kflag = 0x%x",
823                         us_proc_probes, uflag, probes_flags, kflag);
824
825         if (!(probes_flags & kflag)) {
826                 iRet = add_probe_to_list (addr, &probe);
827                 if (iRet) {
828                         EPRINTF ("add_probe_to_list(0x%lx) result=%d!", addr, iRet);
829                         return iRet;
830                 }
831                 probes_flags |= kflag;
832         }
833         if (!(us_proc_probes & uflag)) {
834                 if (!(probes_flags & uflag)) {
835                         iRet = register_kernel_probe (probe);
836                         if (iRet) {
837                                 EPRINTF ("register_kernel_probe(0x%lx) result=%d!", addr, iRet);
838                                 return iRet;
839                         }
840                 }
841                 us_proc_probes |= uflag;
842         }
843
844         if (probe)
845                 *pprobe = probe;
846
847         return 0;
848 }
849
850 static void install_proc_probes(struct task_struct *task, struct proc_probes *proc_p, int atomic);
851
852 int inst_usr_space_proc (void)
853 {
854         int ret, i;
855         struct task_struct *task = 0;
856
857         if (!is_us_instrumentation()) {
858                 return 0;
859         }
860
861         DPRINTF("User space instr");
862
863 #ifdef SLP_APP
864         launchpad_daemon_dentry = dentry_by_path("/usr/bin/launchpad_preloading_preinitializing_daemon");
865         if (launchpad_daemon_dentry == NULL) {
866                 return -EINVAL;
867         }
868
869 #endif /* SLP_APP */
870
871 #ifdef ANDROID_APP
872         app_process_dentry = dentry_by_path("/system/bin/app_process");
873         if (app_process_dentry == NULL) {
874                 return -EINVAL;
875         }
876
877         android_app_vma_start = 0;
878         android_app_vma_end = 0;
879 #endif /* ANDROID_APP */
880
881 #ifdef __ANDROID
882         if (is_java_inst_enabled()) {
883                 libdvm_dentry = dentry_by_path("/system/lib/libdvm.so");
884                 if (libdvm_dentry == NULL) {
885                         return -EINVAL;
886                 }
887
888                 memset(&us_proc_info.libdvm_entry_ip, 0, sizeof(us_proc_ip_t));
889                 memset(&us_proc_info.libdvm_return_ip, 0, sizeof(us_proc_ip_t));
890                 us_proc_info.libdvm_start = 0;
891                 us_proc_info.libdvm_end = 0;
892         }
893 #endif /* __ANDROID */
894
895         for (i = 0; i < us_proc_info.libs_count; i++) {
896                 us_proc_info.p_libs[i].loaded = 0;
897         }
898         /* check whether process is already running
899          * 1) if process is running - look for the libraries in the process maps
900          * 1.1) check if page for symbol does exist
901          * 1.1.1) if page exists - instrument it
902          * 1.1.2) if page does not exist - make sure that do_page_fault handler is installed
903          * 2) if process is not running - make sure that do_page_fault handler is installed
904          * */
905
906         if (is_libonly())
907         {
908                 // FIXME: clear_task_inst_info();
909                 for_each_process (task) {
910                         struct proc_probes *proc_p;
911
912                         if (task->flags & PF_KTHREAD){
913                                 DPRINTF("ignored kernel thread %d\n",
914                                         task->pid);
915                                 continue;
916                         }
917
918                         proc_p = get_proc_probes_by_task_or_new(task);
919                         DPRINTF("trying process");
920 #ifdef __ANDROID
921                         if (is_java_inst_enabled()) {
922                                 find_libdvm_for_task(task, task_inst_info);
923                         }
924 #endif /* __ANDROID */
925                         install_proc_probes(task, proc_p, 1);
926                         //put_task_struct (task);
927                 }
928         }
929         else
930         {
931                 ret = find_task_by_path (us_proc_info.path, &task, NULL);
932                 if ( task  )
933                 {
934                         DPRINTF("task found. installing probes");
935                         us_proc_info.tgid = task->pid;
936 #ifdef __ANDROID
937                         if (is_java_inst_enabled()) {
938                                 find_libdvm_for_task(task, &us_proc_info);
939                         }
940 #endif /* __ANDROID */
941                         install_proc_probes(task, us_proc_info.pp, 0);
942                         put_task_struct (task);
943                 }
944         }
945
946         // enable 'do_page_fault' probe to detect when they will be loaded
947         ret = install_kernel_probe (pf_addr, US_PROC_PF_INSTLD, 0, &pf_probe);
948         if (ret != 0)
949         {
950                 EPRINTF ("install_kernel_probe(do_page_fault) result=%d!", ret);
951                 return ret;
952         }
953         // enable 'do_exit' probe to detect for remove task_struct
954         ret = install_kernel_probe (exit_addr, US_PROC_EXIT_INSTLD, 0, &exit_probe);
955         if (ret != 0)
956         {
957                 EPRINTF ("install_kernel_probe(do_exit) result=%d!", ret);
958                 return ret;
959         }
960         /* enable 'copy_process' */
961         ret = install_kernel_probe (cp_addr, US_PROC_CP_INSTLD, 0, &cp_probe);
962         if (ret != 0)
963         {
964                 EPRINTF ("instpall_kernel_probe(copy_process) result=%d!", ret);
965                 return ret;
966         }
967
968         // enable 'mm_release' probe to detect when for remove user space probes
969         ret = install_kernel_probe (mr_addr, US_PROC_MR_INSTLD, 0, &mr_probe);
970         if (ret != 0)
971         {
972                 EPRINTF ("install_kernel_probe(mm_release) result=%d!", ret);
973                 return ret;
974         }
975
976         // enable 'do_munmap' probe to detect when for remove user space probes
977         ret = install_kernel_probe (unmap_addr, US_PROC_UNMAP_INSTLD, 0, &unmap_probe);
978         if (ret != 0)
979         {
980                 EPRINTF ("install_kernel_probe(do_munmap) result=%d!", ret);
981                 return ret;
982         }
983         return 0;
984 }
985
986 #include "../../tools/gpmu/probes/entry_data.h"
987
988 extern storage_arg_t sa_dpf;
989
990 void do_page_fault_j_pre_code(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
991 {
992         struct task_struct *task = current->group_leader;
993
994         if (task->flags & PF_KTHREAD) {
995                 DPRINTF("ignored kernel thread %d\n", task->pid);
996                 return;
997         }
998
999         if (is_us_instrumentation()) {
1000                 swap_put_entry_data((void *)addr, &sa_dpf);
1001         }
1002 }
1003 EXPORT_SYMBOL_GPL(do_page_fault_j_pre_code);
1004
1005
1006 unsigned long imi_sum_time = 0;
1007 unsigned long imi_sum_hit = 0;
1008 EXPORT_SYMBOL_GPL (imi_sum_time);
1009 EXPORT_SYMBOL_GPL (imi_sum_hit);
1010
1011 static void set_mapping_file(struct file_probes *file_p,
1012                 const struct proc_probes *proc_p,
1013                 const struct task_struct *task,
1014                 const struct vm_area_struct *vma)
1015 {
1016         int app_flag = (vma->vm_file->f_dentry == proc_p->dentry);
1017         char *p;
1018         // if we installed something, post library info for those IPs
1019         p = strrchr(file_p->path, '/');
1020         if(!p) {
1021                 p = file_p->path;
1022         } else {
1023                 p++;
1024         }
1025
1026         file_p->vm_start = vma->vm_start;
1027         file_p->vm_end = vma->vm_end;
1028
1029         pack_event_info(DYN_LIB_PROBE_ID, RECORD_ENTRY, "dspdd",
1030                         task->tgid, p, vma->vm_start,
1031                         vma->vm_end - vma->vm_start, app_flag);
1032 }
1033
1034 void print_vma(struct mm_struct *mm);
1035
1036 static int register_us_page_probe(struct page_probes *page_p,
1037                 const struct file_probes *file_p,
1038                 const struct task_struct *task)
1039 {
1040         int err = 0;
1041         struct us_ip *ip;
1042
1043         spin_lock(&page_p->lock);
1044
1045         if (page_p_is_install(page_p)) {
1046                 printk("page %x in %s task[tgid=%u, pid=%u] already installed\n",
1047                                 page_p->offset, file_p->dentry->d_iname, task->tgid, task->pid);
1048                 print_vma(task->mm);
1049                 return 0;
1050         }
1051
1052         page_p_assert_install(page_p);
1053         page_p_set_all_kp_addr(page_p, file_p);
1054
1055         list_for_each_entry(ip, &page_p->ip_list, list) {
1056                 err = register_usprobe_my(task, ip);
1057                 if (err != 0) {
1058                         //TODO: ERROR
1059                         return err;
1060                 }
1061         }
1062
1063         page_p_installed(page_p);
1064
1065         spin_unlock(&page_p->lock);
1066
1067         return 0;
1068 }
1069
1070 static int unregister_us_page_probe(const struct task_struct *task,
1071                 struct page_probes *page_p, enum US_FLAGS flag)
1072 {
1073         int err = 0;
1074         struct us_ip *ip;
1075
1076         spin_lock(&page_p->lock);
1077         if (!page_p_is_install(page_p)) {
1078                 spin_unlock(&page_p->lock);
1079                 return 0;
1080         }
1081
1082         list_for_each_entry(ip, &page_p->ip_list, list) {
1083                 err = unregister_usprobe_my(task, ip, flag);
1084                 if (err != 0) {
1085                         //TODO: ERROR
1086                         break;
1087                 }
1088         }
1089
1090         if (flag != US_DISARM) {
1091                 page_p_uninstalled(page_p);
1092         }
1093         spin_unlock(&page_p->lock);
1094
1095         return err;
1096 }
1097
1098 static int check_vma(struct vm_area_struct *vma)
1099 {
1100 #ifndef __ANDROID
1101         return vma->vm_file && !(vma->vm_pgoff != 0 || !(vma->vm_flags & VM_EXEC) || (vma->vm_flags & VM_ACCOUNT) ||
1102                         !(vma->vm_flags & (VM_WRITE | VM_MAYWRITE)) ||
1103                         !(vma->vm_flags & (VM_READ | VM_MAYREAD)));
1104 #else // __ANDROID
1105         return vma->vm_file && !(vma->vm_pgoff != 0 || !(vma->vm_flags & VM_EXEC));
1106 #endif // __ANDROID
1107 }
1108
1109
1110 static void install_page_probes(unsigned long page, struct task_struct *task, struct proc_probes *proc_p, int atomic)
1111 {
1112         int lock;
1113         struct mm_struct *mm;
1114         struct vm_area_struct *vma;
1115
1116         mm_read_lock(task, mm, atomic, lock);
1117
1118         vma = find_vma(mm, page);
1119         if (vma && check_vma(vma)) {
1120                 struct file_probes *file_p = proc_p_find_file_p(proc_p, vma);
1121                 if (file_p) {
1122                         struct page_probes *page_p;
1123                         if (!file_p->loaded) {
1124                                 set_mapping_file(file_p, proc_p, task, vma);
1125                                 file_p->loaded = 1;
1126                         }
1127
1128                         page_p = file_p_find_page_p_mapped(file_p, page);
1129                         if (page_p) {
1130                                 register_us_page_probe(page_p, file_p, task);
1131                         }
1132                 }
1133         }
1134
1135         mm_read_unlock(mm, atomic, lock);
1136 }
1137
1138 static void install_file_probes(struct task_struct *task, struct mm_struct *mm, struct file_probes *file_p)
1139 {
1140         struct page_probes *page_p = NULL;
1141         struct hlist_node *node = NULL;
1142         struct hlist_head *head = NULL;
1143         int i, table_size = (1 << file_p->page_probes_hash_bits);
1144
1145         for (i = 0; i < table_size; ++i) {
1146                 head = &file_p->page_probes_table[i];
1147                 hlist_for_each_entry_rcu(page_p, node, head, hlist) {
1148                         if (page_present(mm, page_p->offset)) {
1149                                 register_us_page_probe(page_p, file_p, task);
1150                         }
1151                 }
1152         }
1153 }
1154
1155 static void install_proc_probes(struct task_struct *task, struct proc_probes *proc_p, int atomic)
1156 {
1157         int lock;
1158         struct vm_area_struct *vma;
1159         struct mm_struct *mm;
1160
1161         mm_read_lock(task, mm, atomic, lock);
1162
1163         for (vma = mm->mmap; vma; vma = vma->vm_next) {
1164                 if (check_vma(vma)) {
1165                         struct file_probes *file_p = proc_p_find_file_p(proc_p, vma);
1166                         if (file_p) {
1167                                 if (!file_p->loaded) {
1168                                         set_mapping_file(file_p, proc_p, task, vma);
1169                                         file_p->loaded = 1;
1170                                 }
1171
1172                                 install_file_probes(task, mm, file_p);
1173                         }
1174                 }
1175         }
1176
1177         mm_read_unlock(mm, atomic, lock);
1178 }
1179
1180 static int check_install_pages_in_file(struct task_struct *task, struct file_probes *file_p)
1181 {
1182         int i;
1183         int table_size = (1 << file_p->page_probes_hash_bits);
1184         struct page_probes *page_p;
1185         struct hlist_node *node, *tmp;
1186         struct hlist_head *head;
1187
1188         for (i = 0; i < table_size; ++i) {
1189                 head = &file_p->page_probes_table[i];
1190                 hlist_for_each_entry_safe (page_p, node, tmp, head, hlist) {
1191                         if (page_p->install) {
1192                                 return 1;
1193                         }
1194                 }
1195         }
1196
1197         return 0;
1198 }
1199
1200 static int unregister_us_file_probes(struct task_struct *task, struct file_probes *file_p, enum US_FLAGS flag)
1201 {
1202         int i, err = 0;
1203         int table_size = (1 << file_p->page_probes_hash_bits);
1204         struct page_probes *page_p;
1205         struct hlist_node *node, *tmp;
1206         struct hlist_head *head;
1207
1208         for (i = 0; i < table_size; ++i) {
1209                 head = &file_p->page_probes_table[i];
1210                 hlist_for_each_entry_safe (page_p, node, tmp, head, hlist) {
1211                         err = unregister_us_page_probe(task, page_p, flag);
1212                         if (err != 0) {
1213                                 // TODO: ERROR
1214                                 return err;
1215                         }
1216                 }
1217         }
1218
1219         if (flag != US_DISARM) {
1220                 file_p->loaded = 0;
1221         }
1222
1223         return err;
1224 }
1225
1226 static int uninstall_us_proc_probes(struct task_struct *task, struct proc_probes *proc_p, enum US_FLAGS flag)
1227 {
1228         int err;
1229         struct file_probes *file_p;
1230
1231         list_for_each_entry_rcu(file_p, &proc_p->file_list, list) {
1232                 err = unregister_us_file_probes(task, file_p, flag);
1233                 if (err != 0) {
1234                         // TODO:
1235                         return err;
1236                 }
1237         }
1238
1239         return err;
1240 }
1241
1242 static pid_t find_proc_by_task(const struct task_struct *task, const struct dentry *dentry)
1243 {
1244         struct vm_area_struct *vma;
1245         struct mm_struct *mm = task->active_mm;
1246         if (mm == NULL) {
1247                 return 0;
1248         }
1249
1250         for (vma = mm->mmap; vma; vma = vma->vm_next) {
1251                 if ((vma->vm_flags & VM_EXECUTABLE) && vma->vm_file) {
1252                         if (vma->vm_file->f_dentry == dentry) {
1253                                 return task->tgid;
1254                         }
1255 #ifdef SLP_APP
1256                         if (is_slp_app_with_dentry(vma, dentry)) {
1257                                 return task->tgid;
1258                         }
1259 #endif /* SLP_APP */
1260 #ifdef ANDROID_APP
1261                         if (is_android_app_with_dentry(vma, dentry)) {
1262                                 return task->tgid;
1263                         }
1264 #endif /* ANDROID_APP */
1265                 }
1266         }
1267
1268         return 0;
1269 }
1270
1271 void do_page_fault_ret_pre_code (void)
1272 {
1273         struct task_struct *task = current->group_leader;
1274         struct mm_struct *mm = task->mm;
1275         struct vm_area_struct *vma = 0;
1276         struct proc_probes *proc_p = NULL;
1277         /*
1278          * Because process threads have same address space
1279          * we instrument only group_leader of all this threads
1280          */
1281         unsigned long addr = 0;
1282         int valid_addr;
1283
1284         // overhead
1285         struct timeval imi_tv1;
1286         struct timeval imi_tv2;
1287 #define USEC_IN_SEC_NUM                         1000000
1288
1289         if (task->flags & PF_KTHREAD) {
1290                 DPRINTF("ignored kernel thread %d\n", task->pid);
1291                 return;
1292         }
1293
1294         if (!is_us_instrumentation()) {
1295                 return;
1296         }
1297
1298         addr = (unsigned long)swap_get_entry_data(&sa_dpf);
1299
1300         if (addr == 0) {
1301                 printk("WARNING: do_page_fault_ret_pre_code addr = 0\n");
1302                 return;
1303         }
1304
1305
1306
1307
1308         valid_addr = mm && page_present(mm, addr);
1309         if (!valid_addr) {
1310                 return;
1311         }
1312
1313         if (is_libonly()) {
1314                 proc_p = get_proc_probes_by_task_or_new(task);
1315         } else {
1316                 // find task
1317                 if (us_proc_info.tgid == 0) {
1318                         pid_t tgid = find_proc_by_task(task, us_proc_info.m_f_dentry);
1319                         if (tgid) {
1320                                 us_proc_info.tgid = gl_nNotifyTgid = tgid;
1321                         }
1322                 }
1323
1324                 if (us_proc_info.tgid == task->tgid) {
1325                         proc_p = us_proc_info.pp;
1326                 }
1327         }
1328
1329         if (proc_p) {
1330                 unsigned long page = addr & PAGE_MASK;
1331
1332 #ifdef __ANDROID
1333                 if (is_java_inst_enabled()) {
1334                         find_libdvm_for_task(task, &us_proc_info);
1335                 }
1336 #endif /* __ANDROID */
1337
1338                 // overhead
1339                 do_gettimeofday(&imi_tv1);
1340                 install_page_probes(page, task, proc_p, 1);
1341                 do_gettimeofday(&imi_tv2);
1342                 imi_sum_hit++;
1343                 imi_sum_time += ((imi_tv2.tv_sec - imi_tv1.tv_sec) *  USEC_IN_SEC_NUM +
1344                                 (imi_tv2.tv_usec - imi_tv1.tv_usec));
1345         }
1346 }
1347
1348 EXPORT_SYMBOL_GPL(do_page_fault_ret_pre_code);
1349
1350
1351 void do_exit_probe_pre_code (void)
1352 {
1353         // TODO: remove task
1354 }
1355 EXPORT_SYMBOL_GPL(do_exit_probe_pre_code);
1356
1357 int check_vma_area(struct vm_area_struct *vma, unsigned long start, unsigned long end)
1358 {
1359         return (vma->vm_start >= start && vma->vm_end <= end);
1360 }
1361
1362 void print_vma(struct mm_struct *mm)
1363 {
1364         struct vm_area_struct *vma;
1365         printk("### print_vma: START\n");\
1366         printk("### print_vma: START\n");
1367
1368         for (vma = mm->mmap; vma; vma = vma->vm_next) {
1369                 char *x = vma->vm_flags & VM_EXEC ? "x" : "-";
1370                 char *r = vma->vm_flags & VM_READ ? "r" : "-";
1371                 char *w = vma->vm_flags & VM_WRITE ? "w" : "-";
1372                 char *name = vma->vm_file ? vma->vm_file->f_dentry->d_iname : "N/A";
1373
1374                 printk("### [%8x..%8x] %s%s%s pgoff=\'%8u\' %s\n",
1375                                 vma->vm_start, vma->vm_end, x, r, w, vma->vm_pgoff, name);
1376         }
1377         printk("### print_vma:  END\n");
1378 }
1379
1380 static int remove_unmap_probes(struct task_struct *task, struct proc_probes *proc_p, unsigned long start, size_t len)
1381 {
1382         struct mm_struct *mm = task->mm;
1383         struct vm_area_struct *vma;
1384         unsigned long end, pointer, step;
1385
1386         if ((start & ~PAGE_MASK) || start > TASK_SIZE || len > TASK_SIZE - start) {
1387                 return -EINVAL;
1388         }
1389
1390         if ((len = PAGE_ALIGN(len)) == 0) {
1391                 return -EINVAL;
1392         }
1393
1394         vma = find_vma(mm, start);
1395         if (vma && check_vma(vma)) {
1396                 struct file_probes *file_p;
1397                 unsigned long end = start + len;
1398
1399                 file_p = proc_p_find_file_p(proc_p, vma);
1400                 if (file_p) {
1401                         if (vma->vm_start == start || vma->vm_end == end) {
1402                                 unregister_us_file_probes(task, file_p, US_NOT_RP2);
1403                                 file_p->loaded = 0;
1404                         } else {
1405                                 unsigned long page;
1406                                 struct page_probes *page_p;
1407
1408                                 for (page = vma->vm_start; page < vma->vm_end; page += PAGE_SIZE) {
1409                                         page_p = file_p_find_page_p_mapped(file_p, page);
1410                                         if (page_p) {
1411                                                 unregister_us_page_probe(task, page_p, US_NOT_RP2);
1412                                         }
1413                                 }
1414
1415                                 if (check_install_pages_in_file(task, file_p)) {
1416                                         file_p->loaded = 0;
1417                                 }
1418                         }
1419                 }
1420         }
1421
1422         return 0;
1423 }
1424
1425 void do_munmap_probe_pre_code(struct mm_struct *mm, unsigned long start, size_t len)
1426 {
1427         struct proc_probes *proc_p = NULL;
1428         struct task_struct *task = current;
1429
1430         //if user-space instrumentation is not set
1431         if (!is_us_instrumentation()) {
1432                 return;
1433         }
1434
1435         if (is_libonly()) {
1436                 proc_p = get_proc_probes_by_task(task);
1437         } else {
1438                 if (task->tgid == us_proc_info.tgid) {
1439                         proc_p = us_proc_info.pp;
1440                 }
1441         }
1442
1443         if (proc_p) {
1444                 if (remove_unmap_probes(task, proc_p, start, len)) {
1445                         printk("ERROR do_munmap: start=%x, len=%x\n", start, len);
1446                 }
1447         }
1448 }
1449 EXPORT_SYMBOL_GPL(do_munmap_probe_pre_code);
1450
1451 void mm_release_probe_pre_code(void)
1452 {
1453         struct task_struct *task = current;
1454         struct proc_probes *proc_p = NULL;
1455
1456         if (!is_us_instrumentation() || task->tgid != task->pid) {
1457                 return;
1458         }
1459
1460         if (is_libonly()) {
1461                 proc_p = get_proc_probes_by_task(task);
1462         } else {
1463                 if (task->tgid == us_proc_info.tgid) {
1464                         proc_p = get_proc_probes_by_task(task);
1465                         us_proc_info.tgid = 0;
1466                 }
1467         }
1468
1469         if (proc_p) {
1470                 int ret = uninstall_us_proc_probes(task, proc_p, US_NOT_RP2);
1471                 if (ret != 0) {
1472                         EPRINTF ("failed to uninstall IPs (%d)!", ret);
1473                 }
1474
1475                 dbi_unregister_all_uprobes(task, 1);
1476         }
1477 }
1478 EXPORT_SYMBOL_GPL(mm_release_probe_pre_code);
1479
1480
1481 static void recover_child(struct task_struct *child_task, struct proc_probes *proc_p)
1482 {
1483         uninstall_us_proc_probes(child_task, proc_p, US_DISARM);
1484 }
1485
1486 static void rm_uprobes_child(struct task_struct *new_task)
1487 {
1488         if (is_libonly()) {
1489                 struct proc_probes *proc_p = get_proc_probes_by_task(current);
1490                 if(proc_p) {
1491                         recover_child(new_task, proc_p);
1492                 }
1493         } else {
1494                 if(us_proc_info.tgid == current->tgid) {
1495                         recover_child(new_task, us_proc_info.pp);
1496                 }
1497         }
1498 }
1499
1500 void copy_process_ret_pre_code(struct task_struct *p)
1501 {
1502         if(!p || IS_ERR(p))
1503                 return;
1504
1505         if(p->mm != current->mm)    // check flags CLONE_VM
1506                 rm_uprobes_child(p);
1507 }
1508
1509
1510 DEFINE_PER_CPU(struct us_ip *, gpCurIp) = NULL;
1511 EXPORT_PER_CPU_SYMBOL_GPL(gpCurIp);
1512 DEFINE_PER_CPU(struct pt_regs *, gpUserRegs) = NULL;
1513 EXPORT_PER_CPU_SYMBOL_GPL(gpUserRegs);
1514
1515
1516 unsigned long ujprobe_event_pre_handler(struct us_ip *ip, struct pt_regs *regs)
1517 {
1518         __get_cpu_var (gpCurIp) = ip;
1519         __get_cpu_var (gpUserRegs) = regs;
1520         return 0;
1521 }
1522
1523 #ifdef __ANDROID
1524 int handle_java_event(unsigned long addr)
1525 {
1526         unsigned long start = 0;
1527         struct pt_regs *regs = __get_cpu_var(gpUserRegs);
1528
1529         if (is_libonly()) {
1530                 /* TODO: some stuff here */
1531         } else {
1532                 start = us_proc_info.libdvm_start;
1533         }
1534         unsigned long end = us_proc_info.libdvm_end;
1535
1536         if (addr == start + LIBDVM_ENTRY) {
1537                 unsigned long *p_met = (unsigned long *)regs->ARM_r0;
1538                 char *met_name = p_met ? (char *)(p_met[4]) : 0;
1539                 unsigned long *p_cl = p_met ? (unsigned long *)p_met[0] : 0;
1540                 char *cl_name = p_cl ? (char *)(p_cl[6]) : 0;
1541                 if (!cl_name || !met_name) {
1542                         EPRINTF("warn: class name or method name null\n");
1543                 } else {
1544                         pack_event_info(JAVA_PROBE_ID, RECORD_ENTRY, "pss", addr, cl_name, met_name);
1545                 }
1546                 dbi_uprobe_return ();
1547                 return 1;
1548         }
1549
1550         if (addr == start + LIBDVM_RETURN) {
1551                 unsigned long *p_th = (unsigned long *)regs->ARM_r6;
1552                 unsigned long *p_st = p_th;
1553                 unsigned long *p_met = p_st ? (unsigned long *)p_st[2] : 0;
1554                 char *met_name = p_met ? (char *)(p_met[4]) : 0;
1555                 unsigned long *p_cl = p_met ? (unsigned long *)p_met[0] : 0;
1556                 char *cl_name = p_cl ? (char *)(p_cl[6]) : 0;
1557                 if (!cl_name || !met_name) {
1558                         EPRINTF("warn: class name or method name null\n");
1559                 } else {
1560                         pack_event_info(JAVA_PROBE_ID, RECORD_RET, "pss", addr, cl_name, met_name);
1561                 }
1562                 dbi_uprobe_return ();
1563                 return 1;
1564         }
1565
1566         return 0;
1567 }
1568 #endif /* __ANDROID */
1569
1570 void ujprobe_event_handler (unsigned long arg1, unsigned long arg2, unsigned long arg3, unsigned long arg4, unsigned long arg5, unsigned long arg6)
1571 {
1572         struct us_ip *ip = __get_cpu_var(gpCurIp);
1573         unsigned long addr = (unsigned long)ip->jprobe.kp.addr;
1574
1575 #ifdef __ANDROID
1576         if (is_java_inst_enabled() && handle_java_event(addr)) {
1577                 return;
1578         }
1579 #endif /* __ANDROID */
1580
1581
1582 #if defined(CONFIG_ARM)
1583         if (ip->offset & 0x01)
1584         {
1585                 pack_event_info (US_PROBE_ID, RECORD_ENTRY, "ppppppp", addr | 0x01, arg1, arg2, arg3, arg4, arg5, arg6);
1586         }else{
1587                 pack_event_info (US_PROBE_ID, RECORD_ENTRY, "ppppppp", addr, arg1, arg2, arg3, arg4, arg5, arg6);
1588         }
1589 #else
1590         pack_event_info (US_PROBE_ID, RECORD_ENTRY, "ppppppp", addr, arg1, arg2, arg3, arg4, arg5, arg6);
1591 #endif
1592         // Mr_Nobody: uncomment for valencia
1593         //unregister_usprobe(current, ip, 1);
1594         dbi_uprobe_return ();
1595 }
1596
1597 void send_plt(struct us_ip *ip)
1598 {
1599         unsigned long addr = (unsigned long)ip->jprobe.kp.addr;
1600         struct vm_area_struct *vma = find_vma(current->mm, addr);
1601
1602         if (vma && check_vma(vma)) {
1603                 char *name = NULL;
1604                 unsigned long real_addr;
1605                 unsigned long real_got = vma->vm_flags & VM_EXECUTABLE ?
1606                                 ip->got_addr :
1607                                 ip->got_addr + vma->vm_start;
1608
1609                 if (!read_proc_vm_atomic(current, real_got, &real_addr, sizeof(real_addr))) {
1610                         printk("Failed to read got %p at memory address %p!\n", ip->got_addr, real_got);
1611                         return;
1612                 }
1613
1614                 vma = find_vma(current->mm, real_addr);
1615                 if (vma && (vma->vm_start <= real_addr) && (vma->vm_end > real_addr)) {
1616                         name = vma->vm_file ? vma->vm_file->f_dentry->d_iname : NULL;
1617                 } else {
1618                         printk("Failed to get vma, includes %x address\n", real_addr);
1619                         return;
1620                 }
1621
1622                 if (name) {
1623                         pack_event_info(PLT_ADDR_PROBE_ID, RECORD_RET, "ppsp", addr, real_addr, name, real_addr - vma->vm_start);
1624                 } else {
1625                         pack_event_info(PLT_ADDR_PROBE_ID, RECORD_RET, "ppp", addr, real_addr, real_addr - vma->vm_start);
1626                 }
1627         }
1628 }
1629
1630 int uretprobe_event_handler(struct kretprobe_instance *probe, struct pt_regs *regs, struct us_ip *ip)
1631 {
1632         int retval = regs_return_value(regs);
1633         unsigned long addr = (unsigned long)ip->jprobe.kp.addr;
1634
1635         if (ip->got_addr && ip->flag_got == 0) {
1636                 send_plt(ip);
1637                 ip->flag_got = 1;
1638         }
1639
1640 #if defined(CONFIG_ARM)
1641         if (ip->offset & 0x01)
1642         {
1643                 pack_event_info (US_PROBE_ID, RECORD_RET, "pd", addr | 0x01, retval);
1644         }else{
1645                 pack_event_info (US_PROBE_ID, RECORD_RET, "pd", addr, retval);
1646         }
1647 #else
1648         pack_event_info (US_PROBE_ID, RECORD_RET, "pd", addr, retval);
1649 #endif
1650         // Mr_Nobody: uncomment for valencia
1651         //unregister_usprobe(current, ip, 1);
1652         return 0;
1653 }
1654
1655 static int register_usprobe(struct task_struct *task, struct us_ip *ip, int atomic)
1656 {
1657         int ret = 0;
1658         ip->jprobe.kp.tgid = task->tgid;
1659
1660         if (ip->jprobe.entry == NULL) {
1661                 ip->jprobe.entry = (kprobe_opcode_t *)ujprobe_event_handler;
1662                 DPRINTF("Set default event handler for %x\n", ip->offset);
1663         }
1664
1665         if (ip->jprobe.pre_entry == NULL) {
1666                 ip->jprobe.pre_entry = (kprobe_pre_entry_handler_t)ujprobe_event_pre_handler;
1667                 DPRINTF("Set default pre handler for %x\n", ip->offset);
1668         }
1669
1670         ip->jprobe.priv_arg = ip;
1671         ret = dbi_register_ujprobe(task, &ip->jprobe, atomic);
1672         if (ret) {
1673                 DPRINTF ("dbi_register_ujprobe() failure %d", ret);
1674                 return ret;
1675         }
1676
1677         if (ip->flag_retprobe) {
1678                 // Mr_Nobody: comment for valencia
1679                 ip->retprobe.kp.tgid = task->tgid;
1680                 if (ip->retprobe.handler == NULL) {
1681                         ip->retprobe.handler = (kretprobe_handler_t)uretprobe_event_handler;
1682                         DPRINTF("Set default ret event handler for %x\n", ip->offset);
1683                 }
1684
1685                 ip->retprobe.priv_arg = ip;
1686                 ret = dbi_register_uretprobe(task, &ip->retprobe, atomic);
1687                 if (ret) {
1688                         EPRINTF ("dbi_register_uretprobe() failure %d", ret);
1689                         return ret;
1690                 }
1691         }
1692
1693         return 0;
1694 }
1695
1696 static int unregister_usprobe(struct task_struct *task, struct us_ip *ip, int atomic, int not_rp2)
1697 {
1698         dbi_unregister_ujprobe(task, &ip->jprobe, atomic);
1699
1700         if (ip->flag_retprobe) {
1701                 dbi_unregister_uretprobe(task, &ip->retprobe, atomic, not_rp2);
1702         }
1703
1704         return 0;
1705 }
1706
1707 unsigned long get_stack_size(struct task_struct *task,
1708                 struct pt_regs *regs)
1709 {
1710 #ifdef CONFIG_ADD_THREAD_STACK_INFO
1711         return (task->stack_start - dbi_get_stack_ptr(regs));
1712 #else
1713         struct vm_area_struct *vma = NULL;
1714         struct mm_struct *mm = NULL;
1715         unsigned long result = 0;
1716     int atomic = in_atomic();
1717
1718         mm = (atomic ? task->active_mm: get_task_mm(task));
1719
1720         if (mm) {
1721                 if (!atomic)
1722                         down_read(&mm->mmap_sem);
1723
1724                 vma = find_vma(mm, dbi_get_stack_ptr(regs));
1725
1726                 if (vma)
1727                         result = vma->vm_end - dbi_get_stack_ptr(regs);
1728                 else
1729                         result = 0;
1730
1731                 if (!atomic) {
1732                         up_read(&mm->mmap_sem);
1733                         mmput(mm);
1734                 }
1735         }
1736
1737         return result;
1738 #endif
1739 }
1740 EXPORT_SYMBOL_GPL(get_stack_size);
1741
1742 unsigned long get_stack(struct task_struct *task, struct pt_regs *regs,
1743                 char *buf, unsigned long sz)
1744 {
1745         unsigned long stack_sz = get_stack_size(task, regs);
1746         unsigned long real_sz = (stack_sz > sz ? sz: stack_sz);
1747         int res = read_proc_vm_atomic(task, dbi_get_stack_ptr(regs), buf, real_sz);
1748         return res;
1749 }
1750 EXPORT_SYMBOL_GPL(get_stack);
1751
1752 int dump_to_trace(probe_id_t probe_id, void *addr, const char *buf,
1753                 unsigned long sz)
1754 {
1755         unsigned long rest_sz = sz;
1756         const char *data = buf;
1757
1758         while (rest_sz >= EVENT_MAX_SIZE) {
1759                 pack_event_info(probe_id, RECORD_ENTRY, "pa",
1760                                 addr, EVENT_MAX_SIZE, data);
1761                 rest_sz -= EVENT_MAX_SIZE;
1762                 data += EVENT_MAX_SIZE;
1763         }
1764
1765         if (rest_sz > 0)
1766                 pack_event_info(probe_id, RECORD_ENTRY, "pa", addr, rest_sz, data);
1767
1768         return 0;
1769 }
1770 EXPORT_SYMBOL_GPL(dump_to_trace);
1771
1772 int dump_backtrace(probe_id_t probe_id, struct task_struct *task,
1773                 void *addr, struct pt_regs *regs, unsigned long sz)
1774 {
1775         unsigned long real_sz = 0;
1776         char *buf = NULL;
1777
1778         buf = (char *)kmalloc(sz, GFP_ATOMIC);
1779
1780         if (buf != NULL) {
1781                 real_sz = get_stack(task, regs, buf, sz);
1782                 if (real_sz > 0)
1783                         dump_to_trace(probe_id, addr, buf, real_sz);
1784                 kfree(buf);
1785                 return 0;
1786         } else {
1787                 return -1;
1788         }
1789 }
1790 EXPORT_SYMBOL_GPL(dump_backtrace);
1791
1792 unsigned long get_ret_addr(struct task_struct *task, struct us_ip *ip)
1793 {
1794         unsigned long retaddr = 0;
1795         struct hlist_node *item, *tmp_node;
1796         struct kretprobe_instance *ri;
1797
1798         if (ip) {
1799                 hlist_for_each_safe (item, tmp_node, &ip->retprobe.used_instances) {
1800                         ri = hlist_entry (item, struct kretprobe_instance, uflist);
1801
1802                         if (ri->task && ri->task->pid == task->pid &&
1803                                         ri->task->tgid == task->tgid)
1804                                 retaddr = (unsigned long)ri->ret_addr;
1805                 }
1806         }
1807
1808         if (retaddr)
1809                 return retaddr;
1810         else
1811                 return dbi_get_ret_addr(task_pt_regs(task));
1812 }
1813 EXPORT_SYMBOL_GPL(get_ret_addr);
1814