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