]> bbs.cooldavid.org Git - net-next-2.6.git/blame - tools/perf/util/trace-event-parse.c
perf tools: Handle arrays in print fields for trace parsing
[net-next-2.6.git] / tools / perf / util / trace-event-parse.c
CommitLineData
ea4010d1
SR
1/*
2 * Copyright (C) 2009, Steven Rostedt <srostedt@redhat.com>
3 *
4 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 2 of the License (not later!)
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 *
19 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
20 *
21 * The parts for function graph printing was taken and modified from the
22 * Linux Kernel that were written by Frederic Weisbecker.
23 */
24#define _GNU_SOURCE
25#include <stdio.h>
26#include <stdlib.h>
27#include <string.h>
28#include <ctype.h>
29#include <errno.h>
30
31#undef _GNU_SOURCE
1ef2ed10 32#include "../perf.h"
ea4010d1
SR
33#include "util.h"
34#include "trace-event.h"
35
36int header_page_ts_offset;
37int header_page_ts_size;
38int header_page_size_offset;
39int header_page_size_size;
40int header_page_data_offset;
41int header_page_data_size;
42
43static char *input_buf;
44static unsigned long long input_buf_ptr;
45static unsigned long long input_buf_siz;
46
47static int cpus;
48static int long_size;
49
50static void init_input_buf(char *buf, unsigned long long size)
51{
52 input_buf = buf;
53 input_buf_siz = size;
54 input_buf_ptr = 0;
55}
56
57struct cmdline {
58 char *comm;
59 int pid;
60};
61
62static struct cmdline *cmdlines;
63static int cmdline_count;
64
65static int cmdline_cmp(const void *a, const void *b)
66{
67 const struct cmdline *ca = a;
68 const struct cmdline *cb = b;
69
70 if (ca->pid < cb->pid)
71 return -1;
72 if (ca->pid > cb->pid)
73 return 1;
74
75 return 0;
76}
77
78void parse_cmdlines(char *file, int size __unused)
79{
80 struct cmdline_list {
81 struct cmdline_list *next;
82 char *comm;
83 int pid;
84 } *list = NULL, *item;
85 char *line;
86 char *next = NULL;
87 int i;
88
89 line = strtok_r(file, "\n", &next);
90 while (line) {
91 item = malloc_or_die(sizeof(*item));
92 sscanf(line, "%d %as", &item->pid,
65014ab3 93 (float *)(void *)&item->comm); /* workaround gcc warning */
ea4010d1
SR
94 item->next = list;
95 list = item;
96 line = strtok_r(NULL, "\n", &next);
97 cmdline_count++;
98 }
99
100 cmdlines = malloc_or_die(sizeof(*cmdlines) * cmdline_count);
101
102 i = 0;
103 while (list) {
104 cmdlines[i].pid = list->pid;
105 cmdlines[i].comm = list->comm;
106 i++;
107 item = list;
108 list = list->next;
109 free(item);
110 }
111
112 qsort(cmdlines, cmdline_count, sizeof(*cmdlines), cmdline_cmp);
113}
114
115static struct func_map {
116 unsigned long long addr;
117 char *func;
118 char *mod;
119} *func_list;
120static unsigned int func_count;
121
122static int func_cmp(const void *a, const void *b)
123{
124 const struct func_map *fa = a;
125 const struct func_map *fb = b;
126
127 if (fa->addr < fb->addr)
128 return -1;
129 if (fa->addr > fb->addr)
130 return 1;
131
132 return 0;
133}
134
135void parse_proc_kallsyms(char *file, unsigned int size __unused)
136{
137 struct func_list {
138 struct func_list *next;
139 unsigned long long addr;
140 char *func;
141 char *mod;
142 } *list = NULL, *item;
143 char *line;
144 char *next = NULL;
145 char *addr_str;
146 char ch;
147 int ret;
148 int i;
149
150 line = strtok_r(file, "\n", &next);
151 while (line) {
152 item = malloc_or_die(sizeof(*item));
153 item->mod = NULL;
154 ret = sscanf(line, "%as %c %as\t[%as",
65014ab3 155 (float *)(void *)&addr_str, /* workaround gcc warning */
ea4010d1 156 &ch,
65014ab3
IM
157 (float *)(void *)&item->func,
158 (float *)(void *)&item->mod);
ea4010d1
SR
159 item->addr = strtoull(addr_str, NULL, 16);
160 free(addr_str);
161
162 /* truncate the extra ']' */
163 if (item->mod)
164 item->mod[strlen(item->mod) - 1] = 0;
165
166
167 item->next = list;
168 list = item;
169 line = strtok_r(NULL, "\n", &next);
170 func_count++;
171 }
172
173 func_list = malloc_or_die(sizeof(*func_list) * func_count + 1);
174
175 i = 0;
176 while (list) {
177 func_list[i].func = list->func;
178 func_list[i].addr = list->addr;
179 func_list[i].mod = list->mod;
180 i++;
181 item = list;
182 list = list->next;
183 free(item);
184 }
185
186 qsort(func_list, func_count, sizeof(*func_list), func_cmp);
187
188 /*
189 * Add a special record at the end.
190 */
191 func_list[func_count].func = NULL;
192 func_list[func_count].addr = 0;
193 func_list[func_count].mod = NULL;
194}
195
196/*
197 * We are searching for a record in between, not an exact
198 * match.
199 */
200static int func_bcmp(const void *a, const void *b)
201{
202 const struct func_map *fa = a;
203 const struct func_map *fb = b;
204
205 if ((fa->addr == fb->addr) ||
206
207 (fa->addr > fb->addr &&
208 fa->addr < (fb+1)->addr))
209 return 0;
210
211 if (fa->addr < fb->addr)
212 return -1;
213
214 return 1;
215}
216
217static struct func_map *find_func(unsigned long long addr)
218{
219 struct func_map *func;
220 struct func_map key;
221
222 key.addr = addr;
223
224 func = bsearch(&key, func_list, func_count, sizeof(*func_list),
225 func_bcmp);
226
227 return func;
228}
229
230void print_funcs(void)
231{
232 int i;
233
234 for (i = 0; i < (int)func_count; i++) {
235 printf("%016llx %s",
236 func_list[i].addr,
237 func_list[i].func);
238 if (func_list[i].mod)
239 printf(" [%s]\n", func_list[i].mod);
240 else
241 printf("\n");
242 }
243}
244
245static struct printk_map {
246 unsigned long long addr;
247 char *printk;
248} *printk_list;
249static unsigned int printk_count;
250
251static int printk_cmp(const void *a, const void *b)
252{
253 const struct func_map *fa = a;
254 const struct func_map *fb = b;
255
256 if (fa->addr < fb->addr)
257 return -1;
258 if (fa->addr > fb->addr)
259 return 1;
260
261 return 0;
262}
263
264static struct printk_map *find_printk(unsigned long long addr)
265{
266 struct printk_map *printk;
267 struct printk_map key;
268
269 key.addr = addr;
270
271 printk = bsearch(&key, printk_list, printk_count, sizeof(*printk_list),
272 printk_cmp);
273
274 return printk;
275}
276
277void parse_ftrace_printk(char *file, unsigned int size __unused)
278{
279 struct printk_list {
280 struct printk_list *next;
281 unsigned long long addr;
282 char *printk;
283 } *list = NULL, *item;
284 char *line;
285 char *next = NULL;
286 char *addr_str;
287 int ret;
288 int i;
289
290 line = strtok_r(file, "\n", &next);
291 while (line) {
292 item = malloc_or_die(sizeof(*item));
293 ret = sscanf(line, "%as : %as",
65014ab3
IM
294 (float *)(void *)&addr_str, /* workaround gcc warning */
295 (float *)(void *)&item->printk);
ea4010d1
SR
296 item->addr = strtoull(addr_str, NULL, 16);
297 free(addr_str);
298
299 item->next = list;
300 list = item;
301 line = strtok_r(NULL, "\n", &next);
302 printk_count++;
303 }
304
305 printk_list = malloc_or_die(sizeof(*printk_list) * printk_count + 1);
306
307 i = 0;
308 while (list) {
309 printk_list[i].printk = list->printk;
310 printk_list[i].addr = list->addr;
311 i++;
312 item = list;
313 list = list->next;
314 free(item);
315 }
316
317 qsort(printk_list, printk_count, sizeof(*printk_list), printk_cmp);
318}
319
320void print_printk(void)
321{
322 int i;
323
324 for (i = 0; i < (int)printk_count; i++) {
325 printf("%016llx %s\n",
326 printk_list[i].addr,
327 printk_list[i].printk);
328 }
329}
330
331static struct event *alloc_event(void)
332{
333 struct event *event;
334
335 event = malloc_or_die(sizeof(*event));
336 memset(event, 0, sizeof(*event));
337
338 return event;
339}
340
341enum event_type {
342 EVENT_ERROR,
343 EVENT_NONE,
344 EVENT_SPACE,
345 EVENT_NEWLINE,
346 EVENT_OP,
347 EVENT_DELIM,
348 EVENT_ITEM,
349 EVENT_DQUOTE,
350 EVENT_SQUOTE,
351};
352
353static struct event *event_list;
354
355static void add_event(struct event *event)
356{
357 event->next = event_list;
358 event_list = event;
359}
360
361static int event_item_type(enum event_type type)
362{
363 switch (type) {
364 case EVENT_ITEM ... EVENT_SQUOTE:
365 return 1;
366 case EVENT_ERROR ... EVENT_DELIM:
367 default:
368 return 0;
369 }
370}
371
372static void free_arg(struct print_arg *arg)
373{
374 if (!arg)
375 return;
376
377 switch (arg->type) {
378 case PRINT_ATOM:
379 if (arg->atom.atom)
380 free(arg->atom.atom);
381 break;
382 case PRINT_NULL:
383 case PRINT_FIELD ... PRINT_OP:
384 default:
385 /* todo */
386 break;
387 }
388
389 free(arg);
390}
391
392static enum event_type get_type(int ch)
393{
394 if (ch == '\n')
395 return EVENT_NEWLINE;
396 if (isspace(ch))
397 return EVENT_SPACE;
398 if (isalnum(ch) || ch == '_')
399 return EVENT_ITEM;
400 if (ch == '\'')
401 return EVENT_SQUOTE;
402 if (ch == '"')
403 return EVENT_DQUOTE;
404 if (!isprint(ch))
405 return EVENT_NONE;
406 if (ch == '(' || ch == ')' || ch == ',')
407 return EVENT_DELIM;
408
409 return EVENT_OP;
410}
411
412static int __read_char(void)
413{
414 if (input_buf_ptr >= input_buf_siz)
415 return -1;
416
417 return input_buf[input_buf_ptr++];
418}
419
420static int __peek_char(void)
421{
422 if (input_buf_ptr >= input_buf_siz)
423 return -1;
424
425 return input_buf[input_buf_ptr];
426}
427
428static enum event_type __read_token(char **tok)
429{
430 char buf[BUFSIZ];
431 int ch, last_ch, quote_ch, next_ch;
432 int i = 0;
433 int tok_size = 0;
434 enum event_type type;
435
436 *tok = NULL;
437
438
439 ch = __read_char();
440 if (ch < 0)
441 return EVENT_NONE;
442
443 type = get_type(ch);
444 if (type == EVENT_NONE)
445 return type;
446
447 buf[i++] = ch;
448
449 switch (type) {
450 case EVENT_NEWLINE:
451 case EVENT_DELIM:
452 *tok = malloc_or_die(2);
453 (*tok)[0] = ch;
454 (*tok)[1] = 0;
455 return type;
456
457 case EVENT_OP:
458 switch (ch) {
459 case '-':
460 next_ch = __peek_char();
461 if (next_ch == '>') {
462 buf[i++] = __read_char();
463 break;
464 }
465 /* fall through */
466 case '+':
467 case '|':
468 case '&':
469 case '>':
470 case '<':
471 last_ch = ch;
472 ch = __peek_char();
473 if (ch != last_ch)
474 goto test_equal;
475 buf[i++] = __read_char();
476 switch (last_ch) {
477 case '>':
478 case '<':
479 goto test_equal;
480 default:
481 break;
482 }
483 break;
484 case '!':
485 case '=':
486 goto test_equal;
487 default: /* what should we do instead? */
488 break;
489 }
490 buf[i] = 0;
491 *tok = strdup(buf);
492 return type;
493
494 test_equal:
495 ch = __peek_char();
496 if (ch == '=')
497 buf[i++] = __read_char();
498 break;
499
500 case EVENT_DQUOTE:
501 case EVENT_SQUOTE:
502 /* don't keep quotes */
503 i--;
504 quote_ch = ch;
505 last_ch = 0;
506 do {
507 if (i == (BUFSIZ - 1)) {
508 buf[i] = 0;
509 if (*tok) {
510 *tok = realloc(*tok, tok_size + BUFSIZ);
511 if (!*tok)
512 return EVENT_NONE;
513 strcat(*tok, buf);
514 } else
515 *tok = strdup(buf);
516
517 if (!*tok)
518 return EVENT_NONE;
519 tok_size += BUFSIZ;
520 i = 0;
521 }
522 last_ch = ch;
523 ch = __read_char();
524 buf[i++] = ch;
91ff2bc1
SR
525 /* the '\' '\' will cancel itself */
526 if (ch == '\\' && last_ch == '\\')
527 last_ch = 0;
528 } while (ch != quote_ch || last_ch == '\\');
ea4010d1
SR
529 /* remove the last quote */
530 i--;
531 goto out;
532
533 case EVENT_ERROR ... EVENT_SPACE:
534 case EVENT_ITEM:
535 default:
536 break;
537 }
538
539 while (get_type(__peek_char()) == type) {
540 if (i == (BUFSIZ - 1)) {
541 buf[i] = 0;
542 if (*tok) {
543 *tok = realloc(*tok, tok_size + BUFSIZ);
544 if (!*tok)
545 return EVENT_NONE;
546 strcat(*tok, buf);
547 } else
548 *tok = strdup(buf);
549
550 if (!*tok)
551 return EVENT_NONE;
552 tok_size += BUFSIZ;
553 i = 0;
554 }
555 ch = __read_char();
556 buf[i++] = ch;
557 }
558
559 out:
560 buf[i] = 0;
561 if (*tok) {
562 *tok = realloc(*tok, tok_size + i);
563 if (!*tok)
564 return EVENT_NONE;
565 strcat(*tok, buf);
566 } else
567 *tok = strdup(buf);
568 if (!*tok)
569 return EVENT_NONE;
570
571 return type;
572}
573
574static void free_token(char *tok)
575{
576 if (tok)
577 free(tok);
578}
579
580static enum event_type read_token(char **tok)
581{
582 enum event_type type;
583
584 for (;;) {
585 type = __read_token(tok);
586 if (type != EVENT_SPACE)
587 return type;
588
589 free_token(*tok);
590 }
591
592 /* not reached */
593 return EVENT_NONE;
594}
595
596/* no newline */
597static enum event_type read_token_item(char **tok)
598{
599 enum event_type type;
600
601 for (;;) {
602 type = __read_token(tok);
603 if (type != EVENT_SPACE && type != EVENT_NEWLINE)
604 return type;
605
606 free_token(*tok);
607 }
608
609 /* not reached */
610 return EVENT_NONE;
611}
612
613static int test_type(enum event_type type, enum event_type expect)
614{
615 if (type != expect) {
616 die("Error: expected type %d but read %d",
617 expect, type);
618 return -1;
619 }
620 return 0;
621}
622
623static int test_type_token(enum event_type type, char *token,
cbef79a8 624 enum event_type expect, const char *expect_tok)
ea4010d1
SR
625{
626 if (type != expect) {
627 die("Error: expected type %d but read %d",
628 expect, type);
629 return -1;
630 }
631
632 if (strcmp(token, expect_tok) != 0) {
633 die("Error: expected '%s' but read '%s'",
634 expect_tok, token);
635 return -1;
636 }
637 return 0;
638}
639
640static int __read_expect_type(enum event_type expect, char **tok, int newline_ok)
641{
642 enum event_type type;
643
644 if (newline_ok)
645 type = read_token(tok);
646 else
647 type = read_token_item(tok);
648 return test_type(type, expect);
649}
650
651static int read_expect_type(enum event_type expect, char **tok)
652{
653 return __read_expect_type(expect, tok, 1);
654}
655
cbef79a8 656static int __read_expected(enum event_type expect, const char *str, int newline_ok)
ea4010d1
SR
657{
658 enum event_type type;
659 char *token;
660 int ret;
661
662 if (newline_ok)
663 type = read_token(&token);
664 else
665 type = read_token_item(&token);
666
667 ret = test_type_token(type, token, expect, str);
668
669 free_token(token);
670
671 return 0;
672}
673
cbef79a8 674static int read_expected(enum event_type expect, const char *str)
ea4010d1
SR
675{
676 return __read_expected(expect, str, 1);
677}
678
cbef79a8 679static int read_expected_item(enum event_type expect, const char *str)
ea4010d1
SR
680{
681 return __read_expected(expect, str, 0);
682}
683
684static char *event_read_name(void)
685{
686 char *token;
687
688 if (read_expected(EVENT_ITEM, (char *)"name") < 0)
689 return NULL;
690
691 if (read_expected(EVENT_OP, (char *)":") < 0)
692 return NULL;
693
694 if (read_expect_type(EVENT_ITEM, &token) < 0)
695 goto fail;
696
697 return token;
698
699 fail:
700 free_token(token);
701 return NULL;
702}
703
704static int event_read_id(void)
705{
706 char *token;
707 int id;
708
709 if (read_expected_item(EVENT_ITEM, (char *)"ID") < 0)
710 return -1;
711
712 if (read_expected(EVENT_OP, (char *)":") < 0)
713 return -1;
714
715 if (read_expect_type(EVENT_ITEM, &token) < 0)
716 goto fail;
717
718 id = strtoul(token, NULL, 0);
719 free_token(token);
720 return id;
721
722 fail:
723 free_token(token);
724 return -1;
725}
726
064739bc
TZ
727static int field_is_string(struct format_field *field)
728{
729 if ((field->flags & FIELD_IS_ARRAY) &&
730 (!strstr(field->type, "char") || !strstr(field->type, "u8") ||
731 !strstr(field->type, "s8")))
732 return 1;
733
734 return 0;
735}
736
737static int field_is_dynamic(struct format_field *field)
738{
739 if (!strcmp(field->type, "__data_loc"))
740 return 1;
741
742 return 0;
743}
744
ea4010d1
SR
745static int event_read_fields(struct event *event, struct format_field **fields)
746{
747 struct format_field *field = NULL;
748 enum event_type type;
749 char *token;
750 char *last_token;
751 int count = 0;
752
753 do {
754 type = read_token(&token);
755 if (type == EVENT_NEWLINE) {
756 free_token(token);
757 return count;
758 }
759
760 count++;
761
762 if (test_type_token(type, token, EVENT_ITEM, (char *)"field"))
763 goto fail;
764 free_token(token);
765
766 type = read_token(&token);
767 /*
768 * The ftrace fields may still use the "special" name.
769 * Just ignore it.
770 */
771 if (event->flags & EVENT_FL_ISFTRACE &&
772 type == EVENT_ITEM && strcmp(token, "special") == 0) {
773 free_token(token);
774 type = read_token(&token);
775 }
776
777 if (test_type_token(type, token, EVENT_OP, (char *)":") < 0)
778 return -1;
779
780 if (read_expect_type(EVENT_ITEM, &token) < 0)
781 goto fail;
782
783 last_token = token;
784
785 field = malloc_or_die(sizeof(*field));
786 memset(field, 0, sizeof(*field));
787
788 /* read the rest of the type */
789 for (;;) {
790 type = read_token(&token);
791 if (type == EVENT_ITEM ||
792 (type == EVENT_OP && strcmp(token, "*") == 0) ||
793 /*
794 * Some of the ftrace fields are broken and have
795 * an illegal "." in them.
796 */
797 (event->flags & EVENT_FL_ISFTRACE &&
798 type == EVENT_OP && strcmp(token, ".") == 0)) {
799
800 if (strcmp(token, "*") == 0)
801 field->flags |= FIELD_IS_POINTER;
802
803 if (field->type) {
804 field->type = realloc(field->type,
805 strlen(field->type) +
806 strlen(last_token) + 2);
807 strcat(field->type, " ");
808 strcat(field->type, last_token);
809 } else
810 field->type = last_token;
811 last_token = token;
812 continue;
813 }
814
815 break;
816 }
817
818 if (!field->type) {
819 die("no type found");
820 goto fail;
821 }
822 field->name = last_token;
823
824 if (test_type(type, EVENT_OP))
825 goto fail;
826
827 if (strcmp(token, "[") == 0) {
828 enum event_type last_type = type;
829 char *brackets = token;
830 int len;
831
832 field->flags |= FIELD_IS_ARRAY;
833
834 type = read_token(&token);
835 while (strcmp(token, "]") != 0) {
836 if (last_type == EVENT_ITEM &&
837 type == EVENT_ITEM)
838 len = 2;
839 else
840 len = 1;
841 last_type = type;
842
843 brackets = realloc(brackets,
844 strlen(brackets) +
845 strlen(token) + len);
846 if (len == 2)
847 strcat(brackets, " ");
848 strcat(brackets, token);
849 free_token(token);
850 type = read_token(&token);
851 if (type == EVENT_NONE) {
852 die("failed to find token");
853 goto fail;
854 }
855 }
856
857 free_token(token);
858
859 brackets = realloc(brackets, strlen(brackets) + 2);
860 strcat(brackets, "]");
861
862 /* add brackets to type */
863
864 type = read_token(&token);
865 /*
866 * If the next token is not an OP, then it is of
867 * the format: type [] item;
868 */
869 if (type == EVENT_ITEM) {
870 field->type = realloc(field->type,
871 strlen(field->type) +
872 strlen(field->name) +
873 strlen(brackets) + 2);
874 strcat(field->type, " ");
875 strcat(field->type, field->name);
876 free_token(field->name);
877 strcat(field->type, brackets);
878 field->name = token;
879 type = read_token(&token);
880 } else {
881 field->type = realloc(field->type,
882 strlen(field->type) +
883 strlen(brackets) + 1);
884 strcat(field->type, brackets);
885 }
886 free(brackets);
887 }
888
064739bc
TZ
889 if (field_is_string(field)) {
890 field->flags |= FIELD_IS_STRING;
891 if (field_is_dynamic(field))
892 field->flags |= FIELD_IS_DYNAMIC;
893 }
894
ea4010d1
SR
895 if (test_type_token(type, token, EVENT_OP, (char *)";"))
896 goto fail;
897 free_token(token);
898
899 if (read_expected(EVENT_ITEM, (char *)"offset") < 0)
900 goto fail_expect;
901
902 if (read_expected(EVENT_OP, (char *)":") < 0)
903 goto fail_expect;
904
905 if (read_expect_type(EVENT_ITEM, &token))
906 goto fail;
907 field->offset = strtoul(token, NULL, 0);
908 free_token(token);
909
910 if (read_expected(EVENT_OP, (char *)";") < 0)
911 goto fail_expect;
912
913 if (read_expected(EVENT_ITEM, (char *)"size") < 0)
914 goto fail_expect;
915
916 if (read_expected(EVENT_OP, (char *)":") < 0)
917 goto fail_expect;
918
919 if (read_expect_type(EVENT_ITEM, &token))
920 goto fail;
921 field->size = strtoul(token, NULL, 0);
922 free_token(token);
923
26a50744
TZ
924 if (read_expected(EVENT_OP, (char *)";") < 0)
925 goto fail_expect;
926
927 if (read_expected(EVENT_ITEM, (char *)"signed") < 0)
928 goto fail_expect;
929
930 if (read_expected(EVENT_OP, (char *)":") < 0)
931 goto fail_expect;
932
933 if (read_expect_type(EVENT_ITEM, &token))
934 goto fail;
935 if (strtoul(token, NULL, 0))
936 field->flags |= FIELD_IS_SIGNED;
937 free_token(token);
938
ea4010d1
SR
939 if (read_expected(EVENT_OP, (char *)";") < 0)
940 goto fail_expect;
941
942 if (read_expect_type(EVENT_NEWLINE, &token) < 0)
943 goto fail;
944 free_token(token);
945
946 *fields = field;
947 fields = &field->next;
948
949 } while (1);
950
951 return 0;
952
953fail:
954 free_token(token);
955fail_expect:
956 if (field)
957 free(field);
958 return -1;
959}
960
961static int event_read_format(struct event *event)
962{
963 char *token;
964 int ret;
965
966 if (read_expected_item(EVENT_ITEM, (char *)"format") < 0)
967 return -1;
968
969 if (read_expected(EVENT_OP, (char *)":") < 0)
970 return -1;
971
972 if (read_expect_type(EVENT_NEWLINE, &token))
973 goto fail;
974 free_token(token);
975
976 ret = event_read_fields(event, &event->format.common_fields);
977 if (ret < 0)
978 return ret;
979 event->format.nr_common = ret;
980
981 ret = event_read_fields(event, &event->format.fields);
982 if (ret < 0)
983 return ret;
984 event->format.nr_fields = ret;
985
986 return 0;
987
988 fail:
989 free_token(token);
990 return -1;
991}
992
993enum event_type
994process_arg_token(struct event *event, struct print_arg *arg,
995 char **tok, enum event_type type);
996
997static enum event_type
998process_arg(struct event *event, struct print_arg *arg, char **tok)
999{
1000 enum event_type type;
1001 char *token;
1002
1003 type = read_token(&token);
1004 *tok = token;
1005
1006 return process_arg_token(event, arg, tok, type);
1007}
1008
1009static enum event_type
1010process_cond(struct event *event, struct print_arg *top, char **tok)
1011{
1012 struct print_arg *arg, *left, *right;
1013 enum event_type type;
1014 char *token = NULL;
1015
1016 arg = malloc_or_die(sizeof(*arg));
1017 memset(arg, 0, sizeof(*arg));
1018
1019 left = malloc_or_die(sizeof(*left));
1020
1021 right = malloc_or_die(sizeof(*right));
1022
1023 arg->type = PRINT_OP;
1024 arg->op.left = left;
1025 arg->op.right = right;
1026
1027 *tok = NULL;
1028 type = process_arg(event, left, &token);
1029 if (test_type_token(type, token, EVENT_OP, (char *)":"))
1030 goto out_free;
1031
1032 arg->op.op = token;
1033
1034 type = process_arg(event, right, &token);
1035
1036 top->op.right = arg;
1037
1038 *tok = token;
1039 return type;
1040
1041out_free:
1042 free_token(*tok);
1043 free(right);
1044 free(left);
1045 free_arg(arg);
1046 return EVENT_ERROR;
1047}
1048
0959b8d6
SR
1049static enum event_type
1050process_array(struct event *event, struct print_arg *top, char **tok)
1051{
1052 struct print_arg *arg;
1053 enum event_type type;
1054 char *token = NULL;
1055
1056 arg = malloc_or_die(sizeof(*arg));
1057 memset(arg, 0, sizeof(*arg));
1058
1059 *tok = NULL;
1060 type = process_arg(event, arg, &token);
1061 if (test_type_token(type, token, EVENT_OP, (char *)"]"))
1062 goto out_free;
1063
1064 top->op.right = arg;
1065
1066 free_token(token);
1067 type = read_token_item(&token);
1068 *tok = token;
1069
1070 return type;
1071
1072out_free:
1073 free_token(*tok);
1074 free_arg(arg);
1075 return EVENT_ERROR;
1076}
1077
ea4010d1
SR
1078static int get_op_prio(char *op)
1079{
1080 if (!op[1]) {
1081 switch (op[0]) {
1082 case '*':
1083 case '/':
1084 case '%':
1085 return 6;
1086 case '+':
1087 case '-':
1088 return 7;
1089 /* '>>' and '<<' are 8 */
1090 case '<':
1091 case '>':
1092 return 9;
1093 /* '==' and '!=' are 10 */
1094 case '&':
1095 return 11;
1096 case '^':
1097 return 12;
1098 case '|':
1099 return 13;
1100 case '?':
1101 return 16;
1102 default:
1103 die("unknown op '%c'", op[0]);
1104 return -1;
1105 }
1106 } else {
1107 if (strcmp(op, "++") == 0 ||
1108 strcmp(op, "--") == 0) {
1109 return 3;
1110 } else if (strcmp(op, ">>") == 0 ||
1111 strcmp(op, "<<") == 0) {
1112 return 8;
1113 } else if (strcmp(op, ">=") == 0 ||
1114 strcmp(op, "<=") == 0) {
1115 return 9;
1116 } else if (strcmp(op, "==") == 0 ||
1117 strcmp(op, "!=") == 0) {
1118 return 10;
1119 } else if (strcmp(op, "&&") == 0) {
1120 return 14;
1121 } else if (strcmp(op, "||") == 0) {
1122 return 15;
1123 } else {
1124 die("unknown op '%s'", op);
1125 return -1;
1126 }
1127 }
1128}
1129
1130static void set_op_prio(struct print_arg *arg)
1131{
1132
1133 /* single ops are the greatest */
1134 if (!arg->op.left || arg->op.left->type == PRINT_NULL) {
1135 arg->op.prio = 0;
1136 return;
1137 }
1138
1139 arg->op.prio = get_op_prio(arg->op.op);
1140}
1141
1142static enum event_type
1143process_op(struct event *event, struct print_arg *arg, char **tok)
1144{
1145 struct print_arg *left, *right = NULL;
1146 enum event_type type;
1147 char *token;
1148
1149 /* the op is passed in via tok */
1150 token = *tok;
1151
1152 if (arg->type == PRINT_OP && !arg->op.left) {
1153 /* handle single op */
1154 if (token[1]) {
1155 die("bad op token %s", token);
1156 return EVENT_ERROR;
1157 }
1158 switch (token[0]) {
1159 case '!':
1160 case '+':
1161 case '-':
1162 break;
1163 default:
1164 die("bad op token %s", token);
1165 return EVENT_ERROR;
1166 }
1167
1168 /* make an empty left */
1169 left = malloc_or_die(sizeof(*left));
1170 left->type = PRINT_NULL;
1171 arg->op.left = left;
1172
1173 right = malloc_or_die(sizeof(*right));
1174 arg->op.right = right;
1175
1176 type = process_arg(event, right, tok);
1177
1178 } else if (strcmp(token, "?") == 0) {
1179
1180 left = malloc_or_die(sizeof(*left));
1181 /* copy the top arg to the left */
1182 *left = *arg;
1183
1184 arg->type = PRINT_OP;
1185 arg->op.op = token;
1186 arg->op.left = left;
1187 arg->op.prio = 0;
1188
1189 type = process_cond(event, arg, tok);
1190
1191 } else if (strcmp(token, ">>") == 0 ||
1192 strcmp(token, "<<") == 0 ||
1193 strcmp(token, "&") == 0 ||
1194 strcmp(token, "|") == 0 ||
1195 strcmp(token, "&&") == 0 ||
1196 strcmp(token, "||") == 0 ||
1197 strcmp(token, "-") == 0 ||
1198 strcmp(token, "+") == 0 ||
1199 strcmp(token, "*") == 0 ||
1200 strcmp(token, "^") == 0 ||
1201 strcmp(token, "/") == 0 ||
298ebc3e
SR
1202 strcmp(token, "<") == 0 ||
1203 strcmp(token, ">") == 0 ||
ea4010d1
SR
1204 strcmp(token, "==") == 0 ||
1205 strcmp(token, "!=") == 0) {
1206
1207 left = malloc_or_die(sizeof(*left));
1208
1209 /* copy the top arg to the left */
1210 *left = *arg;
1211
1212 arg->type = PRINT_OP;
1213 arg->op.op = token;
1214 arg->op.left = left;
1215
1216 set_op_prio(arg);
1217
1218 right = malloc_or_die(sizeof(*right));
1219
1220 type = process_arg(event, right, tok);
1221
1222 arg->op.right = right;
1223
0959b8d6
SR
1224 } else if (strcmp(token, "[") == 0) {
1225
1226 left = malloc_or_die(sizeof(*left));
1227 *left = *arg;
1228
1229 arg->type = PRINT_OP;
1230 arg->op.op = token;
1231 arg->op.left = left;
1232
1233 arg->op.prio = 0;
1234 type = process_array(event, arg, tok);
1235
ea4010d1
SR
1236 } else {
1237 die("unknown op '%s'", token);
1238 /* the arg is now the left side */
1239 return EVENT_NONE;
1240 }
1241
1242
1243 if (type == EVENT_OP) {
1244 int prio;
1245
1246 /* higher prios need to be closer to the root */
1247 prio = get_op_prio(*tok);
1248
1249 if (prio > arg->op.prio)
1250 return process_op(event, arg, tok);
1251
1252 return process_op(event, right, tok);
1253 }
1254
1255 return type;
1256}
1257
1258static enum event_type
1259process_entry(struct event *event __unused, struct print_arg *arg,
1260 char **tok)
1261{
1262 enum event_type type;
1263 char *field;
1264 char *token;
1265
1266 if (read_expected(EVENT_OP, (char *)"->") < 0)
1267 return EVENT_ERROR;
1268
1269 if (read_expect_type(EVENT_ITEM, &token) < 0)
1270 goto fail;
1271 field = token;
1272
1273 arg->type = PRINT_FIELD;
1274 arg->field.name = field;
1275
1276 type = read_token(&token);
1277 *tok = token;
1278
1279 return type;
1280
1281fail:
1282 free_token(token);
1283 return EVENT_ERROR;
1284}
1285
1286static char *arg_eval (struct print_arg *arg);
1287
1288static long long arg_num_eval(struct print_arg *arg)
1289{
1290 long long left, right;
1291 long long val = 0;
1292
1293 switch (arg->type) {
1294 case PRINT_ATOM:
1295 val = strtoll(arg->atom.atom, NULL, 0);
1296 break;
1297 case PRINT_TYPE:
1298 val = arg_num_eval(arg->typecast.item);
1299 break;
1300 case PRINT_OP:
1301 switch (arg->op.op[0]) {
1302 case '|':
1303 left = arg_num_eval(arg->op.left);
1304 right = arg_num_eval(arg->op.right);
1305 if (arg->op.op[1])
1306 val = left || right;
1307 else
1308 val = left | right;
1309 break;
1310 case '&':
1311 left = arg_num_eval(arg->op.left);
1312 right = arg_num_eval(arg->op.right);
1313 if (arg->op.op[1])
1314 val = left && right;
1315 else
1316 val = left & right;
1317 break;
1318 case '<':
1319 left = arg_num_eval(arg->op.left);
1320 right = arg_num_eval(arg->op.right);
1321 switch (arg->op.op[1]) {
1322 case 0:
1323 val = left < right;
1324 break;
1325 case '<':
1326 val = left << right;
1327 break;
1328 case '=':
1329 val = left <= right;
1330 break;
1331 default:
1332 die("unknown op '%s'", arg->op.op);
1333 }
1334 break;
1335 case '>':
1336 left = arg_num_eval(arg->op.left);
1337 right = arg_num_eval(arg->op.right);
1338 switch (arg->op.op[1]) {
1339 case 0:
1340 val = left > right;
1341 break;
1342 case '>':
1343 val = left >> right;
1344 break;
1345 case '=':
1346 val = left >= right;
1347 break;
1348 default:
1349 die("unknown op '%s'", arg->op.op);
1350 }
1351 break;
1352 case '=':
1353 left = arg_num_eval(arg->op.left);
1354 right = arg_num_eval(arg->op.right);
1355
1356 if (arg->op.op[1] != '=')
1357 die("unknown op '%s'", arg->op.op);
1358
1359 val = left == right;
1360 break;
1361 case '!':
1362 left = arg_num_eval(arg->op.left);
1363 right = arg_num_eval(arg->op.right);
1364
1365 switch (arg->op.op[1]) {
1366 case '=':
1367 val = left != right;
1368 break;
1369 default:
1370 die("unknown op '%s'", arg->op.op);
1371 }
1372 break;
1373 default:
1374 die("unknown op '%s'", arg->op.op);
1375 }
1376 break;
1377
1378 case PRINT_NULL:
1379 case PRINT_FIELD ... PRINT_SYMBOL:
1380 case PRINT_STRING:
1381 default:
1382 die("invalid eval type %d", arg->type);
1383
1384 }
1385 return val;
1386}
1387
1388static char *arg_eval (struct print_arg *arg)
1389{
1390 long long val;
1391 static char buf[20];
1392
1393 switch (arg->type) {
1394 case PRINT_ATOM:
1395 return arg->atom.atom;
1396 case PRINT_TYPE:
1397 return arg_eval(arg->typecast.item);
1398 case PRINT_OP:
1399 val = arg_num_eval(arg);
1400 sprintf(buf, "%lld", val);
1401 return buf;
1402
1403 case PRINT_NULL:
1404 case PRINT_FIELD ... PRINT_SYMBOL:
1405 case PRINT_STRING:
1406 default:
1407 die("invalid eval type %d", arg->type);
1408 break;
1409 }
1410
1411 return NULL;
1412}
1413
1414static enum event_type
1415process_fields(struct event *event, struct print_flag_sym **list, char **tok)
1416{
1417 enum event_type type;
1418 struct print_arg *arg = NULL;
1419 struct print_flag_sym *field;
1420 char *token = NULL;
1421 char *value;
1422
1423 do {
1424 free_token(token);
1425 type = read_token_item(&token);
1426 if (test_type_token(type, token, EVENT_OP, (char *)"{"))
1427 break;
1428
1429 arg = malloc_or_die(sizeof(*arg));
1430
1431 free_token(token);
1432 type = process_arg(event, arg, &token);
1433 if (test_type_token(type, token, EVENT_DELIM, (char *)","))
1434 goto out_free;
1435
1436 field = malloc_or_die(sizeof(*field));
1437 memset(field, 0, sizeof(field));
1438
1439 value = arg_eval(arg);
1440 field->value = strdup(value);
1441
1442 free_token(token);
1443 type = process_arg(event, arg, &token);
1444 if (test_type_token(type, token, EVENT_OP, (char *)"}"))
1445 goto out_free;
1446
1447 value = arg_eval(arg);
1448 field->str = strdup(value);
1449 free_arg(arg);
1450 arg = NULL;
1451
1452 *list = field;
1453 list = &field->next;
1454
1455 free_token(token);
1456 type = read_token_item(&token);
1457 } while (type == EVENT_DELIM && strcmp(token, ",") == 0);
1458
1459 *tok = token;
1460 return type;
1461
1462out_free:
1463 free_arg(arg);
1464 free_token(token);
1465
1466 return EVENT_ERROR;
1467}
1468
1469static enum event_type
1470process_flags(struct event *event, struct print_arg *arg, char **tok)
1471{
1472 struct print_arg *field;
1473 enum event_type type;
1474 char *token;
1475
1476 memset(arg, 0, sizeof(*arg));
1477 arg->type = PRINT_FLAGS;
1478
1479 if (read_expected_item(EVENT_DELIM, (char *)"(") < 0)
1480 return EVENT_ERROR;
1481
1482 field = malloc_or_die(sizeof(*field));
1483
1484 type = process_arg(event, field, &token);
1485 if (test_type_token(type, token, EVENT_DELIM, (char *)","))
1486 goto out_free;
1487
1488 arg->flags.field = field;
1489
1490 type = read_token_item(&token);
1491 if (event_item_type(type)) {
1492 arg->flags.delim = token;
1493 type = read_token_item(&token);
1494 }
1495
1496 if (test_type_token(type, token, EVENT_DELIM, (char *)","))
1497 goto out_free;
1498
1499 type = process_fields(event, &arg->flags.flags, &token);
1500 if (test_type_token(type, token, EVENT_DELIM, (char *)")"))
1501 goto out_free;
1502
1503 free_token(token);
1504 type = read_token_item(tok);
1505 return type;
1506
1507out_free:
1508 free_token(token);
1509 return EVENT_ERROR;
1510}
1511
1512static enum event_type
1513process_symbols(struct event *event, struct print_arg *arg, char **tok)
1514{
1515 struct print_arg *field;
1516 enum event_type type;
1517 char *token;
1518
1519 memset(arg, 0, sizeof(*arg));
1520 arg->type = PRINT_SYMBOL;
1521
1522 if (read_expected_item(EVENT_DELIM, (char *)"(") < 0)
1523 return EVENT_ERROR;
1524
1525 field = malloc_or_die(sizeof(*field));
1526
1527 type = process_arg(event, field, &token);
1528 if (test_type_token(type, token, EVENT_DELIM, (char *)","))
1529 goto out_free;
1530
1531 arg->symbol.field = field;
1532
1533 type = process_fields(event, &arg->symbol.symbols, &token);
1534 if (test_type_token(type, token, EVENT_DELIM, (char *)")"))
1535 goto out_free;
1536
1537 free_token(token);
1538 type = read_token_item(tok);
1539 return type;
1540
1541out_free:
1542 free_token(token);
1543 return EVENT_ERROR;
1544}
1545
1546static enum event_type
1547process_paren(struct event *event, struct print_arg *arg, char **tok)
1548{
1549 struct print_arg *item_arg;
1550 enum event_type type;
3f9edc23 1551 int ptr_cast = 0;
ea4010d1
SR
1552 char *token;
1553
1554 type = process_arg(event, arg, &token);
1555
1556 if (type == EVENT_ERROR)
1557 return EVENT_ERROR;
1558
3f9edc23
FW
1559 if (type == EVENT_OP) {
1560 /* handle the ptr casts */
1561 if (!strcmp(token, "*")) {
1562 /*
1563 * FIXME: should we zapp whitespaces before ')' ?
1564 * (may require a peek_token_item())
1565 */
1566 if (__peek_char() == ')') {
1567 ptr_cast = 1;
1568 free_token(token);
1569 type = read_token_item(&token);
1570 }
1571 }
1572 if (!ptr_cast) {
1573 type = process_op(event, arg, &token);
ea4010d1 1574
3f9edc23
FW
1575 if (type == EVENT_ERROR)
1576 return EVENT_ERROR;
1577 }
1578 }
ea4010d1
SR
1579
1580 if (test_type_token(type, token, EVENT_DELIM, (char *)")")) {
1581 free_token(token);
1582 return EVENT_ERROR;
1583 }
1584
1585 free_token(token);
1586 type = read_token_item(&token);
1587
1588 /*
1589 * If the next token is an item or another open paren, then
1590 * this was a typecast.
1591 */
1592 if (event_item_type(type) ||
1593 (type == EVENT_DELIM && strcmp(token, "(") == 0)) {
1594
1595 /* make this a typecast and contine */
1596
1597 /* prevous must be an atom */
1598 if (arg->type != PRINT_ATOM)
1599 die("previous needed to be PRINT_ATOM");
1600
1601 item_arg = malloc_or_die(sizeof(*item_arg));
1602
1603 arg->type = PRINT_TYPE;
3f9edc23
FW
1604 if (ptr_cast) {
1605 char *old = arg->atom.atom;
1606
1607 arg->atom.atom = malloc_or_die(strlen(old + 3));
1608 sprintf(arg->atom.atom, "%s *", old);
1609 free(old);
1610 }
ea4010d1
SR
1611 arg->typecast.type = arg->atom.atom;
1612 arg->typecast.item = item_arg;
1613 type = process_arg_token(event, item_arg, &token, type);
1614
1615 }
1616
1617 *tok = token;
1618 return type;
1619}
1620
1621
1622static enum event_type
1623process_str(struct event *event __unused, struct print_arg *arg, char **tok)
1624{
1625 enum event_type type;
1626 char *token;
1627
1628 if (read_expected(EVENT_DELIM, (char *)"(") < 0)
1629 return EVENT_ERROR;
1630
1631 if (read_expect_type(EVENT_ITEM, &token) < 0)
1632 goto fail;
1633
1634 arg->type = PRINT_STRING;
1635 arg->string.string = token;
561f732c 1636 arg->string.offset = -1;
ea4010d1
SR
1637
1638 if (read_expected(EVENT_DELIM, (char *)")") < 0)
1639 return EVENT_ERROR;
1640
1641 type = read_token(&token);
1642 *tok = token;
1643
1644 return type;
1645fail:
1646 free_token(token);
1647 return EVENT_ERROR;
1648}
1649
1650enum event_type
1651process_arg_token(struct event *event, struct print_arg *arg,
1652 char **tok, enum event_type type)
1653{
1654 char *token;
1655 char *atom;
1656
1657 token = *tok;
1658
1659 switch (type) {
1660 case EVENT_ITEM:
1661 if (strcmp(token, "REC") == 0) {
1662 free_token(token);
1663 type = process_entry(event, arg, &token);
1664 } else if (strcmp(token, "__print_flags") == 0) {
1665 free_token(token);
1666 type = process_flags(event, arg, &token);
1667 } else if (strcmp(token, "__print_symbolic") == 0) {
1668 free_token(token);
1669 type = process_symbols(event, arg, &token);
1670 } else if (strcmp(token, "__get_str") == 0) {
1671 free_token(token);
1672 type = process_str(event, arg, &token);
1673 } else {
1674 atom = token;
1675 /* test the next token */
1676 type = read_token_item(&token);
1677
1678 /* atoms can be more than one token long */
1679 while (type == EVENT_ITEM) {
1680 atom = realloc(atom, strlen(atom) + strlen(token) + 2);
1681 strcat(atom, " ");
1682 strcat(atom, token);
1683 free_token(token);
1684 type = read_token_item(&token);
1685 }
1686
1687 /* todo, test for function */
1688
1689 arg->type = PRINT_ATOM;
1690 arg->atom.atom = atom;
1691 }
1692 break;
1693 case EVENT_DQUOTE:
1694 case EVENT_SQUOTE:
1695 arg->type = PRINT_ATOM;
1696 arg->atom.atom = token;
1697 type = read_token_item(&token);
1698 break;
1699 case EVENT_DELIM:
1700 if (strcmp(token, "(") == 0) {
1701 free_token(token);
1702 type = process_paren(event, arg, &token);
1703 break;
1704 }
1705 case EVENT_OP:
1706 /* handle single ops */
1707 arg->type = PRINT_OP;
1708 arg->op.op = token;
1709 arg->op.left = NULL;
1710 type = process_op(event, arg, &token);
1711
1712 break;
1713
1714 case EVENT_ERROR ... EVENT_NEWLINE:
1715 default:
1716 die("unexpected type %d", type);
1717 }
1718 *tok = token;
1719
1720 return type;
1721}
1722
1723static int event_read_print_args(struct event *event, struct print_arg **list)
1724{
1725 enum event_type type;
1726 struct print_arg *arg;
1727 char *token;
1728 int args = 0;
1729
1730 do {
1731 arg = malloc_or_die(sizeof(*arg));
1732 memset(arg, 0, sizeof(*arg));
1733
1734 type = process_arg(event, arg, &token);
1735
1736 if (type == EVENT_ERROR) {
1737 free_arg(arg);
1738 return -1;
1739 }
1740
1741 *list = arg;
1742 args++;
1743
1744 if (type == EVENT_OP) {
1745 type = process_op(event, arg, &token);
1746 list = &arg->next;
1747 continue;
1748 }
1749
1750 if (type == EVENT_DELIM && strcmp(token, ",") == 0) {
1751 free_token(token);
1752 *list = arg;
1753 list = &arg->next;
1754 continue;
1755 }
1756 break;
1757 } while (type != EVENT_NONE);
1758
1759 if (type != EVENT_NONE)
1760 free_token(token);
1761
1762 return args;
1763}
1764
1765static int event_read_print(struct event *event)
1766{
1767 enum event_type type;
1768 char *token;
1769 int ret;
1770
1771 if (read_expected_item(EVENT_ITEM, (char *)"print") < 0)
1772 return -1;
1773
1774 if (read_expected(EVENT_ITEM, (char *)"fmt") < 0)
1775 return -1;
1776
1777 if (read_expected(EVENT_OP, (char *)":") < 0)
1778 return -1;
1779
1780 if (read_expect_type(EVENT_DQUOTE, &token) < 0)
1781 goto fail;
1782
924a79af 1783 concat:
ea4010d1
SR
1784 event->print_fmt.format = token;
1785 event->print_fmt.args = NULL;
1786
1787 /* ok to have no arg */
1788 type = read_token_item(&token);
1789
1790 if (type == EVENT_NONE)
1791 return 0;
1792
924a79af
SR
1793 /* Handle concatination of print lines */
1794 if (type == EVENT_DQUOTE) {
1795 char *cat;
1796
1797 cat = malloc_or_die(strlen(event->print_fmt.format) +
1798 strlen(token) + 1);
1799 strcpy(cat, event->print_fmt.format);
1800 strcat(cat, token);
1801 free_token(token);
1802 free_token(event->print_fmt.format);
1803 event->print_fmt.format = NULL;
1804 token = cat;
1805 goto concat;
1806 }
1807
ea4010d1
SR
1808 if (test_type_token(type, token, EVENT_DELIM, (char *)","))
1809 goto fail;
1810
1811 free_token(token);
1812
1813 ret = event_read_print_args(event, &event->print_fmt.args);
1814 if (ret < 0)
1815 return -1;
1816
1817 return 0;
1818
1819 fail:
1820 free_token(token);
1821 return -1;
1822}
1823
1824static struct format_field *
1825find_common_field(struct event *event, const char *name)
1826{
1827 struct format_field *format;
1828
1829 for (format = event->format.common_fields;
1830 format; format = format->next) {
1831 if (strcmp(format->name, name) == 0)
1832 break;
1833 }
1834
1835 return format;
1836}
1837
1838static struct format_field *
1839find_field(struct event *event, const char *name)
1840{
1841 struct format_field *format;
1842
1843 for (format = event->format.fields;
1844 format; format = format->next) {
1845 if (strcmp(format->name, name) == 0)
1846 break;
1847 }
1848
1849 return format;
1850}
1851
1852static struct format_field *
1853find_any_field(struct event *event, const char *name)
1854{
1855 struct format_field *format;
1856
1857 format = find_common_field(event, name);
1858 if (format)
1859 return format;
1860 return find_field(event, name);
1861}
1862
1863static unsigned long long read_size(void *ptr, int size)
1864{
1865 switch (size) {
1866 case 1:
1867 return *(unsigned char *)ptr;
1868 case 2:
1869 return data2host2(ptr);
1870 case 4:
1871 return data2host4(ptr);
1872 case 8:
1873 return data2host8(ptr);
1874 default:
1875 /* BUG! */
1876 return 0;
1877 }
1878}
1879
46538818
FW
1880unsigned long long
1881raw_field_value(struct event *event, const char *name, void *data)
1882{
1883 struct format_field *field;
1884
1885 field = find_any_field(event, name);
1886 if (!field)
1887 return 0ULL;
1888
1889 return read_size(data + field->offset, field->size);
1890}
1891
1892void *raw_field_ptr(struct event *event, const char *name, void *data)
1893{
1894 struct format_field *field;
1895
1896 field = find_any_field(event, name);
1897 if (!field)
1898 return NULL;
1899
1900 return data + field->offset;
1901}
1902
ea4010d1
SR
1903static int get_common_info(const char *type, int *offset, int *size)
1904{
1905 struct event *event;
1906 struct format_field *field;
1907
1908 /*
1909 * All events should have the same common elements.
1910 * Pick any event to find where the type is;
1911 */
1912 if (!event_list)
1913 die("no event_list!");
1914
1915 event = event_list;
1916 field = find_common_field(event, type);
1917 if (!field)
1918 die("field '%s' not found", type);
1919
1920 *offset = field->offset;
1921 *size = field->size;
1922
1923 return 0;
1924}
1925
ec156764 1926int trace_parse_common_type(void *data)
ea4010d1
SR
1927{
1928 static int type_offset;
1929 static int type_size;
1930 int ret;
1931
1932 if (!type_size) {
1933 ret = get_common_info("common_type",
1934 &type_offset,
1935 &type_size);
1936 if (ret < 0)
1937 return ret;
1938 }
1939 return read_size(data + type_offset, type_size);
1940}
1941
1942static int parse_common_pid(void *data)
1943{
1944 static int pid_offset;
1945 static int pid_size;
1946 int ret;
1947
1948 if (!pid_size) {
1949 ret = get_common_info("common_pid",
1950 &pid_offset,
1951 &pid_size);
1952 if (ret < 0)
1953 return ret;
1954 }
1955
1956 return read_size(data + pid_offset, pid_size);
1957}
1958
ec156764 1959struct event *trace_find_event(int id)
ea4010d1
SR
1960{
1961 struct event *event;
1962
1963 for (event = event_list; event; event = event->next) {
1964 if (event->id == id)
1965 break;
1966 }
1967 return event;
1968}
1969
1970static unsigned long long eval_num_arg(void *data, int size,
1971 struct event *event, struct print_arg *arg)
1972{
1973 unsigned long long val = 0;
1974 unsigned long long left, right;
0959b8d6 1975 struct print_arg *larg;
ea4010d1
SR
1976
1977 switch (arg->type) {
1978 case PRINT_NULL:
1979 /* ?? */
1980 return 0;
1981 case PRINT_ATOM:
1982 return strtoull(arg->atom.atom, NULL, 0);
1983 case PRINT_FIELD:
1984 if (!arg->field.field) {
1985 arg->field.field = find_any_field(event, arg->field.name);
1986 if (!arg->field.field)
1987 die("field %s not found", arg->field.name);
1988 }
1989 /* must be a number */
1990 val = read_size(data + arg->field.field->offset,
1991 arg->field.field->size);
1992 break;
1993 case PRINT_FLAGS:
1994 case PRINT_SYMBOL:
1995 break;
1996 case PRINT_TYPE:
1997 return eval_num_arg(data, size, event, arg->typecast.item);
1998 case PRINT_STRING:
1999 return 0;
2000 break;
2001 case PRINT_OP:
0959b8d6
SR
2002 if (strcmp(arg->op.op, "[") == 0) {
2003 /*
2004 * Arrays are special, since we don't want
2005 * to read the arg as is.
2006 */
2007 if (arg->op.left->type != PRINT_FIELD)
2008 goto default_op; /* oops, all bets off */
2009 larg = arg->op.left;
2010 if (!larg->field.field) {
2011 larg->field.field =
2012 find_any_field(event, larg->field.name);
2013 if (!larg->field.field)
2014 die("field %s not found", larg->field.name);
2015 }
2016 right = eval_num_arg(data, size, event, arg->op.right);
2017 val = read_size(data + larg->field.field->offset +
2018 right * long_size, long_size);
2019 break;
2020 }
2021 default_op:
ea4010d1
SR
2022 left = eval_num_arg(data, size, event, arg->op.left);
2023 right = eval_num_arg(data, size, event, arg->op.right);
2024 switch (arg->op.op[0]) {
2025 case '|':
2026 if (arg->op.op[1])
2027 val = left || right;
2028 else
2029 val = left | right;
2030 break;
2031 case '&':
2032 if (arg->op.op[1])
2033 val = left && right;
2034 else
2035 val = left & right;
2036 break;
2037 case '<':
2038 switch (arg->op.op[1]) {
2039 case 0:
2040 val = left < right;
2041 break;
2042 case '<':
2043 val = left << right;
2044 break;
2045 case '=':
2046 val = left <= right;
2047 break;
2048 default:
2049 die("unknown op '%s'", arg->op.op);
2050 }
2051 break;
2052 case '>':
2053 switch (arg->op.op[1]) {
2054 case 0:
2055 val = left > right;
2056 break;
2057 case '>':
2058 val = left >> right;
2059 break;
2060 case '=':
2061 val = left >= right;
2062 break;
2063 default:
2064 die("unknown op '%s'", arg->op.op);
2065 }
2066 break;
2067 case '=':
2068 if (arg->op.op[1] != '=')
2069 die("unknown op '%s'", arg->op.op);
2070 val = left == right;
2071 break;
2072 default:
2073 die("unknown op '%s'", arg->op.op);
2074 }
2075 break;
2076 default: /* not sure what to do there */
2077 return 0;
2078 }
2079 return val;
2080}
2081
2082struct flag {
2083 const char *name;
2084 unsigned long long value;
2085};
2086
2087static const struct flag flags[] = {
2088 { "HI_SOFTIRQ", 0 },
2089 { "TIMER_SOFTIRQ", 1 },
2090 { "NET_TX_SOFTIRQ", 2 },
2091 { "NET_RX_SOFTIRQ", 3 },
2092 { "BLOCK_SOFTIRQ", 4 },
b934cdd5
TZ
2093 { "BLOCK_IOPOLL_SOFTIRQ", 5 },
2094 { "TASKLET_SOFTIRQ", 6 },
2095 { "SCHED_SOFTIRQ", 7 },
2096 { "HRTIMER_SOFTIRQ", 8 },
2097 { "RCU_SOFTIRQ", 9 },
ea4010d1
SR
2098
2099 { "HRTIMER_NORESTART", 0 },
2100 { "HRTIMER_RESTART", 1 },
2101};
2102
2103static unsigned long long eval_flag(const char *flag)
2104{
2105 int i;
2106
2107 /*
2108 * Some flags in the format files do not get converted.
2109 * If the flag is not numeric, see if it is something that
2110 * we already know about.
2111 */
2112 if (isdigit(flag[0]))
2113 return strtoull(flag, NULL, 0);
2114
2115 for (i = 0; i < (int)(sizeof(flags)/sizeof(flags[0])); i++)
2116 if (strcmp(flags[i].name, flag) == 0)
2117 return flags[i].value;
2118
2119 return 0;
2120}
2121
2122static void print_str_arg(void *data, int size,
2123 struct event *event, struct print_arg *arg)
2124{
2125 struct print_flag_sym *flag;
2126 unsigned long long val, fval;
2127 char *str;
2128 int print;
2129
2130 switch (arg->type) {
2131 case PRINT_NULL:
2132 /* ?? */
2133 return;
2134 case PRINT_ATOM:
2135 printf("%s", arg->atom.atom);
2136 return;
2137 case PRINT_FIELD:
2138 if (!arg->field.field) {
2139 arg->field.field = find_any_field(event, arg->field.name);
2140 if (!arg->field.field)
2141 die("field %s not found", arg->field.name);
2142 }
2143 str = malloc_or_die(arg->field.field->size + 1);
2144 memcpy(str, data + arg->field.field->offset,
2145 arg->field.field->size);
2146 str[arg->field.field->size] = 0;
d498bc1f 2147 printf("%s", str);
ea4010d1
SR
2148 free(str);
2149 break;
2150 case PRINT_FLAGS:
2151 val = eval_num_arg(data, size, event, arg->flags.field);
2152 print = 0;
2153 for (flag = arg->flags.flags; flag; flag = flag->next) {
2154 fval = eval_flag(flag->value);
2155 if (!val && !fval) {
2156 printf("%s", flag->str);
2157 break;
2158 }
2159 if (fval && (val & fval) == fval) {
2160 if (print && arg->flags.delim)
2161 printf("%s", arg->flags.delim);
2162 printf("%s", flag->str);
2163 print = 1;
2164 val &= ~fval;
2165 }
2166 }
2167 break;
2168 case PRINT_SYMBOL:
2169 val = eval_num_arg(data, size, event, arg->symbol.field);
2170 for (flag = arg->symbol.symbols; flag; flag = flag->next) {
2171 fval = eval_flag(flag->value);
2172 if (val == fval) {
2173 printf("%s", flag->str);
2174 break;
2175 }
2176 }
2177 break;
2178
2179 case PRINT_TYPE:
2180 break;
561f732c
FW
2181 case PRINT_STRING: {
2182 int str_offset;
2183
2184 if (arg->string.offset == -1) {
2185 struct format_field *f;
2186
2187 f = find_any_field(event, arg->string.string);
2188 arg->string.offset = f->offset;
2189 }
2190 str_offset = *(int *)(data + arg->string.offset);
2191 str_offset &= 0xffff;
2192 printf("%s", ((char *)data) + str_offset);
ea4010d1 2193 break;
561f732c 2194 }
ea4010d1
SR
2195 case PRINT_OP:
2196 /*
2197 * The only op for string should be ? :
2198 */
2199 if (arg->op.op[0] != '?')
2200 return;
2201 val = eval_num_arg(data, size, event, arg->op.left);
2202 if (val)
2203 print_str_arg(data, size, event, arg->op.right->op.left);
2204 else
2205 print_str_arg(data, size, event, arg->op.right->op.right);
2206 break;
2207 default:
2208 /* well... */
2209 break;
2210 }
2211}
2212
2213static struct print_arg *make_bprint_args(char *fmt, void *data, int size, struct event *event)
2214{
2215 static struct format_field *field, *ip_field;
2216 struct print_arg *args, *arg, **next;
2217 unsigned long long ip, val;
2218 char *ptr;
2219 void *bptr;
2220
2221 if (!field) {
2222 field = find_field(event, "buf");
2223 if (!field)
2224 die("can't find buffer field for binary printk");
2225 ip_field = find_field(event, "ip");
2226 if (!ip_field)
2227 die("can't find ip field for binary printk");
2228 }
2229
2230 ip = read_size(data + ip_field->offset, ip_field->size);
2231
2232 /*
2233 * The first arg is the IP pointer.
2234 */
2235 args = malloc_or_die(sizeof(*args));
2236 arg = args;
2237 arg->next = NULL;
2238 next = &arg->next;
2239
2240 arg->type = PRINT_ATOM;
2241 arg->atom.atom = malloc_or_die(32);
2242 sprintf(arg->atom.atom, "%lld", ip);
2243
2244 /* skip the first "%pf : " */
2245 for (ptr = fmt + 6, bptr = data + field->offset;
2246 bptr < data + size && *ptr; ptr++) {
2247 int ls = 0;
2248
2249 if (*ptr == '%') {
2250 process_again:
2251 ptr++;
2252 switch (*ptr) {
2253 case '%':
2254 break;
2255 case 'l':
2256 ls++;
2257 goto process_again;
2258 case 'L':
2259 ls = 2;
2260 goto process_again;
2261 case '0' ... '9':
2262 goto process_again;
2263 case 'p':
2264 ls = 1;
2265 /* fall through */
2266 case 'd':
2267 case 'u':
2268 case 'x':
2269 case 'i':
2270 bptr = (void *)(((unsigned long)bptr + (long_size - 1)) &
2271 ~(long_size - 1));
2272 switch (ls) {
2273 case 0:
2274 case 1:
2275 ls = long_size;
2276 break;
2277 case 2:
2278 ls = 8;
2279 default:
2280 break;
2281 }
2282 val = read_size(bptr, ls);
2283 bptr += ls;
2284 arg = malloc_or_die(sizeof(*arg));
2285 arg->next = NULL;
2286 arg->type = PRINT_ATOM;
2287 arg->atom.atom = malloc_or_die(32);
2288 sprintf(arg->atom.atom, "%lld", val);
2289 *next = arg;
2290 next = &arg->next;
2291 break;
2292 case 's':
2293 arg = malloc_or_die(sizeof(*arg));
2294 arg->next = NULL;
2295 arg->type = PRINT_STRING;
2296 arg->string.string = strdup(bptr);
2297 bptr += strlen(bptr) + 1;
2298 *next = arg;
2299 next = &arg->next;
2300 default:
2301 break;
2302 }
2303 }
2304 }
2305
2306 return args;
2307}
2308
2309static void free_args(struct print_arg *args)
2310{
2311 struct print_arg *next;
2312
2313 while (args) {
2314 next = args->next;
2315
2316 if (args->type == PRINT_ATOM)
2317 free(args->atom.atom);
2318 else
2319 free(args->string.string);
2320 free(args);
2321 args = next;
2322 }
2323}
2324
2325static char *get_bprint_format(void *data, int size __unused, struct event *event)
2326{
2327 unsigned long long addr;
2328 static struct format_field *field;
2329 struct printk_map *printk;
2330 char *format;
2331 char *p;
2332
2333 if (!field) {
2334 field = find_field(event, "fmt");
2335 if (!field)
2336 die("can't find format field for binary printk");
2337 printf("field->offset = %d size=%d\n", field->offset, field->size);
2338 }
2339
2340 addr = read_size(data + field->offset, field->size);
2341
2342 printk = find_printk(addr);
2343 if (!printk) {
2344 format = malloc_or_die(45);
2345 sprintf(format, "%%pf : (NO FORMAT FOUND at %llx)\n",
2346 addr);
2347 return format;
2348 }
2349
2350 p = printk->printk;
2351 /* Remove any quotes. */
2352 if (*p == '"')
2353 p++;
2354 format = malloc_or_die(strlen(p) + 10);
2355 sprintf(format, "%s : %s", "%pf", p);
2356 /* remove ending quotes and new line since we will add one too */
2357 p = format + strlen(format) - 1;
2358 if (*p == '"')
2359 *p = 0;
2360
2361 p -= 2;
2362 if (strcmp(p, "\\n") == 0)
2363 *p = 0;
2364
2365 return format;
2366}
2367
2368static void pretty_print(void *data, int size, struct event *event)
2369{
2370 struct print_fmt *print_fmt = &event->print_fmt;
2371 struct print_arg *arg = print_fmt->args;
2372 struct print_arg *args = NULL;
2373 const char *ptr = print_fmt->format;
2374 unsigned long long val;
2375 struct func_map *func;
2376 const char *saveptr;
2377 char *bprint_fmt = NULL;
2378 char format[32];
2379 int show_func;
2380 int len;
2381 int ls;
2382
2383 if (event->flags & EVENT_FL_ISFUNC)
2384 ptr = " %pF <-- %pF";
2385
2386 if (event->flags & EVENT_FL_ISBPRINT) {
2387 bprint_fmt = get_bprint_format(data, size, event);
2388 args = make_bprint_args(bprint_fmt, data, size, event);
2389 arg = args;
2390 ptr = bprint_fmt;
2391 }
2392
2393 for (; *ptr; ptr++) {
2394 ls = 0;
91ff2bc1
SR
2395 if (*ptr == '\\') {
2396 ptr++;
2397 switch (*ptr) {
2398 case 'n':
2399 printf("\n");
2400 break;
2401 case 't':
2402 printf("\t");
2403 break;
2404 case 'r':
2405 printf("\r");
2406 break;
2407 case '\\':
2408 printf("\\");
2409 break;
2410 default:
2411 printf("%c", *ptr);
2412 break;
2413 }
2414
2415 } else if (*ptr == '%') {
ea4010d1
SR
2416 saveptr = ptr;
2417 show_func = 0;
2418 cont_process:
2419 ptr++;
2420 switch (*ptr) {
2421 case '%':
2422 printf("%%");
2423 break;
2424 case 'l':
2425 ls++;
2426 goto cont_process;
2427 case 'L':
2428 ls = 2;
2429 goto cont_process;
2430 case 'z':
2431 case 'Z':
2432 case '0' ... '9':
2433 goto cont_process;
2434 case 'p':
2435 if (long_size == 4)
2436 ls = 1;
2437 else
2438 ls = 2;
2439
2440 if (*(ptr+1) == 'F' ||
2441 *(ptr+1) == 'f') {
2442 ptr++;
2443 show_func = *ptr;
2444 }
2445
2446 /* fall through */
2447 case 'd':
2448 case 'i':
2449 case 'x':
2450 case 'X':
2451 case 'u':
2452 if (!arg)
2453 die("no argument match");
2454
2455 len = ((unsigned long)ptr + 1) -
2456 (unsigned long)saveptr;
2457
2458 /* should never happen */
2459 if (len > 32)
2460 die("bad format!");
2461
2462 memcpy(format, saveptr, len);
2463 format[len] = 0;
2464
2465 val = eval_num_arg(data, size, event, arg);
2466 arg = arg->next;
2467
2468 if (show_func) {
2469 func = find_func(val);
2470 if (func) {
2471 printf("%s", func->func);
2472 if (show_func == 'F')
2473 printf("+0x%llx",
2474 val - func->addr);
2475 break;
2476 }
2477 }
2478 switch (ls) {
2479 case 0:
2480 printf(format, (int)val);
2481 break;
2482 case 1:
2483 printf(format, (long)val);
2484 break;
2485 case 2:
2486 printf(format, (long long)val);
2487 break;
2488 default:
2489 die("bad count (%d)", ls);
2490 }
2491 break;
2492 case 's':
2493 if (!arg)
2494 die("no matching argument");
2495
2496 print_str_arg(data, size, event, arg);
2497 arg = arg->next;
2498 break;
2499 default:
2500 printf(">%c<", *ptr);
2501
2502 }
2503 } else
2504 printf("%c", *ptr);
2505 }
2506
2507 if (args) {
2508 free_args(args);
2509 free(bprint_fmt);
2510 }
2511}
2512
2513static inline int log10_cpu(int nb)
2514{
2515 if (nb / 100)
2516 return 3;
2517 if (nb / 10)
2518 return 2;
2519 return 1;
2520}
2521
2522/* taken from Linux, written by Frederic Weisbecker */
2523static void print_graph_cpu(int cpu)
2524{
2525 int i;
2526 int log10_this = log10_cpu(cpu);
2527 int log10_all = log10_cpu(cpus);
2528
2529
2530 /*
2531 * Start with a space character - to make it stand out
2532 * to the right a bit when trace output is pasted into
2533 * email:
2534 */
2535 printf(" ");
2536
2537 /*
2538 * Tricky - we space the CPU field according to the max
2539 * number of online CPUs. On a 2-cpu system it would take
2540 * a maximum of 1 digit - on a 128 cpu system it would
2541 * take up to 3 digits:
2542 */
2543 for (i = 0; i < log10_all - log10_this; i++)
2544 printf(" ");
2545
2546 printf("%d) ", cpu);
2547}
2548
2549#define TRACE_GRAPH_PROCINFO_LENGTH 14
2550#define TRACE_GRAPH_INDENT 2
2551
2552static void print_graph_proc(int pid, const char *comm)
2553{
2554 /* sign + log10(MAX_INT) + '\0' */
2555 char pid_str[11];
2556 int spaces = 0;
2557 int len;
2558 int i;
2559
2560 sprintf(pid_str, "%d", pid);
2561
2562 /* 1 stands for the "-" character */
2563 len = strlen(comm) + strlen(pid_str) + 1;
2564
2565 if (len < TRACE_GRAPH_PROCINFO_LENGTH)
2566 spaces = TRACE_GRAPH_PROCINFO_LENGTH - len;
2567
2568 /* First spaces to align center */
2569 for (i = 0; i < spaces / 2; i++)
2570 printf(" ");
2571
2572 printf("%s-%s", comm, pid_str);
2573
2574 /* Last spaces to align center */
2575 for (i = 0; i < spaces - (spaces / 2); i++)
2576 printf(" ");
2577}
2578
2579static struct record *
2580get_return_for_leaf(int cpu, int cur_pid, unsigned long long cur_func,
2581 struct record *next)
2582{
2583 struct format_field *field;
2584 struct event *event;
2585 unsigned long val;
2586 int type;
2587 int pid;
2588
ec156764
IM
2589 type = trace_parse_common_type(next->data);
2590 event = trace_find_event(type);
ea4010d1
SR
2591 if (!event)
2592 return NULL;
2593
2594 if (!(event->flags & EVENT_FL_ISFUNCRET))
2595 return NULL;
2596
2597 pid = parse_common_pid(next->data);
2598 field = find_field(event, "func");
2599 if (!field)
2600 die("function return does not have field func");
2601
2602 val = read_size(next->data + field->offset, field->size);
2603
2604 if (cur_pid != pid || cur_func != val)
2605 return NULL;
2606
2607 /* this is a leaf, now advance the iterator */
2608 return trace_read_data(cpu);
2609}
2610
2611/* Signal a overhead of time execution to the output */
2612static void print_graph_overhead(unsigned long long duration)
2613{
2614 /* Non nested entry or return */
2615 if (duration == ~0ULL)
2616 return (void)printf(" ");
2617
2618 /* Duration exceeded 100 msecs */
2619 if (duration > 100000ULL)
2620 return (void)printf("! ");
2621
2622 /* Duration exceeded 10 msecs */
2623 if (duration > 10000ULL)
2624 return (void)printf("+ ");
2625
2626 printf(" ");
2627}
2628
2629static void print_graph_duration(unsigned long long duration)
2630{
2631 unsigned long usecs = duration / 1000;
2632 unsigned long nsecs_rem = duration % 1000;
2633 /* log10(ULONG_MAX) + '\0' */
2634 char msecs_str[21];
2635 char nsecs_str[5];
2636 int len;
2637 int i;
2638
2639 sprintf(msecs_str, "%lu", usecs);
2640
2641 /* Print msecs */
2642 len = printf("%lu", usecs);
2643
2644 /* Print nsecs (we don't want to exceed 7 numbers) */
2645 if (len < 7) {
2646 snprintf(nsecs_str, 8 - len, "%03lu", nsecs_rem);
2647 len += printf(".%s", nsecs_str);
2648 }
2649
2650 printf(" us ");
2651
2652 /* Print remaining spaces to fit the row's width */
2653 for (i = len; i < 7; i++)
2654 printf(" ");
2655
2656 printf("| ");
2657}
2658
2659static void
2660print_graph_entry_leaf(struct event *event, void *data, struct record *ret_rec)
2661{
2662 unsigned long long rettime, calltime;
2663 unsigned long long duration, depth;
2664 unsigned long long val;
2665 struct format_field *field;
2666 struct func_map *func;
2667 struct event *ret_event;
2668 int type;
2669 int i;
2670
ec156764
IM
2671 type = trace_parse_common_type(ret_rec->data);
2672 ret_event = trace_find_event(type);
ea4010d1
SR
2673
2674 field = find_field(ret_event, "rettime");
2675 if (!field)
2676 die("can't find rettime in return graph");
2677 rettime = read_size(ret_rec->data + field->offset, field->size);
2678
2679 field = find_field(ret_event, "calltime");
2680 if (!field)
2681 die("can't find rettime in return graph");
2682 calltime = read_size(ret_rec->data + field->offset, field->size);
2683
2684 duration = rettime - calltime;
2685
2686 /* Overhead */
2687 print_graph_overhead(duration);
2688
2689 /* Duration */
2690 print_graph_duration(duration);
2691
2692 field = find_field(event, "depth");
2693 if (!field)
2694 die("can't find depth in entry graph");
2695 depth = read_size(data + field->offset, field->size);
2696
2697 /* Function */
2698 for (i = 0; i < (int)(depth * TRACE_GRAPH_INDENT); i++)
2699 printf(" ");
2700
2701 field = find_field(event, "func");
2702 if (!field)
2703 die("can't find func in entry graph");
2704 val = read_size(data + field->offset, field->size);
2705 func = find_func(val);
2706
2707 if (func)
2708 printf("%s();", func->func);
2709 else
2710 printf("%llx();", val);
2711}
2712
2713static void print_graph_nested(struct event *event, void *data)
2714{
2715 struct format_field *field;
2716 unsigned long long depth;
2717 unsigned long long val;
2718 struct func_map *func;
2719 int i;
2720
2721 /* No overhead */
2722 print_graph_overhead(-1);
2723
2724 /* No time */
2725 printf(" | ");
2726
2727 field = find_field(event, "depth");
2728 if (!field)
2729 die("can't find depth in entry graph");
2730 depth = read_size(data + field->offset, field->size);
2731
2732 /* Function */
2733 for (i = 0; i < (int)(depth * TRACE_GRAPH_INDENT); i++)
2734 printf(" ");
2735
2736 field = find_field(event, "func");
2737 if (!field)
2738 die("can't find func in entry graph");
2739 val = read_size(data + field->offset, field->size);
2740 func = find_func(val);
2741
2742 if (func)
2743 printf("%s() {", func->func);
2744 else
2745 printf("%llx() {", val);
2746}
2747
2748static void
2749pretty_print_func_ent(void *data, int size, struct event *event,
2750 int cpu, int pid, const char *comm,
2751 unsigned long secs, unsigned long usecs)
2752{
2753 struct format_field *field;
2754 struct record *rec;
2755 void *copy_data;
2756 unsigned long val;
2757
2758 printf("%5lu.%06lu | ", secs, usecs);
2759
2760 print_graph_cpu(cpu);
2761 print_graph_proc(pid, comm);
2762
2763 printf(" | ");
2764
2765 field = find_field(event, "func");
2766 if (!field)
2767 die("function entry does not have func field");
2768
2769 val = read_size(data + field->offset, field->size);
2770
2771 /*
2772 * peek_data may unmap the data pointer. Copy it first.
2773 */
2774 copy_data = malloc_or_die(size);
2775 memcpy(copy_data, data, size);
2776 data = copy_data;
2777
2778 rec = trace_peek_data(cpu);
2779 if (rec) {
2780 rec = get_return_for_leaf(cpu, pid, val, rec);
2781 if (rec) {
2782 print_graph_entry_leaf(event, data, rec);
2783 goto out_free;
2784 }
2785 }
2786 print_graph_nested(event, data);
2787out_free:
2788 free(data);
2789}
2790
2791static void
2792pretty_print_func_ret(void *data, int size __unused, struct event *event,
2793 int cpu, int pid, const char *comm,
2794 unsigned long secs, unsigned long usecs)
2795{
2796 unsigned long long rettime, calltime;
2797 unsigned long long duration, depth;
2798 struct format_field *field;
2799 int i;
2800
2801 printf("%5lu.%06lu | ", secs, usecs);
2802
2803 print_graph_cpu(cpu);
2804 print_graph_proc(pid, comm);
2805
2806 printf(" | ");
2807
2808 field = find_field(event, "rettime");
2809 if (!field)
2810 die("can't find rettime in return graph");
2811 rettime = read_size(data + field->offset, field->size);
2812
2813 field = find_field(event, "calltime");
2814 if (!field)
2815 die("can't find calltime in return graph");
2816 calltime = read_size(data + field->offset, field->size);
2817
2818 duration = rettime - calltime;
2819
2820 /* Overhead */
2821 print_graph_overhead(duration);
2822
2823 /* Duration */
2824 print_graph_duration(duration);
2825
2826 field = find_field(event, "depth");
2827 if (!field)
2828 die("can't find depth in entry graph");
2829 depth = read_size(data + field->offset, field->size);
2830
2831 /* Function */
2832 for (i = 0; i < (int)(depth * TRACE_GRAPH_INDENT); i++)
2833 printf(" ");
2834
2835 printf("}");
2836}
2837
2838static void
2839pretty_print_func_graph(void *data, int size, struct event *event,
2840 int cpu, int pid, const char *comm,
2841 unsigned long secs, unsigned long usecs)
2842{
2843 if (event->flags & EVENT_FL_ISFUNCENT)
2844 pretty_print_func_ent(data, size, event,
2845 cpu, pid, comm, secs, usecs);
2846 else if (event->flags & EVENT_FL_ISFUNCRET)
2847 pretty_print_func_ret(data, size, event,
2848 cpu, pid, comm, secs, usecs);
2849 printf("\n");
2850}
2851
2852void print_event(int cpu, void *data, int size, unsigned long long nsecs,
2853 char *comm)
2854{
2855 struct event *event;
2856 unsigned long secs;
2857 unsigned long usecs;
2858 int type;
2859 int pid;
2860
2861 secs = nsecs / NSECS_PER_SEC;
2862 nsecs -= secs * NSECS_PER_SEC;
2863 usecs = nsecs / NSECS_PER_USEC;
2864
ec156764 2865 type = trace_parse_common_type(data);
ea4010d1 2866
ec156764 2867 event = trace_find_event(type);
ea57c4f5
IM
2868 if (!event) {
2869 printf("ug! no event found for type %d\n", type);
2870 return;
2871 }
ea4010d1
SR
2872
2873 pid = parse_common_pid(data);
2874
2875 if (event->flags & (EVENT_FL_ISFUNCENT | EVENT_FL_ISFUNCRET))
2876 return pretty_print_func_graph(data, size, event, cpu,
2877 pid, comm, secs, usecs);
2878
00fc9786 2879 printf("%16s-%-5d [%03d] %5lu.%09Lu: %s: ",
ea4010d1 2880 comm, pid, cpu,
00fc9786 2881 secs, nsecs, event->name);
ea4010d1
SR
2882
2883 pretty_print(data, size, event);
2884 printf("\n");
2885}
2886
2887static void print_fields(struct print_flag_sym *field)
2888{
2889 printf("{ %s, %s }", field->value, field->str);
2890 if (field->next) {
2891 printf(", ");
2892 print_fields(field->next);
2893 }
2894}
2895
2896static void print_args(struct print_arg *args)
2897{
2898 int print_paren = 1;
2899
2900 switch (args->type) {
2901 case PRINT_NULL:
2902 printf("null");
2903 break;
2904 case PRINT_ATOM:
2905 printf("%s", args->atom.atom);
2906 break;
2907 case PRINT_FIELD:
2908 printf("REC->%s", args->field.name);
2909 break;
2910 case PRINT_FLAGS:
2911 printf("__print_flags(");
2912 print_args(args->flags.field);
2913 printf(", %s, ", args->flags.delim);
2914 print_fields(args->flags.flags);
2915 printf(")");
2916 break;
2917 case PRINT_SYMBOL:
2918 printf("__print_symbolic(");
2919 print_args(args->symbol.field);
2920 printf(", ");
2921 print_fields(args->symbol.symbols);
2922 printf(")");
2923 break;
2924 case PRINT_STRING:
2925 printf("__get_str(%s)", args->string.string);
2926 break;
2927 case PRINT_TYPE:
2928 printf("(%s)", args->typecast.type);
2929 print_args(args->typecast.item);
2930 break;
2931 case PRINT_OP:
2932 if (strcmp(args->op.op, ":") == 0)
2933 print_paren = 0;
2934 if (print_paren)
2935 printf("(");
2936 print_args(args->op.left);
2937 printf(" %s ", args->op.op);
2938 print_args(args->op.right);
2939 if (print_paren)
2940 printf(")");
2941 break;
2942 default:
2943 /* we should warn... */
2944 return;
2945 }
2946 if (args->next) {
2947 printf("\n");
2948 print_args(args->next);
2949 }
2950}
2951
2952static void parse_header_field(char *type,
2953 int *offset, int *size)
2954{
2955 char *token;
2956
2957 if (read_expected(EVENT_ITEM, (char *)"field") < 0)
2958 return;
2959 if (read_expected(EVENT_OP, (char *)":") < 0)
2960 return;
2961 /* type */
2962 if (read_expect_type(EVENT_ITEM, &token) < 0)
2963 return;
2964 free_token(token);
2965
2966 if (read_expected(EVENT_ITEM, type) < 0)
2967 return;
2968 if (read_expected(EVENT_OP, (char *)";") < 0)
2969 return;
2970 if (read_expected(EVENT_ITEM, (char *)"offset") < 0)
2971 return;
2972 if (read_expected(EVENT_OP, (char *)":") < 0)
2973 return;
2974 if (read_expect_type(EVENT_ITEM, &token) < 0)
2975 return;
2976 *offset = atoi(token);
2977 free_token(token);
2978 if (read_expected(EVENT_OP, (char *)";") < 0)
2979 return;
2980 if (read_expected(EVENT_ITEM, (char *)"size") < 0)
2981 return;
2982 if (read_expected(EVENT_OP, (char *)":") < 0)
2983 return;
2984 if (read_expect_type(EVENT_ITEM, &token) < 0)
2985 return;
2986 *size = atoi(token);
2987 free_token(token);
26a50744
TZ
2988 if (read_expected(EVENT_OP, (char *)";") < 0)
2989 return;
2990 if (read_expected(EVENT_ITEM, (char *)"signed") < 0)
2991 return;
2992 if (read_expected(EVENT_OP, (char *)":") < 0)
2993 return;
2994 if (read_expect_type(EVENT_ITEM, &token) < 0)
2995 return;
2996 free_token(token);
ea4010d1
SR
2997 if (read_expected(EVENT_OP, (char *)";") < 0)
2998 return;
2999 if (read_expect_type(EVENT_NEWLINE, &token) < 0)
3000 return;
3001 free_token(token);
3002}
3003
3004int parse_header_page(char *buf, unsigned long size)
3005{
3006 init_input_buf(buf, size);
3007
3008 parse_header_field((char *)"timestamp", &header_page_ts_offset,
3009 &header_page_ts_size);
3010 parse_header_field((char *)"commit", &header_page_size_offset,
3011 &header_page_size_size);
3012 parse_header_field((char *)"data", &header_page_data_offset,
3013 &header_page_data_size);
3014
3015 return 0;
3016}
3017
3018int parse_ftrace_file(char *buf, unsigned long size)
3019{
3020 struct format_field *field;
3021 struct print_arg *arg, **list;
3022 struct event *event;
3023 int ret;
3024
3025 init_input_buf(buf, size);
3026
3027 event = alloc_event();
3028 if (!event)
3029 return -ENOMEM;
3030
3031 event->flags |= EVENT_FL_ISFTRACE;
3032
3033 event->name = event_read_name();
3034 if (!event->name)
3035 die("failed to read ftrace event name");
3036
3037 if (strcmp(event->name, "function") == 0)
3038 event->flags |= EVENT_FL_ISFUNC;
3039
3040 else if (strcmp(event->name, "funcgraph_entry") == 0)
3041 event->flags |= EVENT_FL_ISFUNCENT;
3042
3043 else if (strcmp(event->name, "funcgraph_exit") == 0)
3044 event->flags |= EVENT_FL_ISFUNCRET;
3045
3046 else if (strcmp(event->name, "bprint") == 0)
3047 event->flags |= EVENT_FL_ISBPRINT;
3048
3049 event->id = event_read_id();
3050 if (event->id < 0)
3051 die("failed to read ftrace event id");
3052
3053 add_event(event);
3054
3055 ret = event_read_format(event);
3056 if (ret < 0)
3057 die("failed to read ftrace event format");
3058
3059 ret = event_read_print(event);
3060 if (ret < 0)
3061 die("failed to read ftrace event print fmt");
3062
3063 /*
3064 * The arguments for ftrace files are parsed by the fields.
3065 * Set up the fields as their arguments.
3066 */
3067 list = &event->print_fmt.args;
3068 for (field = event->format.fields; field; field = field->next) {
3069 arg = malloc_or_die(sizeof(*arg));
3070 memset(arg, 0, sizeof(*arg));
3071 *list = arg;
3072 list = &arg->next;
3073 arg->type = PRINT_FIELD;
3074 arg->field.name = field->name;
3075 arg->field.field = field;
3076 }
3077 return 0;
3078}
3079
27746018 3080int parse_event_file(char *buf, unsigned long size, char *sys)
ea4010d1
SR
3081{
3082 struct event *event;
3083 int ret;
3084
3085 init_input_buf(buf, size);
3086
3087 event = alloc_event();
3088 if (!event)
3089 return -ENOMEM;
3090
3091 event->name = event_read_name();
3092 if (!event->name)
3093 die("failed to read event name");
3094
3095 event->id = event_read_id();
3096 if (event->id < 0)
3097 die("failed to read event id");
3098
3099 ret = event_read_format(event);
3100 if (ret < 0)
3101 die("failed to read event format");
3102
3103 ret = event_read_print(event);
3104 if (ret < 0)
3105 die("failed to read event print fmt");
3106
27746018
TZ
3107 event->system = strdup(sys);
3108
ea4010d1
SR
3109#define PRINT_ARGS 0
3110 if (PRINT_ARGS && event->print_fmt.args)
3111 print_args(event->print_fmt.args);
3112
3113 add_event(event);
3114 return 0;
3115}
3116
3117void parse_set_info(int nr_cpus, int long_sz)
3118{
3119 cpus = nr_cpus;
3120 long_size = long_sz;
3121}