[IMPROVE] x86: apply jumper for US probes installing
[kernel/swap-modules.git] / parser / msg_parser.c
1 /**
2  * parser/msg_parser.c
3  * @author Vyacheslav Cherkashin
4  * @author Vitaliy Cherepanov
5  *
6  * @sectionLICENSE
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21  *
22  * @section COPYRIGHT
23  *
24  * Copyright (C) Samsung Electronics, 2013
25  *
26  * @section DESCRIPTION
27  *
28  * Message parsing implementation.
29  */
30
31
32 #include <linux/slab.h>
33 #include "msg_parser.h"
34 #include "msg_buf.h"
35 #include "parser_defs.h"
36
37
38 static int str_to_u32(const char* str, u32 *val)
39 {
40         u32 result;
41         if(!str || !*str)
42                 return -EINVAL;
43
44         for (result = 0 ; *str; ++str) {
45                 if (*str < '0' || *str> '9')
46                         return -EINVAL;
47
48                 result = result * 10 + (*str - '0');
49         }
50
51         *val = result;
52
53         return 0;
54 }
55
56
57
58
59
60 /* ============================================================================
61  * ==                               APP_INFO                                 ==
62  * ============================================================================
63  */
64
65 /**
66  * @brief Creates and fills app_info_data struct.
67  *
68  * @param mb Pointer to the message buffer.
69  * @return Pointer to the filled app_info_data struct on success;\n
70  * NULL on error.
71  */
72 struct app_info_data *create_app_info(struct msg_buf *mb)
73 {
74         int ret;
75         struct app_info_data *ai;
76         u32 app_type;
77         char *ta_id, *exec_path;
78
79         print_parse_debug("app_info:\n");
80
81         print_parse_debug("type:");
82         ret = get_u32(mb, &app_type);
83         if (ret) {
84                 print_err("failed to read target application type\n");
85                 return NULL;
86         }
87
88         print_parse_debug("id:");
89         ret = get_string(mb, &ta_id);
90         if (ret) {
91                 print_err("failed to read target application ID\n");
92                 return NULL;
93         }
94
95         print_parse_debug("exec path:");
96         ret = get_string(mb, &exec_path);
97         if (ret) {
98                 print_err("failed to read executable path\n");
99                 goto free_ta_id;
100         }
101
102         ai = kmalloc(sizeof(*ai), GFP_KERNEL);
103         if (ai == NULL) {
104                 print_err("out of memory\n");
105                 goto free_exec_path;
106         }
107
108         switch (app_type) {
109         case AT_TIZEN_NATIVE_APP:
110         case AT_TIZEN_WEB_APP:
111         case AT_COMMON_EXEC:
112                 ai->tgid = 0;
113                 break;
114         case AT_PID: {
115                 u32 tgid = 0;
116
117                 if (*ta_id != '\0') {
118                         ret = str_to_u32(ta_id, &tgid);
119                         if (ret) {
120                                 print_err("converting string to PID, "
121                                           "str='%s'\n", ta_id);
122                                 goto free_ai;
123                         }
124                 }
125
126                 ai->tgid = tgid;
127                 break;
128         }
129         default:
130                 print_err("wrong application type(%u)\n", app_type);
131                 ret = -EINVAL;
132                 goto free_ai;
133         }
134
135         ai->app_type = (enum APP_TYPE)app_type;
136         ai->app_id = ta_id;
137         ai->exec_path = exec_path;
138
139         return ai;
140
141 free_ai:
142         kfree(ai);
143
144 free_exec_path:
145         put_string(exec_path);
146
147 free_ta_id:
148         put_string(ta_id);
149
150         return NULL;
151 }
152
153 /**
154  * @brief app_info_data cleanup.
155  *
156  * @param ai Pointer to the target app_info_data.
157  * @return Void.
158  */
159 void destroy_app_info(struct app_info_data *ai)
160 {
161         put_string(ai->exec_path);
162         put_string(ai->app_id);
163         kfree(ai);
164 }
165
166
167
168
169
170 /* ============================================================================
171  * ==                                CONFIG                                  ==
172  * ============================================================================
173  */
174
175 /**
176  * @brief Creates and fills conf_data struct.
177  *
178  * @param mb Pointer to the message buffer.
179  * @return Pointer to the filled conf_data struct on success;\n
180  * 0 on error.
181  */
182 struct conf_data *create_conf_data(struct msg_buf *mb)
183 {
184         struct conf_data *conf;
185         u64 use_features0, use_features1;
186         u32 stp, dmp;
187
188         print_parse_debug("conf_data:\n");
189
190         print_parse_debug("features:");
191         if (get_u64(mb, &use_features0)) {
192                 print_err("failed to read use_features\n");
193                 return NULL;
194         }
195
196         if (get_u64(mb, &use_features1)) {
197                 print_err("failed to read use_features\n");
198                 return NULL;
199         }
200
201         print_parse_debug("sys trace period:");
202         if (get_u32(mb, &stp)) {
203                 print_err("failed to read sys trace period\n");
204                 return NULL;
205         }
206
207         print_parse_debug("data msg period:");
208         if (get_u32(mb, &dmp)) {
209                 print_err("failed to read data message period\n");
210                 return NULL;
211         }
212
213         conf = kmalloc(sizeof(*conf), GFP_KERNEL);
214         if (conf == NULL) {
215                 print_err("out of memory\n");
216                 return NULL;
217         }
218
219         conf->use_features0 = use_features0;
220         conf->use_features1 = use_features1;
221         conf->sys_trace_period = stp;
222         conf->data_msg_period = dmp;
223
224         return conf;
225 }
226
227 /**
228  * @brief conf_data cleanup.
229  *
230  * @param conf Pointer to the target conf_data.
231  * @return Void.
232  */
233 void destroy_conf_data(struct conf_data *conf)
234 {
235         kfree(conf);
236 }
237
238 static struct conf_data config;
239
240 /**
241  * @brief Saves config to static config variable.
242  *
243  * @param conf Variable to save.
244  * @return Void.
245  */
246 void save_config(const struct conf_data *conf)
247 {
248         memcpy(&config, conf, sizeof(config));
249 }
250
251 /**
252  * @brief Restores config from static config variable.
253  *
254  * @param conf Variable to restore.
255  * @return Void.
256  */
257 void restore_config(struct conf_data *conf)
258 {
259         memcpy(conf, &config, sizeof(*conf));
260 }
261
262
263
264 /* ============================================================================
265  * ==                               FUNC_INST                                ==
266  * ============================================================================
267  */
268
269 /**
270  * @brief Creates and fills func_inst_data struct.
271  *
272  * @param mb Pointer to the message buffer.
273  * @return Pointer to the filled func_inst_data struct on success;\n
274  * 0 on error.
275  */
276 struct func_inst_data *create_func_inst_data(struct msg_buf *mb)
277 {
278         struct func_inst_data *fi;
279         u64 addr;
280         char *args;
281         char ret_type;
282
283         print_parse_debug("func addr:");
284         if (get_u64(mb, &addr)) {
285                 print_err("failed to read data function address\n");
286                 return NULL;
287         }
288
289         print_parse_debug("funct args:");
290         if (get_string(mb, &args)) {
291                 print_err("failed to read data function arguments\n");
292                 return NULL;
293         }
294
295         print_parse_debug("funct ret type:");
296         if (get_u8(mb, (u8 *)&ret_type)) {
297                 print_err("failed to read data function arguments\n");
298                 goto free_args;
299         }
300
301         fi = kmalloc(sizeof(*fi), GFP_KERNEL);
302         if (fi == NULL) {
303                 print_err("out of memory\n");
304                 goto free_args;
305         }
306
307         fi->addr = addr;
308         fi->args = args;
309         fi->ret_type = ret_type;
310
311         return fi;
312
313 free_args:
314         put_string(args);
315         return NULL;
316 }
317
318 /**
319  * @brief func_inst_data cleanup.
320  *
321  * @param fi Pointer to the target func_inst_data.
322  * @return Void.
323  */
324 void destroy_func_inst_data(struct func_inst_data *fi)
325 {
326         put_string(fi->args);
327         kfree(fi);
328 }
329
330
331
332
333
334 /* ============================================================================
335  * ==                               LIB_INST                                 ==
336  * ============================================================================
337  */
338
339 /**
340  * @brief Creates and fills lib_inst_data struct.
341  *
342  * @param mb Pointer to the message buffer.
343  * @return Pointer to the filled lib_inst_data struct on success;\n
344  * 0 on error.
345  */
346 struct lib_inst_data *create_lib_inst_data(struct msg_buf *mb)
347 {
348         struct lib_inst_data *li;
349         struct func_inst_data *fi;
350         char *path;
351         u32 cnt, j, i = 0;
352
353         print_parse_debug("bin path:");
354         if (get_string(mb, &path)) {
355                 print_err("failed to read path of binary\n");
356                 return NULL;
357         }
358
359         print_parse_debug("func count:");
360         if (get_u32(mb, &cnt)) {
361                 print_err("failed to read count of functions\n");
362                 goto free_path;
363         }
364
365         if (remained_mb(mb) / MIN_SIZE_FUNC_INST < cnt) {
366                 print_err("to match count of functions(%u)\n", cnt);
367                 goto free_path;
368         }
369
370         li = kmalloc(sizeof(*li), GFP_KERNEL);
371         if (li == NULL)
372         if (li == NULL) {
373                 print_err("out of memory\n");
374                 goto free_path;
375         }
376
377         li->func = kmalloc(sizeof(struct func_inst_data *) * cnt, GFP_KERNEL);
378         if (li->func == NULL)
379         if (li->func == NULL) {
380                 print_err("out of memory\n");
381                 goto free_li;
382         }
383
384         for (i = 0; i < cnt; ++i) {
385                 print_parse_debug("func #%d:\n", i + 1);
386                 fi = create_func_inst_data(mb);
387                 if (fi == NULL)
388                         goto free_func;
389
390                 li->func[i] = fi;
391         }
392
393         li->path = path;
394         li->cnt_func = cnt;
395
396         return li;
397
398 free_func:
399         for (j = 0; j < i; ++j)
400                 destroy_func_inst_data(li->func[j]);
401         kfree(li->func);
402
403 free_li:
404         kfree(li);
405
406 free_path:
407         put_string(path);
408
409         return NULL;
410 }
411
412 /**
413  * @brief lib_inst_data cleanup.
414  *
415  * @param li Pointer to the target lib_inst_data.
416  * @return Void.
417  */
418 void destroy_lib_inst_data(struct lib_inst_data *li)
419 {
420         int i;
421
422         put_string(li->path);
423
424         for (i = 0; i < li->cnt_func; ++i)
425                 destroy_func_inst_data(li->func[i]);
426
427         kfree(li->func);
428         kfree(li);
429 }
430
431
432
433
434
435 /* ============================================================================
436  * ==                               APP_INST                                 ==
437  * ============================================================================
438  */
439
440 /**
441  * @brief Creates and fills app_inst_data struct.
442  *
443  * @param mb Pointer to the message buffer.
444  * @return Pointer to the filled app_inst_data struct on success;\n
445  * 0 on error.
446  */
447 struct app_inst_data *create_app_inst_data(struct msg_buf *mb)
448 {
449         struct app_inst_data *app_inst;
450         struct app_info_data *app_info;
451         struct func_inst_data *func;
452         struct lib_inst_data *lib;
453         u32 cnt_func, i_func = 0, cnt_lib, i_lib = 0, i;
454
455         app_info = create_app_info(mb);
456         if (app_info == NULL)
457                 return NULL;
458
459         print_parse_debug("func count:");
460         if (get_u32(mb, &cnt_func)) {
461                 print_err("failed to read count of functions\n");
462                 goto free_app_info;
463         }
464
465         if (remained_mb(mb) / MIN_SIZE_FUNC_INST < cnt_func) {
466                 print_err("to match count of functions(%u)\n", cnt_func);
467                 goto free_app_info;
468         }
469
470         app_inst = kmalloc(sizeof(*app_inst), GFP_KERNEL);
471         if (app_inst == NULL) {
472                 print_err("out of memory\n");
473                 goto free_app_info;
474         }
475
476         app_inst->func = kmalloc(sizeof(struct func_inst_data *) * cnt_func,
477                                  GFP_KERNEL);
478         if (app_inst->func == NULL) {
479                 print_err("out of memory\n");
480                 goto free_app_inst;
481         }
482
483         for (i_func = 0; i_func < cnt_func; ++i_func) {
484                 print_parse_debug("func #%d:\n", i_func + 1);
485                 func = create_func_inst_data(mb);
486                 if (func == NULL)
487                         goto free_func;
488
489                 app_inst->func[i_func] = func;
490         }
491
492         print_parse_debug("lib count:");
493         if (get_u32(mb, &cnt_lib)) {
494                 print_err("failed to read count of libraries\n");
495                 goto free_func;
496         }
497
498         if (remained_mb(mb) / MIN_SIZE_LIB_INST < cnt_lib) {
499                 print_err("to match count of libraries(%u)\n", cnt_lib);
500                 goto free_func;
501         }
502
503         app_inst->lib = kmalloc(sizeof(struct lib_inst_data *) * cnt_lib,
504                                 GFP_KERNEL);
505         if (app_inst->lib == NULL) {
506                 print_err("out of memory\n");
507                 goto free_func;
508         }
509
510         for (i_lib = 0; i_lib < cnt_lib; ++i_lib) {
511                 print_parse_debug("lib #%d:\n", i_lib + 1);
512                 lib = create_lib_inst_data(mb);
513                 if (lib == NULL)
514                         goto free_lib;
515
516                 app_inst->lib[i_lib] = lib;
517         }
518
519         app_inst->app_info = app_info;
520         app_inst->cnt_func = cnt_func;
521         app_inst->cnt_lib = cnt_lib;
522
523         return app_inst;
524
525 free_lib:
526         for (i = 0; i < i_lib; ++i)
527                 destroy_lib_inst_data(app_inst->lib[i]);
528         kfree(app_inst->lib);
529
530 free_func:
531         for (i = 0; i < i_func; ++i)
532                 destroy_func_inst_data(app_inst->func[i]);
533         kfree(app_inst->func);
534
535 free_app_inst:
536         kfree(app_inst);
537
538 free_app_info:
539         destroy_app_info(app_info);
540
541         return NULL;
542 }
543
544 /**
545  * @brief app_inst_data cleanup.
546  *
547  * @param ai Pointer to the target app_inst_data.
548  * @return Void.
549  */
550 void destroy_app_inst_data(struct app_inst_data *ai)
551 {
552         int i;
553
554         for (i = 0; i < ai->cnt_lib; ++i)
555                 destroy_lib_inst_data(ai->lib[i]);
556         kfree(ai->lib);
557
558         for (i = 0; i < ai->cnt_func; ++i)
559                 destroy_func_inst_data(ai->func[i]);
560         kfree(ai->func);
561
562         destroy_app_info(ai->app_info);
563         kfree(ai);
564 }
565
566
567
568
569
570 /* ============================================================================
571  * ==                                US_INST                                 ==
572  * ============================================================================
573  */
574
575 /**
576  * @brief Creates and fills us_inst_data struct.
577  *
578  * @param mb Pointer to the message buffer.
579  * @return Pointer to the filled us_inst_data struct on success;\n
580  * 0 on error.
581  */
582 struct us_inst_data *create_us_inst_data(struct msg_buf *mb)
583 {
584         struct us_inst_data *ui;
585         struct app_inst_data *ai;
586         u32 cnt, j, i = 0;
587
588         print_parse_debug("us_inst_data:\n");
589
590         print_parse_debug("app count:");
591         if (get_u32(mb, &cnt)) {
592                 print_err("failed to read count of applications\n");
593                 return NULL;
594         }
595
596         if (remained_mb(mb) / MIN_SIZE_APP_INST < cnt) {
597                 print_err("to match count of applications(%u)\n", cnt);
598                 return NULL;
599         }
600
601         ui = kmalloc(sizeof(struct us_inst_data), GFP_KERNEL);
602         if (ui == NULL) {
603                 print_err("out of memory\n");
604                 return NULL;
605         }
606
607         ui->app_inst = kmalloc(sizeof(struct app_inst_data *) * cnt,
608                                GFP_KERNEL);
609         if (ui->app_inst == NULL) {
610                 print_err("out of memory\n");
611                 goto free_ui;
612         }
613
614         for (i = 0; i < cnt; ++i) {
615                 print_parse_debug("app #%d:\n",i+1);
616                 ai = create_app_inst_data(mb);
617                 if (ai == NULL)
618                         goto free_app_inst;
619
620                 ui->app_inst[i] = ai;
621         }
622
623         ui->cnt = cnt;
624
625         return ui;
626
627 free_app_inst:
628         for (j = 0; j < i; ++j)
629                 destroy_app_inst_data(ui->app_inst[j]);
630         kfree(ui->app_inst);
631
632 free_ui:
633         kfree(ui);
634
635         return NULL;
636 }
637
638 /**
639  * @brief us_inst_data cleanup.
640  *
641  * @param ui Pointer to the target us_inst_data.
642  * @return Void.
643  */
644 void destroy_us_inst_data(struct us_inst_data *ui)
645 {
646         int i;
647
648         for (i = 0; i < ui->cnt; ++i)
649                 destroy_app_inst_data(ui->app_inst[i]);
650
651         kfree(ui->app_inst);
652         kfree(ui);
653 }