[FIX] Correct addr in do_page_fault_j_pre_code
[kernel/swap-modules.git] / driver / us_proc_inst.c
1 ////////////////////////////////////////////////////////////////////////////////////
2 //
3 //      FILE:           us_proc_inst.c
4 //
5 //      DESCRIPTION:
6 //      This file is C source for SWAP driver.
7 //
8 //      SEE ALSO:       us_proc_inst.h
9 //      AUTHOR:         A.Gerenkov, E. Gorelkina
10 //      COMPANY NAME:   Samsung Research Center in Moscow
11 //      DEPT NAME:      Advanced Software Group
12 //      CREATED:        2008.06.02
13 //      VERSION:        1.0
14 //      REVISION DATE:  2008.12.02
15 //
16 ////////////////////////////////////////////////////////////////////////////////////
17
18 #include "module.h"
19 #include "us_proc_inst.h"
20
21 #include "../kprobe/dbi_kprobes_deps.h"
22 #include "../kprobe/dbi_uprobes.h"
23
24 #include "sspt/sspt.h"
25 #include "java_inst.h"
26
27 #define mm_read_lock(task, mm, atomic, lock)                    \
28         mm = atomic ? task->active_mm : get_task_mm(task);      \
29         if (mm == NULL) {                                       \
30                 /* FIXME: */                                    \
31                 panic("ERRR mm_read_lock: mm == NULL\n");       \
32         }                                                       \
33                                                                 \
34         if (atomic) {                                           \
35                 lock = down_read_trylock(&mm->mmap_sem);        \
36         } else {                                                \
37                 lock = 1;                                       \
38                 down_read(&mm->mmap_sem);                       \
39         }
40
41 #define mm_read_unlock(mm, atomic, lock)                        \
42         if (lock) {                                             \
43                 up_read(&mm->mmap_sem);                         \
44         }                                                       \
45                                                                 \
46         if (!atomic) {                                          \
47                 mmput(mm);                                      \
48         }
49
50 #if defined(CONFIG_MIPS)
51 #       define ARCH_REG_VAL(regs, idx)  regs->regs[idx]
52 #elif defined(CONFIG_ARM)
53 #       define ARCH_REG_VAL(regs, idx)  regs->uregs[idx]
54 #else
55 #       define ARCH_REG_VAL(regs, idx)  0
56 #       warning ARCH_REG_VAL is not implemented for this architecture. FBI will work improperly or even crash!!!
57 #endif // ARCH
58
59 unsigned long ujprobe_event_pre_handler (struct us_ip *ip, struct pt_regs *regs);
60 void ujprobe_event_handler (unsigned long arg1, unsigned long arg2, unsigned long arg3, unsigned long arg4, unsigned long arg5, unsigned long arg6);
61 int uretprobe_event_handler (struct kretprobe_instance *probe, struct pt_regs *regs, struct us_ip *ip);
62
63
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                         kretprobe_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                 // for x86 do_page_fault is do_page_fault(struct pt_regs *regs, unsigned long error_code)
638                 // instead of do_page_fault(unsigned long addr, unsigned int fsr, struct pt_regs *regs) for arm
639 #ifdef CONFIG_X86
640                 unsigned long address = read_cr2();
641                 swap_put_entry_data((void *)address, &sa_dpf);
642 #else /* CONFIG_X86 */
643                 swap_put_entry_data((void *)addr, &sa_dpf);
644 #endif /* CONFIG_X86 */
645         }
646 }
647 EXPORT_SYMBOL_GPL(do_page_fault_j_pre_code);
648
649
650 unsigned long imi_sum_time = 0;
651 unsigned long imi_sum_hit = 0;
652
653 static void set_mapping_file(struct sspt_file *file,
654                 const struct sspt_procs *procs,
655                 const struct task_struct *task,
656                 const struct vm_area_struct *vma)
657 {
658         int app_flag = (vma->vm_file->f_dentry == procs->dentry);
659
660         file->vm_start = vma->vm_start;
661         file->vm_end = vma->vm_end;
662
663         pack_event_info(DYN_LIB_PROBE_ID, RECORD_ENTRY, "dspdd",
664                         task->tgid, file->name, vma->vm_start,
665                         vma->vm_end - vma->vm_start, app_flag);
666 }
667
668 void print_vma(struct mm_struct *mm);
669
670 static int register_us_page_probe(struct sspt_page *page,
671                 const struct sspt_file *file,
672                 struct task_struct *task)
673 {
674         int err = 0;
675         struct us_ip *ip, *n;
676
677         spin_lock(&page->lock);
678
679         if (sspt_page_is_install(page)) {
680                 printk("page %lx in %s task[tgid=%u, pid=%u] already installed\n",
681                                 page->offset, file->dentry->d_iname, task->tgid, task->pid);
682                 print_vma(task->mm);
683                 goto unlock;
684         }
685
686         sspt_page_assert_install(page);
687         sspt_set_all_ip_addr(page, file);
688
689         list_for_each_entry_safe(ip, n, &page->ip_list, list) {
690                 err = register_usprobe_my(task, ip);
691                 if (err == -ENOEXEC) {
692                         list_del(&ip->list);
693                         free_ip(ip);
694                         continue;
695                 } else if (err) {
696                         EPRINTF("Failed to install probe");
697                 }
698         }
699 unlock:
700         sspt_page_installed(page);
701         spin_unlock(&page->lock);
702
703         return 0;
704 }
705
706 static int unregister_us_page_probe(struct task_struct *task,
707                 struct sspt_page *page, enum US_FLAGS flag)
708 {
709         int err = 0;
710         struct us_ip *ip;
711
712         spin_lock(&page->lock);
713         if (!sspt_page_is_install(page)) {
714                 spin_unlock(&page->lock);
715                 return 0;
716         }
717
718         list_for_each_entry(ip, &page->ip_list, list) {
719                 err = unregister_usprobe_my(task, ip, flag);
720                 if (err != 0) {
721                         //TODO: ERROR
722                         break;
723                 }
724         }
725
726         if (flag != US_DISARM) {
727                 sspt_page_uninstalled(page);
728         }
729         spin_unlock(&page->lock);
730
731         return err;
732 }
733
734 static void install_page_probes(unsigned long page_addr, struct task_struct *task, struct sspt_procs *procs, int atomic)
735 {
736         int lock;
737         struct mm_struct *mm;
738         struct vm_area_struct *vma;
739
740         mm_read_lock(task, mm, atomic, lock);
741
742         vma = find_vma(mm, page_addr);
743         if (vma && check_vma(vma)) {
744                 struct dentry *dentry = vma->vm_file->f_dentry;
745                 struct sspt_file *file = sspt_procs_find_file(procs, dentry);
746                 if (file) {
747                         struct sspt_page *page;
748                         if (!file->loaded) {
749                                 set_mapping_file(file, procs, task, vma);
750                                 file->loaded = 1;
751                         }
752
753                         page = sspt_find_page_mapped(file, page_addr);
754                         if (page) {
755                                 register_us_page_probe(page, file, task);
756                         }
757                 }
758         }
759
760         mm_read_unlock(mm, atomic, lock);
761 }
762
763 static void install_file_probes(struct task_struct *task, struct mm_struct *mm, struct sspt_file *file)
764 {
765         struct sspt_page *page = NULL;
766         struct hlist_node *node = NULL;
767         struct hlist_head *head = NULL;
768         int i, table_size = (1 << file->page_probes_hash_bits);
769
770         for (i = 0; i < table_size; ++i) {
771                 head = &file->page_probes_table[i];
772                 swap_hlist_for_each_entry_rcu(page, node, head, hlist) {
773                         register_us_page_probe(page, file, task);
774                 }
775         }
776 }
777
778 static void install_proc_probes(struct task_struct *task, struct sspt_procs *procs, int atomic)
779 {
780         int lock;
781         struct vm_area_struct *vma;
782         struct mm_struct *mm;
783
784         mm_read_lock(task, mm, atomic, lock);
785
786         for (vma = mm->mmap; vma; vma = vma->vm_next) {
787                 if (check_vma(vma)) {
788                         struct dentry *dentry = vma->vm_file->f_dentry;
789                         struct sspt_file *file = sspt_procs_find_file(procs, dentry);
790                         if (file) {
791                                 if (!file->loaded) {
792                                         set_mapping_file(file, procs, task, vma);
793                                         file->loaded = 1;
794                                 }
795
796                                 install_file_probes(task, mm, file);
797                         }
798                 }
799         }
800
801         mm_read_unlock(mm, atomic, lock);
802 }
803
804 static int check_install_pages_in_file(struct task_struct *task, struct sspt_file *file)
805 {
806         int i;
807         int table_size = (1 << file->page_probes_hash_bits);
808         struct sspt_page *page;
809         struct hlist_node *node, *tmp;
810         struct hlist_head *head;
811
812         for (i = 0; i < table_size; ++i) {
813                 head = &file->page_probes_table[i];
814                 swap_hlist_for_each_entry_safe (page, node, tmp, head, hlist) {
815                         if (page->install) {
816                                 return 1;
817                         }
818                 }
819         }
820
821         return 0;
822 }
823
824 static int unregister_us_file_probes(struct task_struct *task, struct sspt_file *file, enum US_FLAGS flag)
825 {
826         int i, err = 0;
827         int table_size = (1 << file->page_probes_hash_bits);
828         struct sspt_page *page;
829         struct hlist_node *node, *tmp;
830         struct hlist_head *head;
831
832         for (i = 0; i < table_size; ++i) {
833                 head = &file->page_probes_table[i];
834                 swap_hlist_for_each_entry_safe (page, node, tmp, head, hlist) {
835                         err = unregister_us_page_probe(task, page, flag);
836                         if (err != 0) {
837                                 // TODO: ERROR
838                                 return err;
839                         }
840                 }
841         }
842
843         if (flag != US_DISARM) {
844                 file->loaded = 0;
845         }
846
847         return err;
848 }
849
850 static int uninstall_us_proc_probes(struct task_struct *task, struct sspt_procs *procs, enum US_FLAGS flag)
851 {
852         int err = 0;
853         struct sspt_file *file;
854
855         list_for_each_entry_rcu(file, &procs->file_list, list) {
856                 err = unregister_us_file_probes(task, file, flag);
857                 if (err != 0) {
858                         // TODO:
859                         return err;
860                 }
861         }
862
863         return err;
864 }
865
866 static pid_t find_proc_by_task(const struct task_struct *task, struct dentry *dentry)
867 {
868         struct vm_area_struct *vma;
869         struct mm_struct *mm = task->active_mm;
870         if (mm == NULL) {
871                 return 0;
872         }
873
874         for (vma = mm->mmap; vma; vma = vma->vm_next) {
875                 if (check_vma(vma)) {
876                         if (vma->vm_file->f_dentry == dentry) {
877                                 return task->tgid;
878                         }
879 #ifdef SLP_APP
880                         if (is_slp_app_with_dentry(vma, dentry)) {
881                                 return task->tgid;
882                         }
883 #endif /* SLP_APP */
884 #ifdef ANDROID_APP
885                         if (is_android_app_with_dentry(vma, dentry)) {
886                                 return task->tgid;
887                         }
888 #endif /* ANDROID_APP */
889                 }
890         }
891
892         return 0;
893 }
894
895 void do_page_fault_ret_pre_code (void)
896 {
897         struct task_struct *task = current->group_leader;
898         struct mm_struct *mm = task->mm;
899         struct sspt_procs *procs = NULL;
900         /*
901          * Because process threads have same address space
902          * we instrument only group_leader of all this threads
903          */
904         unsigned long addr = 0;
905         int valid_addr;
906
907         // overhead
908         struct timeval imi_tv1;
909         struct timeval imi_tv2;
910 #define USEC_IN_SEC_NUM                         1000000
911
912         if (task->flags & PF_KTHREAD) {
913                 DPRINTF("ignored kernel thread %d\n", task->pid);
914                 return;
915         }
916
917         if (!is_us_instrumentation()) {
918                 return;
919         }
920
921         addr = (unsigned long)swap_get_entry_data(&sa_dpf);
922
923         if (addr == 0) {
924                 printk("WARNING: do_page_fault_ret_pre_code addr = 0\n");
925                 return;
926         }
927
928
929
930
931         valid_addr = mm && page_present(mm, addr);
932         if (!valid_addr) {
933                 return;
934         }
935
936         if (is_libonly()) {
937                 procs = get_proc_probes_by_task_or_new(task);
938         } else {
939                 // find task
940                 if (us_proc_info.tgid == 0) {
941                         pid_t tgid = find_proc_by_task(task, us_proc_info.m_f_dentry);
942                         if (tgid) {
943                                 us_proc_info.tgid = gl_nNotifyTgid = tgid;
944
945                                 /* install probes in already mapped memory */
946                                 install_proc_probes(task, us_proc_info.pp, 1);
947                         }
948                 }
949
950                 if (us_proc_info.tgid == task->tgid) {
951                         procs = us_proc_info.pp;
952                 }
953         }
954
955         if (procs) {
956                 unsigned long page = addr & PAGE_MASK;
957
958                 // overhead
959                 do_gettimeofday(&imi_tv1);
960                 install_page_probes(page, task, procs, 1);
961                 do_gettimeofday(&imi_tv2);
962                 imi_sum_hit++;
963                 imi_sum_time += ((imi_tv2.tv_sec - imi_tv1.tv_sec) *  USEC_IN_SEC_NUM +
964                                 (imi_tv2.tv_usec - imi_tv1.tv_usec));
965         }
966 }
967
968 EXPORT_SYMBOL_GPL(do_page_fault_ret_pre_code);
969
970
971 void do_exit_probe_pre_code (void)
972 {
973         // TODO: remove task
974 }
975 EXPORT_SYMBOL_GPL(do_exit_probe_pre_code);
976
977 void print_vma(struct mm_struct *mm)
978 {
979         struct vm_area_struct *vma;
980         printk("### print_vma: START\n");\
981         printk("### print_vma: START\n");
982
983         for (vma = mm->mmap; vma; vma = vma->vm_next) {
984                 char *x = vma->vm_flags & VM_EXEC ? "x" : "-";
985                 char *r = vma->vm_flags & VM_READ ? "r" : "-";
986                 char *w = vma->vm_flags & VM_WRITE ? "w" : "-";
987                 char *name = vma->vm_file ? (char *)vma->vm_file->f_dentry->d_iname : "N/A";
988
989                 printk("### [%8lx..%8lx] %s%s%s pgoff=\'%8lu\' %s\n",
990                                 vma->vm_start, vma->vm_end, x, r, w, vma->vm_pgoff, name);
991         }
992         printk("### print_vma:  END\n");
993 }
994
995 static int remove_unmap_probes(struct task_struct *task, struct sspt_procs *procs, unsigned long start, size_t len)
996 {
997         struct mm_struct *mm = task->mm;
998         struct vm_area_struct *vma;
999
1000         if ((start & ~PAGE_MASK) || start > TASK_SIZE || len > TASK_SIZE - start) {
1001                 return -EINVAL;
1002         }
1003
1004         if ((len = PAGE_ALIGN(len)) == 0) {
1005                 return -EINVAL;
1006         }
1007
1008         vma = find_vma(mm, start);
1009         if (vma && check_vma(vma)) {
1010                 struct sspt_file *file;
1011                 unsigned long end = start + len;
1012                 struct dentry *dentry = vma->vm_file->f_dentry;
1013
1014                 file = sspt_procs_find_file(procs, dentry);
1015                 if (file) {
1016                         if (vma->vm_start == start || vma->vm_end == end) {
1017                                 unregister_us_file_probes(task, file, US_NOT_RP2);
1018                                 file->loaded = 0;
1019                         } else {
1020                                 unsigned long page_addr;
1021                                 struct sspt_page *page;
1022
1023                                 for (page_addr = vma->vm_start; page_addr < vma->vm_end; page_addr += PAGE_SIZE) {
1024                                         page = sspt_find_page_mapped(file, page_addr);
1025                                         if (page) {
1026                                                 unregister_us_page_probe(task, page, US_NOT_RP2);
1027                                         }
1028                                 }
1029
1030                                 if (check_install_pages_in_file(task, file)) {
1031                                         file->loaded = 0;
1032                                 }
1033                         }
1034                 }
1035         }
1036
1037         return 0;
1038 }
1039
1040 void do_munmap_probe_pre_code(struct mm_struct *mm, unsigned long start, size_t len)
1041 {
1042         struct sspt_procs *procs = NULL;
1043         struct task_struct *task = current;
1044
1045         //if user-space instrumentation is not set
1046         if (!is_us_instrumentation()) {
1047                 return;
1048         }
1049
1050         if (is_libonly()) {
1051                 procs = get_proc_probes_by_task(task);
1052         } else {
1053                 if (task->tgid == us_proc_info.tgid) {
1054                         procs = us_proc_info.pp;
1055                 }
1056         }
1057
1058         if (procs) {
1059                 if (remove_unmap_probes(task, procs, start, len)) {
1060                         printk("ERROR do_munmap: start=%lx, len=%x\n", start, len);
1061                 }
1062         }
1063 }
1064 EXPORT_SYMBOL_GPL(do_munmap_probe_pre_code);
1065
1066 void mm_release_probe_pre_code(void)
1067 {
1068         struct task_struct *task = current;
1069         struct sspt_procs *procs = NULL;
1070
1071         if (!is_us_instrumentation() || task->tgid != task->pid) {
1072                 return;
1073         }
1074
1075         if (is_libonly()) {
1076                 procs = get_proc_probes_by_task(task);
1077         } else {
1078                 if (task->tgid == us_proc_info.tgid) {
1079                         procs = get_proc_probes_by_task(task);
1080                         us_proc_info.tgid = 0;
1081                 }
1082         }
1083
1084         if (procs) {
1085                 int ret = uninstall_us_proc_probes(task, procs, US_NOT_RP2);
1086                 if (ret != 0) {
1087                         EPRINTF ("failed to uninstall IPs (%d)!", ret);
1088                 }
1089
1090                 dbi_unregister_all_uprobes(task, 1);
1091         }
1092 }
1093 EXPORT_SYMBOL_GPL(mm_release_probe_pre_code);
1094
1095
1096 static void recover_child(struct task_struct *child_task, struct sspt_procs *procs)
1097 {
1098         uninstall_us_proc_probes(child_task, procs, US_DISARM);
1099         dbi_disarm_urp_inst_for_task(current, child_task);
1100 }
1101
1102 static void rm_uprobes_child(struct task_struct *new_task)
1103 {
1104         if (is_libonly()) {
1105                 struct sspt_procs *procs = get_proc_probes_by_task(current);
1106                 if(procs) {
1107                         recover_child(new_task, procs);
1108                 }
1109         } else {
1110                 if(us_proc_info.tgid == current->tgid) {
1111                         recover_child(new_task, us_proc_info.pp);
1112                 }
1113         }
1114 }
1115
1116 void copy_process_ret_pre_code(struct task_struct *p)
1117 {
1118         if(!p || IS_ERR(p))
1119                 return;
1120
1121         if(p->mm != current->mm)    // check flags CLONE_VM
1122                 rm_uprobes_child(p);
1123 }
1124
1125 static DEFINE_PER_CPU(struct us_ip *, gpCurIp) = NULL;
1126 EXPORT_PER_CPU_SYMBOL_GPL(gpCurIp);
1127 static DEFINE_PER_CPU(struct pt_regs *, gpUserRegs) = NULL;
1128 EXPORT_PER_CPU_SYMBOL_GPL(gpUserRegs);
1129
1130 unsigned long ujprobe_event_pre_handler(struct us_ip *ip, struct pt_regs *regs)
1131 {
1132         __get_cpu_var (gpCurIp) = ip;
1133         __get_cpu_var (gpUserRegs) = regs;
1134         return 0;
1135 }
1136
1137 void ujprobe_event_handler (unsigned long arg1, unsigned long arg2, unsigned long arg3, unsigned long arg4, unsigned long arg5, unsigned long arg6)
1138 {
1139         struct us_ip *ip = __get_cpu_var(gpCurIp);
1140         unsigned long addr = (unsigned long)ip->jprobe.kp.addr;
1141
1142 #ifdef __ANDROID
1143         struct pt_regs *regs = __get_cpu_var(gpUserRegs);
1144         if (is_java_inst_enabled() && handle_java_event(regs)) {
1145                 return;
1146         }
1147 #endif /* __ANDROID */
1148
1149
1150 #if defined(CONFIG_ARM)
1151         if (ip->offset & 0x01)
1152         {
1153                 pack_event_info (US_PROBE_ID, RECORD_ENTRY, "ppppppp", addr | 0x01, arg1, arg2, arg3, arg4, arg5, arg6);
1154         }else{
1155                 pack_event_info (US_PROBE_ID, RECORD_ENTRY, "ppppppp", addr, arg1, arg2, arg3, arg4, arg5, arg6);
1156         }
1157 #else
1158         pack_event_info (US_PROBE_ID, RECORD_ENTRY, "ppppppp", addr, arg1, arg2, arg3, arg4, arg5, arg6);
1159 #endif
1160         // Mr_Nobody: uncomment for valencia
1161         //unregister_usprobe(current, ip, 1);
1162         dbi_uprobe_return ();
1163 }
1164
1165 static void send_plt(struct us_ip *ip)
1166 {
1167         unsigned long addr = (unsigned long)ip->jprobe.kp.addr;
1168         struct vm_area_struct *vma = find_vma(current->mm, addr);
1169
1170         if (vma && check_vma(vma)) {
1171                 char *name = NULL;
1172                 unsigned long real_addr;
1173                 unsigned long real_got = current->mm->exe_file == vma->vm_file ?
1174                                 ip->got_addr :
1175                                 ip->got_addr + vma->vm_start;
1176
1177                 if (!read_proc_vm_atomic(current, real_got, &real_addr, sizeof(real_addr))) {
1178                         printk("Failed to read got %lx at memory address %lx!\n", ip->got_addr, real_got);
1179                         return;
1180                 }
1181
1182                 vma = find_vma(current->mm, real_addr);
1183                 if (vma && (vma->vm_start <= real_addr) && (vma->vm_end > real_addr)) {
1184                         name = vma->vm_file ? vma->vm_file->f_dentry->d_iname : NULL;
1185                 } else {
1186                         printk("Failed to get vma, includes %lx address\n", real_addr);
1187                         return;
1188                 }
1189
1190                 if (name) {
1191                         pack_event_info(PLT_ADDR_PROBE_ID, RECORD_RET, "ppsp", addr, real_addr, name, real_addr - vma->vm_start);
1192                 } else {
1193                         pack_event_info(PLT_ADDR_PROBE_ID, RECORD_RET, "ppp", addr, real_addr, real_addr - vma->vm_start);
1194                 }
1195         }
1196 }
1197
1198 int uretprobe_event_handler(struct kretprobe_instance *probe, struct pt_regs *regs, struct us_ip *ip)
1199 {
1200         int retval = regs_return_value(regs);
1201         unsigned long addr = (unsigned long)ip->jprobe.kp.addr;
1202
1203         if (ip->got_addr && ip->flag_got == 0) {
1204                 send_plt(ip);
1205                 ip->flag_got = 1;
1206         }
1207
1208 #if defined(CONFIG_ARM)
1209         if (ip->offset & 0x01)
1210         {
1211                 pack_event_info (US_PROBE_ID, RECORD_RET, "pd", addr | 0x01, retval);
1212         }else{
1213                 pack_event_info (US_PROBE_ID, RECORD_RET, "pd", addr, retval);
1214         }
1215 #else
1216         pack_event_info (US_PROBE_ID, RECORD_RET, "pd", addr, retval);
1217 #endif
1218         // Mr_Nobody: uncomment for valencia
1219         //unregister_usprobe(current, ip, 1);
1220         return 0;
1221 }
1222
1223 int register_usprobe(struct task_struct *task, struct us_ip *ip, int atomic)
1224 {
1225         int ret = 0;
1226         ip->jprobe.kp.tgid = task->tgid;
1227
1228         if (ip->jprobe.entry == NULL) {
1229                 ip->jprobe.entry = (kprobe_opcode_t *)ujprobe_event_handler;
1230                 DPRINTF("Set default event handler for %x\n", ip->offset);
1231         }
1232
1233         if (ip->jprobe.pre_entry == NULL) {
1234                 ip->jprobe.pre_entry = (kprobe_pre_entry_handler_t)ujprobe_event_pre_handler;
1235                 DPRINTF("Set default pre handler for %x\n", ip->offset);
1236         }
1237
1238         ip->jprobe.priv_arg = ip;
1239         ret = dbi_register_ujprobe(task, &ip->jprobe, atomic);
1240         if (ret) {
1241                 if (ret == -ENOEXEC) {
1242                         pack_event_info(ERR_MSG_ID, RECORD_ENTRY, "dp",
1243                                         0x1,
1244                                         ip->jprobe.kp.addr);
1245                 }
1246                 DPRINTF ("dbi_register_ujprobe() failure %d", ret);
1247                 return ret;
1248         }
1249
1250         if (ip->flag_retprobe) {
1251                 // Mr_Nobody: comment for valencia
1252                 ip->retprobe.kp.tgid = task->tgid;
1253                 if (ip->retprobe.handler == NULL) {
1254                         ip->retprobe.handler = (kretprobe_handler_t)uretprobe_event_handler;
1255                         DPRINTF("Set default ret event handler for %x\n", ip->offset);
1256                 }
1257
1258                 ip->retprobe.priv_arg = ip;
1259                 ret = dbi_register_uretprobe(task, &ip->retprobe, atomic);
1260                 if (ret) {
1261                         EPRINTF ("dbi_register_uretprobe() failure %d", ret);
1262                         return ret;
1263                 }
1264         }
1265
1266         return 0;
1267 }
1268
1269 int unregister_usprobe(struct task_struct *task, struct us_ip *ip, int atomic, int not_rp2)
1270 {
1271         dbi_unregister_ujprobe(task, &ip->jprobe, atomic);
1272
1273         if (ip->flag_retprobe) {
1274                 dbi_unregister_uretprobe(task, &ip->retprobe, atomic, not_rp2);
1275         }
1276
1277         return 0;
1278 }
1279
1280 unsigned long get_stack_size(struct task_struct *task,
1281                 struct pt_regs *regs)
1282 {
1283 #ifdef CONFIG_ADD_THREAD_STACK_INFO
1284         return (task->stack_start - dbi_get_stack_ptr(regs));
1285 #else
1286         struct vm_area_struct *vma = NULL;
1287         struct mm_struct *mm = NULL;
1288         unsigned long result = 0;
1289     int atomic = in_atomic();
1290
1291         mm = (atomic ? task->active_mm: get_task_mm(task));
1292
1293         if (mm) {
1294                 if (!atomic)
1295                         down_read(&mm->mmap_sem);
1296
1297                 vma = find_vma(mm, dbi_get_stack_ptr(regs));
1298
1299                 if (vma)
1300                         result = vma->vm_end - dbi_get_stack_ptr(regs);
1301                 else
1302                         result = 0;
1303
1304                 if (!atomic) {
1305                         up_read(&mm->mmap_sem);
1306                         mmput(mm);
1307                 }
1308         }
1309
1310         return result;
1311 #endif
1312 }
1313 EXPORT_SYMBOL_GPL(get_stack_size);
1314
1315 unsigned long get_stack(struct task_struct *task, struct pt_regs *regs,
1316                 char *buf, unsigned long sz)
1317 {
1318         unsigned long stack_sz = get_stack_size(task, regs);
1319         unsigned long real_sz = (stack_sz > sz ? sz: stack_sz);
1320         int res = read_proc_vm_atomic(task, dbi_get_stack_ptr(regs), buf, real_sz);
1321         return res;
1322 }
1323 EXPORT_SYMBOL_GPL(get_stack);
1324
1325 int dump_to_trace(probe_id_t probe_id, void *addr, const char *buf,
1326                 unsigned long sz)
1327 {
1328         unsigned long rest_sz = sz;
1329         const char *data = buf;
1330
1331         while (rest_sz >= EVENT_MAX_SIZE) {
1332                 pack_event_info(probe_id, RECORD_ENTRY, "pa",
1333                                 addr, EVENT_MAX_SIZE, data);
1334                 rest_sz -= EVENT_MAX_SIZE;
1335                 data += EVENT_MAX_SIZE;
1336         }
1337
1338         if (rest_sz > 0)
1339                 pack_event_info(probe_id, RECORD_ENTRY, "pa", addr, rest_sz, data);
1340
1341         return 0;
1342 }
1343 EXPORT_SYMBOL_GPL(dump_to_trace);
1344
1345 int dump_backtrace(probe_id_t probe_id, struct task_struct *task,
1346                 void *addr, struct pt_regs *regs, unsigned long sz)
1347 {
1348         unsigned long real_sz = 0;
1349         char *buf = NULL;
1350
1351         buf = (char *)kmalloc(sz, GFP_ATOMIC);
1352
1353         if (buf != NULL) {
1354                 real_sz = get_stack(task, regs, buf, sz);
1355                 if (real_sz > 0)
1356                         dump_to_trace(probe_id, addr, buf, real_sz);
1357                 kfree(buf);
1358                 return 0;
1359         } else {
1360                 return -1;
1361         }
1362 }
1363 EXPORT_SYMBOL_GPL(dump_backtrace);
1364
1365 struct kretprobe_instance *find_ri(struct task_struct *task, struct us_ip *ip)
1366 {
1367         struct hlist_node *item, *tmp_node;
1368         struct kretprobe_instance *ri;
1369
1370         if (ip == NULL)
1371                 return NULL;
1372
1373         hlist_for_each_safe (item, tmp_node, &ip->retprobe.used_instances) {
1374                 ri = hlist_entry (item, struct kretprobe_instance, uflist);
1375
1376                 if (ri->task && ri->task->pid == task->pid &&
1377                                 ri->task->tgid == task->tgid)
1378                         return ri;
1379         }
1380
1381         return NULL;
1382 }
1383 EXPORT_SYMBOL_GPL(find_ri);
1384
1385 unsigned long get_ret_addr(struct task_struct *task, struct us_ip *ip)
1386 {
1387         struct kretprobe_instance *ri = find_ri(task, ip);;
1388         if (ri)
1389                 return (unsigned long)ri->ret_addr;
1390         else
1391                 return dbi_get_ret_addr(task_pt_regs(task));
1392 }
1393 EXPORT_SYMBOL_GPL(get_ret_addr);
1394
1395 unsigned long get_entry_sp(struct task_struct *task, struct us_ip *ip)
1396 {
1397         struct kretprobe_instance *ri = find_ri(task, ip);
1398         if (ri)
1399                 return (unsigned long)ri->sp;
1400         else
1401                 return dbi_get_stack_ptr(task_pt_regs(task));
1402 }
1403 EXPORT_SYMBOL_GPL(get_entry_sp);