Merge branch 'kernel' of ssh://106.109.8.71/srv/git/dbi into kernel
[kernel/swap-modules.git] / parser / msg_parser.c
1 /*
2  *  SWAP Parser
3  *  modules/parser/msg_parser.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, Vitaliy Cherepanov: SWAP Parser implement
22  *
23  */
24
25
26 #include <linux/slab.h>
27 #include "msg_parser.h"
28 #include "msg_buf.h"
29 #include "parser_defs.h"
30
31
32 static int str_to_u32(const char* str, u32 *val)
33 {
34         u32 result;
35         if(!str || !*str)
36                 return -EINVAL;
37
38         for (result = 0 ; *str; ++str) {
39                 if (*str < '0' || *str> '9')
40                         return -EINVAL;
41
42                 result = result * 10 + (*str - '0');
43         }
44
45         *val = result;
46
47         return 0;
48 }
49
50
51
52
53
54 /* ============================================================================
55  * ==                               APP_INFO                                 ==
56  * ============================================================================
57  */
58 struct app_info_data *create_app_info(struct msg_buf *mb)
59 {
60         int ret;
61         struct app_info_data *ai;
62         u32 app_type;
63         char *ta_id, *exec_path;
64
65         print_parse_debug("app_info:\n");
66
67         print_parse_debug("type:");
68         ret = get_u32(mb, &app_type);
69         if (ret) {
70                 print_err("failed to read target application type\n");
71                 return NULL;
72         }
73
74         print_parse_debug("id:");
75         ret = get_string(mb, &ta_id);
76         if (ret) {
77                 print_err("failed to read target application ID\n");
78                 return NULL;
79         }
80
81         print_parse_debug("exec path:");
82         ret = get_string(mb, &exec_path);
83         if (ret) {
84                 print_err("failed to read executable path\n");
85                 goto free_ta_id;
86         }
87
88         ai = kmalloc(sizeof(*ai), GFP_KERNEL);
89         if (ai == NULL) {
90                 print_err("out of memory\n");
91                 goto free_exec_path;
92         }
93
94         switch (app_type) {
95         case AT_TIZEN_NATIVE_APP:
96         case AT_COMMON_EXEC:
97                 ai->tgid = 0;
98                 break;
99         case AT_PID: {
100                 u32 tgid;
101                 ret = str_to_u32(ta_id, &tgid);
102                 if (ret) {
103                         print_err("converting string to PID, str='%s'\n", ta_id);
104                         goto free_ai;
105                 }
106
107                 ai->tgid = tgid;
108                 break;
109         }
110         default:
111                 print_err("wrong application type(%u)\n", app_type);
112                 ret = -EINVAL;
113                 goto free_ai;
114         }
115
116         ai->app_type = (enum APP_TYPE)app_type;
117         ai->exec_path = exec_path;
118
119         put_string(ta_id);
120
121         return ai;
122
123 free_ai:
124         kfree(ai);
125
126 free_exec_path:
127         put_string(exec_path);
128
129 free_ta_id:
130         put_string(ta_id);
131
132         return NULL;
133 }
134
135 void destroy_app_info(struct app_info_data *ai)
136 {
137         put_string(ai->exec_path);
138         kfree(ai);
139 }
140
141
142
143
144
145 /* ============================================================================
146  * ==                                CONFIG                                  ==
147  * ============================================================================
148  */
149 struct conf_data *create_conf_data(struct msg_buf *mb)
150 {
151         struct conf_data *conf;
152         u64 uf;
153         u32 stp, dmp;
154
155         print_parse_debug("conf_data:\n");
156
157         print_parse_debug("features:");
158         if (get_u64(mb, &uf)) {
159                 print_err("failed to read use_features\n");
160                 return NULL;
161         }
162
163         print_parse_debug("sys trace period:");
164         if (get_u32(mb, &stp)) {
165                 print_err("failed to read sys trace period\n");
166                 return NULL;
167         }
168
169         print_parse_debug("data msg period:");
170         if (get_u32(mb, &dmp)) {
171                 print_err("failed to read data message period\n");
172                 return NULL;
173         }
174
175         conf = kmalloc(sizeof(*conf), GFP_KERNEL);
176         if (conf == NULL) {
177                 print_err("out of memory\n");
178                 return NULL;
179         }
180
181         conf->use_features = uf;
182         conf->sys_trace_period = stp;
183         conf->data_msg_period = dmp;
184
185         return conf;
186 }
187
188 void destroy_conf_data(struct conf_data *conf)
189 {
190         kfree(conf);
191 }
192
193
194
195
196
197 /* ============================================================================
198  * ==                               FUNC_INST                                ==
199  * ============================================================================
200  */
201 struct func_inst_data *create_func_inst_data(struct msg_buf *mb)
202 {
203         struct func_inst_data *fi;
204         u64 addr;
205         char *args;
206
207         print_parse_debug("func addr:");
208         if (get_u64(mb, &addr)) {
209                 print_err("failed to read data function address\n");
210                 return NULL;
211         }
212
213         print_parse_debug("funct args:");
214         if (get_string(mb, &args)) {
215                 print_err("failed to read data function arguments\n");
216                 return NULL;
217         }
218
219         fi = kmalloc(sizeof(*fi), GFP_KERNEL);
220         if (fi == NULL) {
221                 print_err("out of memory\n");
222                 put_string(args);
223                 return NULL;
224         }
225
226         fi->addr = addr;
227         fi->args = args;
228
229         return fi;
230 }
231
232 void destroy_func_inst_data(struct func_inst_data *fi)
233 {
234         put_string(fi->args);
235         kfree(fi);
236 }
237
238
239
240
241
242 /* ============================================================================
243  * ==                               LIB_INST                                 ==
244  * ============================================================================
245  */
246 struct lib_inst_data *create_lib_inst_data(struct msg_buf *mb)
247 {
248         struct lib_inst_data *li;
249         struct func_inst_data *fi;
250         char *path;
251         u32 cnt, j, i = 0;
252
253         print_parse_debug("bin path:");
254         if (get_string(mb, &path)) {
255                 print_err("failed to read path of binary\n");
256                 return NULL;
257         }
258
259         print_parse_debug("func count:");
260         if (get_u32(mb, &cnt)) {
261                 print_err("failed to read count of functions\n");
262                 return NULL;
263         }
264
265         if (remained_mb(mb) / MIN_SIZE_FUNC_INST < cnt) {
266                 print_err("to match count of functions(%u)\n", cnt);
267                 return NULL;
268         }
269
270         li = kmalloc(sizeof(*li), GFP_KERNEL);
271         if (li == NULL)
272         if (li == NULL) {
273                 print_err("out of memory\n");
274                 goto free_path;
275         }
276
277         li->func = kmalloc(sizeof(struct func_inst_data *) * cnt, GFP_KERNEL);
278         if (li->func == NULL)
279         if (li->func == NULL) {
280                 print_err("out of memory\n");
281                 goto free_li;
282         }
283
284         for (i = 0; i < cnt; ++i) {
285                 print_parse_debug("func #%d:\n", i + 1);
286                 fi = create_func_inst_data(mb);
287                 if (fi == NULL)
288                         goto free_func;
289
290                 li->func[i] = fi;
291         }
292
293         li->path = path;
294         li->cnt_func = cnt;
295
296         return li;
297
298 free_func:
299         for (j = 0; j < i; ++j)
300                 destroy_func_inst_data(li->func[j]);
301         kfree(li->func);
302
303 free_li:
304         kfree(li);
305
306 free_path:
307         put_string(path);
308
309         return NULL;
310 }
311
312 void destroy_lib_inst_data(struct lib_inst_data *li)
313 {
314         int i;
315
316         put_string(li->path);
317
318         for (i = 0; i < li->cnt_func; ++i)
319                 destroy_func_inst_data(li->func[i]);
320
321         kfree(li->func);
322         kfree(li);
323 }
324
325
326
327
328
329 /* ============================================================================
330  * ==                               APP_INST                                 ==
331  * ============================================================================
332  */
333 struct app_inst_data *create_app_inst_data(struct msg_buf *mb)
334 {
335         struct app_inst_data *app_inst;
336         struct app_info_data *app_info;
337         struct func_inst_data *func;
338         struct lib_inst_data *lib;
339         u32 cnt_func, i_func = 0, cnt_lib, i_lib = 0, i;
340
341         app_info = create_app_info(mb);
342         if (app_info == NULL)
343                 return NULL;
344
345         print_parse_debug("func count:");
346         if (get_u32(mb, &cnt_func)) {
347                 print_err("failed to read count of functions\n");
348                 goto free_app_info;
349         }
350
351         if (remained_mb(mb) / MIN_SIZE_FUNC_INST < cnt_func) {
352                 print_err("to match count of functions(%u)\n", cnt_func);
353                 goto free_app_info;
354         }
355
356         app_inst = kmalloc(sizeof(*app_inst), GFP_KERNEL);
357         if (app_inst == NULL) {
358                 print_err("out of memory\n");
359                 goto free_app_info;
360         }
361
362         app_inst->func = kmalloc(sizeof(struct func_inst_data *) * cnt_func,
363                                  GFP_KERNEL);
364         if (app_inst->func == NULL) {
365                 print_err("out of memory\n");
366                 goto free_app_inst;
367         }
368
369         for (i_func = 0; i_func < cnt_func; ++i_func) {
370                 print_parse_debug("func #%d:\n", i_func + 1);
371                 func = create_func_inst_data(mb);
372                 if (func == NULL)
373                         goto free_func;
374
375                 app_inst->func[i_func] = func;
376         }
377
378         print_parse_debug("lib count:");
379         if (get_u32(mb, &cnt_lib)) {
380                 print_err("failed to read count of libraries\n");
381                 goto free_func;
382         }
383
384         if (remained_mb(mb) / MIN_SIZE_LIB_INST < cnt_lib) {
385                 print_err("to match count of libraries(%u)\n", cnt_lib);
386                 goto free_func;
387         }
388
389         app_inst->lib = kmalloc(sizeof(struct lib_inst_data *) * cnt_lib,
390                                 GFP_KERNEL);
391         if (app_inst->lib == NULL) {
392                 print_err("out of memory\n");
393                 goto free_func;
394         }
395
396         for (i_lib = 0; i_lib < cnt_lib; ++i_lib) {
397                 print_parse_debug("lib #%d:\n", i_lib + 1);
398                 lib = create_lib_inst_data(mb);
399                 if (lib == NULL)
400                         goto free_lib;
401
402                 app_inst->lib[i_lib] = lib;
403         }
404
405         app_inst->app_info = app_info;
406         app_inst->cnt_func = cnt_func;
407         app_inst->cnt_lib = cnt_lib;
408
409         return app_inst;
410
411 free_lib:
412         for (i = 0; i < i_lib; ++i)
413                 destroy_lib_inst_data(app_inst->lib[i]);
414         kfree(app_inst->lib);
415
416 free_func:
417         for (i = 0; i < i_func; ++i)
418                 destroy_func_inst_data(app_inst->func[i]);
419         kfree(app_inst->func);
420
421 free_app_inst:
422         kfree(app_inst);
423
424 free_app_info:
425         destroy_app_info(app_info);
426
427         return NULL;
428 }
429
430 void destroy_app_inst_data(struct app_inst_data *ai)
431 {
432         int i;
433
434         for (i = 0; i < ai->cnt_lib; ++i)
435                 destroy_lib_inst_data(ai->lib[i]);
436         kfree(ai->lib);
437
438         for (i = 0; i < ai->cnt_func; ++i)
439                 destroy_func_inst_data(ai->func[i]);
440         kfree(ai->func);
441
442         destroy_app_info(ai->app_info);
443         kfree(ai);
444 }
445
446
447
448
449
450 /* ============================================================================
451  * ==                                US_INST                                 ==
452  * ============================================================================
453  */
454 struct us_inst_data *create_us_inst_data(struct msg_buf *mb)
455 {
456         struct us_inst_data *ui;
457         struct app_inst_data *ai;
458         u32 cnt, j, i = 0;
459
460         print_parse_debug("us_inst_data:\n");
461
462         print_parse_debug("app count:");
463         if (get_u32(mb, &cnt)) {
464                 print_err("failed to read count of applications\n");
465                 return NULL;
466         }
467
468         if (remained_mb(mb) / MIN_SIZE_APP_INST < cnt) {
469                 print_err("to match count of applications(%u)\n", cnt);
470                 return NULL;
471         }
472
473         ui = kmalloc(sizeof(struct us_inst_data), GFP_KERNEL);
474         if (ui == NULL) {
475                 print_err("out of memory\n");
476                 return NULL;
477         }
478
479         ui->app_inst = kmalloc(sizeof(struct app_inst_data *) * cnt,
480                                GFP_KERNEL);
481         if (ui->app_inst == NULL) {
482                 print_err("out of memory\n");
483                 goto free_ui;
484         }
485
486         for (i = 0; i < cnt; ++i) {
487                 print_parse_debug("app #%d:\n",i+1);
488                 ai = create_app_inst_data(mb);
489                 if (ai == NULL)
490                         goto free_app_inst;
491
492                 ui->app_inst[i] = ai;
493         }
494
495         ui->cnt = cnt;
496
497         return ui;
498
499 free_app_inst:
500         for (j = 0; j < i; ++j)
501                 destroy_app_inst_data(ui->app_inst[j]);
502         kfree(ui->app_inst);
503
504 free_ui:
505         kfree(ui);
506
507         return NULL;
508 }
509
510 void destroy_us_inst_data(struct us_inst_data *ui)
511 {
512         int i;
513
514         for (i = 0; i < ui->cnt; ++i)
515                 destroy_app_inst_data(ui->app_inst[i]);
516
517         kfree(ui->app_inst);
518         kfree(ui);
519 }