aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSteven Rostedt <srostedt@redhat.com>2009-11-24 15:14:38 -0500
committerSteven Rostedt <rostedt@goodmis.org>2009-11-24 15:14:38 -0500
commit1cdbae6035ce824c312d408336537fbb818a492d (patch)
treefb22045e76c32bc6ebd7a8afc12bb029055eefae
parent68779adbf6b1d04b3515e6b6740c5d0240d20f84 (diff)
Implement typecasting in parser
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
-rw-r--r--parse-events.c116
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
1337static char *arg_eval (struct print_arg *arg); 1337static char *arg_eval (struct print_arg *arg);
1338 1338
1339static unsigned long long
1340eval_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 */
1429static unsigned long long
1430eval_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
1339static long long arg_num_eval(struct print_arg *arg) 1438static 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: