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