summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Zaoui <daniel.zaoui@samsung.com>2015-08-13 14:55:36 +0300
committerDaniel Zaoui <daniel.zaoui@samsung.com>2015-08-16 08:18:24 +0300
commitf5d56b1dd73b224935ea53a66acd1fb4ebee0223 (patch)
treef924976d4107c8b6671808400068c2cbafe1ddca
parentc8ff2a71ffc85da2dd7b2c02336cf25a1a3f5273 (diff)
Support parameters retrieval from Eolian function
CLI parses parameters Request sent to application via Eet Dummy response containing values prepared and sent to client CLI prints values
-rw-r--r--src/bin/CMakeLists.txt2
-rw-r--r--src/bin/cli.c128
-rw-r--r--src/lib/CMakeLists.txt4
-rw-r--r--src/lib/debug_eolian.c218
-rw-r--r--src/lib/debug_eolian.h36
-rw-r--r--src/lib/edbg_preload.c2
6 files changed, 372 insertions, 18 deletions
diff --git a/src/bin/CMakeLists.txt b/src/bin/CMakeLists.txt
index b2a0b2e..9d0ce88 100644
--- a/src/bin/CMakeLists.txt
+++ b/src/bin/CMakeLists.txt
@@ -4,7 +4,7 @@ LIST(APPEND SOURCES cli.c)
4 4
5STRING(REGEX REPLACE "\n" "" EOLIAN_EO_DIR ${EOLIAN_EO_DIR}) 5STRING(REGEX REPLACE "\n" "" EOLIAN_EO_DIR ${EOLIAN_EO_DIR})
6STRING(REGEX REPLACE " " "" EOLIAN_EO_DIR ${EOLIAN_EO_DIR}) 6STRING(REGEX REPLACE " " "" EOLIAN_EO_DIR ${EOLIAN_EO_DIR})
7add_definitions(${CLI_COMMON_DEFINITIONS} -DEOLIAN_EO_DIR="${EOLIAN_EO_DIR}") 7add_definitions(${CLI_COMMON_DEFINITIONS} -DEFL_BETA_API_SUPPORT -DEOLIAN_EO_DIR="${EOLIAN_EO_DIR}")
8add_definitions(${CLI_COMMON_DEFINITIONS}) 8add_definitions(${CLI_COMMON_DEFINITIONS})
9 9
10include_directories( 10include_directories(
diff --git a/src/bin/cli.c b/src/bin/cli.c
index 7f2e819..b191321 100644
--- a/src/bin/cli.c
+++ b/src/bin/cli.c
@@ -7,6 +7,7 @@
7 7
8#include "network.h" 8#include "network.h"
9#include "debug_eo.h" 9#include "debug_eo.h"
10#include "debug_eolian.h"
10#include "debug_common.h" 11#include "debug_common.h"
11 12
12#define MAX_EVENTS 5 13#define MAX_EVENTS 5
@@ -108,17 +109,80 @@ _next_command(Lexer *l)
108 return ret; 109 return ret;
109} 110}
110 111
111static char * 112static Eina_Bool
112_function_invoke(const char *func_str, const char *obj_str) 113_params_parse(Lexer *l, Eina_Iterator *pitr, Eina_List **list)
113{ 114{
115 Eolian_Function_Parameter *p;
116 char *word = NULL;
117 EINA_ITERATOR_FOREACH(pitr, p)
118 {
119 if (word && !_next_token(l, ","))
120 {
121 printf("Expected comma between parameters\n");
122 return EINA_FALSE;
123 }
124 word = _next_word(l, NULL);
125 if (word)
126 {
127 const Eolian_Type *type = eolian_parameter_type_get(p);
128 const char *type_str = eolian_type_c_type_get(type);
129 if (!strcmp(type_str, "int"))
130 {
131 *list = eina_list_append(*list, debug_eolian_param_int_new(atoi(word)));
132 }
133 }
134 else
135 {
136 printf("Expected parameter\n");
137 return EINA_FALSE;
138 }
139 }
140 return EINA_TRUE;
141}
142
143static Eina_Bool
144_function_invoke(unsigned long long obj, Lexer *l, Eina_Bool is_get)
145{
146 Eina_Bool ret = EINA_TRUE;
147 char *func_str = _next_word(l, ".");
148 Eolian_Function_Type type = is_get ? EOLIAN_PROP_GET : EOLIAN_PROP_SET;
149 Eina_List *params = NULL;
150 void *param;
151
152 const Eolian_Function *foo = debug_eolian_function_find_by_name(func_str, type);
153 if (!foo) return EINA_FALSE;
154 Eina_Iterator *keys_itr = eolian_property_keys_get(foo, type), *values_itr = eolian_property_values_get(foo, type);
155
156 if (!_next_token(l, "(") ||
157 (_params_parse(l, keys_itr, &params) &&
158 (is_get || _params_parse(l, values_itr, &params)) &&
159 _next_token(l, ")")
160 )
161 )
162 {
163 int size, size2;
164 void *buf, *buf2;
165 debug_eolian_function_invoke_pack(obj, func_str, type, params, &buf, &size);
166 debug_pack("EOLIAN_FOO_REQ", "EOLIAN_FOO_RESP", buf, size, &buf2, &size2);
167 network_send(-1, buf2, size2);
168 free(buf);
169 free(buf2);
170 }
171 else
172 {
173 printf("Bad parameters\n");
174 ret = EINA_FALSE;
175 }
176 eina_iterator_free(keys_itr);
177 eina_iterator_free(values_itr);
178 EINA_LIST_FREE(params, param) debug_eolian_parameter_free(param);
114 /* 179 /*
115 * Packet preparation 180 * Packet preparation
116 * May be parenthesis with parameter
117 * Sending 181 * Sending
118 * Receiving 182 * Receiving
119 * Parsing response 183 * Parsing response
120 */ 184 */
121 return strdup("37"); 185 return ret;
122} 186}
123 187
124static Eina_Bool 188static Eina_Bool
@@ -143,26 +207,24 @@ _char_consume(Lexer *l, char c)
143 debug_pack("LIST_REQ", "LIST_RESP", buf, size, &buf2, &size2); 207 debug_pack("LIST_REQ", "LIST_RESP", buf, size, &buf2, &size2);
144 network_send(-1, buf2, size2); 208 network_send(-1, buf2, size2);
145 free(buf); 209 free(buf);
146 210 free(buf2);
147 break; 211 break;
148 } 212 }
149 case PRINT_COMMAND: 213 case PRINT_COMMAND:
150 { 214 {
151 char *word = _next_word(l, NULL); 215 char *var = _next_word(l, NULL);
152 const char *value = eina_hash_find(vars_hash, word); 216 unsigned long long *var_value = (unsigned long long *) eina_hash_find(vars_hash, var);
153 if (value) 217 if (var_value)
154 { 218 {
155 if (_next_token(l, "->")) 219 if (_next_token(l, "->"))
156 { 220 {
157 char *res = _function_invoke(l->current, value); 221 _function_invoke(*var_value, l, EINA_TRUE);
158 printf("Result = %s\n", res);
159 free(res);
160 } 222 }
161 else 223 else
162 printf("Word: %s Value: %s\n", word, value); 224 printf("Word: %s Value: 0x%llx\n", var, *var_value);
163 } 225 }
164 else 226 else
165 printf("Unknown variable: %s\n", word); 227 printf("Unknown variable: %s\n", var);
166 228
167 break; 229 break;
168 } 230 }
@@ -181,9 +243,16 @@ _char_consume(Lexer *l, char c)
181 if (_next_word(l, NULL)) 243 if (_next_word(l, NULL))
182 printf("Wrong value after %s\n", value); 244 printf("Wrong value after %s\n", value);
183 else 245 else
184 eina_hash_set(vars_hash, variable, eina_stringshare_add(value)); 246 {
247 if (strstr(value, "0x") == value)
248 {
249 unsigned long long *obj = calloc(1, sizeof(*obj));
250 sscanf(value, "0x%llX", obj);
251 eina_hash_set(vars_hash, variable, obj);
252 match = EINA_TRUE;
253 }
254 }
185 free(value); 255 free(value);
186 match = EINA_TRUE;
187 } 256 }
188 /* variable->func = value */ 257 /* variable->func = value */
189 else if (_next_token(l, "->")) 258 else if (_next_token(l, "->"))
@@ -217,6 +286,27 @@ _char_consume(Lexer *l, char c)
217} 286}
218 287
219static Eina_Bool 288static Eina_Bool
289_eolian_foo_resp_handler(const void *buf, int size, void **buf_ret, int *size_ret)
290{
291 unsigned long long ptr;
292 const char *function_name;
293 Eolian_Function_Type function_type;
294 Eina_List *params;
295 Debug_Eolian_Parameter *p;
296 debug_eolian_function_invoke_unpack(buf, size, &ptr, &function_name, &function_type, &params);
297 printf("ptr 0x%llx function %s:", ptr, function_name);
298 EINA_LIST_FREE(params, p)
299 {
300 Eolian_Expression_Type ptype = debug_eolian_param_type_get(p);
301 if (ptype == EOLIAN_EXPR_INT) printf("%d ", debug_eolian_param_get_as_int(p));
302 }
303 printf("\n");
304 *buf_ret = NULL;
305 *size_ret = 0;
306 return EINA_TRUE;
307}
308
309static Eina_Bool
220_list_resp_handler(const void *buf, int size, void **buf_ret, int *size_ret) 310_list_resp_handler(const void *buf, int size, void **buf_ret, int *size_ret)
221{ 311{
222 Obj_Info *info; 312 Obj_Info *info;
@@ -264,8 +354,13 @@ main()
264 354
265 debug_common_init(); 355 debug_common_init();
266 debug_eo_init(); 356 debug_eo_init();
357 debug_eolian_init();
267 network_init(NETWORK_CLIENT); 358 network_init(NETWORK_CLIENT);
268 debug_opcode_register("LIST_RESP", _list_resp_handler); 359 debug_opcode_register("LIST_RESP", _list_resp_handler);
360 debug_opcode_register("EOLIAN_FOO_RESP", _eolian_foo_resp_handler);
361
362 eolian_init();
363 eolian_directory_scan(EOLIAN_EO_DIR);
269 364
270 buffer = malloc(MAX_BUF); 365 buffer = malloc(MAX_BUF);
271 pthread_create(&thread, NULL, _thread_start, NULL); 366 pthread_create(&thread, NULL, _thread_start, NULL);
@@ -280,6 +375,9 @@ main()
280 } 375 }
281 376
282 free(buffer); 377 free(buffer);
378
379 eolian_shutdown();
380
283 tcsetattr(STDIN_FILENO, TCSANOW, &oldt); 381 tcsetattr(STDIN_FILENO, TCSANOW, &oldt);
284 382
285 return 0; 383 return 0;
diff --git a/src/lib/CMakeLists.txt b/src/lib/CMakeLists.txt
index ecda0d8..6bd89a4 100644
--- a/src/lib/CMakeLists.txt
+++ b/src/lib/CMakeLists.txt
@@ -1,11 +1,11 @@
1set(CMAKE_BUILD_TYPE Debug) 1set(CMAKE_BUILD_TYPE Debug)
2 2
3LIST(APPEND EDBG_COMMON_SOURCES network.c debug_common.c debug_eo.c) 3LIST(APPEND EDBG_COMMON_SOURCES network.c debug_common.c debug_eo.c debug_eolian.c)
4LIST(APPEND EDBG_PRELOAD_SOURCES edbg_preload.c ${EDBG_COMMON_SOURCES}) 4LIST(APPEND EDBG_PRELOAD_SOURCES edbg_preload.c ${EDBG_COMMON_SOURCES})
5 5
6STRING(REGEX REPLACE "\n" "" EOLIAN_EO_DIR ${EOLIAN_EO_DIR}) 6STRING(REGEX REPLACE "\n" "" EOLIAN_EO_DIR ${EOLIAN_EO_DIR})
7STRING(REGEX REPLACE " " "" EOLIAN_EO_DIR ${EOLIAN_EO_DIR}) 7STRING(REGEX REPLACE " " "" EOLIAN_EO_DIR ${EOLIAN_EO_DIR})
8add_definitions(${EDBG_COMMON_DEFINITIONS} -DEOLIAN_EO_DIR="${EOLIAN_EO_DIR}") 8add_definitions(${EDBG_COMMON_DEFINITIONS} -DEFL_BETA_API_SUPPORT -DEOLIAN_EO_DIR="${EOLIAN_EO_DIR}")
9add_definitions(${EDBG_COMMON_DEFINITIONS}) 9add_definitions(${EDBG_COMMON_DEFINITIONS})
10 10
11include_directories (${CMAKE_SOURCE_DIR}/src/lib) 11include_directories (${CMAKE_SOURCE_DIR}/src/lib)
diff --git a/src/lib/debug_eolian.c b/src/lib/debug_eolian.c
new file mode 100644
index 0000000..3dfa26f
--- /dev/null
+++ b/src/lib/debug_eolian.c
@@ -0,0 +1,218 @@
1#include <Eet.h>
2#include <Eolian.h>
3
4#include "debug_eolian.h"
5#include "debug_common.h"
6
7typedef struct
8{
9 unsigned long long ptr;
10 const char *function_name;
11 Eolian_Function_Type function_type;
12 Eina_List *params;
13} _Function_Request;
14
15static Eet_Data_Descriptor *_foo_req_edd = NULL, *_param_info_edd = NULL;
16static Eet_Data_Descriptor *_union_edd = NULL, *_int_edd = NULL;
17
18#define EDD_BASIC_TYPE_CREATE(type, eet_type) \
19 typedef struct \
20 { \
21 type var_##type; \
22 } _st_##type; \
23 static Eet_Data_Descriptor * \
24 _edd_##type##_create() \
25 { \
26 Eet_Data_Descriptor_Class eddc; \
27 EET_EINA_STREAM_DATA_DESCRIPTOR_CLASS_SET(&eddc, _st_##type); \
28 Eet_Data_Descriptor *d = eet_data_descriptor_stream_new(&eddc); \
29 EET_DATA_DESCRIPTOR_ADD_BASIC (d, _st_##type, #type, var_##type, eet_type); \
30 return d; \
31 }
32
33EDD_BASIC_TYPE_CREATE(int, EET_T_INT);
34
35typedef union
36{
37 _st_int st_int;
38 void *value;
39} un_vals;
40
41typedef struct
42{
43 int type; /* eet type */
44 un_vals value;
45} _Debug_Eolian_Parameter;
46
47Eolian_Expression_Type
48debug_eolian_param_type_get(const Debug_Eolian_Parameter *p)
49{
50 _Debug_Eolian_Parameter *_p = (_Debug_Eolian_Parameter *)p;
51 return _p->type;
52}
53
54int
55debug_eolian_param_get_as_int(const Debug_Eolian_Parameter *p)
56{
57 _Debug_Eolian_Parameter *_p = (_Debug_Eolian_Parameter *)p;
58 return _p->value.st_int.var_int;
59}
60
61Debug_Eolian_Parameter *
62debug_eolian_param_int_new(int value)
63{
64 _Debug_Eolian_Parameter *p = calloc(1, sizeof(*p));
65 p->type = EOLIAN_EXPR_INT;
66 p->value.st_int.var_int = value;
67 return (Debug_Eolian_Parameter *)p;
68}
69
70void
71debug_eolian_parameter_free(Debug_Eolian_Parameter *p)
72{
73 _Debug_Eolian_Parameter *_p = (_Debug_Eolian_Parameter *)p;
74// free(param->value_buf);
75 free(_p);
76}
77
78const Eolian_Function *
79debug_eolian_function_find_by_name(const char *full_name, Eolian_Function_Type ftype)
80{
81 const Eolian_Function *func = NULL;
82 char *func_klname = strdup(full_name);
83 char *func_name = strrchr(func_klname, '.');
84 if (func_name)
85 {
86 const Eolian_Class *func_kl = NULL;
87 *func_name = '\0';
88 func_name++;
89 func_kl = eolian_class_get_by_name(func_klname);
90 if (!func_kl)
91 {
92 Eina_Strbuf *buf = eina_strbuf_new();
93 eina_strbuf_append(buf, func_klname);
94 eina_strbuf_replace_all(buf, ".", "_");
95 eina_strbuf_append(buf, ".eo");
96 char *tmp = eina_strbuf_string_steal(buf);
97 eina_strbuf_free(buf);
98 eina_str_tolower(&tmp);
99 eolian_file_parse(tmp);
100 func_kl = eolian_class_get_by_name(func_klname);
101 if (!func_kl) printf("Class %s not found.\n", func_klname);
102 free(tmp);
103 }
104 func = eolian_class_function_get_by_name(func_kl, func_name, ftype);
105 }
106 free(func_klname);
107 return func;
108}
109
110static Eina_Bool
111_eolian_req_handle(const void *buf, int size, void **buf_ret, int *size_ret)
112{
113 _Function_Request *req = eet_data_descriptor_decode(_foo_req_edd, buf, size);
114 printf("EOLIAN_REQ %s\n", req->function_name);
115 const Eolian_Function *foo = debug_eolian_function_find_by_name(req->function_name, req->function_type);
116 if (foo)
117 {
118 Eina_List *list = NULL;
119 printf("dlsym %s\n", eolian_function_full_c_name_get(foo, req->function_type, EINA_FALSE));
120 list = eina_list_append(list, debug_eolian_param_int_new(300));
121 list = eina_list_append(list, debug_eolian_param_int_new(400));
122 req->params = list;
123 *buf_ret = eet_data_descriptor_encode(_foo_req_edd, req, size_ret);
124 }
125 return EINA_TRUE;
126}
127
128static const char *
129_union_type_get(const void *data, Eina_Bool *unknow)
130{
131 int type = *(int *) data;
132 if (unknow) *unknow = EINA_FALSE;
133 switch (type)
134 {
135 case EOLIAN_EXPR_INT: return "int";
136 default: break;
137 }
138 if (unknow) *unknow = EINA_TRUE;
139 return NULL;
140}
141
142static Eina_Bool
143_union_type_set(const char *type, void *data, Eina_Bool unknow)
144{
145 int itype = EOLIAN_EXPR_UNKNOWN;
146 if (unknow) return EINA_FALSE;
147 if (!strcmp(type, "int")) itype = EOLIAN_EXPR_INT;
148 if (itype)
149 {
150 *((int *)data) = itype;
151 return EINA_TRUE;
152 }
153 return EINA_FALSE;
154}
155
156#define EDDC_INIT(type, edd) \
157 Eet_Data_Descriptor_Class edd##c; \
158 EET_EINA_STREAM_DATA_DESCRIPTOR_CLASS_SET(&edd##c, type); \
159 edd = eet_data_descriptor_stream_new(&edd##c);
160
161void
162debug_eolian_init()
163{
164 eet_init();
165 EDDC_INIT(_Function_Request, _param_info_edd);
166 EDDC_INIT(_Function_Request, _foo_req_edd);
167
168 Eet_Data_Descriptor_Class un_eddc;
169 EET_EINA_STREAM_DATA_DESCRIPTOR_CLASS_SET(&un_eddc, un_vals);
170 un_eddc.version = EET_DATA_DESCRIPTOR_CLASS_VERSION;
171 un_eddc.func.type_get = _union_type_get;
172 un_eddc.func.type_set = _union_type_set;
173
174 _union_edd = eet_data_descriptor_stream_new(&un_eddc);
175 _int_edd = _edd_int_create();
176 EET_DATA_DESCRIPTOR_ADD_MAPPING(_union_edd, "int",_int_edd);
177
178 EET_DATA_DESCRIPTOR_ADD_BASIC(_param_info_edd, _Debug_Eolian_Parameter, "type", type, EET_T_INT);
179 EET_DATA_DESCRIPTOR_ADD_UNION(_param_info_edd, _Debug_Eolian_Parameter, "value", value, type, _union_edd);
180
181 EET_DATA_DESCRIPTOR_ADD_BASIC(_foo_req_edd, _Function_Request, "ptr", ptr, EET_T_ULONG_LONG);
182 EET_DATA_DESCRIPTOR_ADD_BASIC(_foo_req_edd, _Function_Request, "function_name", function_name, EET_T_STRING);
183 EET_DATA_DESCRIPTOR_ADD_BASIC(_foo_req_edd, _Function_Request, "function_type", function_type, EET_T_INT);
184 EET_DATA_DESCRIPTOR_ADD_LIST(_foo_req_edd, _Function_Request, "params", params, _param_info_edd);
185
186 eolian_init();
187 eolian_directory_scan(EOLIAN_EO_DIR);
188
189 debug_opcode_register("EOLIAN_FOO_REQ", _eolian_req_handle);
190}
191
192Eina_Bool
193debug_eolian_function_invoke_pack(unsigned long long obj,
194 const char *func_name, Eolian_Function_Type func_type, Eina_List *params,
195 void **buf_ret, int *size_ret)
196{
197 _Function_Request r;
198 r.ptr = obj;
199 r.function_name = func_name;
200 r.function_type = func_type;
201 r.params = params;
202 *buf_ret = eet_data_descriptor_encode(_foo_req_edd, &r, size_ret);
203 return EINA_TRUE;
204}
205
206Eina_Bool
207debug_eolian_function_invoke_unpack(const void *buf, int size,
208 unsigned long long *obj, const char **func_name, Eolian_Function_Type *func_type,
209 Eina_List **params)
210{
211 _Function_Request *req = eet_data_descriptor_decode(_foo_req_edd, buf, size);
212 if (obj) *obj = req->ptr;
213 if (func_name) *func_name = req->function_name;
214 if (func_type) *func_type = req->function_type;
215 if (params) *params = req->params;
216 return EINA_TRUE;
217}
218
diff --git a/src/lib/debug_eolian.h b/src/lib/debug_eolian.h
new file mode 100644
index 0000000..b0a5a45
--- /dev/null
+++ b/src/lib/debug_eolian.h
@@ -0,0 +1,36 @@
1#ifndef __DEBUG_EOLIAN_H
2#define __DEBUG_EOLIAN_H
3
4#include <Eina.h>
5#include <Eolian.h>
6
7typedef struct _Debug_Eolian_Parameter Debug_Eolian_Parameter;
8
9void debug_eolian_init();
10
11const Eolian_Function *
12debug_eolian_function_find_by_name(const char *full_name, Eolian_Function_Type ftype);
13
14Eina_Bool debug_eolian_function_invoke_pack(unsigned long long obj,
15 const char *func_name, Eolian_Function_Type func_type, Eina_List *params,
16 void **buf_ret, int *size_ret);
17
18Eina_Bool
19debug_eolian_function_invoke_unpack(const void *buf, int size,
20 unsigned long long *obj, const char **func_name, Eolian_Function_Type *func_type,
21 Eina_List **params);
22
23Eolian_Expression_Type
24debug_eolian_param_type_get(const Debug_Eolian_Parameter *p);
25
26int
27debug_eolian_param_get_as_int(const Debug_Eolian_Parameter *p);
28
29Debug_Eolian_Parameter *
30debug_eolian_param_int_new(int value);
31
32void
33debug_eolian_parameter_free(Debug_Eolian_Parameter *param);
34
35#endif
36
diff --git a/src/lib/edbg_preload.c b/src/lib/edbg_preload.c
index 7fa205b..d55021a 100644
--- a/src/lib/edbg_preload.c
+++ b/src/lib/edbg_preload.c
@@ -9,6 +9,7 @@
9 9
10#include "network.h" 10#include "network.h"
11#include "debug_eo.h" 11#include "debug_eo.h"
12#include "debug_eolian.h"
12#include "debug_common.h" 13#include "debug_common.h"
13 14
14#define MAX_BUF 1000000 15#define MAX_BUF 1000000
@@ -51,6 +52,7 @@ eo_init(void)
51 { 52 {
52 debug_common_init(); 53 debug_common_init();
53 debug_eo_init(); 54 debug_eo_init();
55 debug_eolian_init();
54 buffer = malloc(MAX_BUF); 56 buffer = malloc(MAX_BUF);
55 pthread_create(&thread, NULL, _thread_start, NULL); 57 pthread_create(&thread, NULL, _thread_start, NULL);
56 } 58 }