diff options
author | Steven Rostedt <srostedt@redhat.com> | 2009-11-24 15:14:38 -0500 |
---|---|---|
committer | Steven Rostedt <rostedt@goodmis.org> | 2009-11-24 15:14:38 -0500 |
commit | 1cdbae6035ce824c312d408336537fbb818a492d (patch) | |
tree | fb22045e76c32bc6ebd7a8afc12bb029055eefae | |
parent | 68779adbf6b1d04b3515e6b6740c5d0240d20f84 (diff) |
Implement typecasting in parser
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
-rw-r--r-- | parse-events.c | 116 |
1 files changed, 110 insertions, 6 deletions
diff --git a/parse-events.c b/parse-events.c index f4ee0c1..964b7c1 100644 --- a/parse-events.c +++ b/parse-events.c | |||
@@ -1336,6 +1336,105 @@ fail: | |||
1336 | 1336 | ||
1337 | static char *arg_eval (struct print_arg *arg); | 1337 | static char *arg_eval (struct print_arg *arg); |
1338 | 1338 | ||
1339 | static unsigned long long | ||
1340 | eval_type_str(unsigned long long val, const char *type, int pointer) | ||
1341 | { | ||
1342 | int sign = 0; | ||
1343 | char *ref; | ||
1344 | int len; | ||
1345 | |||
1346 | len = strlen(type); | ||
1347 | |||
1348 | if (pointer) { | ||
1349 | |||
1350 | if (type[len-1] != '*') { | ||
1351 | warning("pointer expected with non pointer type"); | ||
1352 | return val; | ||
1353 | } | ||
1354 | |||
1355 | ref = malloc_or_die(len); | ||
1356 | memcpy(ref, type, len); | ||
1357 | |||
1358 | /* chop off the " *" */ | ||
1359 | ref[len - 2] = 0; | ||
1360 | |||
1361 | val = eval_type_str(val, ref, 0); | ||
1362 | free(ref); | ||
1363 | return val; | ||
1364 | } | ||
1365 | |||
1366 | /* check if this is a pointer */ | ||
1367 | if (type[len - 1] == '*') | ||
1368 | return val; | ||
1369 | |||
1370 | /* Try to figure out the arg size*/ | ||
1371 | if (strncmp(type, "struct", 6) == 0) | ||
1372 | /* all bets off */ | ||
1373 | return val; | ||
1374 | |||
1375 | if (strcmp(type, "u8") == 0) | ||
1376 | return val & 0xff; | ||
1377 | |||
1378 | if (strcmp(type, "u16") == 0) | ||
1379 | return val & 0xffff; | ||
1380 | |||
1381 | if (strcmp(type, "u32") == 0) | ||
1382 | return val & 0xffffffff; | ||
1383 | |||
1384 | if (strcmp(type, "u64") == 0 || | ||
1385 | strcmp(type, "s64")) | ||
1386 | return val; | ||
1387 | |||
1388 | if (strcmp(type, "s8") == 0) | ||
1389 | return (unsigned long long)(char)val & 0xff; | ||
1390 | |||
1391 | if (strcmp(type, "s16") == 0) | ||
1392 | return (unsigned long long)(short)val & 0xffff; | ||
1393 | |||
1394 | if (strcmp(type, "s32") == 0) | ||
1395 | return (unsigned long long)(int)val & 0xffffffff; | ||
1396 | |||
1397 | if (strncmp(type, "unsigned ", 9) == 0) { | ||
1398 | sign = 0; | ||
1399 | type += 9; | ||
1400 | } | ||
1401 | |||
1402 | if (strcmp(type, "char") == 0) { | ||
1403 | if (sign) | ||
1404 | return (unsigned long long)(char)val & 0xff; | ||
1405 | else | ||
1406 | return val & 0xff; | ||
1407 | } | ||
1408 | |||
1409 | if (strcmp(type, "short") == 0) { | ||
1410 | if (sign) | ||
1411 | return (unsigned long long)(short)val & 0xffff; | ||
1412 | else | ||
1413 | return val & 0xffff; | ||
1414 | } | ||
1415 | |||
1416 | if (strcmp(type, "int") == 0) { | ||
1417 | if (sign) | ||
1418 | return (unsigned long long)(int)val & 0xffffffff; | ||
1419 | else | ||
1420 | return val & 0xffffffff; | ||
1421 | } | ||
1422 | |||
1423 | return val; | ||
1424 | } | ||
1425 | |||
1426 | /* | ||
1427 | * Try to figure out the type. | ||
1428 | */ | ||
1429 | static unsigned long long | ||
1430 | eval_type(unsigned long long val, struct print_arg *arg, int pointer) | ||
1431 | { | ||
1432 | if (arg->type != PRINT_TYPE) | ||
1433 | die("expected type argument"); | ||
1434 | |||
1435 | return eval_type_str(val, arg->typecast.type, pointer); | ||
1436 | } | ||
1437 | |||
1339 | static long long arg_num_eval(struct print_arg *arg) | 1438 | static long long arg_num_eval(struct print_arg *arg) |
1340 | { | 1439 | { |
1341 | long long left, right; | 1440 | long long left, right; |
@@ -1347,6 +1446,7 @@ static long long arg_num_eval(struct print_arg *arg) | |||
1347 | break; | 1446 | break; |
1348 | case PRINT_TYPE: | 1447 | case PRINT_TYPE: |
1349 | val = arg_num_eval(arg->typecast.item); | 1448 | val = arg_num_eval(arg->typecast.item); |
1449 | val = eval_type(val, arg, 0); | ||
1350 | break; | 1450 | break; |
1351 | case PRINT_OP: | 1451 | case PRINT_OP: |
1352 | switch (arg->op.op[0]) { | 1452 | switch (arg->op.op[0]) { |
@@ -2075,9 +2175,9 @@ static unsigned long long eval_num_arg(void *data, int size, | |||
2075 | { | 2175 | { |
2076 | unsigned long long val = 0; | 2176 | unsigned long long val = 0; |
2077 | unsigned long long left, right; | 2177 | unsigned long long left, right; |
2178 | struct print_arg *typearg = NULL; | ||
2078 | struct print_arg *larg; | 2179 | struct print_arg *larg; |
2079 | unsigned long offset; | 2180 | unsigned long offset; |
2080 | int len; | ||
2081 | 2181 | ||
2082 | switch (arg->type) { | 2182 | switch (arg->type) { |
2083 | case PRINT_NULL: | 2183 | case PRINT_NULL: |
@@ -2099,7 +2199,8 @@ static unsigned long long eval_num_arg(void *data, int size, | |||
2099 | case PRINT_SYMBOL: | 2199 | case PRINT_SYMBOL: |
2100 | break; | 2200 | break; |
2101 | case PRINT_TYPE: | 2201 | case PRINT_TYPE: |
2102 | return eval_num_arg(data, size, event, arg->typecast.item); | 2202 | val = eval_num_arg(data, size, event, arg->typecast.item); |
2203 | return eval_type(val, arg, 0); | ||
2103 | case PRINT_STRING: | 2204 | case PRINT_STRING: |
2104 | return 0; | 2205 | return 0; |
2105 | break; | 2206 | break; |
@@ -2113,8 +2214,11 @@ static unsigned long long eval_num_arg(void *data, int size, | |||
2113 | 2214 | ||
2114 | /* handle typecasts */ | 2215 | /* handle typecasts */ |
2115 | larg = arg->op.left; | 2216 | larg = arg->op.left; |
2116 | while (larg->type == PRINT_TYPE) | 2217 | while (larg->type == PRINT_TYPE) { |
2218 | if (!typearg) | ||
2219 | typearg = larg; | ||
2117 | larg = larg->typecast.item; | 2220 | larg = larg->typecast.item; |
2221 | } | ||
2118 | 2222 | ||
2119 | switch (larg->type) { | 2223 | switch (larg->type) { |
2120 | case PRINT_DYNAMIC_ARRAY: | 2224 | case PRINT_DYNAMIC_ARRAY: |
@@ -2127,7 +2231,6 @@ static unsigned long long eval_num_arg(void *data, int size, | |||
2127 | */ | 2231 | */ |
2128 | offset &= 0xffff; | 2232 | offset &= 0xffff; |
2129 | offset += right; | 2233 | offset += right; |
2130 | len = 1; | ||
2131 | break; | 2234 | break; |
2132 | case PRINT_FIELD: | 2235 | case PRINT_FIELD: |
2133 | if (!larg->field.field) { | 2236 | if (!larg->field.field) { |
@@ -2138,12 +2241,13 @@ static unsigned long long eval_num_arg(void *data, int size, | |||
2138 | } | 2241 | } |
2139 | offset = larg->field.field->offset + | 2242 | offset = larg->field.field->offset + |
2140 | right * long_size; | 2243 | right * long_size; |
2141 | len = long_size; | ||
2142 | break; | 2244 | break; |
2143 | default: | 2245 | default: |
2144 | goto default_op; /* oops, all bets off */ | 2246 | goto default_op; /* oops, all bets off */ |
2145 | } | 2247 | } |
2146 | val = read_size(data + offset, len); | 2248 | val = read_size(data + offset, long_size); |
2249 | if (typearg) | ||
2250 | val = eval_type(val, typearg, 1); | ||
2147 | break; | 2251 | break; |
2148 | } | 2252 | } |
2149 | default_op: | 2253 | default_op: |