4 * @author Vyacheslav Cherkashin
5 * @author Vitaliy Cherepanov <v.cherepanov@samsung.com>
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.
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.
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.
25 * Copyright (C) Samsung Electronics, 2013
27 * @section DESCRIPTION
29 * Message parsing implementation.
33 #include <linux/slab.h>
34 #include <linux/vmalloc.h>
35 #include <us_manager/probes/probes.h>
36 #include "msg_parser.h"
38 #include "parser_defs.h"
41 static int str_to_u32(const char *str, u32 *val)
47 for (result = 0 ; *str; ++str) {
48 if (*str < '0' || *str > '9')
51 result = result * 10 + (*str - '0');
63 /* ============================================================================
65 * ============================================================================
69 * @brief Creates and fills app_info_data struct.
71 * @param mb Pointer to the message buffer.
72 * @return Pointer to the filled app_info_data struct on success;\n
75 struct app_info_data *create_app_info(struct msg_buf *mb)
78 struct app_info_data *ai;
80 char *ta_id, *exec_path;
82 print_parse_debug("app_info:\n");
84 print_parse_debug("type:");
85 ret = get_u32(mb, &app_type);
87 print_err("failed to read target application type\n");
91 print_parse_debug("id:");
92 ret = get_string(mb, &ta_id);
94 print_err("failed to read target application ID\n");
98 print_parse_debug("exec path:");
99 ret = get_string(mb, &exec_path);
101 print_err("failed to read executable path\n");
105 ai = kmalloc(sizeof(*ai), GFP_KERNEL);
107 print_err("out of memory\n");
112 case AT_TIZEN_NATIVE_APP:
113 case AT_TIZEN_WEB_APP:
120 if (*ta_id != '\0') {
121 ret = str_to_u32(ta_id, &tgid);
123 print_err("converting string to PID, "
124 "str='%s'\n", ta_id);
133 print_err("wrong application type(%u)\n", app_type);
138 ai->app_type = (enum APP_TYPE)app_type;
140 ai->exec_path = exec_path;
148 put_string(exec_path);
157 * @brief app_info_data cleanup.
159 * @param ai Pointer to the target app_info_data.
162 void destroy_app_info(struct app_info_data *ai)
164 put_string(ai->exec_path);
165 put_string(ai->app_id);
173 /* ============================================================================
175 * ============================================================================
179 * @brief Creates and fills conf_data struct.
181 * @param mb Pointer to the message buffer.
182 * @return Pointer to the filled conf_data struct on success;\n
185 struct conf_data *create_conf_data(struct msg_buf *mb)
187 struct conf_data *conf;
188 u64 use_features0, use_features1;
191 print_parse_debug("conf_data:\n");
193 print_parse_debug("features:");
194 if (get_u64(mb, &use_features0)) {
195 print_err("failed to read use_features\n");
199 if (get_u64(mb, &use_features1)) {
200 print_err("failed to read use_features\n");
204 print_parse_debug("sys trace period:");
205 if (get_u32(mb, &stp)) {
206 print_err("failed to read sys trace period\n");
210 print_parse_debug("data msg period:");
211 if (get_u32(mb, &dmp)) {
212 print_err("failed to read data message period\n");
216 conf = kmalloc(sizeof(*conf), GFP_KERNEL);
218 print_err("out of memory\n");
222 conf->use_features0 = use_features0;
223 conf->use_features1 = use_features1;
224 conf->sys_trace_period = stp;
225 conf->data_msg_period = dmp;
231 * @brief conf_data cleanup.
233 * @param conf Pointer to the target conf_data.
236 void destroy_conf_data(struct conf_data *conf)
241 static struct conf_data config;
244 * @brief Saves config to static config variable.
246 * @param conf Variable to save.
249 void save_config(const struct conf_data *conf)
251 memcpy(&config, conf, sizeof(config));
255 * @brief Restores config from static config variable.
257 * @param conf Variable to restore.
260 void restore_config(struct conf_data *conf)
262 memcpy(conf, &config, sizeof(*conf));
267 /* ============================================================================
268 * == PROBES PARSING ==
269 * ============================================================================
273 * @brief Gets retprobe data and puts it to the probe_info struct.
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.
279 int get_retprobe(struct msg_buf *mb, struct probe_info *pi)
284 print_parse_debug("funct args:");
285 if (get_string(mb, &args)) {
286 print_err("failed to read data function arguments\n");
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");
296 pi->probe_type = SWAP_RETPROBE;
298 pi->rp_i.args = args;
299 pi->rp_i.ret_type = ret_type;
309 * @brief Gets webprobe data and puts it to the probe_info struct.
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.
315 int get_webprobe(struct msg_buf *mb, struct probe_info *pi)
317 pi->probe_type = SWAP_WEBPROBE;
324 * @brief Retprobe data cleanup.
326 * @param pi Pointer to the probe_info comprising retprobe.
329 void put_retprobe(struct probe_info *pi)
331 put_string(pi->rp_i.args);
335 * @brief Gets preload data and puts it to the probe_info struct.
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.
341 int get_preload_probe(struct msg_buf *mb, struct probe_info *pi)
346 print_parse_debug("funct handler:");
347 if (get_u64(mb, &handler)) {
348 print_err("failed to read function handler\n");
352 print_parse_debug("collect events flag:");
353 if (get_u8(mb, &flags)) {
354 print_err("failed to read collect events type\n");
358 pi->probe_type = SWAP_PRELOAD_PROBE;
360 pi->pl_i.handler = handler;
361 pi->pl_i.flags = flags;
367 * @brief Preload probe data cleanup.
369 * @param pi Pointer to the probe_info comprising retprobe.
372 void put_preload_probe(struct probe_info *pi)
377 * @brief Gets preload get_caller and puts it to the probe_info struct.
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.
384 int get_get_caller_probe(struct msg_buf *mb, struct probe_info *pi)
386 pi->probe_type = SWAP_GET_CALLER;
393 * @brief Preload get_caller probe data cleanup.
395 * @param pi Pointer to the probe_info comprising retprobe.
398 void put_get_caller_probe(struct probe_info *pi)
403 * @brief Gets preload get_call_type and puts it to the probe_info struct.
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.
409 int get_get_call_type_probe(struct msg_buf *mb, struct probe_info *pi)
411 pi->probe_type = SWAP_GET_CALL_TYPE;
418 * @brief Preload get_call type probe data cleanup.
420 * @param pi Pointer to the probe_info comprising retprobe.
423 void put_get_call_type_probe(struct probe_info *pi)
428 * @brief Gets preload write_msg and puts it to the probe_info struct.
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.
434 int get_write_msg_probe(struct msg_buf *mb, struct probe_info *pi)
436 pi->probe_type = SWAP_WRITE_MSG;
443 * @brief Preload write_msg type probe data cleanup.
445 * @param pi Pointer to the probe_info comprising retprobe.
448 void put_write_msg_probe(struct probe_info *pi)
456 * @brief Gets FBI probe data and puts it to the probe_info struct.
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.
462 int get_fbi_data(struct msg_buf *mb, struct fbi_var_data *vd)
469 struct fbi_step *steps = NULL;
471 print_parse_debug("var ID:");
472 if (get_u64(mb, &var_id)) {
473 print_err("failed to read var ID\n");
477 print_parse_debug("register offset:");
478 if (get_u64(mb, ®_offset)) {
479 print_err("failed to read register offset\n");
483 print_parse_debug("register number:");
484 if (get_u8(mb, ®_n)) {
485 print_err("failed to read number of the register\n");
489 print_parse_debug("data size:");
490 if (get_u32(mb, &data_size)) {
491 print_err("failed to read data size\n");
495 print_parse_debug("steps count:");
496 if (get_u8(mb, &steps_count)) {
497 print_err("failed to read steps count\n");
501 if (steps_count > 0) {
502 steps = kmalloc(steps_count * sizeof(*vd->steps),
505 print_err("MALLOC FAIL\n");
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",
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",
526 vd->reg_offset = reg_offset;
527 vd->data_size = data_size;
529 vd->steps_count = steps_count;
539 int get_fbi_probe(struct msg_buf *mb, struct probe_info *pi)
541 uint8_t var_count, i;
542 struct fbi_var_data *vars;
544 print_parse_debug("var count:");
545 if (get_u8(mb, &var_count)) {
546 print_err("failed to read var ID\n");
550 vars = kmalloc(var_count * sizeof(*vars), GFP_KERNEL);
552 print_err("alloc vars error\n");
556 for (i = 0; i != var_count; i++) {
557 if (get_fbi_data(mb, &vars[i]) != 0)
561 pi->probe_type = SWAP_FBIPROBE;
562 pi->fbi_i.var_count = var_count;
563 pi->fbi_i.vars = vars;
576 * @brief FBI probe data cleanup.
578 * @param pi Pointer to the probe_info comprising FBI probe.
581 void put_fbi_probe(struct probe_info *pi)
587 /* ============================================================================
589 * ============================================================================
593 * @brief Creates and fills func_inst_data struct.
595 * @param mb Pointer to the message buffer.
596 * @return Pointer to the filled func_inst_data struct on success;\n
599 struct func_inst_data *create_func_inst_data(struct msg_buf *mb)
601 struct func_inst_data *fi;
605 print_parse_debug("func addr:");
606 if (get_u64(mb, &addr)) {
607 print_err("failed to read data function address\n");
611 print_parse_debug("probe type:");
612 if (get_u8(mb, &type)) {
613 print_err("failed to read data probe type\n");
617 fi = kmalloc(sizeof(*fi), GFP_KERNEL);
619 print_err("out of memory\n");
627 if (get_retprobe(mb, &(fi->probe_i)) != 0)
631 if (get_webprobe(mb, &(fi->probe_i)) != 0)
634 case SWAP_PRELOAD_PROBE:
635 if (get_preload_probe(mb, &(fi->probe_i)) != 0)
638 case SWAP_GET_CALLER:
639 if (get_get_caller_probe(mb, &(fi->probe_i)) != 0)
642 case SWAP_GET_CALL_TYPE:
643 if (get_get_call_type_probe(mb, &(fi->probe_i)) != 0)
647 if (get_fbi_probe(mb, &(fi->probe_i)) != 0)
651 if (get_write_msg_probe(mb, &(fi->probe_i)) != 0)
655 printk(KERN_WARNING "SWAP PARSER: Wrong probe type %d!\n",
669 * @brief func_inst_data cleanup.
671 * @param fi Pointer to the target func_inst_data.
674 void destroy_func_inst_data(struct func_inst_data *fi)
676 switch (fi->probe_i.probe_type) {
678 put_retprobe(&(fi->probe_i));
682 case SWAP_PRELOAD_PROBE:
683 put_preload_probe(&(fi->probe_i));
685 case SWAP_GET_CALLER:
686 put_get_caller_probe(&(fi->probe_i));
688 case SWAP_GET_CALL_TYPE:
689 put_get_call_type_probe(&(fi->probe_i));
692 put_fbi_probe(&(fi->probe_i));
695 put_write_msg_probe(&(fi->probe_i));
698 printk(KERN_WARNING "SWAP PARSER: Wrong probe type %d!\n",
699 fi->probe_i.probe_type);
709 /* ============================================================================
711 * ============================================================================
715 * @brief Creates and fills lib_inst_data struct.
717 * @param mb Pointer to the message buffer.
718 * @return Pointer to the filled lib_inst_data struct on success;\n
721 struct lib_inst_data *create_lib_inst_data(struct msg_buf *mb)
723 struct lib_inst_data *li;
724 struct func_inst_data *fi;
728 print_parse_debug("bin path:");
729 if (get_string(mb, &path)) {
730 print_err("failed to read path of binary\n");
734 print_parse_debug("func count:");
735 if (get_u32(mb, &cnt)) {
736 print_err("failed to read count of functions\n");
740 if (remained_mb(mb) / MIN_SIZE_FUNC_INST < cnt) {
741 print_err("to match count of functions(%u)\n", cnt);
745 li = kmalloc(sizeof(*li), GFP_KERNEL);
747 print_err("out of memory\n");
752 li->func = vmalloc(sizeof(*li->func) * cnt);
753 if (li->func == NULL) {
754 print_err("out of memory\n");
758 for (i = 0; i < cnt; ++i) {
759 print_parse_debug("func #%d:\n", i + 1);
760 fi = create_func_inst_data(mb);
776 for (j = 0; j < i; ++j)
777 destroy_func_inst_data(li->func[j]);
790 * @brief lib_inst_data cleanup.
792 * @param li Pointer to the target lib_inst_data.
795 void destroy_lib_inst_data(struct lib_inst_data *li)
799 put_string(li->path);
801 for (i = 0; i < li->cnt_func; ++i)
802 destroy_func_inst_data(li->func[i]);
812 /* ============================================================================
814 * ============================================================================
818 * @brief Creates and fills app_inst_data struct.
820 * @param mb Pointer to the message buffer.
821 * @return Pointer to the filled app_inst_data struct on success;\n
824 struct app_inst_data *create_app_inst_data(struct msg_buf *mb)
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;
832 app_info = create_app_info(mb);
833 if (app_info == NULL)
836 print_parse_debug("func count:");
837 if (get_u32(mb, &cnt_func)) {
838 print_err("failed to read count of functions\n");
842 if (remained_mb(mb) / MIN_SIZE_FUNC_INST < cnt_func) {
843 print_err("to match count of functions(%u)\n", cnt_func);
847 app_inst = kmalloc(sizeof(*app_inst), GFP_KERNEL);
848 if (app_inst == NULL) {
849 print_err("out of memory\n");
854 app_inst->func = vmalloc(sizeof(*app_inst->func) * cnt_func);
855 if (app_inst->func == NULL) {
856 print_err("out of memory\n");
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);
866 app_inst->func[i_func] = func;
869 app_inst->func = NULL;
872 print_parse_debug("lib count:");
873 if (get_u32(mb, &cnt_lib)) {
874 print_err("failed to read count of libraries\n");
878 if (remained_mb(mb) / MIN_SIZE_LIB_INST < cnt_lib) {
879 print_err("to match count of libraries(%u)\n", 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");
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);
896 app_inst->lib[i_lib] = lib;
899 app_inst->lib = NULL;
902 app_inst->app_info = app_info;
903 app_inst->cnt_func = cnt_func;
904 app_inst->cnt_lib = cnt_lib;
909 for (i = 0; i < i_lib; ++i)
910 destroy_lib_inst_data(app_inst->lib[i]);
911 vfree(app_inst->lib);
914 for (i = 0; i < i_func; ++i)
915 destroy_func_inst_data(app_inst->func[i]);
916 vfree(app_inst->func);
922 destroy_app_info(app_info);
928 * @brief app_inst_data cleanup.
930 * @param ai Pointer to the target app_inst_data.
933 void destroy_app_inst_data(struct app_inst_data *ai)
937 for (i = 0; i < ai->cnt_lib; ++i)
938 destroy_lib_inst_data(ai->lib[i]);
941 for (i = 0; i < ai->cnt_func; ++i)
942 destroy_func_inst_data(ai->func[i]);
945 destroy_app_info(ai->app_info);
953 /* ============================================================================
955 * ============================================================================
959 * @brief Creates and fills us_inst_data struct.
961 * @param mb Pointer to the message buffer.
962 * @return Pointer to the filled us_inst_data struct on success;\n
965 struct us_inst_data *create_us_inst_data(struct msg_buf *mb)
967 struct us_inst_data *ui;
968 struct app_inst_data *ai;
971 print_parse_debug("us_inst_data:\n");
973 print_parse_debug("app count:");
974 if (get_u32(mb, &cnt)) {
975 print_err("failed to read count of applications\n");
979 if (remained_mb(mb) / MIN_SIZE_APP_INST < cnt) {
980 print_err("to match count of applications(%u)\n", cnt);
984 ui = kmalloc(sizeof(struct us_inst_data), GFP_KERNEL);
986 print_err("out of memory\n");
990 ui->app_inst = kmalloc(sizeof(struct app_inst_data *) * cnt,
992 if (ui->app_inst == NULL) {
993 print_err("out of memory\n");
997 for (i = 0; i < cnt; ++i) {
998 print_parse_debug("app #%d:\n", i + 1);
999 ai = create_app_inst_data(mb);
1003 ui->app_inst[i] = ai;
1011 for (j = 0; j < i; ++j)
1012 destroy_app_inst_data(ui->app_inst[j]);
1013 kfree(ui->app_inst);
1022 * @brief us_inst_data cleanup.
1024 * @param ui Pointer to the target us_inst_data.
1027 void destroy_us_inst_data(struct us_inst_data *ui)
1031 for (i = 0; i < ui->cnt; ++i)
1032 destroy_app_inst_data(ui->app_inst[i]);
1034 kfree(ui->app_inst);