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