From 7a76b43942410512a7f0d767121ae7433ca9bccd Mon Sep 17 00:00:00 2001 From: Alexander Aksenov Date: Wed, 26 Mar 2014 16:44:19 +0400 Subject: [PATCH] [IMPROVE] Implement different kind of probes Now probe type is transferred right after the probe address, before the probe's data. Supported probe types: 0 - retprobe 1 - function body instrumentation probe 2 - preloaded API probe Change-Id: Ie309e3f911619f3a1b4c821f1ad17932ce9f1c4d Signed-off-by: Alexander Aksenov --- daemon/da_inst.c | 21 ++++++++++++--- daemon/da_protocol.h | 14 +++++++--- daemon/da_protocol_inst.c | 65 +++++++++++++++++++++++++++++------------------ 3 files changed, 67 insertions(+), 33 deletions(-) diff --git a/daemon/da_inst.c b/daemon/da_inst.c index 78446cd..4c16122 100644 --- a/daemon/da_inst.c +++ b/daemon/da_inst.c @@ -268,14 +268,27 @@ static struct data_list_t *data_list_find_data(struct data_list_t *whered, struc return NULL; } +// Check whether functions are equal. If so, returns first argument, otherwise - NULL +static struct probe_list_t *probes_equal(struct probe_list_t *first, struct probe_list_t *second) +{ + if (first->size != second->size) + return NULL; + + if (first->func->func_addr != second->func->func_addr) + return NULL; + + if (first->func->probe_type != second->func->probe_type) + return NULL; + + return first; +} + static struct probe_list_t *find_probe(struct data_list_t *where, struct probe_list_t *probe) { struct probe_list_t *p ; for (p = where->list; p != NULL; p = p->next) - if (p->size == probe->size) - if (p->func->func_addr == probe->func->func_addr) - if (strcmp(p->func->args, probe->func->args) == 0) - break; + if (probes_equal(p, probe)) + break; return p; } diff --git a/daemon/da_protocol.h b/daemon/da_protocol.h index 24aeefd..22a2e81 100644 --- a/daemon/da_protocol.h +++ b/daemon/da_protocol.h @@ -148,6 +148,12 @@ enum feature_code{ }; +enum probe_type { + SWAP_RETPROBE = 0, //Common retprobe + SWAP_FBI_PROBE = 1, //Function body instrumentation probe + SWAP_LD_PROBE = 2 //Preloaded API probe +}; + #define IS_OPT_SET_IN(OPT, reg) (reg & (OPT)) #define IS_OPT_SET(OPT) IS_OPT_SET_IN((OPT), prof_session.conf.use_features0) @@ -246,11 +252,11 @@ struct us_func_inst_plane_t { //name | type | len | info //------------------------------------------ //func_addr | uint64 | 8 | - //args | string | len(args) |end with '\0' - //ret_type | char | 1 | + //probe_type | char | 1 | uint64_t func_addr; - char args[0]; -}; + char probe_type; + char probe_info[0]; +} __attribute__ ((packed)); struct us_lib_inst_t { char *bin_path; diff --git a/daemon/da_protocol_inst.c b/daemon/da_protocol_inst.c index 26ffb35..2a55702 100644 --- a/daemon/da_protocol_inst.c +++ b/daemon/da_protocol_inst.c @@ -63,42 +63,56 @@ static int parse_us_inst_func(struct msg_buf_t *msg, struct probe_list_t **dest) //name | type | len | info //------------------------------------------ //func_addr | uint64 | 8 | - //args | string | len(args) |end with '\0' - //ret_type | char | 1 | + //probe_type | char | 1 | uint32_t size = 0; - struct us_func_inst_plane_t *func; - int par_count = 0; - char *ret_type = NULL; + struct us_func_inst_plane_t *func = NULL; + char type; + uint64_t addr; - par_count = strlen(msg->cur_pos + sizeof(func->func_addr)); - size = sizeof(*func) + par_count + 1 + - sizeof(char) /* sizeof(char) for ret_type */; - func = malloc(size); - if (!parse_int64(msg, &(func->func_addr))) { + size = sizeof(*func); + + if (!parse_int64(msg, &addr)) { LOGE("func addr parsing error\n"); - goto err_ret; + return 0; } - if (!parse_string_no_alloc(msg, func->args) || - !check_us_inst_func_args(func->args)) - { - LOGE("args format parsing error\n"); - goto err_ret; + if (!parse_int8(msg, &type)) { + LOGE("func type parsing error\n"); + return 0; } - //func->args type is char[0] - //and we need put ret_type after func->args - ret_type = func->args + par_count + 1; - if (!parse_int8(msg, (uint8_t *)ret_type) || - !check_us_inst_func_ret_type(*ret_type)) - { - LOGE("return type parsing error\n"); + switch (type) { + case SWAP_RETPROBE: + size += strlen(msg->cur_pos) + 1 + sizeof(char); + break; + case SWAP_FBI_PROBE: + size += sizeof(uint32_t) + /* register number */ + sizeof(uint64_t) + /* register offset */ + sizeof(uint32_t) + /* data size */ + sizeof(uint64_t) + /* var id */ + sizeof(uint32_t); /* pointer order */ + break; + case SWAP_LD_PROBE: + size += sizeof(uint64_t); /* ld preload handler addr */ + break; + default: + LOGE("wrong probe type <%u>\n", type); goto err_ret; - } else { - parse_deb("ret type = <%c>\n", *ret_type); } + func = malloc(size); + if (func == NULL) { + LOGE("no memory\n"); + return 0; + } + + func->probe_type = type; + func->func_addr = addr; + + memcpy(&func->probe_info, msg->cur_pos, size - sizeof(*func)); + msg->cur_pos += size - sizeof(*func); + *dest = new_probe(); if (*dest == NULL) { LOGE("alloc new_probe error\n"); @@ -107,6 +121,7 @@ static int parse_us_inst_func(struct msg_buf_t *msg, struct probe_list_t **dest) (*dest)->size = size; (*dest)->func = func; return 1; + err_ret: free(func); return 0; -- 2.7.4