From 942248a7868dcb4606b6d139602f8bd1f9f42811 Mon Sep 17 00:00:00 2001 From: Anatolii Nikulin Date: Thu, 20 Aug 2015 15:05:49 +0300 Subject: [PATCH] [REFACTOR] add support for manipulating probes depend on probe info Change-Id: I966f8703051d3f8853fd05e3a68a5049b1a2fe07 Signed-off-by: Anatolii Nikulin --- parser/msg_cmd.c | 66 ++++- parser/msg_parser.c | 552 +++++++++++++++++++++++-------------- parser/msg_parser.h | 45 +-- parser/us_inst.c | 66 +++-- parser/us_inst.h | 4 +- us_manager/img/img_file.c | 13 +- us_manager/img/img_file.h | 3 +- us_manager/img/img_ip.c | 9 +- us_manager/img/img_ip.h | 2 +- us_manager/img/img_proc.c | 5 +- us_manager/img/img_proc.h | 5 +- us_manager/pf/pf_group.c | 4 +- us_manager/pf/pf_group.h | 2 +- us_manager/probes/probe_info_new.c | 2 +- us_manager/probes/probes.h | 1 - us_manager/sspt/ip.c | 2 +- webprobe/webprobe.c | 6 +- webprobe/webprobe_prof.c | 86 +++++- webprobe/webprobe_prof.h | 2 +- 19 files changed, 558 insertions(+), 317 deletions(-) diff --git a/parser/msg_cmd.c b/parser/msg_cmd.c index 352e757..b0ff1c5 100644 --- a/parser/msg_cmd.c +++ b/parser/msg_cmd.c @@ -40,6 +40,7 @@ #include +static LIST_HEAD(app_inst_head); static int wrt_launcher_port; static int set_config(struct conf_data *conf) @@ -76,14 +77,14 @@ int msg_keep_alive(struct msg_buf *mb) int msg_start(struct msg_buf *mb) { int ret = 0; - struct us_inst_data *us_inst; + u32 cnt; struct conf_data conf; swap_msg_seq_num_reset(); swap_msg_discard_reset(); - us_inst = create_us_inst_data(mb); - if (us_inst == NULL) + cnt = create_us_inst_data(mb, &app_inst_head); + if (!cnt) return -EINVAL; if (!is_end_mb(mb)) { @@ -92,7 +93,7 @@ int msg_start(struct msg_buf *mb) goto free_us_inst; } - ret = mod_us_inst(us_inst, MT_ADD); + ret = mod_us_inst(&app_inst_head, MT_ADD); if (ret) { printk(KERN_INFO "Cannot mod us inst, ret = %d\n", ret); ret = -EINVAL; @@ -106,8 +107,10 @@ int msg_start(struct msg_buf *mb) restore_config(&conf); set_config(&conf); + return ret; + free_us_inst: - destroy_us_inst_data(us_inst); + destroy_us_inst_data(&app_inst_head); return ret; } @@ -145,6 +148,8 @@ int msg_stop(struct msg_buf *mb) printk(KERN_INFO "discarded messages: %d\n", discarded); swap_msg_discard_reset(); + destroy_us_inst_data(&app_inst_head); + return ret; } @@ -192,10 +197,13 @@ free_conf_data: int msg_swap_inst_add(struct msg_buf *mb) { int ret = 0; - struct us_inst_data *us_inst; + u32 cnt; + struct app_inst_data *src, *n; + struct list_head app_head; - us_inst = create_us_inst_data(mb); - if (us_inst == NULL) + INIT_LIST_HEAD(&app_head); + cnt = create_us_inst_data(mb, &app_head); + if (!cnt) return -EINVAL; if (!is_end_mb(mb)) { @@ -204,10 +212,22 @@ int msg_swap_inst_add(struct msg_buf *mb) goto free_us_inst; } - ret = mod_us_inst(us_inst, MT_ADD); + list_for_each_entry_safe(src, n, &app_head, list) { + struct app_inst_data *dst; + + dst = app_inst_data_find(&app_inst_head, src); + if (dst) { + app_inst_data_splice(dst, src); + } else { + list_del(&src->list); + list_add_tail(&src->list, &app_inst_head); + } + } + + ret = mod_us_inst(&app_inst_head, MT_ADD); free_us_inst: - destroy_us_inst_data(us_inst); + destroy_us_inst_data(&app_head); return ret; } @@ -221,10 +241,13 @@ free_us_inst: int msg_swap_inst_remove(struct msg_buf *mb) { int ret = 0; - struct us_inst_data *us_inst; + u32 cnt; + struct list_head app_head; + struct app_inst_data *src, *n; - us_inst = create_us_inst_data(mb); - if (us_inst == NULL) + INIT_LIST_HEAD(&app_head); + cnt = create_us_inst_data(mb, &app_head); + if (!cnt) return -EINVAL; if (!is_end_mb(mb)) { @@ -233,10 +256,23 @@ int msg_swap_inst_remove(struct msg_buf *mb) goto free_us_inst; } - ret = mod_us_inst(us_inst, MT_DEL); + list_for_each_entry_safe(src, n, &app_inst_head, list) { + struct app_inst_data *dst; + + dst = app_inst_data_find(&app_head, src); + if (dst) { + app_inst_data_move(dst, src); + if (list_empty(&src->f_head) && + list_empty(&src->l_head)) { + destroy_app_inst_data(src); + } + } + } + + ret = mod_us_inst(&app_head, MT_DEL); free_us_inst: - destroy_us_inst_data(us_inst); + destroy_us_inst_data(&app_head); return ret; } diff --git a/parser/msg_parser.c b/parser/msg_parser.c index 9af49a5..5e21d86 100644 --- a/parser/msg_parser.c +++ b/parser/msg_parser.c @@ -37,29 +37,6 @@ #include "msg_buf.h" #include "parser_defs.h" - -static int str_to_u32(const char *str, u32 *val) -{ - u32 result; - if (!str || !*str) - return -EINVAL; - - for (result = 0 ; *str; ++str) { - if (*str < '0' || *str > '9') - return -EINVAL; - - result = result * 10 + (*str - '0'); - } - - *val = result; - - return 0; -} - - - - - /* ============================================================================ * == APP_INFO == * ============================================================================ @@ -69,13 +46,12 @@ static int str_to_u32(const char *str, u32 *val) * @brief Creates and fills app_info_data struct. * * @param mb Pointer to the message buffer. - * @return Pointer to the filled app_info_data struct on success;\n - * NULL on error. + * @param ai Pointer to the target app_inst_data. + * @return 0 on success, error code on error. */ -struct app_info_data *create_app_info(struct msg_buf *mb) +int create_app_info(struct msg_buf *mb, struct app_inst_data *ai) { int ret; - struct app_info_data *ai; u32 app_type; char *ta_id, *exec_path; @@ -85,14 +61,14 @@ struct app_info_data *create_app_info(struct msg_buf *mb) ret = get_u32(mb, &app_type); if (ret) { print_err("failed to read target application type\n"); - return NULL; + return -EINVAL; } print_parse_debug("id:"); ret = get_string(mb, &ta_id); if (ret) { print_err("failed to read target application ID\n"); - return NULL; + return -EINVAL; } print_parse_debug("exec path:"); @@ -102,12 +78,6 @@ struct app_info_data *create_app_info(struct msg_buf *mb) goto free_ta_id; } - ai = kmalloc(sizeof(*ai), GFP_KERNEL); - if (ai == NULL) { - print_err("out of memory\n"); - goto free_exec_path; - } - switch (app_type) { case AT_TIZEN_NATIVE_APP: case AT_TIZEN_WEB_APP: @@ -118,11 +88,11 @@ struct app_info_data *create_app_info(struct msg_buf *mb) u32 tgid = 0; if (*ta_id != '\0') { - ret = str_to_u32(ta_id, &tgid); + ret = kstrtou32(ta_id, 10, &tgid); if (ret) { print_err("converting string to PID, " "str='%s'\n", ta_id); - goto free_ai; + goto free_exec_path; } } @@ -132,17 +102,14 @@ struct app_info_data *create_app_info(struct msg_buf *mb) default: print_err("wrong application type(%u)\n", app_type); ret = -EINVAL; - goto free_ai; + goto free_exec_path; } - ai->app_type = (enum APP_TYPE)app_type; - ai->app_id = ta_id; - ai->exec_path = exec_path; - - return ai; + ai->type = (enum APP_TYPE)app_type; + ai->id = ta_id; + ai->path = exec_path; -free_ai: - kfree(ai); + return 0; free_exec_path: put_string(exec_path); @@ -150,26 +117,11 @@ free_exec_path: free_ta_id: put_string(ta_id); - return NULL; -} - -/** - * @brief app_info_data cleanup. - * - * @param ai Pointer to the target app_info_data. - * @return Void. - */ -void destroy_app_info(struct app_info_data *ai) -{ - put_string(ai->exec_path); - put_string(ai->app_id); - kfree(ai); + return -EINVAL; } - - /* ============================================================================ * == CONFIG == * ============================================================================ @@ -180,7 +132,7 @@ void destroy_app_info(struct app_info_data *ai) * * @param mb Pointer to the message buffer. * @return Pointer to the filled conf_data struct on success;\n - * 0 on error. + * NULL on error. */ struct conf_data *create_conf_data(struct msg_buf *mb) { @@ -273,7 +225,7 @@ void restore_config(struct conf_data *conf) * @brief Gets retprobe data and puts it to the probe_info struct. * * @param mb Pointer to the message buffer. - * @param pi Pointer to the probe_info struct. + * @param pd Pointer to the probe_desc struct. * @return 0 on success, error code on error. */ int get_retprobe(struct msg_buf *mb, struct probe_desc *pd) @@ -308,7 +260,7 @@ free_args: * @brief Gets webprobe data and puts it to the probe_info struct. * * @param mb Pointer to the message buffer. - * @param pi Pointer to the probe_info struct. + * @param pd Pointer to the probe_desc struct. * @return 0 on success, error code on error. */ int get_webprobe(struct msg_buf *mb, struct probe_desc *pd) @@ -333,7 +285,7 @@ void put_retprobe(struct probe_info *pi) * @brief Gets preload data and puts it to the probe_info struct. * * @param mb Pointer to the message buffer. - * @param pi Pointer to the probe_info struct. + * @param pd Pointer to the probe_desc struct. * @return 0 on success, error code on error. */ int get_preload_probe(struct msg_buf *mb, struct probe_desc *pd) @@ -363,7 +315,7 @@ int get_preload_probe(struct msg_buf *mb, struct probe_desc *pd) /** * @brief Preload probe data cleanup. * - * @param pi Pointer to the probe_info comprising retprobe. + * @param pi Pointer to the probe_info struct. * @return Void. */ void put_preload_probe(struct probe_info *pi) @@ -374,7 +326,7 @@ void put_preload_probe(struct probe_info *pi) * @brief Gets preload get_caller and puts it to the probe_info struct. * * @param mb Pointer to the message buffer. - * @param pi Pointer to the probe_info struct. + * @param pd Pointer to the probe_desc struct. * @return 0 on success, error code on error. */ @@ -388,7 +340,7 @@ int get_get_caller_probe(struct msg_buf *mb, struct probe_desc *pd) /** * @brief Preload get_caller probe data cleanup. * - * @param pi Pointer to the probe_info comprising retprobe. + * @param pi Pointer to the probe_info struct. * @return Void. */ void put_get_caller_probe(struct probe_info *pi) @@ -399,7 +351,7 @@ void put_get_caller_probe(struct probe_info *pi) * @brief Gets preload get_call_type and puts it to the probe_info struct. * * @param mb Pointer to the message buffer. - * @param pi Pointer to the probe_info struct. + * @param pd Pointer to the probe_desc struct. * @return 0 on success, error code on error. */ int get_get_call_type_probe(struct msg_buf *mb, struct probe_desc *pd) @@ -412,7 +364,7 @@ int get_get_call_type_probe(struct msg_buf *mb, struct probe_desc *pd) /** * @brief Preload get_call type probe data cleanup. * - * @param pi Pointer to the probe_info comprising retprobe. + * @param pi Pointer to the probe_info struct. * @return Void. */ void put_get_call_type_probe(struct probe_info *pi) @@ -592,6 +544,7 @@ void put_fbi_probe(struct probe_info *pi) struct func_inst_data *create_func_inst_data(struct msg_buf *mb) { struct func_inst_data *fi; + struct probe_desc *pd; u64 addr; u8 type; @@ -612,48 +565,49 @@ struct func_inst_data *create_func_inst_data(struct msg_buf *mb) print_err("out of memory\n"); return NULL; } + INIT_LIST_HEAD(&fi->list); + fi->registered = 0; - fi->addr = addr; + pd = &fi->p_desc; switch (type) { case SWAP_RETPROBE: - if (get_retprobe(mb, &fi->p_desc) != 0) - goto free_func_inst; + if (get_retprobe(mb, pd) != 0) + goto err; break; case SWAP_WEBPROBE: - if (get_webprobe(mb, &fi->p_desc) != 0) - goto free_func_inst; + if (get_webprobe(mb, pd) != 0) + goto err; break; case SWAP_PRELOAD_PROBE: - if (get_preload_probe(mb, &fi->p_desc) != 0) - goto free_func_inst; + if (get_preload_probe(mb, pd) != 0) + goto err; break; case SWAP_GET_CALLER: - if (get_get_caller_probe(mb, &fi->p_desc) != 0) - goto free_func_inst; + if (get_get_caller_probe(mb, pd) != 0) + goto err; break; case SWAP_GET_CALL_TYPE: - if (get_get_call_type_probe(mb, &fi->p_desc) != 0) - goto free_func_inst; + if (get_get_call_type_probe(mb, pd) != 0) + goto err; break; case SWAP_FBIPROBE: - if (get_fbi_probe(mb, &fi->p_desc) != 0) - goto free_func_inst; + if (get_fbi_probe(mb, pd) != 0) + goto err; break; case SWAP_WRITE_MSG: - if (get_write_msg_probe(mb, &fi->p_desc) != 0) - goto free_func_inst; + if (get_write_msg_probe(mb, pd) != 0) + goto err; break; default: printk(KERN_WARNING "SWAP PARSER: Wrong probe type %d!\n", type); - goto free_func_inst; + goto err; } - fi->p_desc.type = type; + fi->addr = addr; return fi; - -free_func_inst: +err: kfree(fi); return NULL; @@ -696,7 +650,82 @@ void destroy_func_inst_data(struct func_inst_data *fi) kfree(fi); } +/** + * @brief func_inst_data find. + * + * @param head Pointer to the list head with func_inst_data. + * @param func Pointer to the func_inst_data looking for. + * @return Pointer to the found func_inst_data struct on success;\n + * NULL on error. + */ +struct func_inst_data *func_inst_data_find(struct list_head *head, + struct func_inst_data *func) +{ + struct func_inst_data *f; + + list_for_each_entry(f, head, list) { + if (func->addr == f->addr) + return f; + } + return NULL; +} + +/** + * @brief func_inst_data lists splice + * + * @param dst Pointer to the destination list head. + * @param src Pointer to the source list head. + * @return u32 count of spliced elements. + */ +u32 func_inst_data_splice(struct list_head *dst, + struct list_head *src) +{ + struct func_inst_data *f, *n, *s; + u32 cnt = 0; + + list_for_each_entry_safe(f, n, src, list) { + s = func_inst_data_find(dst, f); + if (s) { + printk(KERN_WARNING "duplicate func probe\n"); + continue; + } + + list_del(&f->list); + list_add_tail(&f->list, dst); + cnt++; + } + + return cnt; +} + +/** + * @brief func_inst_data move from one list to another + * + * @param dst Pointer to the destination list head. + * @param src Pointer to the source list head. + * @return u32 Counter of moved elements. + */ +u32 func_inst_data_move(struct list_head *dst, + struct list_head *src) +{ + struct func_inst_data *f, *n, *s; + u32 cnt = 0; + + list_for_each_entry_safe(f, n, src, list) { + s = func_inst_data_find(dst, f); + if (s) { + print_parse_debug("move func 0x%016llX\n", f->addr); + list_del(&f->list); + list_del(&s->list); + destroy_func_inst_data(s); + list_add_tail(&f->list, dst); + cnt++; + } + } + + return cnt; +} @@ -715,9 +744,9 @@ void destroy_func_inst_data(struct func_inst_data *fi) struct lib_inst_data *create_lib_inst_data(struct msg_buf *mb) { struct lib_inst_data *li; - struct func_inst_data *fi; + struct func_inst_data *fi, *fin; char *path; - u32 cnt, j, i = 0; + u32 cnt, i = 0; print_parse_debug("bin path:"); if (get_string(mb, &path)) { @@ -741,24 +770,17 @@ struct lib_inst_data *create_lib_inst_data(struct msg_buf *mb) print_err("out of memory\n"); goto free_path; } + INIT_LIST_HEAD(&li->list); + INIT_LIST_HEAD(&li->f_head); if (cnt) { - li->func = vmalloc(sizeof(*li->func) * cnt); - if (li->func == NULL) { - print_err("out of memory\n"); - goto free_li; - } - for (i = 0; i < cnt; ++i) { print_parse_debug("func #%d:\n", i + 1); fi = create_func_inst_data(mb); if (fi == NULL) goto free_func; - - li->func[i] = fi; + list_add_tail(&fi->list, &li->f_head); } - } else { - li->func = NULL; } li->path = path; @@ -767,12 +789,10 @@ struct lib_inst_data *create_lib_inst_data(struct msg_buf *mb) return li; free_func: - for (j = 0; j < i; ++j) - destroy_func_inst_data(li->func[j]); - vfree(li->func); - -free_li: - kfree(li); + list_for_each_entry_safe(fi, fin, &li->f_head, list) { + list_del(&fi->list); + destroy_func_inst_data(fi); + } free_path: put_string(path); @@ -788,19 +808,99 @@ free_path: */ void destroy_lib_inst_data(struct lib_inst_data *li) { - int i; + struct func_inst_data *fi, *fin; + + list_for_each_entry_safe(fi, fin, &li->f_head, list) { + list_del(&fi->list); + destroy_func_inst_data(fi); + } put_string(li->path); + kfree(li); +} - for (i = 0; i < li->cnt_func; ++i) - destroy_func_inst_data(li->func[i]); +/** + * @brief lib_inst_data find. + * + * @param head Pointer to the list head with lib_inst_data. + * @param lib Pointer to the lib_inst_data looking for. + * @return Pointer to the found lib_inst_data struct on success;\n + * NULL on error. + */ +struct lib_inst_data *lib_inst_data_find(struct list_head *head, + struct lib_inst_data *lib) +{ + struct lib_inst_data *l; - vfree(li->func); - kfree(li); + list_for_each_entry(l, head, list) { + if (!strcmp(l->path, lib->path)) + return l; + } + + return NULL; } +/** + * @brief lib_inst_data lists splice + * + * @param dst Pointer to the destination list head. + * @param src Pointer to the source list head. + * @return u32 count of spliced elements. + */ +u32 lib_inst_data_splice(struct list_head *dst, struct list_head *src) +{ + struct lib_inst_data *l, *n, *s; + u32 cnt = 0; + + list_for_each_entry_safe(l, n, src, list) { + s = lib_inst_data_find(dst, l); + + if (s) { + print_parse_debug("update lib %s\n", s->path); + s->cnt_func += func_inst_data_splice(&s->f_head, + &l->f_head); + + } else { + print_parse_debug("add new lib %s\n", s->path); + list_del(&l->list); + list_add_tail(&l->list, dst); + cnt++; + } + } + + return cnt; +} +/** + * @brief lib_inst_data move from one list to another + * + * @param dst Pointer to the destination list head. + * @param src Pointer to the source list head. + * @return u32 Counter of moved elements. + */ +u32 lib_inst_data_move(struct list_head *dst, struct list_head *src) +{ + struct lib_inst_data *l, *n, *s; + u32 cnt = 0; + + list_for_each_entry_safe(l, n, src, list) { + s = lib_inst_data_find(dst, l); + + if (s) { + print_parse_debug("update lib %s\n", s->path); + l->cnt_func -= func_inst_data_move(&s->f_head, + &l->f_head); + if (list_empty(&l->f_head)) { + list_del(&l->list); + destroy_lib_inst_data(l); + cnt++; + } + } + } + + return cnt; +} /* ============================================================================ @@ -818,56 +918,49 @@ void destroy_lib_inst_data(struct lib_inst_data *li) struct app_inst_data *create_app_inst_data(struct msg_buf *mb) { struct app_inst_data *app_inst; - struct app_info_data *app_info; - struct func_inst_data *func; - struct lib_inst_data *lib; - u32 cnt_func, i_func = 0, cnt_lib, i_lib = 0, i; + struct func_inst_data *func, *func_n; + struct lib_inst_data *lib, *lib_n; + u32 cnt_func, i_func = 0, cnt_lib, i_lib = 0; - app_info = create_app_info(mb); - if (app_info == NULL) + app_inst = kmalloc(sizeof(*app_inst), GFP_KERNEL); + if (app_inst == NULL) { + print_err("out of memory\n"); return NULL; + } + + INIT_LIST_HEAD(&app_inst->list); + INIT_LIST_HEAD(&app_inst->f_head); + INIT_LIST_HEAD(&app_inst->l_head); + + if (create_app_info(mb, app_inst)) + goto err; - print_parse_debug("func count:"); if (get_u32(mb, &cnt_func)) { print_err("failed to read count of functions\n"); - goto free_app_info; + goto err; } + print_parse_debug("func count:%d", cnt_func); if (remained_mb(mb) / MIN_SIZE_FUNC_INST < cnt_func) { print_err("to match count of functions(%u)\n", cnt_func); - goto free_app_info; - } - - app_inst = kmalloc(sizeof(*app_inst), GFP_KERNEL); - if (app_inst == NULL) { - print_err("out of memory\n"); - goto free_app_info; + goto err; } if (cnt_func) { - app_inst->func = vmalloc(sizeof(*app_inst->func) * cnt_func); - if (app_inst->func == NULL) { - print_err("out of memory\n"); - goto free_app_inst; - } - for (i_func = 0; i_func < cnt_func; ++i_func) { print_parse_debug("func #%d:\n", i_func + 1); func = create_func_inst_data(mb); if (func == NULL) goto free_func; - - app_inst->func[i_func] = func; + list_add_tail(&func->list, &app_inst->f_head); } - } else { - app_inst->func = NULL; } - print_parse_debug("lib count:"); if (get_u32(mb, &cnt_lib)) { print_err("failed to read count of libraries\n"); goto free_func; } + print_parse_debug("lib count:i%d", cnt_lib); if (remained_mb(mb) / MIN_SIZE_LIB_INST < cnt_lib) { print_err("to match count of libraries(%u)\n", cnt_lib); @@ -875,46 +968,36 @@ struct app_inst_data *create_app_inst_data(struct msg_buf *mb) } if (cnt_lib) { - app_inst->lib = vmalloc(sizeof(*app_inst->lib) * cnt_lib); - if (app_inst->lib == NULL) { - print_err("out of memory\n"); - goto free_func; - } - for (i_lib = 0; i_lib < cnt_lib; ++i_lib) { print_parse_debug("lib #%d:\n", i_lib + 1); lib = create_lib_inst_data(mb); if (lib == NULL) goto free_lib; - app_inst->lib[i_lib] = lib; + list_add_tail(&lib->list, &app_inst->l_head); } - } else { - app_inst->lib = NULL; } - app_inst->app_info = app_info; app_inst->cnt_func = cnt_func; app_inst->cnt_lib = cnt_lib; return app_inst; free_lib: - for (i = 0; i < i_lib; ++i) - destroy_lib_inst_data(app_inst->lib[i]); - vfree(app_inst->lib); + list_for_each_entry_safe(lib, lib_n, &app_inst->l_head, list) { + list_del(&lib->list); + destroy_lib_inst_data(lib); + } free_func: - for (i = 0; i < i_func; ++i) - destroy_func_inst_data(app_inst->func[i]); - vfree(app_inst->func); + list_for_each_entry_safe(func, func_n, &app_inst->f_head, list) { + list_del(&func->list); + destroy_func_inst_data(func); + } -free_app_inst: +err: kfree(app_inst); -free_app_info: - destroy_app_info(app_info); - return NULL; } @@ -926,23 +1009,93 @@ free_app_info: */ void destroy_app_inst_data(struct app_inst_data *ai) { - int i; + struct func_inst_data *func, *func_n; + struct lib_inst_data *lib, *lib_n; - for (i = 0; i < ai->cnt_lib; ++i) - destroy_lib_inst_data(ai->lib[i]); - vfree(ai->lib); + list_for_each_entry_safe(lib, lib_n, &ai->l_head, list) { + list_del(&lib->list); + destroy_lib_inst_data(lib); + } - for (i = 0; i < ai->cnt_func; ++i) - destroy_func_inst_data(ai->func[i]); - vfree(ai->func); + list_for_each_entry_safe(func, func_n, &ai->f_head, list) { + list_del(&func->list); + destroy_func_inst_data(func); + } + + put_string(ai->path); + put_string(ai->id); - destroy_app_info(ai->app_info); kfree(ai); } +/** + * @brief find app_inst_data. + * + * @param head Pointer to the list head with app_inst_data. + * @param ai Pointer to the target app_inst_data. + * @return Pointer to the target app_inst_data. + */ +struct app_inst_data *app_inst_data_find(struct list_head *head, + struct app_inst_data *ai) +{ + struct app_inst_data *p; + + list_for_each_entry(p, head, list) { + + print_parse_debug("app1: %d, %d, %s, %s\n", + p->type, p->tgid, p->id, p->path); + + print_parse_debug("app2: %d, %d, %s, %s\n", + ai->type, ai->tgid, ai->id, ai->path); + + if ((p->type == ai->type) && + (p->tgid == ai->tgid) && + !strcmp(p->id, ai->id) && + !strcmp(p->path, ai->path)) { + return p; + } + } + + return NULL; +} + +/** + * @brief app_inst_data splice + * + * @param dst Pointer to the destination app_inst_data. + * @param src Pointer to the source app_inst_data.. + * @return void. + */ +void app_inst_data_splice(struct app_inst_data *dst, + struct app_inst_data *src) +{ + print_parse_debug("find app, splice func and lib to %s\n", + dst->path); + + dst->cnt_func += func_inst_data_splice(&dst->f_head, &src->f_head); + dst->cnt_lib += lib_inst_data_splice(&dst->l_head, &src->l_head); + + return; +} +/** + * @brief app_inst_data move from one to another + * + * @param dst Pointer to the destination app_inst_data. + * @param src Pointer to the source app_inst_data. + * @return void. + */ +void app_inst_data_move(struct app_inst_data *dst, + struct app_inst_data *src) +{ + print_parse_debug("find app, delete func and lib from %s\n", + dst->path); + dst->cnt_func -= func_inst_data_move(&dst->f_head, &src->f_head); + dst->cnt_lib -= lib_inst_data_move(&dst->l_head, &src->l_head); + return; +} /* ============================================================================ * == US_INST == @@ -953,78 +1106,59 @@ void destroy_app_inst_data(struct app_inst_data *ai) * @brief Creates and fills us_inst_data struct. * * @param mb Pointer to the message buffer. - * @return Pointer to the filled us_inst_data struct on success;\n - * 0 on error. + * @param head Pointer to the list head. + * @return u32 count of created elements. */ -struct us_inst_data *create_us_inst_data(struct msg_buf *mb) +u32 create_us_inst_data(struct msg_buf *mb, + struct list_head *head) { - struct us_inst_data *ui; - struct app_inst_data *ai; - u32 cnt, j, i = 0; + struct app_inst_data *ai, *n; + u32 cnt, i = 0; print_parse_debug("us_inst_data:\n"); print_parse_debug("app count:"); if (get_u32(mb, &cnt)) { print_err("failed to read count of applications\n"); - return NULL; + return 0; } if (remained_mb(mb) / MIN_SIZE_APP_INST < cnt) { print_err("to match count of applications(%u)\n", cnt); - return NULL; - } - - ui = kmalloc(sizeof(struct us_inst_data), GFP_KERNEL); - if (ui == NULL) { - print_err("out of memory\n"); - return NULL; - } - - ui->app_inst = kmalloc(sizeof(struct app_inst_data *) * cnt, - GFP_KERNEL); - if (ui->app_inst == NULL) { - print_err("out of memory\n"); - goto free_ui; + return 0; } for (i = 0; i < cnt; ++i) { print_parse_debug("app #%d:\n", i + 1); ai = create_app_inst_data(mb); if (ai == NULL) - goto free_app_inst; + goto err; - ui->app_inst[i] = ai; + list_add_tail(&ai->list, head); } - ui->cnt = cnt; + return cnt; - return ui; - -free_app_inst: - for (j = 0; j < i; ++j) - destroy_app_inst_data(ui->app_inst[j]); - kfree(ui->app_inst); - -free_ui: - kfree(ui); +err: + list_for_each_entry_safe(ai, n, head, list) { + list_del(&ai->list); + destroy_app_inst_data(ai); + } - return NULL; + return 0; } /** * @brief us_inst_data cleanup. * - * @param ui Pointer to the target us_inst_data. + * @param head Pointer to the list head. * @return Void. */ -void destroy_us_inst_data(struct us_inst_data *ui) +void destroy_us_inst_data(struct list_head *head) { - int i; - - for (i = 0; i < ui->cnt; ++i) - destroy_app_inst_data(ui->app_inst[i]); - - kfree(ui->app_inst); - kfree(ui); + struct app_inst_data *ai, *n; + list_for_each_entry_safe(ai, n, head, list) { + list_del(&ai->list); + destroy_app_inst_data(ai); + } } diff --git a/parser/msg_parser.h b/parser/msg_parser.h index ec76a26..cd16327 100644 --- a/parser/msg_parser.h +++ b/parser/msg_parser.h @@ -82,8 +82,10 @@ struct conf_data { * @brief Application and library functions to set probes. */ struct func_inst_data { + struct list_head list; u64 addr; /**< Function address. */ struct probe_desc p_desc; /**< Probe info. */ + int registered; }; /** @@ -91,9 +93,10 @@ struct func_inst_data { * @brief Library struct. */ struct lib_inst_data { + struct list_head list; char *path; /**< Library path. */ u32 cnt_func; /**< Function probes count in this library. */ - struct func_inst_data **func; /**< Pointer to the probes array. */ + struct list_head f_head; /**< List head of func_inst_data */ }; /** @@ -101,25 +104,18 @@ struct lib_inst_data { * @brief Application struct. */ struct app_inst_data { - struct app_info_data *app_info; /**< Pointer to app_info struct. */ - u32 cnt_func; /**< Function probes count in app. */ - struct func_inst_data **func; /**< Pointer to the probes array. */ - u32 cnt_lib; /**< Libs count. */ - struct lib_inst_data **lib; /**< Pointer to the libs array. */ + struct list_head list; + enum APP_TYPE type; /**< Application type. */ + pid_t tgid; /**< Application PID. */ + char *id; /**< Application ID */ + char *path; /**< Application execution path. */ + struct list_head f_head; /**< List head of func_inst_data */ + struct list_head l_head; /**< List head of lib_inst_data */ + u32 cnt_func; /**< Function probes count in app. */ + u32 cnt_lib; /**< Libs count. */ }; -/** - * @struct us_inst_data - * @brief User space instrumentation struct. - */ -struct us_inst_data { - u32 cnt; /**< Apps count. */ - struct app_inst_data **app_inst; /**< Pointer to the apps array. */ -}; - - -struct app_info_data *create_app_info(struct msg_buf *mb); -void destroy_app_info(struct app_info_data *app_info); +int create_app_info(struct msg_buf *mb, struct app_inst_data *ai); struct conf_data *create_conf_data(struct msg_buf *mb); void destroy_conf_data(struct conf_data *conf); @@ -135,9 +131,15 @@ void destroy_lib_inst_data(struct lib_inst_data *lib_inst); struct app_inst_data *create_app_inst_data(struct msg_buf *mb); void destroy_app_inst_data(struct app_inst_data *app_inst); +struct app_inst_data *app_inst_data_find(struct list_head *head, + struct app_inst_data *ai); +void app_inst_data_move(struct app_inst_data *dst, + struct app_inst_data *src); +void app_inst_data_splice(struct app_inst_data *dst, + struct app_inst_data *src); -struct us_inst_data *create_us_inst_data(struct msg_buf *mb); -void destroy_us_inst_data(struct us_inst_data *us_inst); +u32 create_us_inst_data(struct msg_buf *mb, struct list_head *head); +void destroy_us_inst_data(struct list_head *head); /* empty functions for calculating size fields in structures */ @@ -158,8 +160,7 @@ enum { MIN_SIZE_APP_INFO = SIZE_APP_TYPE + MIN_SIZE_STRING + MIN_SIZE_STRING, MIN_SIZE_APP_INST = MIN_SIZE_APP_INFO + sizeof(make_app_inst_data().cnt_func) + - sizeof(make_app_inst_data().cnt_lib), - MIN_SIZE_US_INST = sizeof(make_us_inst_data().cnt) + sizeof(make_app_inst_data().cnt_lib) }; #endif /* _MSG_PARSER_H */ diff --git a/parser/us_inst.c b/parser/us_inst.c index 648f3bf..f9293da 100644 --- a/parser/us_inst.c +++ b/parser/us_inst.c @@ -143,15 +143,24 @@ void pfg_put_all(void) static int mod_func_inst(struct func_inst_data *func, struct pf_group *pfg, struct dentry *dentry, enum MOD_TYPE mt) { - int ret; + int ret = 0; switch (mt) { case MT_ADD: - ret = pf_register_probe(pfg, dentry, func->addr, - &func->p_desc); + if (func->registered == 0) { + ret = pf_register_probe(pfg, dentry, func->addr, + &func->p_desc); + if (!ret) + func->registered = 1; + } break; case MT_DEL: - ret = pf_unregister_probe(pfg, dentry, func->addr); + if (func->registered == 1) { + ret = pf_unregister_probe(pfg, dentry, func->addr, + &func->p_desc); + if (!ret) + func->registered = 0; + } break; default: printk(KERN_INFO "ERROR: mod_type=0x%x\n", mt); @@ -164,7 +173,8 @@ static int mod_func_inst(struct func_inst_data *func, struct pf_group *pfg, static int mod_lib_inst(struct lib_inst_data *lib, struct pf_group *pfg, enum MOD_TYPE mt) { - int ret = 0, i; + struct func_inst_data *func; + int ret = 0; struct dentry *dentry; dentry = dentry_by_path(lib->path); @@ -173,8 +183,8 @@ static int mod_lib_inst(struct lib_inst_data *lib, struct pf_group *pfg, return -EINVAL; } - for (i = 0; i < lib->cnt_func; ++i) { - ret = mod_func_inst(lib->func[i], pfg, dentry, mt); + list_for_each_entry(func, &lib->f_head, list) { + ret = mod_func_inst(func, pfg, dentry, mt); if (ret) { printk(KERN_INFO "Cannot mod func inst, ret = %d\n", ret); @@ -185,27 +195,27 @@ static int mod_lib_inst(struct lib_inst_data *lib, struct pf_group *pfg, return ret; } -static int get_pfg_by_app_info(struct app_info_data *app_info, +static int get_pfg_by_app_info(struct app_inst_data *ai, struct pf_group **pfg) { struct dentry *dentry; - dentry = dentry_by_path(app_info->exec_path); + dentry = dentry_by_path(ai->path); if (dentry == NULL) return -EINVAL; - switch (app_info->app_type) { + switch (ai->type) { case AT_PID: - if (app_info->tgid == 0) { - if (app_info->exec_path[0] == '\0') + if (ai->tgid == 0) { + if (ai->path[0] == '\0') *pfg = get_pf_group_dumb(dentry); else goto pf_dentry; } else - *pfg = get_pf_group_by_tgid(app_info->tgid, dentry); + *pfg = get_pf_group_by_tgid(ai->tgid, dentry); break; case AT_TIZEN_WEB_APP: - *pfg = get_pf_group_by_comm(app_info->app_id, dentry); + *pfg = get_pf_group_by_comm(ai->id, dentry); break; case AT_TIZEN_NATIVE_APP: case AT_COMMON_EXEC: @@ -213,7 +223,7 @@ static int get_pfg_by_app_info(struct app_info_data *app_info, *pfg = get_pf_group_by_dentry(dentry, dentry); break; default: - printk(KERN_INFO "ERROR: app_type=0x%x\n", app_info->app_type); + printk(KERN_INFO "ERROR: app_type=0x%x\n", ai->type); return -EINVAL; } @@ -222,11 +232,13 @@ static int get_pfg_by_app_info(struct app_info_data *app_info, static int mod_us_app_inst(struct app_inst_data *app_inst, enum MOD_TYPE mt) { - int ret, i; + int ret; struct pf_group *pfg; struct dentry *dentry; + struct func_inst_data *func; + struct lib_inst_data *lib; - ret = get_pfg_by_app_info(app_inst->app_info, &pfg); + ret = get_pfg_by_app_info(app_inst, &pfg); if (ret) { printk(KERN_INFO "Cannot get pfg by app info, ret = %d\n", ret); return ret; @@ -239,16 +251,16 @@ static int mod_us_app_inst(struct app_inst_data *app_inst, enum MOD_TYPE mt) return ret; } - for (i = 0; i < app_inst->cnt_func; ++i) { + list_for_each_entry(func, &app_inst->f_head, list) { /* TODO: */ - dentry = dentry_by_path(app_inst->app_info->exec_path); + dentry = dentry_by_path(app_inst->path); if (dentry == NULL) { printk(KERN_INFO "Cannot find dentry by path %s\n", - app_inst->app_info->exec_path); + app_inst->path); return -EINVAL; } - ret = mod_func_inst(app_inst->func[i], pfg, dentry, mt); + ret = mod_func_inst(func, pfg, dentry, mt); if (ret) { printk(KERN_INFO "Cannot mod func inst, ret = %d\n", ret); @@ -256,8 +268,8 @@ static int mod_us_app_inst(struct app_inst_data *app_inst, enum MOD_TYPE mt) } } - for (i = 0; i < app_inst->cnt_lib; ++i) { - ret = mod_lib_inst(app_inst->lib[i], pfg, mt); + list_for_each_entry(lib, &app_inst->l_head, list) { + ret = mod_lib_inst(lib, pfg, mt); if (ret) { printk(KERN_INFO "Cannot mod lib inst, ret = %d\n", ret); @@ -275,13 +287,13 @@ static int mod_us_app_inst(struct app_inst_data *app_inst, enum MOD_TYPE mt) * @param mt Modificator, indicates whether we install or remove probes. * @return 0 on suceess, error code on error. */ -int mod_us_inst(struct us_inst_data *us_inst, enum MOD_TYPE mt) +int mod_us_inst(struct list_head *head, enum MOD_TYPE mt) { - u32 i; int ret; + struct app_inst_data *ai; - for (i = 0; i < us_inst->cnt; ++i) { - ret = mod_us_app_inst(us_inst->app_inst[i], mt); + list_for_each_entry(ai, head, list) { + ret = mod_us_app_inst(ai, mt); if (ret) { printk(KERN_INFO "Cannot mod us app inst, ret = %d\n", ret); diff --git a/parser/us_inst.h b/parser/us_inst.h index e3fc6bc..3ba3907 100644 --- a/parser/us_inst.h +++ b/parser/us_inst.h @@ -39,9 +39,7 @@ enum MOD_TYPE { MT_DEL /**< Remove probes. */ }; -struct us_inst_data; - -int mod_us_inst(struct us_inst_data *us_inst, enum MOD_TYPE mt); +int mod_us_inst(struct list_head *head, enum MOD_TYPE mt); void pfg_put_all(void); #endif /* _US_INST_H */ diff --git a/us_manager/img/img_file.c b/us_manager/img/img_file.c index 07b1ba4..03b6d7f 100644 --- a/us_manager/img/img_file.c +++ b/us_manager/img/img_file.c @@ -77,12 +77,14 @@ static void img_del_ip_by_list(struct img_ip *ip) list_del(&ip->list); } -static struct img_ip *find_img_ip(struct img_file *file, unsigned long addr) +static struct img_ip *find_img_ip(struct img_file *file, unsigned long addr, + struct probe_desc *pd) { struct img_ip *ip; list_for_each_entry(ip, &file->ip_list, list) { - if (ip->addr == addr) + if ((ip->addr == addr) && + (ip->desc == pd)) return ip; } @@ -103,7 +105,7 @@ int img_file_add_ip(struct img_file *file, unsigned long addr, { struct img_ip *ip; - ip = find_img_ip(file, addr); + ip = find_img_ip(file, addr, pd); if (ip) { /* ip already exists in img */ return 0; @@ -122,11 +124,12 @@ int img_file_add_ip(struct img_file *file, unsigned long addr, * @param addr Function address * @return Error code */ -int img_file_del_ip(struct img_file *file, unsigned long addr) +int img_file_del_ip(struct img_file *file, unsigned long addr, + struct probe_desc *pd) { struct img_ip *ip; - ip = find_img_ip(file, addr); + ip = find_img_ip(file, addr, pd); if (ip == NULL) { printk(KERN_INFO "Warning: no ip found in img, addr = %lx\n", addr); diff --git a/us_manager/img/img_file.h b/us_manager/img/img_file.h index 081a1ba..7b33980 100644 --- a/us_manager/img/img_file.h +++ b/us_manager/img/img_file.h @@ -45,7 +45,8 @@ void free_img_file(struct img_file *ip); int img_file_add_ip(struct img_file *file, unsigned long addr, struct probe_desc *pd); -int img_file_del_ip(struct img_file *file, unsigned long addr); +int img_file_del_ip(struct img_file *file, unsigned long addr, + struct probe_desc *pd); int img_file_empty(struct img_file *file); diff --git a/us_manager/img/img_ip.c b/us_manager/img/img_ip.c index d03b09c..5ec1e9a 100644 --- a/us_manager/img/img_ip.c +++ b/us_manager/img/img_ip.c @@ -46,10 +46,7 @@ struct img_ip *create_img_ip(unsigned long addr, struct probe_desc *pd) INIT_LIST_HEAD(&ip->list); INIT_LIST_HEAD(&ip->ihead); ip->addr = addr; - /* TODO replace struct probe_desc in img_ip - * with pointer on struct probe_desc - */ - memcpy(&ip->desc, pd, sizeof(struct probe_desc)); + ip->desc = pd; return ip; } @@ -85,8 +82,8 @@ void free_img_ip(struct img_ip *ip) /* debug */ void img_ip_print(struct img_ip *ip) { - if (ip->desc.type == SWAP_RETPROBE) + if (ip->desc->type == SWAP_RETPROBE) printk(KERN_INFO "### addr=8%lx, args=%s\n", - ip->addr, ip->desc.info.rp_i.args); + ip->addr, ip->desc->info.rp_i.args); } /* debug */ diff --git a/us_manager/img/img_ip.h b/us_manager/img/img_ip.h index 115cdc1..d5ed218 100644 --- a/us_manager/img/img_ip.h +++ b/us_manager/img/img_ip.h @@ -37,7 +37,7 @@ struct img_ip { struct list_head list; /**< For img_file */ unsigned long addr; /**< Function address */ struct list_head ihead; /**< List head for sspt ip */ - struct probe_desc desc; /**< Probe info */ + struct probe_desc *desc; /**< Probe info */ }; struct img_ip *create_img_ip(unsigned long addr, struct probe_desc *info); diff --git a/us_manager/img/img_proc.c b/us_manager/img/img_proc.c index 6e5a95e..12aa816 100644 --- a/us_manager/img/img_proc.c +++ b/us_manager/img/img_proc.c @@ -154,7 +154,8 @@ unlock: */ int img_proc_del_ip(struct img_proc *proc, struct dentry *dentry, - unsigned long addr) + unsigned long addr, + struct probe_desc *pd) { int ret; struct img_file *file; @@ -166,7 +167,7 @@ int img_proc_del_ip(struct img_proc *proc, goto unlock; } - ret = img_file_del_ip(file, addr); + ret = img_file_del_ip(file, addr, pd); if (ret == 0 && img_file_empty(file)) { img_del_file_by_list(file); free_img_file(file); diff --git a/us_manager/img/img_proc.h b/us_manager/img/img_proc.h index 713bcf0..70d924e 100644 --- a/us_manager/img/img_proc.h +++ b/us_manager/img/img_proc.h @@ -37,9 +37,8 @@ void free_img_proc(struct img_proc *proc); int img_proc_add_ip(struct img_proc *proc, struct dentry *dentry, unsigned long addr, struct probe_desc *pd); -int img_proc_del_ip(struct img_proc *proc, - struct dentry *dentry, - unsigned long addr); +int img_proc_del_ip(struct img_proc *proc, struct dentry *dentry, + unsigned long addri, struct probe_desc *pd); void img_proc_copy_to_sspt(struct img_proc *i_proc, struct sspt_proc *proc); diff --git a/us_manager/pf/pf_group.c b/us_manager/pf/pf_group.c index b251bd7..408d4e4 100644 --- a/us_manager/pf/pf_group.c +++ b/us_manager/pf/pf_group.c @@ -421,9 +421,9 @@ EXPORT_SYMBOL_GPL(pf_register_probe); * @return Error code */ int pf_unregister_probe(struct pf_group *pfg, struct dentry *dentry, - unsigned long offset) + unsigned long offset, struct probe_desc *pd) { - return img_proc_del_ip(pfg->i_proc, dentry, offset); + return img_proc_del_ip(pfg->i_proc, dentry, offset, pd); } EXPORT_SYMBOL_GPL(pf_unregister_probe); diff --git a/us_manager/pf/pf_group.h b/us_manager/pf/pf_group.h index 5c61567..ad29796 100644 --- a/us_manager/pf/pf_group.h +++ b/us_manager/pf/pf_group.h @@ -58,7 +58,7 @@ struct pfg_msg_cb *pfg_msg_cb_get(struct pf_group *pfg); int pf_register_probe(struct pf_group *pfg, struct dentry *dentry, unsigned long offset, struct probe_desc *pd); int pf_unregister_probe(struct pf_group *pfg, struct dentry *dentry, - unsigned long offset); + unsigned long offset, struct probe_desc *pd); void install_all(void); void uninstall_all(void); diff --git a/us_manager/probes/probe_info_new.c b/us_manager/probes/probe_info_new.c index fbeb4be..b5a05bd 100644 --- a/us_manager/probes/probe_info_new.c +++ b/us_manager/probes/probe_info_new.c @@ -100,7 +100,7 @@ int pin_unregister(struct probe_new *probe, struct pf_group *pfg, { int ret; - ret = pf_unregister_probe(pfg, dentry, probe->offset); + ret = pf_unregister_probe(pfg, dentry, probe->offset, probe->desc); if (ret) { printk(KERN_ERR "%s: unregister probe failed (%d)\n", __FUNCTION__, ret); diff --git a/us_manager/probes/probes.h b/us_manager/probes/probes.h index fa40dd1..f6dec06 100644 --- a/us_manager/probes/probes.h +++ b/us_manager/probes/probes.h @@ -75,7 +75,6 @@ struct probe_info { struct probe_desc { enum probe_t type; - unsigned long offset; union { struct { diff --git a/us_manager/sspt/ip.c b/us_manager/sspt/ip.c index 3625181..624ddcf 100644 --- a/us_manager/sspt/ip.c +++ b/us_manager/sspt/ip.c @@ -51,7 +51,7 @@ struct us_ip *create_ip(struct img_ip *img_ip) INIT_LIST_HEAD(&ip->list); INIT_LIST_HEAD(&ip->img_list); ip->offset = img_ip->addr; - ip->desc = &img_ip->desc; + ip->desc = img_ip->desc; ip->iip = img_ip; list_add(&ip->img_list, &img_ip->ihead); diff --git a/webprobe/webprobe.c b/webprobe/webprobe.c index ce7109a..9f4e983 100644 --- a/webprobe/webprobe.c +++ b/webprobe/webprobe.c @@ -72,11 +72,11 @@ static int webprobe_register_probe(struct us_ip *ip) static void webprobe_unregister_probe(struct us_ip *ip, int disarm) { if (ip->orig_addr == inspserver_addr_local) - web_func_inst_remove(web_prof_addr(INSPSERVER_START)); + web_func_inst_remove(INSPSERVER_START); else if (ip->orig_addr == willexecute_addr_local) - web_func_inst_remove(web_prof_addr(WILL_EXECUTE)); + web_func_inst_remove(WILL_EXECUTE); else if (ip->orig_addr == didexecute_addr_local) - web_func_inst_remove(web_prof_addr(DID_EXECUTE)); + web_func_inst_remove(DID_EXECUTE); __swap_unregister_uretprobe(&ip->retprobe, disarm); } diff --git a/webprobe/webprobe_prof.c b/webprobe/webprobe_prof.c index fffef1c..0da0809 100644 --- a/webprobe/webprobe_prof.c +++ b/webprobe/webprobe_prof.c @@ -40,8 +40,11 @@ struct web_prof_data { struct dentry *lib_dentry; struct pf_group *pfg; u64 inspserver_addr; + struct probe_desc *inspserver; u64 willexecute_addr; + struct probe_desc *willexecute; u64 didexecute_addr; + struct probe_desc *didexecute; enum web_prof_state_t enabled; }; @@ -93,30 +96,65 @@ unsigned long web_prof_addr(enum web_prof_addr_t type) return addr; } -static int web_func_inst_add(unsigned long addr) +static struct probe_desc *web_func_inst_add(unsigned long addr) { int ret; - struct probe_desc probe; + struct probe_desc *probe = NULL; - probe.type = SWAP_WEBPROBE; + probe = kmalloc(sizeof(*probe), GFP_KERNEL); + + if (!probe) + return NULL; + + memset(probe, 0, sizeof(*probe)); + probe->type = SWAP_WEBPROBE; ret = pf_register_probe(web_data->pfg, web_data->lib_dentry, - addr, &probe); + addr, probe); - return ret; + return probe; } -int web_func_inst_remove(unsigned long addr) +static int __web_func_inst_remove(unsigned long addr, struct probe_desc *pd) { int ret; + if (!addr || !pd) + return -EINVAL; + /* FIXME: check that address needs removing */ ret = pf_unregister_probe(web_data->pfg, web_data->lib_dentry, - addr); + addr, pd); return ret; } +int web_func_inst_remove(enum web_prof_addr_t type) +{ + unsigned long addr = 0; + struct probe_desc *pd = NULL; + + switch (type) { + case INSPSERVER_START: + addr = web_data->inspserver_addr; + pd = web_data->inspserver; + break; + case WILL_EXECUTE: + addr = web_data->willexecute_addr; + pd = web_data->willexecute; + break; + case DID_EXECUTE: + addr = web_data->didexecute_addr; + pd = web_data->didexecute; + break; + default: + pr_err("ERROR: WEB_PROF_ADDR_TYPE=0x%x\n", type); + } + + + return __web_func_inst_remove(addr, pd); +} + int web_prof_data_set(char *app_path, char *app_id) { web_data->app_dentry = dentry_by_path(app_path); @@ -161,9 +199,14 @@ int web_prof_enable(void) pr_err("ERROR: Can't enable web profiling\n"); ret = -EFAULT; } else { - web_func_inst_add(web_data->inspserver_addr); - web_func_inst_add(web_data->willexecute_addr); - web_func_inst_add(web_data->didexecute_addr); + web_data->inspserver = + web_func_inst_add(web_data->inspserver_addr); + + web_data->willexecute = + web_func_inst_add(web_data->willexecute_addr); + + web_data->didexecute = + web_func_inst_add(web_data->didexecute_addr); } } else { pr_err("ERROR: Web profiling is already enabled\n"); @@ -187,9 +230,17 @@ int web_prof_disable(void) pr_err("ERROR: Can't disable web profiling\n"); ret = -EFAULT; } else { - web_func_inst_remove(web_data->inspserver_addr); - web_func_inst_remove(web_data->willexecute_addr); - web_func_inst_remove(web_data->didexecute_addr); + if (!__web_func_inst_remove(web_data->inspserver_addr, + web_data->inspserver)) + kfree(web_data->inspserver); + + if (!__web_func_inst_remove(web_data->willexecute_addr, + web_data->willexecute)) + kfree(web_data->willexecute); + + if (!__web_func_inst_remove(web_data->didexecute_addr, + web_data->didexecute)) + kfree(web_data->willexecute); } } else { pr_err("ERROR: Web profiling is already disabled\n"); @@ -218,5 +269,14 @@ void web_prof_exit(void) if (web_data->pfg) put_pf_group(web_data->pfg); + if (web_data->inspserver) + kfree(web_data->inspserver); + + if (web_data->willexecute) + kfree(web_data->willexecute); + + if (web_data->didexecute) + kfree(web_data->didexecute); + kfree(web_data); } diff --git a/webprobe/webprobe_prof.h b/webprobe/webprobe_prof.h index d0144f9..83de851 100644 --- a/webprobe/webprobe_prof.h +++ b/webprobe/webprobe_prof.h @@ -44,7 +44,7 @@ void web_prof_exit(void); int web_prof_enable(void); int web_prof_disable(void); enum web_prof_state_t web_prof_enabled(void); -int web_func_inst_remove(unsigned long addr); +int web_func_inst_remove(enum web_prof_addr_t type); u64 *web_prof_addr_ptr(enum web_prof_addr_t type); unsigned long web_prof_addr(enum web_prof_addr_t type); int web_prof_data_set(char *app_path, char *app_id); -- 2.7.4