8d1d52f8c08fa47a0f8c9817b316d8ea7624fb42
[kernel/swap-modules.git] / driver / sspt / sspt_procs.c
1 /*
2  *  Dynamic Binary Instrumentation Module based on KProbes
3  *  modules/driver/sspt/sspt_procs.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 "sspt_procs.h"
26 #include <linux/slab.h>
27 #include <linux/list.h>
28
29 extern struct list_head proc_probes_list;
30
31 struct sspt_procs *sspt_procs_create(struct dentry* dentry, pid_t tgid)
32 {
33         struct sspt_procs *procs = kmalloc(sizeof(*procs), GFP_ATOMIC);
34
35         if (procs) {
36                 INIT_LIST_HEAD(&procs->list);
37                 procs->tgid = tgid;
38                 procs->dentry = dentry;
39                 INIT_LIST_HEAD(&procs->file_list);
40         }
41
42         return procs;
43 }
44
45 void sspt_procs_free(struct sspt_procs *procs)
46 {
47         struct sspt_file *file, *n;
48         list_for_each_entry_safe(file, n, &procs->file_list, list) {
49                 list_del(&file->list);
50                 sspt_file_free(file);
51         }
52
53         kfree(procs);
54 }
55
56 // TODO: remove "us_proc_info"
57 #include "../storage.h"
58 extern inst_us_proc_t us_proc_info;
59
60 void sspt_procs_free_all(void)
61 {
62         // is user-space instrumentation
63         if (us_proc_info.path == NULL) {
64                 return;
65         }
66
67         if (strcmp(us_proc_info.path,"*") == 0) {
68                 // app
69                 sspt_procs_free(us_proc_info.pp);
70                 us_proc_info.pp = NULL;
71         } else {
72                 // libonly
73                 struct sspt_procs *procs, *n;
74                 list_for_each_entry_safe(procs, n, &proc_probes_list, list) {
75                         list_del(&procs->list);
76                         sspt_procs_free(procs);
77                 }
78         }
79 }
80
81 static void sspt_procs_add_file(struct sspt_procs *procs, struct sspt_file *file)
82 {
83         list_add(&file->list, &procs->file_list);
84         file->procs = procs;
85 }
86
87 struct sspt_file *sspt_procs_find_file_or_new(struct sspt_procs *procs,
88                 struct dentry *dentry, char *name)
89 {
90         struct sspt_file *file;
91
92         list_for_each_entry(file, &procs->file_list, list) {
93                 if (file->dentry == dentry) {
94                         return file;
95                 }
96         }
97
98         file = sspt_file_create(name, dentry, 10);
99         sspt_procs_add_file(procs, file);
100
101         return file;
102 }
103
104 void sspt_procs_add_ip_data(struct sspt_procs *procs, struct dentry* dentry,
105                 char *name, struct ip_data *ip_d)
106 {
107         struct sspt_file *file = sspt_procs_find_file_or_new(procs, dentry, name);
108         sspt_file_add_ip(file, ip_d);
109 }
110
111 struct sspt_procs *sspt_procs_copy(struct sspt_procs *procs, struct task_struct *task)
112 {
113         struct sspt_file *file;
114         struct sspt_procs *procs_out = sspt_procs_create(procs->dentry, task->tgid);
115
116         list_for_each_entry(file, &procs->file_list, list) {
117                 sspt_procs_add_file(procs_out, sspt_file_copy(file));
118         }
119
120         return procs_out;
121 }
122
123 struct sspt_file *sspt_procs_find_file(struct sspt_procs *procs, struct dentry *dentry)
124 {
125         struct sspt_file *file;
126
127         list_for_each_entry(file, &procs->file_list, list) {
128                 if (dentry == file->dentry) {
129                         return file;
130                 }
131         }
132
133         return NULL;
134 }