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