Merge commit 'cc09f10e84d5' into kernel
[kernel/swap-modules.git] / driver / us_def_handler.c
1 #include <linux/module.h>
2 #include <asm/percpu.h>
3 #include <ec_probe.h>
4 #include <picl.h>
5 #include <swap_uprobes.h>
6 #include <sspt/ip.h>
7 #include <dbi_kprobes_deps.h>
8 #include "storage.h"
9 #include "us_proc_inst.h"
10 #include <sspt/sspt.h>
11
12 DEFINE_PER_CPU(struct us_ip *, gpCurIp) = NULL;
13 EXPORT_PER_CPU_SYMBOL_GPL(gpCurIp);
14 DEFINE_PER_CPU(struct pt_regs *, gpUserRegs) = NULL;
15 EXPORT_PER_CPU_SYMBOL_GPL(gpUserRegs);
16
17 unsigned long ujprobe_event_pre_handler(struct us_ip *ip, struct pt_regs *regs)
18 {
19         __get_cpu_var(gpCurIp) = ip;
20         __get_cpu_var(gpUserRegs) = regs;
21         return 0;
22 }
23 EXPORT_SYMBOL_GPL(ujprobe_event_pre_handler);
24
25 void ujprobe_event_handler(unsigned long arg0, unsigned long arg1,
26                            unsigned long arg2, unsigned long arg3,
27                            unsigned long arg4, unsigned long arg5)
28 {
29         struct us_ip *ip = __get_cpu_var(gpCurIp);
30         unsigned long addr = (unsigned long)ip->jprobe.up.kp.addr;
31
32 #if defined(CONFIG_ARM)
33         addr = ip->offset & 0x01 ? addr | 0x01 : addr;
34 #endif
35
36         ptr_pack_task_event_info(current, US_PROBE_ID, RECORD_ENTRY, "ppppppp", addr, arg0, arg1,
37                         arg2, arg3, arg4, arg5);
38         swap_ujprobe_return();
39 }
40 EXPORT_SYMBOL_GPL(ujprobe_event_handler);
41
42 static void send_plt(struct us_ip *ip)
43 {
44         unsigned long addr = (unsigned long)ip->jprobe.up.kp.addr;
45         struct vm_area_struct *vma = find_vma(current->mm, addr);
46
47         if (vma && check_vma(vma)) {
48                 char *name = NULL;
49                 unsigned long real_addr;
50                 unsigned long real_got = current->mm->exe_file == vma->vm_file ?
51                                          ip->got_addr :
52                                          ip->got_addr + vma->vm_start;
53
54                 if (!read_proc_vm_atomic(current, real_got, &real_addr, sizeof(real_addr))) {
55                         printk("Failed to read got %lx at memory address %lx!\n", ip->got_addr, real_got);
56                         return;
57                 }
58
59                 vma = find_vma(current->mm, real_addr);
60                 if (vma && (vma->vm_start <= real_addr) && (vma->vm_end > real_addr)) {
61                         name = vma->vm_file ? vma->vm_file->f_dentry->d_iname : NULL;
62                 } else {
63                         printk("Failed to get vma, includes %lx address\n", real_addr);
64                         return;
65                 }
66
67                 if (name)
68                         ptr_pack_task_event_info(current, PLT_ADDR_PROBE_ID, RECORD_RET, "ppsp",
69                                         addr, real_addr, name,
70                                         real_addr - vma->vm_start);
71                 else
72                         ptr_pack_task_event_info(current, PLT_ADDR_PROBE_ID, RECORD_RET, "ppp",
73                                         addr, real_addr,
74                                         real_addr - vma->vm_start);
75         }
76 }
77
78 int uretprobe_event_handler(struct uretprobe_instance *probe,
79                             struct pt_regs *regs,
80                             struct us_ip *ip)
81 {
82         int retval = regs_return_value(regs);
83         unsigned long addr = (unsigned long)ip->jprobe.up.kp.addr;
84
85         if (ip->got_addr && ip->flag_got == 0) {
86                 send_plt(ip);
87                 ip->flag_got = 1;
88         }
89
90 #if defined(CONFIG_ARM)
91         addr = ip->offset & 0x01 ? addr | 0x01 : addr;
92 #endif
93
94         ptr_pack_task_event_info(current, US_PROBE_ID, RECORD_RET, "pd", addr, retval);
95
96         return 0;
97 }
98 EXPORT_SYMBOL_GPL(uretprobe_event_handler);