[PROTO] add return type for exit_event()
[kernel/swap-modules.git] / us_manager / sspt / ip.c
1 /*
2  *  Dynamic Binary Instrumentation Module based on KProbes
3  *  modules/driver/sspt/ip.c
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18  *
19  * Copyright (C) Samsung Electronics, 2013
20  *
21  * 2013         Vyacheslav Cherkashin <v.cherkashin@samsung.com>
22  *
23  */
24
25 #include <linux/slab.h>
26 #include "ip.h"
27 #include "sspt_page.h"
28 #include "sspt_file.h"
29 #include <writer/swap_writer_module.h>
30 #include <us_manager/us_manager.h>
31
32
33 static int entry_handler(struct uretprobe_instance *ri, struct pt_regs *regs)
34 {
35         struct uretprobe *rp = ri->rp;
36
37         if (rp && get_quiet() == QT_OFF) {
38                 struct us_ip *ip = container_of(rp, struct us_ip, retprobe);
39
40                 entry_event(ip->args, regs, PT_US, PST_NONE);
41         }
42
43         return 0;
44 }
45
46 static int ret_handler(struct uretprobe_instance *ri, struct pt_regs *regs)
47 {
48         struct uretprobe *rp = ri->rp;
49
50         if (rp && get_quiet() == QT_OFF) {
51                 struct us_ip *ip = container_of(rp, struct us_ip, retprobe);
52                 unsigned long addr = (unsigned long)ip->retprobe.up.kp.addr;
53                 unsigned long ret_addr = (unsigned long)ri->ret_addr;
54
55 #if defined(CONFIG_ARM)
56                 addr = ip->offset & 0x01 ? addr | 0x01 : addr;
57 #endif
58
59                 exit_event(ip->ret_type, regs, addr, ret_addr);
60         }
61
62         return 0;
63 }
64
65 struct us_ip *create_ip(unsigned long offset, const char *args, char ret_type)
66 {
67         size_t len = strlen(args) + 1;
68         struct us_ip *ip = kmalloc(sizeof(*ip) + len, GFP_ATOMIC);
69
70         if (ip != NULL) {
71                 memset(ip, 0, sizeof(*ip));
72
73                 INIT_LIST_HEAD(&ip->list);
74                 ip->offset = offset;
75                 ip->args = (char *)ip + sizeof(*ip);
76                 ip->ret_type = ret_type;
77
78                 /* copy args */
79                 memcpy(ip->args, args, len);
80
81                 /* retprobe */
82                 ip->retprobe.handler = ret_handler;
83                 ip->retprobe.entry_handler = entry_handler;
84         } else {
85                 printk("Cannot kmalloc in create_ip function!\n");
86         }
87
88         return ip;
89 }
90
91 void free_ip(struct us_ip *ip)
92 {
93         kfree(ip);
94 }