[REFACTOR] add support for manipulating probes depend on probe info 51/46451/3
authorAnatolii Nikulin <nikulin.a@samsung.com>
Thu, 20 Aug 2015 12:05:49 +0000 (15:05 +0300)
committerAnatolii Nikulin <nikulin.a@samsung.com>
Tue, 20 Oct 2015 08:54:04 +0000 (11:54 +0300)
Change-Id: I966f8703051d3f8853fd05e3a68a5049b1a2fe07
Signed-off-by: Anatolii Nikulin <nikulin.a@samsung.com>
19 files changed:
parser/msg_cmd.c
parser/msg_parser.c
parser/msg_parser.h
parser/us_inst.c
parser/us_inst.h
us_manager/img/img_file.c
us_manager/img/img_file.h
us_manager/img/img_ip.c
us_manager/img/img_ip.h
us_manager/img/img_proc.c
us_manager/img/img_proc.h
us_manager/pf/pf_group.c
us_manager/pf/pf_group.h
us_manager/probes/probe_info_new.c
us_manager/probes/probes.h
us_manager/sspt/ip.c
webprobe/webprobe.c
webprobe/webprobe_prof.c
webprobe/webprobe_prof.h

index 352e757..b0ff1c5 100644 (file)
@@ -40,6 +40,7 @@
 #include <us_manager/us_manager.h>
 
 
+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;
 }
index 9af49a5..5e21d86 100644 (file)
 #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);
+       }
 }
index ec76a26..cd16327 100644 (file)
@@ -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 */
index 648f3bf..f9293da 100644 (file)
@@ -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);
index e3fc6bc..3ba3907 100644 (file)
@@ -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 */
index 07b1ba4..03b6d7f 100644 (file)
@@ -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);
index 081a1ba..7b33980 100644 (file)
@@ -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);
 
index d03b09c..5ec1e9a 100644 (file)
@@ -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 */
index 115cdc1..d5ed218 100644 (file)
@@ -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);
index 6e5a95e..12aa816 100644 (file)
@@ -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);
index 713bcf0..70d924e 100644 (file)
@@ -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);
 
index b251bd7..408d4e4 100644 (file)
@@ -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);
 
index 5c61567..ad29796 100644 (file)
@@ -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);
index fbeb4be..b5a05bd 100644 (file)
@@ -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);
index fa40dd1..f6dec06 100644 (file)
@@ -75,7 +75,6 @@ struct probe_info {
 
 struct probe_desc {
        enum probe_t type;
-       unsigned long offset;
 
        union {
                struct {
index 3625181..624ddcf 100644 (file)
@@ -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);
 
index ce7109a..9f4e983 100644 (file)
@@ -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);
 }
index fffef1c..0da0809 100644 (file)
@@ -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);
 }
index d0144f9..83de851 100644 (file)
@@ -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);