summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Aksenov <a.aksenov@samsung.com>2014-03-26 16:44:19 +0400
committerAlexander Aksenov <a.aksenov@samsung.com>2014-11-13 03:21:17 -0800
commit7a76b43942410512a7f0d767121ae7433ca9bccd (patch)
treea5dcb9edd1c1eb1a6fc97cff90e3217858bfce4a
parentaa0677154d76c386df595ab9f22e9700bf5fc880 (diff)
downloadswap-manager-7a76b43942410512a7f0d767121ae7433ca9bccd.tar.gz
swap-manager-7a76b43942410512a7f0d767121ae7433ca9bccd.tar.bz2
swap-manager-7a76b43942410512a7f0d767121ae7433ca9bccd.zip
[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 <a.aksenov@samsung.com>
-rw-r--r--daemon/da_inst.c21
-rw-r--r--daemon/da_protocol.h14
-rw-r--r--daemon/da_protocol_inst.c65
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;