ARM: tizen_tm1_defconfig: Enable missing features related with CGROUPS
[profile/mobile/platform/kernel/linux-3.10-sc7730.git] / kernel / swap / parser / msg_parser.c
1 /**
2  * parser/msg_parser.c
3  *
4  * @author Vyacheslav Cherkashin
5  * @author Vitaliy Cherepanov <v.cherepanov@samsung.com>
6  *
7  * @sectionLICENSE
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22  *
23  * @section COPYRIGHT
24  *
25  * Copyright (C) Samsung Electronics, 2013
26  *
27  * @section DESCRIPTION
28  *
29  * Message parsing implementation.
30  */
31
32
33 #include <linux/slab.h>
34 #include <linux/vmalloc.h>
35 #include <us_manager/probes/probes.h>
36 #include "msg_parser.h"
37 #include "msg_buf.h"
38 #include "parser_defs.h"
39
40
41 static int str_to_u32(const char *str, u32 *val)
42 {
43         u32 result;
44         if (!str || !*str)
45                 return -EINVAL;
46
47         for (result = 0 ; *str; ++str) {
48                 if (*str < '0' || *str > '9')
49                         return -EINVAL;
50
51                 result = result * 10 + (*str - '0');
52         }
53
54         *val = result;
55
56         return 0;
57 }
58
59
60
61
62
63 /* ============================================================================
64  * ==                               APP_INFO                                 ==
65  * ============================================================================
66  */
67
68 /**
69  * @brief Creates and fills app_info_data struct.
70  *
71  * @param mb Pointer to the message buffer.
72  * @return Pointer to the filled app_info_data struct on success;\n
73  * NULL on error.
74  */
75 struct app_info_data *create_app_info(struct msg_buf *mb)
76 {
77         int ret;
78         struct app_info_data *ai;
79         u32 app_type;
80         char *ta_id, *exec_path;
81
82         print_parse_debug("app_info:\n");
83
84         print_parse_debug("type:");
85         ret = get_u32(mb, &app_type);
86         if (ret) {
87                 print_err("failed to read target application type\n");
88                 return NULL;
89         }
90
91         print_parse_debug("id:");
92         ret = get_string(mb, &ta_id);
93         if (ret) {
94                 print_err("failed to read target application ID\n");
95                 return NULL;
96         }
97
98         print_parse_debug("exec path:");
99         ret = get_string(mb, &exec_path);
100         if (ret) {
101                 print_err("failed to read executable path\n");
102                 goto free_ta_id;
103         }
104
105         ai = kmalloc(sizeof(*ai), GFP_KERNEL);
106         if (ai == NULL) {
107                 print_err("out of memory\n");
108                 goto free_exec_path;
109         }
110
111         switch (app_type) {
112         case AT_TIZEN_NATIVE_APP:
113         case AT_TIZEN_WEB_APP:
114         case AT_COMMON_EXEC:
115                 ai->tgid = 0;
116                 break;
117         case AT_PID: {
118                 u32 tgid = 0;
119
120                 if (*ta_id != '\0') {
121                         ret = str_to_u32(ta_id, &tgid);
122                         if (ret) {
123                                 print_err("converting string to PID, "
124                                           "str='%s'\n", ta_id);
125                                 goto free_ai;
126                         }
127                 }
128
129                 ai->tgid = tgid;
130                 break;
131         }
132         default:
133                 print_err("wrong application type(%u)\n", app_type);
134                 ret = -EINVAL;
135                 goto free_ai;
136         }
137
138         ai->app_type = (enum APP_TYPE)app_type;
139         ai->app_id = ta_id;
140         ai->exec_path = exec_path;
141
142         return ai;
143
144 free_ai:
145         kfree(ai);
146
147 free_exec_path:
148         put_string(exec_path);
149
150 free_ta_id:
151         put_string(ta_id);
152
153         return NULL;
154 }
155
156 /**
157  * @brief app_info_data cleanup.
158  *
159  * @param ai Pointer to the target app_info_data.
160  * @return Void.
161  */
162 void destroy_app_info(struct app_info_data *ai)
163 {
164         put_string(ai->exec_path);
165         put_string(ai->app_id);
166         kfree(ai);
167 }
168
169
170
171
172
173 /* ============================================================================
174  * ==                                CONFIG                                  ==
175  * ============================================================================
176  */
177
178 /**
179  * @brief Creates and fills conf_data struct.
180  *
181  * @param mb Pointer to the message buffer.
182  * @return Pointer to the filled conf_data struct on success;\n
183  * 0 on error.
184  */
185 struct conf_data *create_conf_data(struct msg_buf *mb)
186 {
187         struct conf_data *conf;
188         u64 use_features0, use_features1;
189         u32 stp, dmp;
190
191         print_parse_debug("conf_data:\n");
192
193         print_parse_debug("features:");
194         if (get_u64(mb, &use_features0)) {
195                 print_err("failed to read use_features\n");
196                 return NULL;
197         }
198
199         if (get_u64(mb, &use_features1)) {
200                 print_err("failed to read use_features\n");
201                 return NULL;
202         }
203
204         print_parse_debug("sys trace period:");
205         if (get_u32(mb, &stp)) {
206                 print_err("failed to read sys trace period\n");
207                 return NULL;
208         }
209
210         print_parse_debug("data msg period:");
211         if (get_u32(mb, &dmp)) {
212                 print_err("failed to read data message period\n");
213                 return NULL;
214         }
215
216         conf = kmalloc(sizeof(*conf), GFP_KERNEL);
217         if (conf == NULL) {
218                 print_err("out of memory\n");
219                 return NULL;
220         }
221
222         conf->use_features0 = use_features0;
223         conf->use_features1 = use_features1;
224         conf->sys_trace_period = stp;
225         conf->data_msg_period = dmp;
226
227         return conf;
228 }
229
230 /**
231  * @brief conf_data cleanup.
232  *
233  * @param conf Pointer to the target conf_data.
234  * @return Void.
235  */
236 void destroy_conf_data(struct conf_data *conf)
237 {
238         kfree(conf);
239 }
240
241 static struct conf_data config;
242
243 /**
244  * @brief Saves config to static config variable.
245  *
246  * @param conf Variable to save.
247  * @return Void.
248  */
249 void save_config(const struct conf_data *conf)
250 {
251         memcpy(&config, conf, sizeof(config));
252 }
253
254 /**
255  * @brief Restores config from static config variable.
256  *
257  * @param conf Variable to restore.
258  * @return Void.
259  */
260 void restore_config(struct conf_data *conf)
261 {
262         memcpy(conf, &config, sizeof(*conf));
263 }
264
265
266
267 /* ============================================================================
268  * ==                             PROBES PARSING                             ==
269  * ============================================================================
270  */
271
272 /**
273  * @brief Gets retprobe data and puts it to the probe_info struct.
274  *
275  * @param mb Pointer to the message buffer.
276  * @param pi Pointer to the probe_info struct.
277  * @return 0 on success, error code on error.
278  */
279 int get_retprobe(struct msg_buf *mb, struct probe_info *pi)
280 {
281         char *args;
282         char ret_type;
283
284         print_parse_debug("funct args:");
285         if (get_string(mb, &args)) {
286                 print_err("failed to read data function arguments\n");
287                 return -EINVAL;
288         }
289
290         print_parse_debug("funct ret type:");
291         if (get_u8(mb, (u8 *)&ret_type)) {
292                 print_err("failed to read data function arguments\n");
293                 goto free_args;
294         }
295
296         pi->probe_type = SWAP_RETPROBE;
297         pi->size = 0;
298         pi->rp_i.args = args;
299         pi->rp_i.ret_type = ret_type;
300
301         return 0;
302
303 free_args:
304         put_string(args);
305         return -EINVAL;
306 }
307
308 /**
309  * @brief Gets webprobe data and puts it to the probe_info struct.
310  *
311  * @param mb Pointer to the message buffer.
312  * @param pi Pointer to the probe_info struct.
313  * @return 0 on success, error code on error.
314  */
315 int get_webprobe(struct msg_buf *mb, struct probe_info *pi)
316 {
317         pi->probe_type = SWAP_WEBPROBE;
318         pi->size = 0;
319
320         return 0;
321 }
322
323 /**
324  * @brief Retprobe data cleanup.
325  *
326  * @param pi Pointer to the probe_info comprising retprobe.
327  * @return Void.
328  */
329 void put_retprobe(struct probe_info *pi)
330 {
331         put_string(pi->rp_i.args);
332 }
333
334 /**
335  * @brief Gets preload data and puts it to the probe_info struct.
336  *
337  * @param mb Pointer to the message buffer.
338  * @param pi Pointer to the probe_info struct.
339  * @return 0 on success, error code on error.
340  */
341 int get_preload_probe(struct msg_buf *mb, struct probe_info *pi)
342 {
343         u64 handler;
344         u8 flags;
345
346         print_parse_debug("funct handler:");
347         if (get_u64(mb, &handler)) {
348                 print_err("failed to read function handler\n");
349                 return -EINVAL;
350         }
351
352         print_parse_debug("collect events flag:");
353         if (get_u8(mb, &flags)) {
354                 print_err("failed to read collect events type\n");
355                 return -EINVAL;
356         }
357
358         pi->probe_type = SWAP_PRELOAD_PROBE;
359         pi->size = 0;
360         pi->pl_i.handler = handler;
361         pi->pl_i.flags = flags;
362
363         return 0;
364 }
365
366 /**
367  * @brief Preload probe data cleanup.
368  *
369  * @param pi Pointer to the probe_info comprising retprobe.
370  * @return Void.
371  */
372 void put_preload_probe(struct probe_info *pi)
373 {
374 }
375
376 /**
377  * @brief Gets preload get_caller and puts it to the probe_info struct.
378  *
379  * @param mb Pointer to the message buffer.
380  * @param pi Pointer to the probe_info struct.
381  * @return 0 on success, error code on error.
382  */
383
384 int get_get_caller_probe(struct msg_buf *mb, struct probe_info *pi)
385 {
386         pi->probe_type = SWAP_GET_CALLER;
387         pi->size = 0;
388
389         return 0;
390 }
391
392 /**
393  * @brief Preload get_caller probe data cleanup.
394  *
395  * @param pi Pointer to the probe_info comprising retprobe.
396  * @return Void.
397  */
398 void put_get_caller_probe(struct probe_info *pi)
399 {
400 }
401
402 /**
403  * @brief Gets preload get_call_type and puts it to the probe_info struct.
404  *
405  * @param mb Pointer to the message buffer.
406  * @param pi Pointer to the probe_info struct.
407  * @return 0 on success, error code on error.
408  */
409 int get_get_call_type_probe(struct msg_buf *mb, struct probe_info *pi)
410 {
411         pi->probe_type = SWAP_GET_CALL_TYPE;
412         pi->size = 0;
413
414         return 0;
415 }
416
417 /**
418  * @brief Preload get_call type probe data cleanup.
419  *
420  * @param pi Pointer to the probe_info comprising retprobe.
421  * @return Void.
422  */
423 void put_get_call_type_probe(struct probe_info *pi)
424 {
425 }
426
427 /**
428  * @brief Gets preload write_msg and puts it to the probe_info struct.
429  *
430  * @param mb Pointer to the message buffer.
431  * @param pi Pointer to the probe_info struct.
432  * @return 0 on success, error code on error.
433  */
434 int get_write_msg_probe(struct msg_buf *mb, struct probe_info *pi)
435 {
436         pi->probe_type = SWAP_WRITE_MSG;
437         pi->size = 0;
438
439         return 0;
440 }
441
442 /**
443  * @brief Preload write_msg type probe data cleanup.
444  *
445  * @param pi Pointer to the probe_info comprising retprobe.
446  * @return Void.
447  */
448 void put_write_msg_probe(struct probe_info *pi)
449 {
450 }
451
452
453
454
455 /**
456  * @brief Gets FBI probe data and puts it to the probe_info struct.
457  *
458  * @param mb Pointer to the message buffer.
459  * @param pi Pointer to the probe_info struct.
460  * @return 0 on success, error code on error.
461  */
462 int get_fbi_data(struct msg_buf *mb, struct fbi_var_data *vd)
463 {
464         u64 var_id;
465         u64 reg_offset;
466         u8 reg_n;
467         u32 data_size;
468         u8 steps_count, i;
469         struct fbi_step *steps = NULL;
470
471         print_parse_debug("var ID:");
472         if (get_u64(mb, &var_id)) {
473                 print_err("failed to read var ID\n");
474                 return -EINVAL;
475         }
476
477         print_parse_debug("register offset:");
478         if (get_u64(mb, &reg_offset)) {
479                 print_err("failed to read register offset\n");
480                 return -EINVAL;
481         }
482
483         print_parse_debug("register number:");
484         if (get_u8(mb, &reg_n)) {
485                 print_err("failed to read number of the register\n");
486                 return -EINVAL;
487         }
488
489         print_parse_debug("data size:");
490         if (get_u32(mb, &data_size)) {
491                 print_err("failed to read data size\n");
492                 return -EINVAL;
493         }
494
495         print_parse_debug("steps count:");
496         if (get_u8(mb, &steps_count)) {
497                 print_err("failed to read steps count\n");
498                 return -EINVAL;
499         }
500
501         if (steps_count > 0) {
502                 steps = kmalloc(steps_count * sizeof(*vd->steps),
503                                 GFP_KERNEL);
504                 if (steps == NULL) {
505                         print_err("MALLOC FAIL\n");
506                         return -ENOMEM;
507                 }
508
509                 for (i = 0; i != steps_count; i++) {
510                         print_parse_debug("steps #%d ptr_order:", i);
511                         if (get_u8(mb, &(steps[i].ptr_order))) {
512                                 print_err("failed to read pointer order(step #%d)\n",
513                                           i);
514                                 goto free_steps;
515                         }
516                         print_parse_debug("steps #%d data_offset:", i);
517                         if (get_u64(mb, &(steps[i].data_offset))){
518                                 print_err("failed to read offset (steps #%d)\n",
519                                           i);
520                                 goto free_steps;
521                         }
522                 }
523         }
524
525         vd->reg_n = reg_n;
526         vd->reg_offset = reg_offset;
527         vd->data_size = data_size;
528         vd->var_id = var_id;
529         vd->steps_count = steps_count;
530         vd->steps = steps;
531
532         return 0;
533
534 free_steps:
535         kfree(steps);
536         return -EINVAL;
537 }
538
539 int get_fbi_probe(struct msg_buf *mb, struct probe_info *pi)
540 {
541         uint8_t var_count, i;
542         struct fbi_var_data *vars;
543
544         print_parse_debug("var count:");
545         if (get_u8(mb, &var_count)) {
546                 print_err("failed to read var ID\n");
547                 return -EINVAL;
548         }
549
550         vars = kmalloc(var_count * sizeof(*vars), GFP_KERNEL);
551         if (vars == NULL) {
552                 print_err("alloc vars error\n");
553                 goto err;
554         }
555
556         for (i = 0; i != var_count; i++) {
557                 if (get_fbi_data(mb, &vars[i]) != 0)
558                         goto free_vars;
559         }
560
561         pi->probe_type = SWAP_FBIPROBE;
562         pi->fbi_i.var_count = var_count;
563         pi->fbi_i.vars = vars;
564         pi->size =0 ;
565         return 0;
566
567 free_vars:
568         kfree(vars);
569
570 err:
571         return -EINVAL;
572
573 }
574
575 /**
576  * @brief FBI probe data cleanup.
577  *
578  * @param pi Pointer to the probe_info comprising FBI probe.
579  * @return Void.
580  */
581 void put_fbi_probe(struct probe_info *pi)
582 {
583         return;
584 }
585
586
587 /* ============================================================================
588  * ==                               FUNC_INST                                ==
589  * ============================================================================
590  */
591
592 /**
593  * @brief Creates and fills func_inst_data struct.
594  *
595  * @param mb Pointer to the message buffer.
596  * @return Pointer to the filled func_inst_data struct on success;\n
597  * 0 on error.
598  */
599 struct func_inst_data *create_func_inst_data(struct msg_buf *mb)
600 {
601         struct func_inst_data *fi;
602         u64 addr;
603         u8 type;
604
605         print_parse_debug("func addr:");
606         if (get_u64(mb, &addr)) {
607                 print_err("failed to read data function address\n");
608                 return NULL;
609         }
610
611         print_parse_debug("probe type:");
612         if (get_u8(mb, &type)) {
613                 print_err("failed to read data probe type\n");
614                 return NULL;
615         }
616
617         fi = kmalloc(sizeof(*fi), GFP_KERNEL);
618         if (fi == NULL) {
619                 print_err("out of memory\n");
620                 return NULL;
621         }
622
623         fi->addr = addr;
624
625         switch (type) {
626         case SWAP_RETPROBE:
627                 if (get_retprobe(mb, &(fi->probe_i)) != 0)
628                         goto free_func_inst;
629                 break;
630         case SWAP_WEBPROBE:
631                 if (get_webprobe(mb, &(fi->probe_i)) != 0)
632                         goto free_func_inst;
633                 break;
634         case SWAP_PRELOAD_PROBE:
635                 if (get_preload_probe(mb, &(fi->probe_i)) != 0)
636                         goto free_func_inst;
637                 break;
638         case SWAP_GET_CALLER:
639                 if (get_get_caller_probe(mb, &(fi->probe_i)) != 0)
640                         goto free_func_inst;
641                 break;
642         case SWAP_GET_CALL_TYPE:
643                 if (get_get_call_type_probe(mb, &(fi->probe_i)) != 0)
644                         goto free_func_inst;
645                 break;
646         case SWAP_FBIPROBE:
647                 if (get_fbi_probe(mb, &(fi->probe_i)) != 0)
648                         goto free_func_inst;
649                 break;
650         case SWAP_WRITE_MSG:
651                 if (get_write_msg_probe(mb, &(fi->probe_i)) != 0)
652                         goto free_func_inst;
653                 break;
654         default:
655                 printk(KERN_WARNING "SWAP PARSER: Wrong probe type %d!\n",
656                        type);
657                 goto free_func_inst;
658         }
659
660         return fi;
661
662 free_func_inst:
663
664         kfree(fi);
665         return NULL;
666 }
667
668 /**
669  * @brief func_inst_data cleanup.
670  *
671  * @param fi Pointer to the target func_inst_data.
672  * @return Void.
673  */
674 void destroy_func_inst_data(struct func_inst_data *fi)
675 {
676         switch (fi->probe_i.probe_type) {
677         case SWAP_RETPROBE:
678                 put_retprobe(&(fi->probe_i));
679                 break;
680         case SWAP_WEBPROBE:
681                 break;
682         case SWAP_PRELOAD_PROBE:
683                 put_preload_probe(&(fi->probe_i));
684                 break;
685         case SWAP_GET_CALLER:
686                 put_get_caller_probe(&(fi->probe_i));
687                 break;
688         case SWAP_GET_CALL_TYPE:
689                 put_get_call_type_probe(&(fi->probe_i));
690                 break;
691         case SWAP_FBIPROBE:
692                 put_fbi_probe(&(fi->probe_i));
693                 break;
694         case SWAP_WRITE_MSG:
695                 put_write_msg_probe(&(fi->probe_i));
696                 break;
697         default:
698                 printk(KERN_WARNING "SWAP PARSER: Wrong probe type %d!\n",
699                    fi->probe_i.probe_type);
700         }
701
702         kfree(fi);
703 }
704
705
706
707
708
709 /* ============================================================================
710  * ==                               LIB_INST                                 ==
711  * ============================================================================
712  */
713
714 /**
715  * @brief Creates and fills lib_inst_data struct.
716  *
717  * @param mb Pointer to the message buffer.
718  * @return Pointer to the filled lib_inst_data struct on success;\n
719  * 0 on error.
720  */
721 struct lib_inst_data *create_lib_inst_data(struct msg_buf *mb)
722 {
723         struct lib_inst_data *li;
724         struct func_inst_data *fi;
725         char *path;
726         u32 cnt, j, i = 0;
727
728         print_parse_debug("bin path:");
729         if (get_string(mb, &path)) {
730                 print_err("failed to read path of binary\n");
731                 return NULL;
732         }
733
734         print_parse_debug("func count:");
735         if (get_u32(mb, &cnt)) {
736                 print_err("failed to read count of functions\n");
737                 goto free_path;
738         }
739
740         if (remained_mb(mb) / MIN_SIZE_FUNC_INST < cnt) {
741                 print_err("to match count of functions(%u)\n", cnt);
742                 goto free_path;
743         }
744
745         li = kmalloc(sizeof(*li), GFP_KERNEL);
746         if (li == NULL) {
747                 print_err("out of memory\n");
748                 goto free_path;
749         }
750
751         if (cnt) {
752                 li->func = vmalloc(sizeof(*li->func) * cnt);
753                 if (li->func == NULL) {
754                         print_err("out of memory\n");
755                         goto free_li;
756                 }
757
758                 for (i = 0; i < cnt; ++i) {
759                         print_parse_debug("func #%d:\n", i + 1);
760                         fi = create_func_inst_data(mb);
761                         if (fi == NULL)
762                                 goto free_func;
763
764                         li->func[i] = fi;
765                 }
766         } else {
767                 li->func = NULL;
768         }
769
770         li->path = path;
771         li->cnt_func = cnt;
772
773         return li;
774
775 free_func:
776         for (j = 0; j < i; ++j)
777                 destroy_func_inst_data(li->func[j]);
778         vfree(li->func);
779
780 free_li:
781         kfree(li);
782
783 free_path:
784         put_string(path);
785
786         return NULL;
787 }
788
789 /**
790  * @brief lib_inst_data cleanup.
791  *
792  * @param li Pointer to the target lib_inst_data.
793  * @return Void.
794  */
795 void destroy_lib_inst_data(struct lib_inst_data *li)
796 {
797         int i;
798
799         put_string(li->path);
800
801         for (i = 0; i < li->cnt_func; ++i)
802                 destroy_func_inst_data(li->func[i]);
803
804         vfree(li->func);
805         kfree(li);
806 }
807
808
809
810
811
812 /* ============================================================================
813  * ==                               APP_INST                                 ==
814  * ============================================================================
815  */
816
817 /**
818  * @brief Creates and fills app_inst_data struct.
819  *
820  * @param mb Pointer to the message buffer.
821  * @return Pointer to the filled app_inst_data struct on success;\n
822  * 0 on error.
823  */
824 struct app_inst_data *create_app_inst_data(struct msg_buf *mb)
825 {
826         struct app_inst_data *app_inst;
827         struct app_info_data *app_info;
828         struct func_inst_data *func;
829         struct lib_inst_data *lib;
830         u32 cnt_func, i_func = 0, cnt_lib, i_lib = 0, i;
831
832         app_info = create_app_info(mb);
833         if (app_info == NULL)
834                 return NULL;
835
836         print_parse_debug("func count:");
837         if (get_u32(mb, &cnt_func)) {
838                 print_err("failed to read count of functions\n");
839                 goto free_app_info;
840         }
841
842         if (remained_mb(mb) / MIN_SIZE_FUNC_INST < cnt_func) {
843                 print_err("to match count of functions(%u)\n", cnt_func);
844                 goto free_app_info;
845         }
846
847         app_inst = kmalloc(sizeof(*app_inst), GFP_KERNEL);
848         if (app_inst == NULL) {
849                 print_err("out of memory\n");
850                 goto free_app_info;
851         }
852
853         if (cnt_func) {
854                 app_inst->func = vmalloc(sizeof(*app_inst->func) * cnt_func);
855                 if (app_inst->func == NULL) {
856                         print_err("out of memory\n");
857                         goto free_app_inst;
858                 }
859
860                 for (i_func = 0; i_func < cnt_func; ++i_func) {
861                         print_parse_debug("func #%d:\n", i_func + 1);
862                         func = create_func_inst_data(mb);
863                         if (func == NULL)
864                                 goto free_func;
865
866                         app_inst->func[i_func] = func;
867                 }
868         } else {
869                 app_inst->func = NULL;
870         }
871
872         print_parse_debug("lib count:");
873         if (get_u32(mb, &cnt_lib)) {
874                 print_err("failed to read count of libraries\n");
875                 goto free_func;
876         }
877
878         if (remained_mb(mb) / MIN_SIZE_LIB_INST < cnt_lib) {
879                 print_err("to match count of libraries(%u)\n", cnt_lib);
880                 goto free_func;
881         }
882
883         if (cnt_lib) {
884                 app_inst->lib = vmalloc(sizeof(*app_inst->lib) * cnt_lib);
885                 if (app_inst->lib == NULL) {
886                         print_err("out of memory\n");
887                         goto free_func;
888                 }
889
890                 for (i_lib = 0; i_lib < cnt_lib; ++i_lib) {
891                         print_parse_debug("lib #%d:\n", i_lib + 1);
892                         lib = create_lib_inst_data(mb);
893                         if (lib == NULL)
894                                 goto free_lib;
895
896                         app_inst->lib[i_lib] = lib;
897                 }
898         } else {
899                 app_inst->lib = NULL;
900         }
901
902         app_inst->app_info = app_info;
903         app_inst->cnt_func = cnt_func;
904         app_inst->cnt_lib = cnt_lib;
905
906         return app_inst;
907
908 free_lib:
909         for (i = 0; i < i_lib; ++i)
910                 destroy_lib_inst_data(app_inst->lib[i]);
911         vfree(app_inst->lib);
912
913 free_func:
914         for (i = 0; i < i_func; ++i)
915                 destroy_func_inst_data(app_inst->func[i]);
916         vfree(app_inst->func);
917
918 free_app_inst:
919         kfree(app_inst);
920
921 free_app_info:
922         destroy_app_info(app_info);
923
924         return NULL;
925 }
926
927 /**
928  * @brief app_inst_data cleanup.
929  *
930  * @param ai Pointer to the target app_inst_data.
931  * @return Void.
932  */
933 void destroy_app_inst_data(struct app_inst_data *ai)
934 {
935         int i;
936
937         for (i = 0; i < ai->cnt_lib; ++i)
938                 destroy_lib_inst_data(ai->lib[i]);
939         vfree(ai->lib);
940
941         for (i = 0; i < ai->cnt_func; ++i)
942                 destroy_func_inst_data(ai->func[i]);
943         vfree(ai->func);
944
945         destroy_app_info(ai->app_info);
946         kfree(ai);
947 }
948
949
950
951
952
953 /* ============================================================================
954  * ==                                US_INST                                 ==
955  * ============================================================================
956  */
957
958 /**
959  * @brief Creates and fills us_inst_data struct.
960  *
961  * @param mb Pointer to the message buffer.
962  * @return Pointer to the filled us_inst_data struct on success;\n
963  * 0 on error.
964  */
965 struct us_inst_data *create_us_inst_data(struct msg_buf *mb)
966 {
967         struct us_inst_data *ui;
968         struct app_inst_data *ai;
969         u32 cnt, j, i = 0;
970
971         print_parse_debug("us_inst_data:\n");
972
973         print_parse_debug("app count:");
974         if (get_u32(mb, &cnt)) {
975                 print_err("failed to read count of applications\n");
976                 return NULL;
977         }
978
979         if (remained_mb(mb) / MIN_SIZE_APP_INST < cnt) {
980                 print_err("to match count of applications(%u)\n", cnt);
981                 return NULL;
982         }
983
984         ui = kmalloc(sizeof(struct us_inst_data), GFP_KERNEL);
985         if (ui == NULL) {
986                 print_err("out of memory\n");
987                 return NULL;
988         }
989
990         ui->app_inst = kmalloc(sizeof(struct app_inst_data *) * cnt,
991                                GFP_KERNEL);
992         if (ui->app_inst == NULL) {
993                 print_err("out of memory\n");
994                 goto free_ui;
995         }
996
997         for (i = 0; i < cnt; ++i) {
998                 print_parse_debug("app #%d:\n", i + 1);
999                 ai = create_app_inst_data(mb);
1000                 if (ai == NULL)
1001                         goto free_app_inst;
1002
1003                 ui->app_inst[i] = ai;
1004         }
1005
1006         ui->cnt = cnt;
1007
1008         return ui;
1009
1010 free_app_inst:
1011         for (j = 0; j < i; ++j)
1012                 destroy_app_inst_data(ui->app_inst[j]);
1013         kfree(ui->app_inst);
1014
1015 free_ui:
1016         kfree(ui);
1017
1018         return NULL;
1019 }
1020
1021 /**
1022  * @brief us_inst_data cleanup.
1023  *
1024  * @param ui Pointer to the target us_inst_data.
1025  * @return Void.
1026  */
1027 void destroy_us_inst_data(struct us_inst_data *ui)
1028 {
1029         int i;
1030
1031         for (i = 0; i < ui->cnt; ++i)
1032                 destroy_app_inst_data(ui->app_inst[i]);
1033
1034         kfree(ui->app_inst);
1035         kfree(ui);
1036 }