aboutsummaryrefslogtreecommitdiffstats
path: root/tools/lib/traceevent/event-parse.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/lib/traceevent/event-parse.c')
-rw-r--r--tools/lib/traceevent/event-parse.c399
1 files changed, 295 insertions, 104 deletions
diff --git a/tools/lib/traceevent/event-parse.c b/tools/lib/traceevent/event-parse.c
index 554828219c33..5f34aa371b56 100644
--- a/tools/lib/traceevent/event-parse.c
+++ b/tools/lib/traceevent/event-parse.c
@@ -467,8 +467,10 @@ int pevent_register_function(struct pevent *pevent, char *func,
467 item->mod = NULL; 467 item->mod = NULL;
468 item->addr = addr; 468 item->addr = addr;
469 469
470 pevent->funclist = item; 470 if (!item->func || (mod && !item->mod))
471 die("malloc func");
471 472
473 pevent->funclist = item;
472 pevent->func_count++; 474 pevent->func_count++;
473 475
474 return 0; 476 return 0;
@@ -511,12 +513,12 @@ struct printk_list {
511 513
512static int printk_cmp(const void *a, const void *b) 514static int printk_cmp(const void *a, const void *b)
513{ 515{
514 const struct func_map *fa = a; 516 const struct printk_map *pa = a;
515 const struct func_map *fb = b; 517 const struct printk_map *pb = b;
516 518
517 if (fa->addr < fb->addr) 519 if (pa->addr < pb->addr)
518 return -1; 520 return -1;
519 if (fa->addr > fb->addr) 521 if (pa->addr > pb->addr)
520 return 1; 522 return 1;
521 523
522 return 0; 524 return 0;
@@ -583,10 +585,13 @@ int pevent_register_print_string(struct pevent *pevent, char *fmt,
583 item = malloc_or_die(sizeof(*item)); 585 item = malloc_or_die(sizeof(*item));
584 586
585 item->next = pevent->printklist; 587 item->next = pevent->printklist;
586 pevent->printklist = item;
587 item->printk = strdup(fmt); 588 item->printk = strdup(fmt);
588 item->addr = addr; 589 item->addr = addr;
589 590
591 if (!item->printk)
592 die("malloc fmt");
593
594 pevent->printklist = item;
590 pevent->printk_count++; 595 pevent->printk_count++;
591 596
592 return 0; 597 return 0;
@@ -616,7 +621,9 @@ static struct event_format *alloc_event(void)
616{ 621{
617 struct event_format *event; 622 struct event_format *event;
618 623
619 event = malloc_or_die(sizeof(*event)); 624 event = malloc(sizeof(*event));
625 if (!event)
626 return NULL;
620 memset(event, 0, sizeof(*event)); 627 memset(event, 0, sizeof(*event));
621 628
622 return event; 629 return event;
@@ -626,12 +633,8 @@ static void add_event(struct pevent *pevent, struct event_format *event)
626{ 633{
627 int i; 634 int i;
628 635
629 if (!pevent->events) 636 pevent->events = realloc(pevent->events, sizeof(event) *
630 pevent->events = malloc_or_die(sizeof(event)); 637 (pevent->nr_events + 1));
631 else
632 pevent->events =
633 realloc(pevent->events, sizeof(event) *
634 (pevent->nr_events + 1));
635 if (!pevent->events) 638 if (!pevent->events)
636 die("Can not allocate events"); 639 die("Can not allocate events");
637 640
@@ -697,6 +700,10 @@ static void free_arg(struct print_arg *arg)
697 free_arg(arg->symbol.field); 700 free_arg(arg->symbol.field);
698 free_flag_sym(arg->symbol.symbols); 701 free_flag_sym(arg->symbol.symbols);
699 break; 702 break;
703 case PRINT_HEX:
704 free_arg(arg->hex.field);
705 free_arg(arg->hex.size);
706 break;
700 case PRINT_TYPE: 707 case PRINT_TYPE:
701 free(arg->typecast.type); 708 free(arg->typecast.type);
702 free_arg(arg->typecast.item); 709 free_arg(arg->typecast.item);
@@ -775,6 +782,25 @@ int pevent_peek_char(void)
775 return __peek_char(); 782 return __peek_char();
776} 783}
777 784
785static int extend_token(char **tok, char *buf, int size)
786{
787 char *newtok = realloc(*tok, size);
788
789 if (!newtok) {
790 free(*tok);
791 *tok = NULL;
792 return -1;
793 }
794
795 if (!*tok)
796 strcpy(newtok, buf);
797 else
798 strcat(newtok, buf);
799 *tok = newtok;
800
801 return 0;
802}
803
778static enum event_type force_token(const char *str, char **tok); 804static enum event_type force_token(const char *str, char **tok);
779 805
780static enum event_type __read_token(char **tok) 806static enum event_type __read_token(char **tok)
@@ -859,17 +885,10 @@ static enum event_type __read_token(char **tok)
859 do { 885 do {
860 if (i == (BUFSIZ - 1)) { 886 if (i == (BUFSIZ - 1)) {
861 buf[i] = 0; 887 buf[i] = 0;
862 if (*tok) { 888 tok_size += BUFSIZ;
863 *tok = realloc(*tok, tok_size + BUFSIZ);
864 if (!*tok)
865 return EVENT_NONE;
866 strcat(*tok, buf);
867 } else
868 *tok = strdup(buf);
869 889
870 if (!*tok) 890 if (extend_token(tok, buf, tok_size) < 0)
871 return EVENT_NONE; 891 return EVENT_NONE;
872 tok_size += BUFSIZ;
873 i = 0; 892 i = 0;
874 } 893 }
875 last_ch = ch; 894 last_ch = ch;
@@ -908,17 +927,10 @@ static enum event_type __read_token(char **tok)
908 while (get_type(__peek_char()) == type) { 927 while (get_type(__peek_char()) == type) {
909 if (i == (BUFSIZ - 1)) { 928 if (i == (BUFSIZ - 1)) {
910 buf[i] = 0; 929 buf[i] = 0;
911 if (*tok) { 930 tok_size += BUFSIZ;
912 *tok = realloc(*tok, tok_size + BUFSIZ);
913 if (!*tok)
914 return EVENT_NONE;
915 strcat(*tok, buf);
916 } else
917 *tok = strdup(buf);
918 931
919 if (!*tok) 932 if (extend_token(tok, buf, tok_size) < 0)
920 return EVENT_NONE; 933 return EVENT_NONE;
921 tok_size += BUFSIZ;
922 i = 0; 934 i = 0;
923 } 935 }
924 ch = __read_char(); 936 ch = __read_char();
@@ -927,14 +939,7 @@ static enum event_type __read_token(char **tok)
927 939
928 out: 940 out:
929 buf[i] = 0; 941 buf[i] = 0;
930 if (*tok) { 942 if (extend_token(tok, buf, tok_size + i + 1) < 0)
931 *tok = realloc(*tok, tok_size + i);
932 if (!*tok)
933 return EVENT_NONE;
934 strcat(*tok, buf);
935 } else
936 *tok = strdup(buf);
937 if (!*tok)
938 return EVENT_NONE; 943 return EVENT_NONE;
939 944
940 if (type == EVENT_ITEM) { 945 if (type == EVENT_ITEM) {
@@ -1255,9 +1260,15 @@ static int event_read_fields(struct event_format *event, struct format_field **f
1255 field->flags |= FIELD_IS_POINTER; 1260 field->flags |= FIELD_IS_POINTER;
1256 1261
1257 if (field->type) { 1262 if (field->type) {
1258 field->type = realloc(field->type, 1263 char *new_type;
1259 strlen(field->type) + 1264 new_type = realloc(field->type,
1260 strlen(last_token) + 2); 1265 strlen(field->type) +
1266 strlen(last_token) + 2);
1267 if (!new_type) {
1268 free(last_token);
1269 goto fail;
1270 }
1271 field->type = new_type;
1261 strcat(field->type, " "); 1272 strcat(field->type, " ");
1262 strcat(field->type, last_token); 1273 strcat(field->type, last_token);
1263 free(last_token); 1274 free(last_token);
@@ -1282,6 +1293,7 @@ static int event_read_fields(struct event_format *event, struct format_field **f
1282 if (strcmp(token, "[") == 0) { 1293 if (strcmp(token, "[") == 0) {
1283 enum event_type last_type = type; 1294 enum event_type last_type = type;
1284 char *brackets = token; 1295 char *brackets = token;
1296 char *new_brackets;
1285 int len; 1297 int len;
1286 1298
1287 field->flags |= FIELD_IS_ARRAY; 1299 field->flags |= FIELD_IS_ARRAY;
@@ -1301,9 +1313,14 @@ static int event_read_fields(struct event_format *event, struct format_field **f
1301 len = 1; 1313 len = 1;
1302 last_type = type; 1314 last_type = type;
1303 1315
1304 brackets = realloc(brackets, 1316 new_brackets = realloc(brackets,
1305 strlen(brackets) + 1317 strlen(brackets) +
1306 strlen(token) + len); 1318 strlen(token) + len);
1319 if (!new_brackets) {
1320 free(brackets);
1321 goto fail;
1322 }
1323 brackets = new_brackets;
1307 if (len == 2) 1324 if (len == 2)
1308 strcat(brackets, " "); 1325 strcat(brackets, " ");
1309 strcat(brackets, token); 1326 strcat(brackets, token);
@@ -1319,7 +1336,12 @@ static int event_read_fields(struct event_format *event, struct format_field **f
1319 1336
1320 free_token(token); 1337 free_token(token);
1321 1338
1322 brackets = realloc(brackets, strlen(brackets) + 2); 1339 new_brackets = realloc(brackets, strlen(brackets) + 2);
1340 if (!new_brackets) {
1341 free(brackets);
1342 goto fail;
1343 }
1344 brackets = new_brackets;
1323 strcat(brackets, "]"); 1345 strcat(brackets, "]");
1324 1346
1325 /* add brackets to type */ 1347 /* add brackets to type */
@@ -1330,10 +1352,16 @@ static int event_read_fields(struct event_format *event, struct format_field **f
1330 * the format: type [] item; 1352 * the format: type [] item;
1331 */ 1353 */
1332 if (type == EVENT_ITEM) { 1354 if (type == EVENT_ITEM) {
1333 field->type = realloc(field->type, 1355 char *new_type;
1334 strlen(field->type) + 1356 new_type = realloc(field->type,
1335 strlen(field->name) + 1357 strlen(field->type) +
1336 strlen(brackets) + 2); 1358 strlen(field->name) +
1359 strlen(brackets) + 2);
1360 if (!new_type) {
1361 free(brackets);
1362 goto fail;
1363 }
1364 field->type = new_type;
1337 strcat(field->type, " "); 1365 strcat(field->type, " ");
1338 strcat(field->type, field->name); 1366 strcat(field->type, field->name);
1339 free_token(field->name); 1367 free_token(field->name);
@@ -1341,9 +1369,15 @@ static int event_read_fields(struct event_format *event, struct format_field **f
1341 field->name = token; 1369 field->name = token;
1342 type = read_token(&token); 1370 type = read_token(&token);
1343 } else { 1371 } else {
1344 field->type = realloc(field->type, 1372 char *new_type;
1345 strlen(field->type) + 1373 new_type = realloc(field->type,
1346 strlen(brackets) + 1); 1374 strlen(field->type) +
1375 strlen(brackets) + 1);
1376 if (!new_type) {
1377 free(brackets);
1378 goto fail;
1379 }
1380 field->type = new_type;
1347 strcat(field->type, brackets); 1381 strcat(field->type, brackets);
1348 } 1382 }
1349 free(brackets); 1383 free(brackets);
@@ -1726,10 +1760,16 @@ process_op(struct event_format *event, struct print_arg *arg, char **tok)
1726 /* could just be a type pointer */ 1760 /* could just be a type pointer */
1727 if ((strcmp(arg->op.op, "*") == 0) && 1761 if ((strcmp(arg->op.op, "*") == 0) &&
1728 type == EVENT_DELIM && (strcmp(token, ")") == 0)) { 1762 type == EVENT_DELIM && (strcmp(token, ")") == 0)) {
1763 char *new_atom;
1764
1729 if (left->type != PRINT_ATOM) 1765 if (left->type != PRINT_ATOM)
1730 die("bad pointer type"); 1766 die("bad pointer type");
1731 left->atom.atom = realloc(left->atom.atom, 1767 new_atom = realloc(left->atom.atom,
1732 strlen(left->atom.atom) + 3); 1768 strlen(left->atom.atom) + 3);
1769 if (!new_atom)
1770 goto out_free;
1771
1772 left->atom.atom = new_atom;
1733 strcat(left->atom.atom, " *"); 1773 strcat(left->atom.atom, " *");
1734 free(arg->op.op); 1774 free(arg->op.op);
1735 *arg = *left; 1775 *arg = *left;
@@ -2146,6 +2186,8 @@ process_fields(struct event_format *event, struct print_flag_sym **list, char **
2146 if (value == NULL) 2186 if (value == NULL)
2147 goto out_free; 2187 goto out_free;
2148 field->value = strdup(value); 2188 field->value = strdup(value);
2189 if (field->value == NULL)
2190 goto out_free;
2149 2191
2150 free_arg(arg); 2192 free_arg(arg);
2151 arg = alloc_arg(); 2193 arg = alloc_arg();
@@ -2159,6 +2201,8 @@ process_fields(struct event_format *event, struct print_flag_sym **list, char **
2159 if (value == NULL) 2201 if (value == NULL)
2160 goto out_free; 2202 goto out_free;
2161 field->str = strdup(value); 2203 field->str = strdup(value);
2204 if (field->str == NULL)
2205 goto out_free;
2162 free_arg(arg); 2206 free_arg(arg);
2163 arg = NULL; 2207 arg = NULL;
2164 2208
@@ -2260,6 +2304,45 @@ process_symbols(struct event_format *event, struct print_arg *arg, char **tok)
2260} 2304}
2261 2305
2262static enum event_type 2306static enum event_type
2307process_hex(struct event_format *event, struct print_arg *arg, char **tok)
2308{
2309 struct print_arg *field;
2310 enum event_type type;
2311 char *token;
2312
2313 memset(arg, 0, sizeof(*arg));
2314 arg->type = PRINT_HEX;
2315
2316 field = alloc_arg();
2317 type = process_arg(event, field, &token);
2318
2319 if (test_type_token(type, token, EVENT_DELIM, ","))
2320 goto out_free;
2321
2322 arg->hex.field = field;
2323
2324 free_token(token);
2325
2326 field = alloc_arg();
2327 type = process_arg(event, field, &token);
2328
2329 if (test_type_token(type, token, EVENT_DELIM, ")"))
2330 goto out_free;
2331
2332 arg->hex.size = field;
2333
2334 free_token(token);
2335 type = read_token_item(tok);
2336 return type;
2337
2338 out_free:
2339 free_arg(field);
2340 free_token(token);
2341 *tok = NULL;
2342 return EVENT_ERROR;
2343}
2344
2345static enum event_type
2263process_dynamic_array(struct event_format *event, struct print_arg *arg, char **tok) 2346process_dynamic_array(struct event_format *event, struct print_arg *arg, char **tok)
2264{ 2347{
2265 struct format_field *field; 2348 struct format_field *field;
@@ -2488,6 +2571,10 @@ process_function(struct event_format *event, struct print_arg *arg,
2488 is_symbolic_field = 1; 2571 is_symbolic_field = 1;
2489 return process_symbols(event, arg, tok); 2572 return process_symbols(event, arg, tok);
2490 } 2573 }
2574 if (strcmp(token, "__print_hex") == 0) {
2575 free_token(token);
2576 return process_hex(event, arg, tok);
2577 }
2491 if (strcmp(token, "__get_str") == 0) { 2578 if (strcmp(token, "__get_str") == 0) {
2492 free_token(token); 2579 free_token(token);
2493 return process_str(event, arg, tok); 2580 return process_str(event, arg, tok);
@@ -2541,7 +2628,16 @@ process_arg_token(struct event_format *event, struct print_arg *arg,
2541 } 2628 }
2542 /* atoms can be more than one token long */ 2629 /* atoms can be more than one token long */
2543 while (type == EVENT_ITEM) { 2630 while (type == EVENT_ITEM) {
2544 atom = realloc(atom, strlen(atom) + strlen(token) + 2); 2631 char *new_atom;
2632 new_atom = realloc(atom,
2633 strlen(atom) + strlen(token) + 2);
2634 if (!new_atom) {
2635 free(atom);
2636 *tok = NULL;
2637 free_token(token);
2638 return EVENT_ERROR;
2639 }
2640 atom = new_atom;
2545 strcat(atom, " "); 2641 strcat(atom, " ");
2546 strcat(atom, token); 2642 strcat(atom, token);
2547 free_token(token); 2643 free_token(token);
@@ -2835,7 +2931,7 @@ static int get_common_info(struct pevent *pevent,
2835 event = pevent->events[0]; 2931 event = pevent->events[0];
2836 field = pevent_find_common_field(event, type); 2932 field = pevent_find_common_field(event, type);
2837 if (!field) 2933 if (!field)
2838 die("field '%s' not found", type); 2934 return -1;
2839 2935
2840 *offset = field->offset; 2936 *offset = field->offset;
2841 *size = field->size; 2937 *size = field->size;
@@ -2886,15 +2982,16 @@ static int parse_common_flags(struct pevent *pevent, void *data)
2886 2982
2887static int parse_common_lock_depth(struct pevent *pevent, void *data) 2983static int parse_common_lock_depth(struct pevent *pevent, void *data)
2888{ 2984{
2889 int ret; 2985 return __parse_common(pevent, data,
2890 2986 &pevent->ld_size, &pevent->ld_offset,
2891 ret = __parse_common(pevent, data, 2987 "common_lock_depth");
2892 &pevent->ld_size, &pevent->ld_offset, 2988}
2893 "common_lock_depth");
2894 if (ret < 0)
2895 return -1;
2896 2989
2897 return ret; 2990static int parse_common_migrate_disable(struct pevent *pevent, void *data)
2991{
2992 return __parse_common(pevent, data,
2993 &pevent->ld_size, &pevent->ld_offset,
2994 "common_migrate_disable");
2898} 2995}
2899 2996
2900static int events_id_cmp(const void *a, const void *b); 2997static int events_id_cmp(const void *a, const void *b);
@@ -2995,6 +3092,7 @@ eval_num_arg(void *data, int size, struct event_format *event, struct print_arg
2995 break; 3092 break;
2996 case PRINT_FLAGS: 3093 case PRINT_FLAGS:
2997 case PRINT_SYMBOL: 3094 case PRINT_SYMBOL:
3095 case PRINT_HEX:
2998 break; 3096 break;
2999 case PRINT_TYPE: 3097 case PRINT_TYPE:
3000 val = eval_num_arg(data, size, event, arg->typecast.item); 3098 val = eval_num_arg(data, size, event, arg->typecast.item);
@@ -3214,11 +3312,13 @@ static void print_str_arg(struct trace_seq *s, void *data, int size,
3214{ 3312{
3215 struct pevent *pevent = event->pevent; 3313 struct pevent *pevent = event->pevent;
3216 struct print_flag_sym *flag; 3314 struct print_flag_sym *flag;
3315 struct format_field *field;
3217 unsigned long long val, fval; 3316 unsigned long long val, fval;
3218 unsigned long addr; 3317 unsigned long addr;
3219 char *str; 3318 char *str;
3319 unsigned char *hex;
3220 int print; 3320 int print;
3221 int len; 3321 int i, len;
3222 3322
3223 switch (arg->type) { 3323 switch (arg->type) {
3224 case PRINT_NULL: 3324 case PRINT_NULL:
@@ -3228,27 +3328,29 @@ static void print_str_arg(struct trace_seq *s, void *data, int size,
3228 print_str_to_seq(s, format, len_arg, arg->atom.atom); 3328 print_str_to_seq(s, format, len_arg, arg->atom.atom);
3229 return; 3329 return;
3230 case PRINT_FIELD: 3330 case PRINT_FIELD:
3231 if (!arg->field.field) { 3331 field = arg->field.field;
3232 arg->field.field = pevent_find_any_field(event, arg->field.name); 3332 if (!field) {
3233 if (!arg->field.field) 3333 field = pevent_find_any_field(event, arg->field.name);
3334 if (!field)
3234 die("field %s not found", arg->field.name); 3335 die("field %s not found", arg->field.name);
3336 arg->field.field = field;
3235 } 3337 }
3236 /* Zero sized fields, mean the rest of the data */ 3338 /* Zero sized fields, mean the rest of the data */
3237 len = arg->field.field->size ? : size - arg->field.field->offset; 3339 len = field->size ? : size - field->offset;
3238 3340
3239 /* 3341 /*
3240 * Some events pass in pointers. If this is not an array 3342 * Some events pass in pointers. If this is not an array
3241 * and the size is the same as long_size, assume that it 3343 * and the size is the same as long_size, assume that it
3242 * is a pointer. 3344 * is a pointer.
3243 */ 3345 */
3244 if (!(arg->field.field->flags & FIELD_IS_ARRAY) && 3346 if (!(field->flags & FIELD_IS_ARRAY) &&
3245 arg->field.field->size == pevent->long_size) { 3347 field->size == pevent->long_size) {
3246 addr = *(unsigned long *)(data + arg->field.field->offset); 3348 addr = *(unsigned long *)(data + field->offset);
3247 trace_seq_printf(s, "%lx", addr); 3349 trace_seq_printf(s, "%lx", addr);
3248 break; 3350 break;
3249 } 3351 }
3250 str = malloc_or_die(len + 1); 3352 str = malloc_or_die(len + 1);
3251 memcpy(str, data + arg->field.field->offset, len); 3353 memcpy(str, data + field->offset, len);
3252 str[len] = 0; 3354 str[len] = 0;
3253 print_str_to_seq(s, format, len_arg, str); 3355 print_str_to_seq(s, format, len_arg, str);
3254 free(str); 3356 free(str);
@@ -3281,6 +3383,23 @@ static void print_str_arg(struct trace_seq *s, void *data, int size,
3281 } 3383 }
3282 } 3384 }
3283 break; 3385 break;
3386 case PRINT_HEX:
3387 field = arg->hex.field->field.field;
3388 if (!field) {
3389 str = arg->hex.field->field.name;
3390 field = pevent_find_any_field(event, str);
3391 if (!field)
3392 die("field %s not found", str);
3393 arg->hex.field->field.field = field;
3394 }
3395 hex = data + field->offset;
3396 len = eval_num_arg(data, size, event, arg->hex.size);
3397 for (i = 0; i < len; i++) {
3398 if (i)
3399 trace_seq_putc(s, ' ');
3400 trace_seq_printf(s, "%02x", hex[i]);
3401 }
3402 break;
3284 3403
3285 case PRINT_TYPE: 3404 case PRINT_TYPE:
3286 break; 3405 break;
@@ -3299,7 +3418,7 @@ static void print_str_arg(struct trace_seq *s, void *data, int size,
3299 break; 3418 break;
3300 } 3419 }
3301 case PRINT_BSTRING: 3420 case PRINT_BSTRING:
3302 trace_seq_printf(s, format, arg->string.string); 3421 print_str_to_seq(s, format, len_arg, arg->string.string);
3303 break; 3422 break;
3304 case PRINT_OP: 3423 case PRINT_OP:
3305 /* 3424 /*
@@ -3363,6 +3482,10 @@ process_defined_func(struct trace_seq *s, void *data, int size,
3363 string = malloc_or_die(sizeof(*string)); 3482 string = malloc_or_die(sizeof(*string));
3364 string->next = strings; 3483 string->next = strings;
3365 string->str = strdup(str.buffer); 3484 string->str = strdup(str.buffer);
3485 if (!string->str)
3486 die("malloc str");
3487
3488 args[i] = (unsigned long long)string->str;
3366 strings = string; 3489 strings = string;
3367 trace_seq_destroy(&str); 3490 trace_seq_destroy(&str);
3368 break; 3491 break;
@@ -3400,6 +3523,7 @@ static struct print_arg *make_bprint_args(char *fmt, void *data, int size, struc
3400 unsigned long long ip, val; 3523 unsigned long long ip, val;
3401 char *ptr; 3524 char *ptr;
3402 void *bptr; 3525 void *bptr;
3526 int vsize;
3403 3527
3404 field = pevent->bprint_buf_field; 3528 field = pevent->bprint_buf_field;
3405 ip_field = pevent->bprint_ip_field; 3529 ip_field = pevent->bprint_ip_field;
@@ -3448,6 +3572,8 @@ static struct print_arg *make_bprint_args(char *fmt, void *data, int size, struc
3448 goto process_again; 3572 goto process_again;
3449 case '0' ... '9': 3573 case '0' ... '9':
3450 goto process_again; 3574 goto process_again;
3575 case '.':
3576 goto process_again;
3451 case 'p': 3577 case 'p':
3452 ls = 1; 3578 ls = 1;
3453 /* fall through */ 3579 /* fall through */
@@ -3455,23 +3581,30 @@ static struct print_arg *make_bprint_args(char *fmt, void *data, int size, struc
3455 case 'u': 3581 case 'u':
3456 case 'x': 3582 case 'x':
3457 case 'i': 3583 case 'i':
3458 /* the pointers are always 4 bytes aligned */
3459 bptr = (void *)(((unsigned long)bptr + 3) &
3460 ~3);
3461 switch (ls) { 3584 switch (ls) {
3462 case 0: 3585 case 0:
3463 ls = 4; 3586 vsize = 4;
3464 break; 3587 break;
3465 case 1: 3588 case 1:
3466 ls = pevent->long_size; 3589 vsize = pevent->long_size;
3467 break; 3590 break;
3468 case 2: 3591 case 2:
3469 ls = 8; 3592 vsize = 8;
3593 break;
3470 default: 3594 default:
3595 vsize = ls; /* ? */
3471 break; 3596 break;
3472 } 3597 }
3473 val = pevent_read_number(pevent, bptr, ls); 3598 /* fall through */
3474 bptr += ls; 3599 case '*':
3600 if (*ptr == '*')
3601 vsize = 4;
3602
3603 /* the pointers are always 4 bytes aligned */
3604 bptr = (void *)(((unsigned long)bptr + 3) &
3605 ~3);
3606 val = pevent_read_number(pevent, bptr, vsize);
3607 bptr += vsize;
3475 arg = alloc_arg(); 3608 arg = alloc_arg();
3476 arg->next = NULL; 3609 arg->next = NULL;
3477 arg->type = PRINT_ATOM; 3610 arg->type = PRINT_ATOM;
@@ -3479,12 +3612,21 @@ static struct print_arg *make_bprint_args(char *fmt, void *data, int size, struc
3479 sprintf(arg->atom.atom, "%lld", val); 3612 sprintf(arg->atom.atom, "%lld", val);
3480 *next = arg; 3613 *next = arg;
3481 next = &arg->next; 3614 next = &arg->next;
3615 /*
3616 * The '*' case means that an arg is used as the length.
3617 * We need to continue to figure out for what.
3618 */
3619 if (*ptr == '*')
3620 goto process_again;
3621
3482 break; 3622 break;
3483 case 's': 3623 case 's':
3484 arg = alloc_arg(); 3624 arg = alloc_arg();
3485 arg->next = NULL; 3625 arg->next = NULL;
3486 arg->type = PRINT_BSTRING; 3626 arg->type = PRINT_BSTRING;
3487 arg->string.string = strdup(bptr); 3627 arg->string.string = strdup(bptr);
3628 if (!arg->string.string)
3629 break;
3488 bptr += strlen(bptr) + 1; 3630 bptr += strlen(bptr) + 1;
3489 *next = arg; 3631 *next = arg;
3490 next = &arg->next; 3632 next = &arg->next;
@@ -3589,6 +3731,16 @@ static void print_mac_arg(struct trace_seq *s, int mac, void *data, int size,
3589 trace_seq_printf(s, fmt, buf[0], buf[1], buf[2], buf[3], buf[4], buf[5]); 3731 trace_seq_printf(s, fmt, buf[0], buf[1], buf[2], buf[3], buf[4], buf[5]);
3590} 3732}
3591 3733
3734static int is_printable_array(char *p, unsigned int len)
3735{
3736 unsigned int i;
3737
3738 for (i = 0; i < len && p[i]; i++)
3739 if (!isprint(p[i]))
3740 return 0;
3741 return 1;
3742}
3743
3592static void print_event_fields(struct trace_seq *s, void *data, int size, 3744static void print_event_fields(struct trace_seq *s, void *data, int size,
3593 struct event_format *event) 3745 struct event_format *event)
3594{ 3746{
@@ -3608,7 +3760,8 @@ static void print_event_fields(struct trace_seq *s, void *data, int size,
3608 len = offset >> 16; 3760 len = offset >> 16;
3609 offset &= 0xffff; 3761 offset &= 0xffff;
3610 } 3762 }
3611 if (field->flags & FIELD_IS_STRING) { 3763 if (field->flags & FIELD_IS_STRING &&
3764 is_printable_array(data + offset, len)) {
3612 trace_seq_printf(s, "%s", (char *)data + offset); 3765 trace_seq_printf(s, "%s", (char *)data + offset);
3613 } else { 3766 } else {
3614 trace_seq_puts(s, "ARRAY["); 3767 trace_seq_puts(s, "ARRAY[");
@@ -3619,6 +3772,7 @@ static void print_event_fields(struct trace_seq *s, void *data, int size,
3619 *((unsigned char *)data + offset + i)); 3772 *((unsigned char *)data + offset + i));
3620 } 3773 }
3621 trace_seq_putc(s, ']'); 3774 trace_seq_putc(s, ']');
3775 field->flags &= ~FIELD_IS_STRING;
3622 } 3776 }
3623 } else { 3777 } else {
3624 val = pevent_read_number(event->pevent, data + field->offset, 3778 val = pevent_read_number(event->pevent, data + field->offset,
@@ -3758,6 +3912,7 @@ static void pretty_print(struct trace_seq *s, void *data, int size, struct event
3758 } else if (*(ptr+1) == 'M' || *(ptr+1) == 'm') { 3912 } else if (*(ptr+1) == 'M' || *(ptr+1) == 'm') {
3759 print_mac_arg(s, *(ptr+1), data, size, event, arg); 3913 print_mac_arg(s, *(ptr+1), data, size, event, arg);
3760 ptr++; 3914 ptr++;
3915 arg = arg->next;
3761 break; 3916 break;
3762 } 3917 }
3763 3918
@@ -3794,14 +3949,15 @@ static void pretty_print(struct trace_seq *s, void *data, int size, struct event
3794 break; 3949 break;
3795 } 3950 }
3796 } 3951 }
3797 if (pevent->long_size == 8 && ls) { 3952 if (pevent->long_size == 8 && ls &&
3953 sizeof(long) != 8) {
3798 char *p; 3954 char *p;
3799 3955
3800 ls = 2; 3956 ls = 2;
3801 /* make %l into %ll */ 3957 /* make %l into %ll */
3802 p = strchr(format, 'l'); 3958 p = strchr(format, 'l');
3803 if (p) 3959 if (p)
3804 memmove(p, p+1, strlen(p)+1); 3960 memmove(p+1, p, strlen(p)+1);
3805 else if (strcmp(format, "%p") == 0) 3961 else if (strcmp(format, "%p") == 0)
3806 strcpy(format, "0x%llx"); 3962 strcpy(format, "0x%llx");
3807 } 3963 }
@@ -3878,8 +4034,7 @@ static void pretty_print(struct trace_seq *s, void *data, int size, struct event
3878 * pevent_data_lat_fmt - parse the data for the latency format 4034 * pevent_data_lat_fmt - parse the data for the latency format
3879 * @pevent: a handle to the pevent 4035 * @pevent: a handle to the pevent
3880 * @s: the trace_seq to write to 4036 * @s: the trace_seq to write to
3881 * @data: the raw data to read from 4037 * @record: the record to read from
3882 * @size: currently unused.
3883 * 4038 *
3884 * This parses out the Latency format (interrupts disabled, 4039 * This parses out the Latency format (interrupts disabled,
3885 * need rescheduling, in hard/soft interrupt, preempt count 4040 * need rescheduling, in hard/soft interrupt, preempt count
@@ -3889,10 +4044,13 @@ void pevent_data_lat_fmt(struct pevent *pevent,
3889 struct trace_seq *s, struct pevent_record *record) 4044 struct trace_seq *s, struct pevent_record *record)
3890{ 4045{
3891 static int check_lock_depth = 1; 4046 static int check_lock_depth = 1;
4047 static int check_migrate_disable = 1;
3892 static int lock_depth_exists; 4048 static int lock_depth_exists;
4049 static int migrate_disable_exists;
3893 unsigned int lat_flags; 4050 unsigned int lat_flags;
3894 unsigned int pc; 4051 unsigned int pc;
3895 int lock_depth; 4052 int lock_depth;
4053 int migrate_disable;
3896 int hardirq; 4054 int hardirq;
3897 int softirq; 4055 int softirq;
3898 void *data = record->data; 4056 void *data = record->data;
@@ -3900,18 +4058,26 @@ void pevent_data_lat_fmt(struct pevent *pevent,
3900 lat_flags = parse_common_flags(pevent, data); 4058 lat_flags = parse_common_flags(pevent, data);
3901 pc = parse_common_pc(pevent, data); 4059 pc = parse_common_pc(pevent, data);
3902 /* lock_depth may not always exist */ 4060 /* lock_depth may not always exist */
3903 if (check_lock_depth) {
3904 struct format_field *field;
3905 struct event_format *event;
3906
3907 check_lock_depth = 0;
3908 event = pevent->events[0];
3909 field = pevent_find_common_field(event, "common_lock_depth");
3910 if (field)
3911 lock_depth_exists = 1;
3912 }
3913 if (lock_depth_exists) 4061 if (lock_depth_exists)
3914 lock_depth = parse_common_lock_depth(pevent, data); 4062 lock_depth = parse_common_lock_depth(pevent, data);
4063 else if (check_lock_depth) {
4064 lock_depth = parse_common_lock_depth(pevent, data);
4065 if (lock_depth < 0)
4066 check_lock_depth = 0;
4067 else
4068 lock_depth_exists = 1;
4069 }
4070
4071 /* migrate_disable may not always exist */
4072 if (migrate_disable_exists)
4073 migrate_disable = parse_common_migrate_disable(pevent, data);
4074 else if (check_migrate_disable) {
4075 migrate_disable = parse_common_migrate_disable(pevent, data);
4076 if (migrate_disable < 0)
4077 check_migrate_disable = 0;
4078 else
4079 migrate_disable_exists = 1;
4080 }
3915 4081
3916 hardirq = lat_flags & TRACE_FLAG_HARDIRQ; 4082 hardirq = lat_flags & TRACE_FLAG_HARDIRQ;
3917 softirq = lat_flags & TRACE_FLAG_SOFTIRQ; 4083 softirq = lat_flags & TRACE_FLAG_SOFTIRQ;
@@ -3930,6 +4096,13 @@ void pevent_data_lat_fmt(struct pevent *pevent,
3930 else 4096 else
3931 trace_seq_putc(s, '.'); 4097 trace_seq_putc(s, '.');
3932 4098
4099 if (migrate_disable_exists) {
4100 if (migrate_disable < 0)
4101 trace_seq_putc(s, '.');
4102 else
4103 trace_seq_printf(s, "%d", migrate_disable);
4104 }
4105
3933 if (lock_depth_exists) { 4106 if (lock_depth_exists) {
3934 if (lock_depth < 0) 4107 if (lock_depth < 0)
3935 trace_seq_putc(s, '.'); 4108 trace_seq_putc(s, '.');
@@ -3996,10 +4169,7 @@ const char *pevent_data_comm_from_pid(struct pevent *pevent, int pid)
3996 * pevent_data_comm_from_pid - parse the data into the print format 4169 * pevent_data_comm_from_pid - parse the data into the print format
3997 * @s: the trace_seq to write to 4170 * @s: the trace_seq to write to
3998 * @event: the handle to the event 4171 * @event: the handle to the event
3999 * @cpu: the cpu the event was recorded on 4172 * @record: the record to read from
4000 * @data: the raw data
4001 * @size: the size of the raw data
4002 * @nsecs: the timestamp of the event
4003 * 4173 *
4004 * This parses the raw @data using the given @event information and 4174 * This parses the raw @data using the given @event information and
4005 * writes the print format into the trace_seq. 4175 * writes the print format into the trace_seq.
@@ -4279,6 +4449,13 @@ static void print_args(struct print_arg *args)
4279 trace_seq_destroy(&s); 4449 trace_seq_destroy(&s);
4280 printf(")"); 4450 printf(")");
4281 break; 4451 break;
4452 case PRINT_HEX:
4453 printf("__print_hex(");
4454 print_args(args->hex.field);
4455 printf(", ");
4456 print_args(args->hex.size);
4457 printf(")");
4458 break;
4282 case PRINT_STRING: 4459 case PRINT_STRING:
4283 case PRINT_BSTRING: 4460 case PRINT_BSTRING:
4284 printf("__get_str(%s)", args->string.string); 4461 printf("__get_str(%s)", args->string.string);
@@ -4541,6 +4718,8 @@ int pevent_parse_event(struct pevent *pevent,
4541 die("failed to read event id"); 4718 die("failed to read event id");
4542 4719
4543 event->system = strdup(sys); 4720 event->system = strdup(sys);
4721 if (!event->system)
4722 die("failed to allocate system");
4544 4723
4545 /* Add pevent to event so that it can be referenced */ 4724 /* Add pevent to event so that it can be referenced */
4546 event->pevent = pevent; 4725 event->pevent = pevent;
@@ -4582,6 +4761,11 @@ int pevent_parse_event(struct pevent *pevent,
4582 list = &arg->next; 4761 list = &arg->next;
4583 arg->type = PRINT_FIELD; 4762 arg->type = PRINT_FIELD;
4584 arg->field.name = strdup(field->name); 4763 arg->field.name = strdup(field->name);
4764 if (!arg->field.name) {
4765 do_warning("failed to allocate field name");
4766 event->flags |= EVENT_FL_FAILED;
4767 return -1;
4768 }
4585 arg->field.field = field; 4769 arg->field.field = field;
4586 } 4770 }
4587 return 0; 4771 return 0;
@@ -4753,7 +4937,7 @@ int pevent_get_any_field_val(struct trace_seq *s, struct event_format *event,
4753 * @record: The record with the field name. 4937 * @record: The record with the field name.
4754 * @err: print default error if failed. 4938 * @err: print default error if failed.
4755 * 4939 *
4756 * Returns: 0 on success, -1 field not fould, or 1 if buffer is full. 4940 * Returns: 0 on success, -1 field not found, or 1 if buffer is full.
4757 */ 4941 */
4758int pevent_print_num_field(struct trace_seq *s, const char *fmt, 4942int pevent_print_num_field(struct trace_seq *s, const char *fmt,
4759 struct event_format *event, const char *name, 4943 struct event_format *event, const char *name,
@@ -4795,11 +4979,12 @@ static void free_func_handle(struct pevent_function_handler *func)
4795 * pevent_register_print_function - register a helper function 4979 * pevent_register_print_function - register a helper function
4796 * @pevent: the handle to the pevent 4980 * @pevent: the handle to the pevent
4797 * @func: the function to process the helper function 4981 * @func: the function to process the helper function
4982 * @ret_type: the return type of the helper function
4798 * @name: the name of the helper function 4983 * @name: the name of the helper function
4799 * @parameters: A list of enum pevent_func_arg_type 4984 * @parameters: A list of enum pevent_func_arg_type
4800 * 4985 *
4801 * Some events may have helper functions in the print format arguments. 4986 * Some events may have helper functions in the print format arguments.
4802 * This allows a plugin to dynmically create a way to process one 4987 * This allows a plugin to dynamically create a way to process one
4803 * of these functions. 4988 * of these functions.
4804 * 4989 *
4805 * The @parameters is a variable list of pevent_func_arg_type enums that 4990 * The @parameters is a variable list of pevent_func_arg_type enums that
@@ -4870,12 +5055,13 @@ int pevent_register_print_function(struct pevent *pevent,
4870} 5055}
4871 5056
4872/** 5057/**
4873 * pevent_register_event_handle - register a way to parse an event 5058 * pevent_register_event_handler - register a way to parse an event
4874 * @pevent: the handle to the pevent 5059 * @pevent: the handle to the pevent
4875 * @id: the id of the event to register 5060 * @id: the id of the event to register
4876 * @sys_name: the system name the event belongs to 5061 * @sys_name: the system name the event belongs to
4877 * @event_name: the name of the event 5062 * @event_name: the name of the event
4878 * @func: the function to call to parse the event information 5063 * @func: the function to call to parse the event information
5064 * @context: the data to be passed to @func
4879 * 5065 *
4880 * This function allows a developer to override the parsing of 5066 * This function allows a developer to override the parsing of
4881 * a given event. If for some reason the default print format 5067 * a given event. If for some reason the default print format
@@ -4925,6 +5111,11 @@ int pevent_register_event_handler(struct pevent *pevent,
4925 if (sys_name) 5111 if (sys_name)
4926 handle->sys_name = strdup(sys_name); 5112 handle->sys_name = strdup(sys_name);
4927 5113
5114 if ((event_name && !handle->event_name) ||
5115 (sys_name && !handle->sys_name)) {
5116 die("Failed to allocate event/sys name");
5117 }
5118
4928 handle->func = func; 5119 handle->func = func;
4929 handle->next = pevent->handlers; 5120 handle->next = pevent->handlers;
4930 pevent->handlers = handle; 5121 pevent->handlers = handle;