#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)
{
}
-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;
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;
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)
{
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 */
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;
}
/* 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;
}
}
{
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;
}
* @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;
}
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);
}
}
- 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;
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.
*