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