1 ////////////////////////////////////////////////////////////////////////////////////
3 // FILE: us_proc_inst.c
6 // This file is C source for SWAP driver.
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
14 // REVISION DATE: 2008.12.02
16 ////////////////////////////////////////////////////////////////////////////////////
19 #include "us_proc_inst.h"
21 #include "../kprobe/dbi_kprobes_deps.h"
22 #include "../uprobe/swap_uprobes.h"
24 #include "sspt/sspt.h"
25 #include "java_inst.h"
27 #include <dbi_insn_slots.h>
29 #define mm_read_lock(task, mm, atomic, lock) \
30 mm = atomic ? task->active_mm : get_task_mm(task); \
33 panic("ERRR mm_read_lock: mm == NULL\n"); \
37 lock = down_read_trylock(&mm->mmap_sem); \
40 down_read(&mm->mmap_sem); \
43 #define mm_read_unlock(mm, atomic, lock) \
45 up_read(&mm->mmap_sem); \
52 #if defined(CONFIG_MIPS)
53 # define ARCH_REG_VAL(regs, idx) regs->regs[idx]
54 #elif defined(CONFIG_ARM)
55 # define ARCH_REG_VAL(regs, idx) regs->uregs[idx]
57 # define ARCH_REG_VAL(regs, idx) 0
58 # warning ARCH_REG_VAL is not implemented for this architecture. FBI will work improperly or even crash!!!
61 unsigned long ujprobe_event_pre_handler (struct us_ip *ip, struct pt_regs *regs);
62 void ujprobe_event_handler (unsigned long arg1, unsigned long arg2, unsigned long arg3, unsigned long arg4, unsigned long arg5, unsigned long arg6);
63 int uretprobe_event_handler(struct uretprobe_instance *probe, struct pt_regs *regs, struct us_ip *ip);
68 LIST_HEAD(proc_probes_list);
72 unsigned long android_app_vma_start = 0;
73 unsigned long android_app_vma_end = 0;
74 struct dentry *app_process_dentry = NULL;
75 #endif /* ANDROID_APP */
78 static struct dentry *launchpad_daemon_dentry = NULL;
79 EXPORT_SYMBOL_GPL(launchpad_daemon_dentry);
82 #define print_event(fmt, args...) \
85 sprintf(buf, fmt, ##args); \
86 pack_event_info(US_PROBE_ID, RECORD_ENTRY, "ds", 0x0badc0de, buf); \
89 static inline int is_libonly(void)
91 return !strcmp(us_proc_info.path,"*");
94 // is user-space instrumentation
95 static inline int is_us_instrumentation(void)
97 return !!us_proc_info.path;
100 static unsigned long alloc_user_pages(struct task_struct *task, unsigned long len, unsigned long prot, unsigned long flags)
102 unsigned long ret = 0;
103 struct task_struct *otask = current;
104 struct mm_struct *mm;
105 int atomic = in_atomic();
107 mm = atomic ? task->active_mm : get_task_mm (task);
110 if (!down_write_trylock(&mm->mmap_sem)) {
113 up_read(&mm->mmap_sem);
114 down_write(&mm->mmap_sem);
119 // FIXME: its seems to be bad decision to replace 'current' pointer temporarily
120 current_thread_info()->task = task;
121 ret = do_mmap_pgoff(NULL, 0, len, prot, flags, 0);
122 current_thread_info()->task = otask;
124 downgrade_write (&mm->mmap_sem);
128 printk("proc %d has no mm", task->tgid);
134 static void *sm_alloc_us(struct slot_manager *sm)
136 struct task_struct *task = sm->data;
138 return (void *)alloc_user_pages(task, PAGE_SIZE,
139 PROT_EXEC|PROT_READ|PROT_WRITE,
140 MAP_ANONYMOUS|MAP_PRIVATE);
143 static void sm_free_us(struct slot_manager *sm, void *ptr)
145 struct task_struct *task = sm->data;
148 * E. G.: This code provides kernel dump because of rescheduling while atomic.
149 * As workaround, this code was commented. In this case we will have memory leaks
150 * for instrumented process, but instrumentation process should functionate correctly.
151 * Planned that good solution for this problem will be done during redesigning KProbe
152 * for improving supportability and performance.
155 mm = get_task_mm(task);
157 down_write(&mm->mmap_sem);
158 do_munmap(mm, (unsigned long)(ptr), PAGE_SIZE);
159 up_write(&mm->mmap_sem);
163 /* FIXME: implement the removal of memory for task */
166 struct slot_manager *create_sm_us(struct task_struct *task)
168 struct slot_manager *sm = kmalloc(sizeof(*sm), GFP_ATOMIC);
169 sm->slot_size = UPROBES_TRAMP_LEN;
170 sm->alloc = sm_alloc_us;
171 sm->free = sm_free_us;
172 INIT_HLIST_NODE(&sm->page_list);
176 void free_sm_us(struct slot_manager *sm)
181 static struct sspt_procs *get_proc_probes_by_task(struct task_struct *task)
183 struct sspt_procs *procs, *tmp;
186 if (task != current) {
187 printk("ERROR get_proc_probes_by_task: \'task != current\'\n");
191 return us_proc_info.pp;
194 list_for_each_entry_safe(procs, tmp, &proc_probes_list, list) {
195 if (procs->tgid == task->tgid) {
203 static void add_proc_probes(struct task_struct *task, struct sspt_procs *procs)
205 list_add_tail(&procs->list, &proc_probes_list);
208 static struct sspt_procs *get_proc_probes_by_task_or_new(struct task_struct *task)
210 struct sspt_procs *procs = get_proc_probes_by_task(task);
212 procs = sspt_procs_copy(us_proc_info.pp, task);
213 procs->sm = create_sm_us(task);
214 add_proc_probes(task, procs);
221 static int is_slp_app_with_dentry(struct vm_area_struct *vma,
222 struct dentry *dentry)
224 struct vm_area_struct *slp_app_vma = NULL;
226 if (vma->vm_file->f_dentry == launchpad_daemon_dentry) {
228 while (slp_app_vma) {
229 if (slp_app_vma->vm_file) {
230 if (slp_app_vma->vm_file->f_dentry == dentry &&
231 slp_app_vma->vm_pgoff == 0) {
235 slp_app_vma = slp_app_vma->vm_next;
244 static int is_android_app_with_dentry(struct vm_area_struct *vma,
245 struct dentry *dentry)
247 struct vm_area_struct *android_app_vma = NULL;
249 if (vma->vm_file->f_dentry == app_process_dentry) {
250 android_app_vma = vma;
251 while (android_app_vma) {
252 if (android_app_vma->vm_file) {
253 if (android_app_vma->vm_file->f_dentry == dentry) {
254 android_app_vma_start = android_app_vma->vm_start;
255 android_app_vma_end = android_app_vma->vm_end;
259 android_app_vma = android_app_vma->vm_next;
265 #endif /* ANDROID_APP */
267 struct dentry *dentry_by_path(const char *path)
269 struct dentry *dentry;
270 #if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 38)
272 if (kern_path(path, LOOKUP_FOLLOW, &st_path) != 0) {
273 #else /* LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 38) */
275 if (path_lookup(path, LOOKUP_FOLLOW, &nd) != 0) {
276 #endif /* LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 38) */
277 EPRINTF("failed to lookup dentry for path %s!", path);
281 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 25)
284 #elif LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 38)
285 dentry = nd.path.dentry;
287 #else /* LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 38) */
288 dentry = st_path.dentry;
290 #endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 25) */
294 static int check_vma(struct vm_area_struct *vma)
297 return vma->vm_file && !(vma->vm_pgoff != 0 || !(vma->vm_flags & VM_EXEC) || (vma->vm_flags & VM_ACCOUNT) ||
298 !(vma->vm_flags & (VM_WRITE | VM_MAYWRITE)) ||
299 !(vma->vm_flags & (VM_READ | VM_MAYREAD)));
301 return vma->vm_file && !(vma->vm_pgoff != 0 || !(vma->vm_flags & VM_EXEC));
305 static int find_task_by_path (const char *path, struct task_struct **p_task, struct list_head *tids)
308 struct task_struct *task;
309 struct vm_area_struct *vma;
310 struct mm_struct *mm;
311 struct dentry *dentry = dentry_by_path(path);
315 /* find corresponding dir entry, this is also check for valid path */
316 // TODO: test - try to instrument process with non-existing path
317 // TODO: test - try to instrument process with existing path and delete file just after start
318 if (dentry == NULL) {
323 for_each_process (task) {
325 if ( 0 != inst_pid && ( inst_pid != task->pid ) )
328 mm = get_task_mm(task);
333 if (check_vma(vma)) {
334 if (vma->vm_file->f_dentry == dentry) {
337 get_task_struct (task);
343 if (is_slp_app_with_dentry(vma, dentry)) {
345 get_task_struct(task);
351 if (is_android_app_with_dentry(vma, dentry)) {
353 get_task_struct(task);
356 #endif /* ANDROID_APP */
360 // only decrement usage count on mm since we cannot sleep here
361 atomic_dec(&mm->mm_users);
368 DPRINTF ("found pid %d for %s.", (*p_task)->pid, path);
369 *p_task = (*p_task)->group_leader;
370 gl_nNotifyTgid = (*p_task)->tgid;
372 DPRINTF ("pid for %s not found!", path);
378 static void set_mapping_file(struct sspt_file *file,
379 const struct sspt_procs *procs,
380 const struct task_struct *task,
381 const struct vm_area_struct *vma);
383 int install_otg_ip(unsigned long addr,
384 kprobe_pre_entry_handler_t pre_handler,
385 unsigned long jp_handler,
386 uretprobe_handler_t rp_handler)
389 struct task_struct *task = current->group_leader;
390 struct mm_struct *mm = task->mm;
393 struct vm_area_struct *vma = find_vma(mm, addr);
394 if (vma && (vma->vm_flags & VM_EXEC) &&
395 vma->vm_file && vma->vm_file->f_dentry) {
396 unsigned long offset_addr = addr - vma->vm_start;
397 struct dentry *dentry = vma->vm_file->f_dentry;
398 char *name = dentry->d_iname;
399 struct sspt_procs *procs = get_proc_probes_by_task(task);
400 struct ip_data pd = {
401 .offset = offset_addr,
402 .pre_handler = pre_handler,
403 .jp_handler = jp_handler,
404 .rp_handler = rp_handler,
408 struct sspt_file *file = sspt_procs_find_file_or_new(procs, dentry, name);
409 struct sspt_page *page = sspt_get_page(file, offset_addr);
410 struct us_ip *ip = sspt_find_ip(page, offset_addr & ~PAGE_MASK);
413 set_mapping_file(file, procs, task, vma);
418 // TODO: sspt_procs_find_file_or_new --> sspt_procs_find_file ?!
419 struct sspt_file *file = sspt_procs_find_file_or_new(procs, dentry, name);
420 sspt_file_add_ip(file, &pd);
422 /* if addr mapping, that probe install, else it be installed in do_page_fault handler */
423 if (page_present(mm, addr)) {
424 ip = sspt_find_ip(page, offset_addr & ~PAGE_MASK);
425 sspt_set_ip_addr(ip, page, file);
428 ret = register_usprobe_my(task, ip);
430 sspt_page_installed(page);
432 printk("ERROR install_otg_ip: ret=%d\n", ret);
443 EXPORT_SYMBOL_GPL(install_otg_ip);
445 static int uninstall_kernel_probe (unsigned long addr, int uflag, int kflag, kernel_probe_t ** pprobe)
447 kernel_probe_t *probe = NULL;
449 if (probes_flags & kflag) {
450 probe = find_probe(addr);
452 iRet = remove_probe_from_list (addr);
454 EPRINTF ("remove_probe_from_list(0x%lx) result=%d!", addr, iRet);
458 probes_flags &= ~kflag;
460 if (us_proc_probes & uflag) {
461 if (!(probes_flags & uflag)) {
463 iRet = unregister_kernel_probe(probe);
465 EPRINTF ("unregister_kernel_probe(0x%lx) result=%d!",
471 us_proc_probes &= ~uflag;
476 static int uninstall_us_proc_probes(struct task_struct *task, struct sspt_procs *procs, enum US_FLAGS flag);
478 int deinst_usr_space_proc (void)
480 int iRet = 0, found = 0;
481 struct task_struct *task = NULL;
483 if (!is_us_instrumentation()) {
487 iRet = uninstall_kernel_probe (pf_addr, US_PROC_PF_INSTLD,
490 EPRINTF ("uninstall_kernel_probe(do_page_fault) result=%d!", iRet);
492 iRet = uninstall_kernel_probe (cp_addr, US_PROC_CP_INSTLD,
495 EPRINTF ("uninstall_kernel_probe(copy_process) result=%d!", iRet);
497 iRet = uninstall_kernel_probe (mr_addr, US_PROC_MR_INSTLD,
500 EPRINTF ("uninstall_kernel_probe(mm_release) result=%d!", iRet);
502 iRet = uninstall_kernel_probe (exit_addr, US_PROC_EXIT_INSTLD,
505 EPRINTF ("uninstall_kernel_probe(do_exit) result=%d!", iRet);
507 iRet = uninstall_kernel_probe (unmap_addr, US_PROC_UNMAP_INSTLD,
510 EPRINTF ("uninstall_kernel_probe(do_munmap) result=%d!", iRet);
513 struct sspt_procs *procs;
515 for_each_process(task) {
516 procs = get_proc_probes_by_task(task);
518 int ret = uninstall_us_proc_probes(task, procs, US_UNREGS_PROBE);
520 EPRINTF ("failed to uninstall IPs (%d)!", ret);
523 dbi_unregister_all_uprobes(task, 1);
529 if (us_proc_info.tgid == 0)
532 for_each_process (task)
534 if (task->tgid == us_proc_info.tgid)
537 get_task_struct (task);
546 ret = uninstall_us_proc_probes(task, us_proc_info.pp, US_UNREGS_PROBE);
548 EPRINTF ("failed to uninstall IPs %d!", ret);
551 put_task_struct (task);
553 printk("### 1 ### dbi_unregister_all_uprobes:\n");
554 dbi_unregister_all_uprobes(task, 1);
555 us_proc_info.tgid = 0;
556 for(i = 0; i < us_proc_info.libs_count; i++)
557 us_proc_info.p_libs[i].loaded = 0;
563 static int install_kernel_probe (unsigned long addr, int uflag, int kflag, kernel_probe_t ** pprobe)
565 kernel_probe_t *probe = NULL;
568 DPRINTF("us_proc_probes = 0x%x, uflag = 0x%x, "
569 "probes_flags = 0x%x, kflag = 0x%x",
570 us_proc_probes, uflag, probes_flags, kflag);
572 if (!(probes_flags & kflag)) {
573 iRet = add_probe_to_list (addr, &probe);
575 EPRINTF ("add_probe_to_list(0x%lx) result=%d!", addr, iRet);
578 probes_flags |= kflag;
580 if (!(us_proc_probes & uflag)) {
581 if (!(probes_flags & uflag)) {
582 iRet = register_kernel_probe (probe);
584 EPRINTF ("register_kernel_probe(0x%lx) result=%d!", addr, iRet);
588 us_proc_probes |= uflag;
597 static void install_proc_probes(struct task_struct *task, struct sspt_procs *procs, int atomic);
599 int inst_usr_space_proc (void)
602 struct task_struct *task = NULL;
604 if (!is_us_instrumentation()) {
608 DPRINTF("User space instr");
611 launchpad_daemon_dentry = dentry_by_path("/usr/bin/launchpad_preloading_preinitializing_daemon");
612 if (launchpad_daemon_dentry == NULL) {
619 app_process_dentry = dentry_by_path("/system/bin/app_process");
620 if (app_process_dentry == NULL) {
624 android_app_vma_start = 0;
625 android_app_vma_end = 0;
626 #endif /* ANDROID_APP */
628 for (i = 0; i < us_proc_info.libs_count; i++) {
629 us_proc_info.p_libs[i].loaded = 0;
631 /* check whether process is already running
632 * 1) if process is running - look for the libraries in the process maps
633 * 1.1) check if page for symbol does exist
634 * 1.1.1) if page exists - instrument it
635 * 1.1.2) if page does not exist - make sure that do_page_fault handler is installed
636 * 2) if process is not running - make sure that do_page_fault handler is installed
641 // FIXME: clear_task_inst_info();
642 for_each_process (task) {
643 struct sspt_procs *procs;
645 if (task->flags & PF_KTHREAD){
646 DPRINTF("ignored kernel thread %d\n",
651 procs = get_proc_probes_by_task_or_new(task);
652 DPRINTF("trying process");
653 install_proc_probes(task, procs, 1);
654 //put_task_struct (task);
659 ret = find_task_by_path (us_proc_info.path, &task, NULL);
662 DPRINTF("task found. installing probes");
663 us_proc_info.tgid = task->pid;
664 us_proc_info.pp->sm = create_sm_us(task);
665 install_proc_probes(task, us_proc_info.pp, 0);
666 put_task_struct (task);
670 // enable 'do_page_fault' probe to detect when they will be loaded
671 ret = install_kernel_probe (pf_addr, US_PROC_PF_INSTLD, 0, &pf_probe);
674 EPRINTF ("install_kernel_probe(do_page_fault) result=%d!", ret);
677 // enable 'do_exit' probe to detect for remove task_struct
678 ret = install_kernel_probe (exit_addr, US_PROC_EXIT_INSTLD, 0, &exit_probe);
681 EPRINTF ("install_kernel_probe(do_exit) result=%d!", ret);
684 /* enable 'copy_process' */
685 ret = install_kernel_probe (cp_addr, US_PROC_CP_INSTLD, 0, &cp_probe);
688 EPRINTF ("instpall_kernel_probe(copy_process) result=%d!", ret);
692 // enable 'mm_release' probe to detect when for remove user space probes
693 ret = install_kernel_probe (mr_addr, US_PROC_MR_INSTLD, 0, &mr_probe);
696 EPRINTF ("install_kernel_probe(mm_release) result=%d!", ret);
700 // enable 'do_munmap' probe to detect when for remove user space probes
701 ret = install_kernel_probe (unmap_addr, US_PROC_UNMAP_INSTLD, 0, &unmap_probe);
704 EPRINTF ("install_kernel_probe(do_munmap) result=%d!", ret);
710 #include "../../tools/gpmu/probes/entry_data.h"
712 void do_page_fault_j_pre_code(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
714 struct task_struct *task = current->group_leader;
716 if (task->flags & PF_KTHREAD) {
717 DPRINTF("ignored kernel thread %d\n", task->pid);
721 if (is_us_instrumentation()) {
722 swap_put_entry_data((void *)addr, &sa_dpf);
725 EXPORT_SYMBOL_GPL(do_page_fault_j_pre_code);
728 unsigned long imi_sum_time = 0;
729 unsigned long imi_sum_hit = 0;
731 static void set_mapping_file(struct sspt_file *file,
732 const struct sspt_procs *procs,
733 const struct task_struct *task,
734 const struct vm_area_struct *vma)
736 int app_flag = (vma->vm_file->f_dentry == procs->dentry);
738 file->vm_start = vma->vm_start;
739 file->vm_end = vma->vm_end;
741 pack_event_info(DYN_LIB_PROBE_ID, RECORD_ENTRY, "dspdd",
742 task->tgid, file->name, vma->vm_start,
743 vma->vm_end - vma->vm_start, app_flag);
746 void print_vma(struct mm_struct *mm);
748 static int register_us_page_probe(struct sspt_page *page,
749 const struct sspt_file *file,
750 struct task_struct *task)
755 spin_lock(&page->lock);
757 if (sspt_page_is_install(page)) {
758 printk("page %lx in %s task[tgid=%u, pid=%u] already installed\n",
759 page->offset, file->dentry->d_iname, task->tgid, task->pid);
764 sspt_page_assert_install(page);
765 sspt_set_all_ip_addr(page, file);
767 list_for_each_entry(ip, &page->ip_list, list) {
768 err = register_usprobe_my(task, ip);
775 sspt_page_installed(page);
778 spin_unlock(&page->lock);
783 static int unregister_us_page_probe(struct task_struct *task,
784 struct sspt_page *page, enum US_FLAGS flag)
789 spin_lock(&page->lock);
790 if (!sspt_page_is_install(page)) {
791 spin_unlock(&page->lock);
795 list_for_each_entry(ip, &page->ip_list, list) {
796 err = unregister_usprobe_my(task, ip, flag);
803 if (flag != US_DISARM) {
804 sspt_page_uninstalled(page);
806 spin_unlock(&page->lock);
811 static void install_page_probes(unsigned long page_addr, struct task_struct *task, struct sspt_procs *procs, int atomic)
814 struct mm_struct *mm;
815 struct vm_area_struct *vma;
817 mm_read_lock(task, mm, atomic, lock);
819 vma = find_vma(mm, page_addr);
820 if (vma && check_vma(vma)) {
821 struct dentry *dentry = vma->vm_file->f_dentry;
822 struct sspt_file *file = sspt_procs_find_file(procs, dentry);
824 struct sspt_page *page;
826 set_mapping_file(file, procs, task, vma);
830 page = sspt_find_page_mapped(file, page_addr);
832 register_us_page_probe(page, file, task);
837 mm_read_unlock(mm, atomic, lock);
840 static void install_file_probes(struct task_struct *task, struct mm_struct *mm, struct sspt_file *file)
842 struct sspt_page *page = NULL;
843 struct hlist_node *node = NULL;
844 struct hlist_head *head = NULL;
845 int i, table_size = (1 << file->page_probes_hash_bits);
847 for (i = 0; i < table_size; ++i) {
848 head = &file->page_probes_table[i];
849 hlist_for_each_entry_rcu(page, node, head, hlist) {
850 register_us_page_probe(page, file, task);
855 static void install_proc_probes(struct task_struct *task, struct sspt_procs *procs, int atomic)
858 struct vm_area_struct *vma;
859 struct mm_struct *mm;
861 mm_read_lock(task, mm, atomic, lock);
863 for (vma = mm->mmap; vma; vma = vma->vm_next) {
864 if (check_vma(vma)) {
865 struct dentry *dentry = vma->vm_file->f_dentry;
866 struct sspt_file *file = sspt_procs_find_file(procs, dentry);
869 set_mapping_file(file, procs, task, vma);
873 install_file_probes(task, mm, file);
878 mm_read_unlock(mm, atomic, lock);
881 static int check_install_pages_in_file(struct task_struct *task, struct sspt_file *file)
884 int table_size = (1 << file->page_probes_hash_bits);
885 struct sspt_page *page;
886 struct hlist_node *node, *tmp;
887 struct hlist_head *head;
889 for (i = 0; i < table_size; ++i) {
890 head = &file->page_probes_table[i];
891 hlist_for_each_entry_safe (page, node, tmp, head, hlist) {
901 static int unregister_us_file_probes(struct task_struct *task, struct sspt_file *file, enum US_FLAGS flag)
904 int table_size = (1 << file->page_probes_hash_bits);
905 struct sspt_page *page;
906 struct hlist_node *node, *tmp;
907 struct hlist_head *head;
909 for (i = 0; i < table_size; ++i) {
910 head = &file->page_probes_table[i];
911 hlist_for_each_entry_safe (page, node, tmp, head, hlist) {
912 err = unregister_us_page_probe(task, page, flag);
920 if (flag != US_DISARM) {
927 static int uninstall_us_proc_probes(struct task_struct *task, struct sspt_procs *procs, enum US_FLAGS flag)
930 struct sspt_file *file;
932 list_for_each_entry_rcu(file, &procs->file_list, list) {
933 err = unregister_us_file_probes(task, file, flag);
943 static pid_t find_proc_by_task(const struct task_struct *task, struct dentry *dentry)
945 struct vm_area_struct *vma;
946 struct mm_struct *mm = task->active_mm;
951 for (vma = mm->mmap; vma; vma = vma->vm_next) {
952 if (check_vma(vma)) {
953 if (vma->vm_file->f_dentry == dentry) {
957 if (is_slp_app_with_dentry(vma, dentry)) {
962 if (is_android_app_with_dentry(vma, dentry)) {
965 #endif /* ANDROID_APP */
972 void do_page_fault_ret_pre_code (void)
974 struct task_struct *task = current->group_leader;
975 struct mm_struct *mm = task->mm;
976 struct sspt_procs *procs = NULL;
978 * Because process threads have same address space
979 * we instrument only group_leader of all this threads
981 unsigned long addr = 0;
985 struct timeval imi_tv1;
986 struct timeval imi_tv2;
987 #define USEC_IN_SEC_NUM 1000000
989 if (task->flags & PF_KTHREAD) {
990 DPRINTF("ignored kernel thread %d\n", task->pid);
994 if (!is_us_instrumentation()) {
998 addr = (unsigned long)swap_get_entry_data(&sa_dpf);
1001 printk("WARNING: do_page_fault_ret_pre_code addr = 0\n");
1008 valid_addr = mm && page_present(mm, addr);
1014 procs = get_proc_probes_by_task_or_new(task);
1017 if (us_proc_info.tgid == 0) {
1018 pid_t tgid = find_proc_by_task(task, us_proc_info.m_f_dentry);
1020 us_proc_info.tgid = gl_nNotifyTgid = tgid;
1022 us_proc_info.pp->sm = create_sm_us(task);
1023 /* install probes in already mapped memory */
1024 install_proc_probes(task, us_proc_info.pp, 1);
1028 if (us_proc_info.tgid == task->tgid) {
1029 procs = us_proc_info.pp;
1034 unsigned long page = addr & PAGE_MASK;
1037 do_gettimeofday(&imi_tv1);
1038 install_page_probes(page, task, procs, 1);
1039 do_gettimeofday(&imi_tv2);
1041 imi_sum_time += ((imi_tv2.tv_sec - imi_tv1.tv_sec) * USEC_IN_SEC_NUM +
1042 (imi_tv2.tv_usec - imi_tv1.tv_usec));
1046 EXPORT_SYMBOL_GPL(do_page_fault_ret_pre_code);
1049 void do_exit_probe_pre_code (void)
1051 // TODO: remove task
1053 EXPORT_SYMBOL_GPL(do_exit_probe_pre_code);
1055 void print_vma(struct mm_struct *mm)
1057 struct vm_area_struct *vma;
1058 printk("### print_vma: START\n");\
1059 printk("### print_vma: START\n");
1061 for (vma = mm->mmap; vma; vma = vma->vm_next) {
1062 char *x = vma->vm_flags & VM_EXEC ? "x" : "-";
1063 char *r = vma->vm_flags & VM_READ ? "r" : "-";
1064 char *w = vma->vm_flags & VM_WRITE ? "w" : "-";
1065 char *name = vma->vm_file ? (char *)vma->vm_file->f_dentry->d_iname : "N/A";
1067 printk("### [%8lx..%8lx] %s%s%s pgoff=\'%8lu\' %s\n",
1068 vma->vm_start, vma->vm_end, x, r, w, vma->vm_pgoff, name);
1070 printk("### print_vma: END\n");
1073 static int remove_unmap_probes(struct task_struct *task, struct sspt_procs *procs, unsigned long start, size_t len)
1075 struct mm_struct *mm = task->mm;
1076 struct vm_area_struct *vma;
1078 if ((start & ~PAGE_MASK) || start > TASK_SIZE || len > TASK_SIZE - start) {
1082 if ((len = PAGE_ALIGN(len)) == 0) {
1086 vma = find_vma(mm, start);
1087 if (vma && check_vma(vma)) {
1088 struct sspt_file *file;
1089 unsigned long end = start + len;
1090 struct dentry *dentry = vma->vm_file->f_dentry;
1092 file = sspt_procs_find_file(procs, dentry);
1094 if (vma->vm_start == start || vma->vm_end == end) {
1095 unregister_us_file_probes(task, file, US_UNREGS_PROBE);
1098 unsigned long page_addr;
1099 struct sspt_page *page;
1101 for (page_addr = vma->vm_start; page_addr < vma->vm_end; page_addr += PAGE_SIZE) {
1102 page = sspt_find_page_mapped(file, page_addr);
1104 unregister_us_page_probe(task, page, US_UNREGS_PROBE);
1108 if (check_install_pages_in_file(task, file)) {
1118 void do_munmap_probe_pre_code(struct mm_struct *mm, unsigned long start, size_t len)
1120 struct sspt_procs *procs = NULL;
1121 struct task_struct *task = current;
1123 //if user-space instrumentation is not set
1124 if (!is_us_instrumentation()) {
1129 procs = get_proc_probes_by_task(task);
1131 if (task->tgid == us_proc_info.tgid) {
1132 procs = us_proc_info.pp;
1137 if (remove_unmap_probes(task, procs, start, len)) {
1138 printk("ERROR do_munmap: start=%lx, len=%x\n", start, len);
1142 EXPORT_SYMBOL_GPL(do_munmap_probe_pre_code);
1144 void mm_release_probe_pre_code(void)
1146 struct task_struct *task = current;
1147 struct sspt_procs *procs = NULL;
1149 if (!is_us_instrumentation() || task->tgid != task->pid) {
1154 procs = get_proc_probes_by_task(task);
1156 if (task->tgid == us_proc_info.tgid) {
1157 procs = get_proc_probes_by_task(task);
1158 us_proc_info.tgid = 0;
1163 int ret = uninstall_us_proc_probes(task, procs, US_UNREGS_PROBE);
1165 EPRINTF ("failed to uninstall IPs (%d)!", ret);
1168 dbi_unregister_all_uprobes(task, 1);
1171 EXPORT_SYMBOL_GPL(mm_release_probe_pre_code);
1174 static void recover_child(struct task_struct *child_task, struct sspt_procs *procs)
1176 uninstall_us_proc_probes(child_task, procs, US_DISARM);
1177 dbi_disarm_urp_inst_for_task(current, child_task);
1180 static void rm_uprobes_child(struct task_struct *new_task)
1183 struct sspt_procs *procs = get_proc_probes_by_task(current);
1185 recover_child(new_task, procs);
1188 if(us_proc_info.tgid == current->tgid) {
1189 recover_child(new_task, us_proc_info.pp);
1194 void copy_process_ret_pre_code(struct task_struct *p)
1199 if(p->mm != current->mm) // check flags CLONE_VM
1200 rm_uprobes_child(p);
1203 static DEFINE_PER_CPU(struct us_ip *, gpCurIp) = NULL;
1204 EXPORT_PER_CPU_SYMBOL_GPL(gpCurIp);
1205 static DEFINE_PER_CPU(struct pt_regs *, gpUserRegs) = NULL;
1206 EXPORT_PER_CPU_SYMBOL_GPL(gpUserRegs);
1208 unsigned long ujprobe_event_pre_handler(struct us_ip *ip, struct pt_regs *regs)
1210 __get_cpu_var (gpCurIp) = ip;
1211 __get_cpu_var (gpUserRegs) = regs;
1215 void ujprobe_event_handler (unsigned long arg1, unsigned long arg2, unsigned long arg3, unsigned long arg4, unsigned long arg5, unsigned long arg6)
1217 struct us_ip *ip = __get_cpu_var(gpCurIp);
1218 unsigned long addr = (unsigned long)ip->jprobe.up.kp.addr;
1221 struct pt_regs *regs = __get_cpu_var(gpUserRegs);
1222 if (is_java_inst_enabled() && handle_java_event(regs)) {
1225 #endif /* __ANDROID */
1228 #if defined(CONFIG_ARM)
1229 if (ip->offset & 0x01)
1231 pack_event_info (US_PROBE_ID, RECORD_ENTRY, "ppppppp", addr | 0x01, arg1, arg2, arg3, arg4, arg5, arg6);
1233 pack_event_info (US_PROBE_ID, RECORD_ENTRY, "ppppppp", addr, arg1, arg2, arg3, arg4, arg5, arg6);
1236 pack_event_info (US_PROBE_ID, RECORD_ENTRY, "ppppppp", addr, arg1, arg2, arg3, arg4, arg5, arg6);
1238 // Mr_Nobody: uncomment for valencia
1239 //unregister_usprobe(current, ip, 1);
1240 dbi_uprobe_return ();
1243 static void send_plt(struct us_ip *ip)
1245 unsigned long addr = (unsigned long)ip->jprobe.up.kp.addr;
1246 struct vm_area_struct *vma = find_vma(current->mm, addr);
1248 if (vma && check_vma(vma)) {
1250 unsigned long real_addr;
1251 unsigned long real_got = current->mm->exe_file == vma->vm_file ?
1253 ip->got_addr + vma->vm_start;
1255 if (!read_proc_vm_atomic(current, real_got, &real_addr, sizeof(real_addr))) {
1256 printk("Failed to read got %lx at memory address %lx!\n", ip->got_addr, real_got);
1260 vma = find_vma(current->mm, real_addr);
1261 if (vma && (vma->vm_start <= real_addr) && (vma->vm_end > real_addr)) {
1262 name = vma->vm_file ? vma->vm_file->f_dentry->d_iname : NULL;
1264 printk("Failed to get vma, includes %lx address\n", real_addr);
1269 pack_event_info(PLT_ADDR_PROBE_ID, RECORD_RET, "ppsp", addr, real_addr, name, real_addr - vma->vm_start);
1271 pack_event_info(PLT_ADDR_PROBE_ID, RECORD_RET, "ppp", addr, real_addr, real_addr - vma->vm_start);
1276 int uretprobe_event_handler(struct uretprobe_instance *probe, struct pt_regs *regs, struct us_ip *ip)
1278 int retval = regs_return_value(regs);
1279 unsigned long addr = (unsigned long)ip->jprobe.up.kp.addr;
1281 if (ip->got_addr && ip->flag_got == 0) {
1286 #if defined(CONFIG_ARM)
1287 if (ip->offset & 0x01)
1289 pack_event_info (US_PROBE_ID, RECORD_RET, "pd", addr | 0x01, retval);
1291 pack_event_info (US_PROBE_ID, RECORD_RET, "pd", addr, retval);
1294 pack_event_info (US_PROBE_ID, RECORD_RET, "pd", addr, retval);
1296 // Mr_Nobody: uncomment for valencia
1297 //unregister_usprobe(current, ip, 1);
1301 int register_usprobe(struct task_struct *task, struct us_ip *ip, int atomic)
1305 if (ip->jprobe.entry == NULL) {
1306 ip->jprobe.entry = (void *)ujprobe_event_handler;
1307 DPRINTF("Set default event handler for %x\n", ip->offset);
1310 if (ip->jprobe.pre_entry == NULL) {
1311 ip->jprobe.pre_entry = (uprobe_pre_entry_handler_t)ujprobe_event_pre_handler;
1312 DPRINTF("Set default pre handler for %x\n", ip->offset);
1315 ip->jprobe.priv_arg = ip;
1316 ip->jprobe.up.task = task;
1317 ip->jprobe.up.sm = ip->page->file->procs->sm;
1318 ret = dbi_register_ujprobe(&ip->jprobe, atomic);
1320 if (ret == -ENOEXEC) {
1321 pack_event_info(ERR_MSG_ID, RECORD_ENTRY, "dp",
1323 ip->jprobe.up.kp.addr);
1325 DPRINTF ("dbi_register_ujprobe() failure %d", ret);
1329 if (ip->flag_retprobe) {
1330 // Mr_Nobody: comment for valencia
1331 if (ip->retprobe.handler == NULL) {
1332 ip->retprobe.handler = (uretprobe_handler_t)uretprobe_event_handler;
1333 DPRINTF("Set default ret event handler for %x\n", ip->offset);
1336 ip->retprobe.priv_arg = ip;
1337 ip->retprobe.up.task = task;
1338 ip->retprobe.up.sm = ip->page->file->procs->sm;
1339 ret = dbi_register_uretprobe(&ip->retprobe, atomic);
1341 EPRINTF ("dbi_register_uretprobe() failure %d", ret);
1349 int unregister_usprobe(struct task_struct *task, struct us_ip *ip, int atomic)
1351 dbi_unregister_ujprobe(&ip->jprobe, atomic);
1353 if (ip->flag_retprobe) {
1354 dbi_unregister_uretprobe(&ip->retprobe, atomic);
1360 unsigned long get_stack_size(struct task_struct *task,
1361 struct pt_regs *regs)
1363 #ifdef CONFIG_ADD_THREAD_STACK_INFO
1364 return (task->stack_start - dbi_get_stack_ptr(regs));
1366 struct vm_area_struct *vma = NULL;
1367 struct mm_struct *mm = NULL;
1368 unsigned long result = 0;
1369 int atomic = in_atomic();
1371 mm = (atomic ? task->active_mm: get_task_mm(task));
1375 down_read(&mm->mmap_sem);
1377 vma = find_vma(mm, dbi_get_stack_ptr(regs));
1380 result = vma->vm_end - dbi_get_stack_ptr(regs);
1385 up_read(&mm->mmap_sem);
1393 EXPORT_SYMBOL_GPL(get_stack_size);
1395 unsigned long get_stack(struct task_struct *task, struct pt_regs *regs,
1396 char *buf, unsigned long sz)
1398 unsigned long stack_sz = get_stack_size(task, regs);
1399 unsigned long real_sz = (stack_sz > sz ? sz: stack_sz);
1400 int res = read_proc_vm_atomic(task, dbi_get_stack_ptr(regs), buf, real_sz);
1403 EXPORT_SYMBOL_GPL(get_stack);
1405 int dump_to_trace(probe_id_t probe_id, void *addr, const char *buf,
1408 unsigned long rest_sz = sz;
1409 const char *data = buf;
1411 while (rest_sz >= EVENT_MAX_SIZE) {
1412 pack_event_info(probe_id, RECORD_ENTRY, "pa",
1413 addr, EVENT_MAX_SIZE, data);
1414 rest_sz -= EVENT_MAX_SIZE;
1415 data += EVENT_MAX_SIZE;
1419 pack_event_info(probe_id, RECORD_ENTRY, "pa", addr, rest_sz, data);
1423 EXPORT_SYMBOL_GPL(dump_to_trace);
1425 int dump_backtrace(probe_id_t probe_id, struct task_struct *task,
1426 void *addr, struct pt_regs *regs, unsigned long sz)
1428 unsigned long real_sz = 0;
1431 buf = (char *)kmalloc(sz, GFP_ATOMIC);
1434 real_sz = get_stack(task, regs, buf, sz);
1436 dump_to_trace(probe_id, addr, buf, real_sz);
1443 EXPORT_SYMBOL_GPL(dump_backtrace);
1445 struct uretprobe_instance *find_ri(struct task_struct *task, struct us_ip *ip)
1447 struct hlist_node *item, *tmp_node;
1448 struct uretprobe_instance *ri;
1453 hlist_for_each_safe (item, tmp_node, &ip->retprobe.used_instances) {
1454 ri = hlist_entry(item, struct uretprobe_instance, uflist);
1456 if (ri->task && ri->task->pid == task->pid &&
1457 ri->task->tgid == task->tgid)
1463 EXPORT_SYMBOL_GPL(find_ri);
1465 unsigned long get_ret_addr(struct task_struct *task, struct us_ip *ip)
1467 struct uretprobe_instance *ri = find_ri(task, ip);;
1469 return (unsigned long)ri->ret_addr;
1471 return dbi_get_ret_addr(task_pt_regs(task));
1473 EXPORT_SYMBOL_GPL(get_ret_addr);
1475 unsigned long get_entry_sp(struct task_struct *task, struct us_ip *ip)
1477 struct uretprobe_instance *ri = find_ri(task, ip);
1479 return (unsigned long)ri->sp;
1481 return dbi_get_stack_ptr(task_pt_regs(task));
1483 EXPORT_SYMBOL_GPL(get_entry_sp);