[FEATURE] FBI multi probing 62/38862/9
authorVitaliy Cherepanov <v.cherepanov@samsung.com>
Tue, 2 Dec 2014 14:40:59 +0000 (17:40 +0300)
committerVitaliy Andreevich <v.cherepanov@samsung.com>
Fri, 15 May 2015 09:32:46 +0000 (02:32 -0700)
Change-Id: I27186afb057ad97724225c93e6a1f596d2df6ff3
Signed-off-by: Vitaliy Cherepanov <v.cherepanov@samsung.com>
fbiprobe/fbiprobe.c
fbiprobe/fbiprobe.h
parser/msg_parser.c

index d37e4c0..1eba7d8 100644 (file)
@@ -60,7 +60,7 @@
 #define MAX_STRING_LEN (512)
 
 /* you shoud free allocated data buffer */
-static char *fbi_probe_alloc_and_read_from_addr(const struct fbi_info *fbi_i,
+static char *fbi_probe_alloc_and_read_from_addr(const struct fbi_var_data *fbi_i,
                                                unsigned long addr,
                                                uint32_t *size)
 {
@@ -139,7 +139,7 @@ fail_exit:
 
 }
 
-static int fbi_probe_get_data_from_reg(const struct fbi_info *fbi_i,
+static int fbi_probe_get_data_from_reg(const struct fbi_var_data *fbi_i,
                                       struct pt_regs *regs)
 {
        unsigned long *reg_ptr;
@@ -155,7 +155,7 @@ static int fbi_probe_get_data_from_reg(const struct fbi_info *fbi_i,
        return 0;
 }
 
-static int fbi_probe_get_data_from_ptrs(const struct fbi_info *fbi_i,
+static int fbi_probe_get_data_from_ptrs(const struct fbi_var_data *fbi_i,
                                        struct pt_regs *regs)
 {
        unsigned long *reg_ptr;
@@ -200,7 +200,7 @@ exit:
        return vma;
 }
 
-static int fbi_probe_get_data_from_direct_addr(const struct fbi_info *fbi_i,
+static int fbi_probe_get_data_from_direct_addr(const struct fbi_var_data *fbi_i,
                                               struct us_ip *ip,
                                               struct pt_regs *regs)
 {
@@ -239,6 +239,8 @@ static int fbi_probe_handler(struct kprobe *p, struct pt_regs *regs)
        struct uprobe *up = container_of(p, struct uprobe, kp);
        struct us_ip *ip = container_of(up, struct us_ip, uprobe);
        struct fbi_info *fbi_i = &ip->probe_i.fbi_i;
+       struct fbi_var_data *fbi_d = NULL;
+       uint8_t i;
 
        if (ip->probe_i.probe_type != SWAP_FBIPROBE) {
                /* How this can occure? Doesn't matter, just print and go */
@@ -246,12 +248,19 @@ static int fbi_probe_handler(struct kprobe *p, struct pt_regs *regs)
                return 0;
        }
 
-       if (fbi_i->reg_n == DIRECT_ADDR)
-               return fbi_probe_get_data_from_direct_addr(fbi_i, ip, regs);
-       else if (fbi_i->steps_count == 0)
-               return fbi_probe_get_data_from_reg(fbi_i, regs);
-       else
-               return fbi_probe_get_data_from_ptrs(fbi_i, regs);
+       for (i = 0; i != fbi_i->var_count; i++) {
+               fbi_d = &fbi_i->vars[i];
+               if (fbi_d->reg_n == DIRECT_ADDR) {
+                       if (0 != fbi_probe_get_data_from_direct_addr(fbi_d, ip, regs))
+                               print_err("fbi_probe_get_data_from_direct_addr error\n");
+               } else if (fbi_d->steps_count == 0) {
+                       if (0 != fbi_probe_get_data_from_reg(fbi_d, regs))
+                               print_err("fbi_probe_get_data_from_reg error\n");
+               } else {
+                       if (0 != fbi_probe_get_data_from_ptrs(fbi_d, regs))
+                               print_err("fbi_probe_get_data_from_ptrs error\n");
+               }
+       }
 
        return 0;
 }
@@ -259,12 +268,21 @@ static int fbi_probe_handler(struct kprobe *p, struct pt_regs *regs)
 /* FBI probe interfaces */
 void fbi_probe_cleanup(struct probe_info *probe_i)
 {
-       struct fbi_step *steps;
-       steps = probe_i->fbi_i.steps;
-       if (steps != NULL) {
-               kfree(steps);
-               probe_i->fbi_i.steps = NULL;
-               probe_i->fbi_i.steps_count = 0;
+       uint8_t i;
+       struct fbi_info *fbi_i = &(probe_i->fbi_i);
+
+       for (i = 0; i != fbi_i->var_count; i++) {
+               if (fbi_i->vars[i].steps != NULL) {
+                       if (fbi_i->vars[i].steps != NULL)
+                               kfree(fbi_i->vars[i].steps);
+                       fbi_i->vars[i].steps = NULL;
+                       fbi_i->vars[i].steps_count = 0;
+               }
+       }
+
+       if (fbi_i->vars) {
+               kfree(fbi_i->vars);
+               fbi_i->vars = NULL;
        }
 }
 
@@ -298,24 +316,39 @@ int fbi_probe_copy(struct probe_info *dest, const struct probe_info *source)
 {
        uint8_t steps_count;
        size_t steps_size;
+       size_t vars_size;
+       struct fbi_var_data *vars;
        struct fbi_step *steps_source;
        struct fbi_step *steps_dest = NULL;
+       uint8_t i;
 
-       steps_source = source->fbi_i.steps;
-       steps_count = source->fbi_i.steps_count;
-       steps_size = sizeof(*steps_source) * steps_count;
 
        memcpy(dest, source, sizeof(*source));
-       if (steps_size != 0 && steps_source != NULL) {
-               steps_dest = kmalloc(steps_size, GFP_KERNEL);
-               if (steps_dest == NULL) {
-                       print_err("can not alloc data\n");
-                       return -ENOMEM;
-               }
 
-               memcpy(steps_dest, steps_source, steps_size);
+       vars_size = source->fbi_i.var_count * sizeof(*source->fbi_i.vars);
+       vars = kmalloc(vars_size, GFP_KERNEL);
+       memcpy(vars, source->fbi_i.vars, vars_size);
+
+       for (i = 0; i != source->fbi_i.var_count; i++) {
+               steps_dest = NULL;
+               steps_count = vars[i].steps_count;
+               steps_size = sizeof(*steps_source) * steps_count;
+               steps_source = vars[i].steps;
+
+               if (steps_size != 0 && steps_source != NULL) {
+                       steps_dest = kmalloc(steps_size, GFP_KERNEL);
+                       if (steps_dest == NULL) {
+                               print_err("can not alloc data\n");
+                               return -ENOMEM;
+                       }
+
+                       memcpy(steps_dest, steps_source, steps_size);
+               }
+               vars[i].steps = steps_dest;
        }
-       dest->fbi_i.steps = steps_dest;
+
+       dest->fbi_i.vars = vars;
+
        return 0;
 }
 
index fbd8359..125995d 100644 (file)
@@ -47,8 +47,8 @@ struct fbi_step {
        uint64_t data_offset;
 } __packed;
 
-/* FBI info */
-struct fbi_info {
+/* FBI var data */
+struct fbi_var_data {
        /* Variable position is evaluated by the following rule:
         * var_position = *(pointer_to_register) - reg_offset
         * It is expected that the offset is not null only when we're taking
@@ -65,4 +65,10 @@ struct fbi_info {
        struct fbi_step *steps;    /* extract steps */
 };
 
+/* FBI info */
+struct fbi_info {
+       uint8_t var_count;
+       struct fbi_var_data *vars;
+};
+
 #endif /* __FBI_PROBE_H__ */
index 4f0108f..4c327ba 100644 (file)
@@ -432,7 +432,7 @@ void put_get_call_type_probe(struct probe_info *pi)
  * @param pi Pointer to the probe_info struct.
  * @return 0 on success, error code on error.
  */
-int get_fbi_probe(struct msg_buf *mb, struct probe_info *pi)
+int get_fbi_data(struct msg_buf *mb, struct fbi_var_data *vd)
 {
        u64 var_id;
        u64 reg_offset;
@@ -472,10 +472,12 @@ int get_fbi_probe(struct msg_buf *mb, struct probe_info *pi)
        }
 
        if (steps_count > 0) {
-               steps = kmalloc(steps_count * sizeof(pi->fbi_i.steps[0]),
+               steps = kmalloc(steps_count * sizeof(*vd->steps),
                                GFP_KERNEL);
-               if (steps == NULL)
+               if (steps == NULL) {
+                       print_err("MALLOC FAIL\n");
                        return -ENOMEM;
+               }
 
                for (i = 0; i != steps_count; i++) {
                        print_parse_debug("steps #%d ptr_order:", i);
@@ -493,14 +495,12 @@ int get_fbi_probe(struct msg_buf *mb, struct probe_info *pi)
                }
        }
 
-       pi->probe_type = SWAP_FBIPROBE;
-       pi->fbi_i.reg_n = reg_n;
-       pi->fbi_i.reg_offset = reg_offset;
-       pi->fbi_i.data_size = data_size;
-       pi->fbi_i.var_id = var_id;
-       pi->fbi_i.steps_count = steps_count;
-       pi->fbi_i.steps = steps;
-       pi->size = 0;
+       vd->reg_n = reg_n;
+       vd->reg_offset = reg_offset;
+       vd->data_size = data_size;
+       vd->var_id = var_id;
+       vd->steps_count = steps_count;
+       vd->steps = steps;
 
        return 0;
 
@@ -509,6 +509,42 @@ free_steps:
        return -EINVAL;
 }
 
+int get_fbi_probe(struct msg_buf *mb, struct probe_info *pi)
+{
+       uint8_t var_count, i;
+       struct fbi_var_data *vars;
+
+       print_parse_debug("var count:");
+       if (get_u8(mb, &var_count)) {
+               print_err("failed to read var ID\n");
+               return -EINVAL;
+       }
+
+       vars = kmalloc(var_count * sizeof(*vars), GFP_KERNEL);
+       if (vars == NULL) {
+               print_err("alloc vars error\n");
+               goto err;
+       }
+
+       for (i = 0; i != var_count; i++) {
+               if (get_fbi_data(mb, &vars[i]) != 0)
+                       goto free_vars;
+       }
+
+       pi->probe_type = SWAP_FBIPROBE;
+       pi->fbi_i.var_count = var_count;
+       pi->fbi_i.vars = vars;
+       pi->size =0 ;
+       return 0;
+
+free_vars:
+       kfree(vars);
+
+err:
+       return -EINVAL;
+
+}
+
 /**
  * @brief FBI probe data cleanup.
  *