blob: 99b0cd4b79d495d35537c74eb26daaf4bde1c6ec [file] [log] [blame]
Steven Rostedtf7d82352012-04-06 00:47:53 +02001/*
2 * Copyright (C) 2009, 2010 Red Hat Inc, Steven Rostedt <srostedt@redhat.com>
3 *
4 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation;
8 * version 2.1 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 Lesser General Public License for more details.
14 *
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
20 *
21 * The parts for function graph printing was taken and modified from the
22 * Linux Kernel that were written by
23 * - Copyright (C) 2009 Frederic Weisbecker,
24 * Frederic Weisbecker gave his permission to relicense the code to
25 * the Lesser General Public License.
26 */
27#define _GNU_SOURCE
28#include <stdio.h>
29#include <stdlib.h>
30#include <string.h>
31#include <stdarg.h>
32#include <ctype.h>
33#include <errno.h>
34
35#include "event-parse.h"
Steven Rostedt668fe012012-04-06 00:47:55 +020036#include "event-utils.h"
Steven Rostedtf7d82352012-04-06 00:47:53 +020037
38static const char *input_buf;
39static unsigned long long input_buf_ptr;
40static unsigned long long input_buf_siz;
41
Tom Zanussi5205aec2012-04-06 00:47:58 +020042static int is_flag_field;
43static int is_symbolic_field;
44
Steven Rostedtf7d82352012-04-06 00:47:53 +020045static int show_warning = 1;
46
47#define do_warning(fmt, ...) \
48 do { \
49 if (show_warning) \
50 warning(fmt, ##__VA_ARGS__); \
51 } while (0)
52
53static void init_input_buf(const char *buf, unsigned long long size)
54{
55 input_buf = buf;
56 input_buf_siz = size;
57 input_buf_ptr = 0;
58}
59
60const char *pevent_get_input_buf(void)
61{
62 return input_buf;
63}
64
65unsigned long long pevent_get_input_buf_ptr(void)
66{
67 return input_buf_ptr;
68}
69
70struct event_handler {
71 struct event_handler *next;
72 int id;
73 const char *sys_name;
74 const char *event_name;
75 pevent_event_handler_func func;
76 void *context;
77};
78
79struct pevent_func_params {
80 struct pevent_func_params *next;
81 enum pevent_func_arg_type type;
82};
83
84struct pevent_function_handler {
85 struct pevent_function_handler *next;
86 enum pevent_func_arg_type ret_type;
87 char *name;
88 pevent_func_handler func;
89 struct pevent_func_params *params;
90 int nr_args;
91};
92
93static unsigned long long
94process_defined_func(struct trace_seq *s, void *data, int size,
95 struct event_format *event, struct print_arg *arg);
96
97static void free_func_handle(struct pevent_function_handler *func);
98
99/**
100 * pevent_buffer_init - init buffer for parsing
101 * @buf: buffer to parse
102 * @size: the size of the buffer
103 *
104 * For use with pevent_read_token(), this initializes the internal
105 * buffer that pevent_read_token() will parse.
106 */
107void pevent_buffer_init(const char *buf, unsigned long long size)
108{
109 init_input_buf(buf, size);
110}
111
112void breakpoint(void)
113{
114 static int x;
115 x++;
116}
117
118struct print_arg *alloc_arg(void)
119{
120 struct print_arg *arg;
121
122 arg = malloc_or_die(sizeof(*arg));
123 if (!arg)
124 return NULL;
125 memset(arg, 0, sizeof(*arg));
126
127 return arg;
128}
129
130struct cmdline {
131 char *comm;
132 int pid;
133};
134
135static int cmdline_cmp(const void *a, const void *b)
136{
137 const struct cmdline *ca = a;
138 const struct cmdline *cb = b;
139
140 if (ca->pid < cb->pid)
141 return -1;
142 if (ca->pid > cb->pid)
143 return 1;
144
145 return 0;
146}
147
148struct cmdline_list {
149 struct cmdline_list *next;
150 char *comm;
151 int pid;
152};
153
154static int cmdline_init(struct pevent *pevent)
155{
156 struct cmdline_list *cmdlist = pevent->cmdlist;
157 struct cmdline_list *item;
158 struct cmdline *cmdlines;
159 int i;
160
161 cmdlines = malloc_or_die(sizeof(*cmdlines) * pevent->cmdline_count);
162
163 i = 0;
164 while (cmdlist) {
165 cmdlines[i].pid = cmdlist->pid;
166 cmdlines[i].comm = cmdlist->comm;
167 i++;
168 item = cmdlist;
169 cmdlist = cmdlist->next;
170 free(item);
171 }
172
173 qsort(cmdlines, pevent->cmdline_count, sizeof(*cmdlines), cmdline_cmp);
174
175 pevent->cmdlines = cmdlines;
176 pevent->cmdlist = NULL;
177
178 return 0;
179}
180
181static char *find_cmdline(struct pevent *pevent, int pid)
182{
183 const struct cmdline *comm;
184 struct cmdline key;
185
186 if (!pid)
187 return "<idle>";
188
189 if (!pevent->cmdlines)
190 cmdline_init(pevent);
191
192 key.pid = pid;
193
194 comm = bsearch(&key, pevent->cmdlines, pevent->cmdline_count,
195 sizeof(*pevent->cmdlines), cmdline_cmp);
196
197 if (comm)
198 return comm->comm;
199 return "<...>";
200}
201
202/**
203 * pevent_pid_is_registered - return if a pid has a cmdline registered
204 * @pevent: handle for the pevent
205 * @pid: The pid to check if it has a cmdline registered with.
206 *
207 * Returns 1 if the pid has a cmdline mapped to it
208 * 0 otherwise.
209 */
210int pevent_pid_is_registered(struct pevent *pevent, int pid)
211{
212 const struct cmdline *comm;
213 struct cmdline key;
214
215 if (!pid)
216 return 1;
217
218 if (!pevent->cmdlines)
219 cmdline_init(pevent);
220
221 key.pid = pid;
222
223 comm = bsearch(&key, pevent->cmdlines, pevent->cmdline_count,
224 sizeof(*pevent->cmdlines), cmdline_cmp);
225
226 if (comm)
227 return 1;
228 return 0;
229}
230
231/*
232 * If the command lines have been converted to an array, then
233 * we must add this pid. This is much slower than when cmdlines
234 * are added before the array is initialized.
235 */
236static int add_new_comm(struct pevent *pevent, const char *comm, int pid)
237{
238 struct cmdline *cmdlines = pevent->cmdlines;
239 const struct cmdline *cmdline;
240 struct cmdline key;
241
242 if (!pid)
243 return 0;
244
245 /* avoid duplicates */
246 key.pid = pid;
247
248 cmdline = bsearch(&key, pevent->cmdlines, pevent->cmdline_count,
249 sizeof(*pevent->cmdlines), cmdline_cmp);
250 if (cmdline) {
251 errno = EEXIST;
252 return -1;
253 }
254
255 cmdlines = realloc(cmdlines, sizeof(*cmdlines) * (pevent->cmdline_count + 1));
256 if (!cmdlines) {
257 errno = ENOMEM;
258 return -1;
259 }
260
261 cmdlines[pevent->cmdline_count].pid = pid;
262 cmdlines[pevent->cmdline_count].comm = strdup(comm);
263 if (!cmdlines[pevent->cmdline_count].comm)
264 die("malloc comm");
265
266 if (cmdlines[pevent->cmdline_count].comm)
267 pevent->cmdline_count++;
268
269 qsort(cmdlines, pevent->cmdline_count, sizeof(*cmdlines), cmdline_cmp);
270 pevent->cmdlines = cmdlines;
271
272 return 0;
273}
274
275/**
276 * pevent_register_comm - register a pid / comm mapping
277 * @pevent: handle for the pevent
278 * @comm: the command line to register
279 * @pid: the pid to map the command line to
280 *
281 * This adds a mapping to search for command line names with
282 * a given pid. The comm is duplicated.
283 */
284int pevent_register_comm(struct pevent *pevent, const char *comm, int pid)
285{
286 struct cmdline_list *item;
287
288 if (pevent->cmdlines)
289 return add_new_comm(pevent, comm, pid);
290
291 item = malloc_or_die(sizeof(*item));
292 item->comm = strdup(comm);
293 if (!item->comm)
294 die("malloc comm");
295 item->pid = pid;
296 item->next = pevent->cmdlist;
297
298 pevent->cmdlist = item;
299 pevent->cmdline_count++;
300
301 return 0;
302}
303
304struct func_map {
305 unsigned long long addr;
306 char *func;
307 char *mod;
308};
309
310struct func_list {
311 struct func_list *next;
312 unsigned long long addr;
313 char *func;
314 char *mod;
315};
316
317static int func_cmp(const void *a, const void *b)
318{
319 const struct func_map *fa = a;
320 const struct func_map *fb = b;
321
322 if (fa->addr < fb->addr)
323 return -1;
324 if (fa->addr > fb->addr)
325 return 1;
326
327 return 0;
328}
329
330/*
331 * We are searching for a record in between, not an exact
332 * match.
333 */
334static int func_bcmp(const void *a, const void *b)
335{
336 const struct func_map *fa = a;
337 const struct func_map *fb = b;
338
339 if ((fa->addr == fb->addr) ||
340
341 (fa->addr > fb->addr &&
342 fa->addr < (fb+1)->addr))
343 return 0;
344
345 if (fa->addr < fb->addr)
346 return -1;
347
348 return 1;
349}
350
351static int func_map_init(struct pevent *pevent)
352{
353 struct func_list *funclist;
354 struct func_list *item;
355 struct func_map *func_map;
356 int i;
357
358 func_map = malloc_or_die(sizeof(*func_map) * (pevent->func_count + 1));
359 funclist = pevent->funclist;
360
361 i = 0;
362 while (funclist) {
363 func_map[i].func = funclist->func;
364 func_map[i].addr = funclist->addr;
365 func_map[i].mod = funclist->mod;
366 i++;
367 item = funclist;
368 funclist = funclist->next;
369 free(item);
370 }
371
372 qsort(func_map, pevent->func_count, sizeof(*func_map), func_cmp);
373
374 /*
375 * Add a special record at the end.
376 */
377 func_map[pevent->func_count].func = NULL;
378 func_map[pevent->func_count].addr = 0;
379 func_map[pevent->func_count].mod = NULL;
380
381 pevent->func_map = func_map;
382 pevent->funclist = NULL;
383
384 return 0;
385}
386
387static struct func_map *
388find_func(struct pevent *pevent, unsigned long long addr)
389{
390 struct func_map *func;
391 struct func_map key;
392
393 if (!pevent->func_map)
394 func_map_init(pevent);
395
396 key.addr = addr;
397
398 func = bsearch(&key, pevent->func_map, pevent->func_count,
399 sizeof(*pevent->func_map), func_bcmp);
400
401 return func;
402}
403
404/**
405 * pevent_find_function - find a function by a given address
406 * @pevent: handle for the pevent
407 * @addr: the address to find the function with
408 *
409 * Returns a pointer to the function stored that has the given
410 * address. Note, the address does not have to be exact, it
411 * will select the function that would contain the address.
412 */
413const char *pevent_find_function(struct pevent *pevent, unsigned long long addr)
414{
415 struct func_map *map;
416
417 map = find_func(pevent, addr);
418 if (!map)
419 return NULL;
420
421 return map->func;
422}
423
424/**
425 * pevent_find_function_address - find a function address by a given address
426 * @pevent: handle for the pevent
427 * @addr: the address to find the function with
428 *
429 * Returns the address the function starts at. This can be used in
430 * conjunction with pevent_find_function to print both the function
431 * name and the function offset.
432 */
433unsigned long long
434pevent_find_function_address(struct pevent *pevent, unsigned long long addr)
435{
436 struct func_map *map;
437
438 map = find_func(pevent, addr);
439 if (!map)
440 return 0;
441
442 return map->addr;
443}
444
445/**
446 * pevent_register_function - register a function with a given address
447 * @pevent: handle for the pevent
448 * @function: the function name to register
449 * @addr: the address the function starts at
450 * @mod: the kernel module the function may be in (NULL for none)
451 *
452 * This registers a function name with an address and module.
453 * The @func passed in is duplicated.
454 */
455int pevent_register_function(struct pevent *pevent, char *func,
456 unsigned long long addr, char *mod)
457{
458 struct func_list *item;
459
460 item = malloc_or_die(sizeof(*item));
461
462 item->next = pevent->funclist;
463 item->func = strdup(func);
464 if (mod)
465 item->mod = strdup(mod);
466 else
467 item->mod = NULL;
468 item->addr = addr;
469
Namhyung Kimca638582012-04-09 11:54:31 +0900470 if (!item->func || (mod && !item->mod))
471 die("malloc func");
Steven Rostedtf7d82352012-04-06 00:47:53 +0200472
Namhyung Kimca638582012-04-09 11:54:31 +0900473 pevent->funclist = item;
Steven Rostedtf7d82352012-04-06 00:47:53 +0200474 pevent->func_count++;
475
476 return 0;
477}
478
479/**
480 * pevent_print_funcs - print out the stored functions
481 * @pevent: handle for the pevent
482 *
483 * This prints out the stored functions.
484 */
485void pevent_print_funcs(struct pevent *pevent)
486{
487 int i;
488
489 if (!pevent->func_map)
490 func_map_init(pevent);
491
492 for (i = 0; i < (int)pevent->func_count; i++) {
493 printf("%016llx %s",
494 pevent->func_map[i].addr,
495 pevent->func_map[i].func);
496 if (pevent->func_map[i].mod)
497 printf(" [%s]\n", pevent->func_map[i].mod);
498 else
499 printf("\n");
500 }
501}
502
503struct printk_map {
504 unsigned long long addr;
505 char *printk;
506};
507
508struct printk_list {
509 struct printk_list *next;
510 unsigned long long addr;
511 char *printk;
512};
513
514static int printk_cmp(const void *a, const void *b)
515{
Namhyung Kim0fc45ef2012-04-09 11:54:29 +0900516 const struct printk_map *pa = a;
517 const struct printk_map *pb = b;
Steven Rostedtf7d82352012-04-06 00:47:53 +0200518
Namhyung Kim0fc45ef2012-04-09 11:54:29 +0900519 if (pa->addr < pb->addr)
Steven Rostedtf7d82352012-04-06 00:47:53 +0200520 return -1;
Namhyung Kim0fc45ef2012-04-09 11:54:29 +0900521 if (pa->addr > pb->addr)
Steven Rostedtf7d82352012-04-06 00:47:53 +0200522 return 1;
523
524 return 0;
525}
526
527static void printk_map_init(struct pevent *pevent)
528{
529 struct printk_list *printklist;
530 struct printk_list *item;
531 struct printk_map *printk_map;
532 int i;
533
534 printk_map = malloc_or_die(sizeof(*printk_map) * (pevent->printk_count + 1));
535
536 printklist = pevent->printklist;
537
538 i = 0;
539 while (printklist) {
540 printk_map[i].printk = printklist->printk;
541 printk_map[i].addr = printklist->addr;
542 i++;
543 item = printklist;
544 printklist = printklist->next;
545 free(item);
546 }
547
548 qsort(printk_map, pevent->printk_count, sizeof(*printk_map), printk_cmp);
549
550 pevent->printk_map = printk_map;
551 pevent->printklist = NULL;
552}
553
554static struct printk_map *
555find_printk(struct pevent *pevent, unsigned long long addr)
556{
557 struct printk_map *printk;
558 struct printk_map key;
559
560 if (!pevent->printk_map)
561 printk_map_init(pevent);
562
563 key.addr = addr;
564
565 printk = bsearch(&key, pevent->printk_map, pevent->printk_count,
566 sizeof(*pevent->printk_map), printk_cmp);
567
568 return printk;
569}
570
571/**
572 * pevent_register_print_string - register a string by its address
573 * @pevent: handle for the pevent
574 * @fmt: the string format to register
575 * @addr: the address the string was located at
576 *
577 * This registers a string by the address it was stored in the kernel.
578 * The @fmt passed in is duplicated.
579 */
580int pevent_register_print_string(struct pevent *pevent, char *fmt,
581 unsigned long long addr)
582{
583 struct printk_list *item;
584
585 item = malloc_or_die(sizeof(*item));
586
587 item->next = pevent->printklist;
Steven Rostedtf7d82352012-04-06 00:47:53 +0200588 item->printk = strdup(fmt);
589 item->addr = addr;
590
Namhyung Kimca638582012-04-09 11:54:31 +0900591 if (!item->printk)
592 die("malloc fmt");
593
594 pevent->printklist = item;
Steven Rostedtf7d82352012-04-06 00:47:53 +0200595 pevent->printk_count++;
596
597 return 0;
598}
599
600/**
601 * pevent_print_printk - print out the stored strings
602 * @pevent: handle for the pevent
603 *
604 * This prints the string formats that were stored.
605 */
606void pevent_print_printk(struct pevent *pevent)
607{
608 int i;
609
610 if (!pevent->printk_map)
611 printk_map_init(pevent);
612
613 for (i = 0; i < (int)pevent->printk_count; i++) {
614 printf("%016llx %s\n",
615 pevent->printk_map[i].addr,
616 pevent->printk_map[i].printk);
617 }
618}
619
620static struct event_format *alloc_event(void)
621{
622 struct event_format *event;
623
Namhyung Kim50d8f9e2012-06-11 15:28:53 +0900624 event = malloc(sizeof(*event));
625 if (!event)
626 return NULL;
Steven Rostedtf7d82352012-04-06 00:47:53 +0200627 memset(event, 0, sizeof(*event));
628
629 return event;
630}
631
632static void add_event(struct pevent *pevent, struct event_format *event)
633{
634 int i;
635
636 if (!pevent->events)
637 pevent->events = malloc_or_die(sizeof(event));
638 else
639 pevent->events =
640 realloc(pevent->events, sizeof(event) *
641 (pevent->nr_events + 1));
642 if (!pevent->events)
643 die("Can not allocate events");
644
645 for (i = 0; i < pevent->nr_events; i++) {
646 if (pevent->events[i]->id > event->id)
647 break;
648 }
649 if (i < pevent->nr_events)
650 memmove(&pevent->events[i + 1],
651 &pevent->events[i],
652 sizeof(event) * (pevent->nr_events - i));
653
654 pevent->events[i] = event;
655 pevent->nr_events++;
656
657 event->pevent = pevent;
658}
659
660static int event_item_type(enum event_type type)
661{
662 switch (type) {
663 case EVENT_ITEM ... EVENT_SQUOTE:
664 return 1;
665 case EVENT_ERROR ... EVENT_DELIM:
666 default:
667 return 0;
668 }
669}
670
671static void free_flag_sym(struct print_flag_sym *fsym)
672{
673 struct print_flag_sym *next;
674
675 while (fsym) {
676 next = fsym->next;
677 free(fsym->value);
678 free(fsym->str);
679 free(fsym);
680 fsym = next;
681 }
682}
683
684static void free_arg(struct print_arg *arg)
685{
686 struct print_arg *farg;
687
688 if (!arg)
689 return;
690
691 switch (arg->type) {
692 case PRINT_ATOM:
693 free(arg->atom.atom);
694 break;
695 case PRINT_FIELD:
696 free(arg->field.name);
697 break;
698 case PRINT_FLAGS:
699 free_arg(arg->flags.field);
700 free(arg->flags.delim);
701 free_flag_sym(arg->flags.flags);
702 break;
703 case PRINT_SYMBOL:
704 free_arg(arg->symbol.field);
705 free_flag_sym(arg->symbol.symbols);
706 break;
Namhyung Kime080e6f2012-06-27 09:41:41 +0900707 case PRINT_HEX:
708 free_arg(arg->hex.field);
709 free_arg(arg->hex.size);
710 break;
Steven Rostedtf7d82352012-04-06 00:47:53 +0200711 case PRINT_TYPE:
712 free(arg->typecast.type);
713 free_arg(arg->typecast.item);
714 break;
715 case PRINT_STRING:
716 case PRINT_BSTRING:
717 free(arg->string.string);
718 break;
719 case PRINT_DYNAMIC_ARRAY:
720 free(arg->dynarray.index);
721 break;
722 case PRINT_OP:
723 free(arg->op.op);
724 free_arg(arg->op.left);
725 free_arg(arg->op.right);
726 break;
727 case PRINT_FUNC:
728 while (arg->func.args) {
729 farg = arg->func.args;
730 arg->func.args = farg->next;
731 free_arg(farg);
732 }
733 break;
734
735 case PRINT_NULL:
736 default:
737 break;
738 }
739
740 free(arg);
741}
742
743static enum event_type get_type(int ch)
744{
745 if (ch == '\n')
746 return EVENT_NEWLINE;
747 if (isspace(ch))
748 return EVENT_SPACE;
749 if (isalnum(ch) || ch == '_')
750 return EVENT_ITEM;
751 if (ch == '\'')
752 return EVENT_SQUOTE;
753 if (ch == '"')
754 return EVENT_DQUOTE;
755 if (!isprint(ch))
756 return EVENT_NONE;
757 if (ch == '(' || ch == ')' || ch == ',')
758 return EVENT_DELIM;
759
760 return EVENT_OP;
761}
762
763static int __read_char(void)
764{
765 if (input_buf_ptr >= input_buf_siz)
766 return -1;
767
768 return input_buf[input_buf_ptr++];
769}
770
771static int __peek_char(void)
772{
773 if (input_buf_ptr >= input_buf_siz)
774 return -1;
775
776 return input_buf[input_buf_ptr];
777}
778
779/**
780 * pevent_peek_char - peek at the next character that will be read
781 *
782 * Returns the next character read, or -1 if end of buffer.
783 */
784int pevent_peek_char(void)
785{
786 return __peek_char();
787}
788
Namhyung Kimdeba3fb2012-04-09 11:54:30 +0900789static int extend_token(char **tok, char *buf, int size)
790{
791 char *newtok = realloc(*tok, size);
792
793 if (!newtok) {
794 free(*tok);
795 *tok = NULL;
796 return -1;
797 }
798
799 if (!*tok)
800 strcpy(newtok, buf);
801 else
802 strcat(newtok, buf);
803 *tok = newtok;
804
805 return 0;
806}
807
Steven Rostedtf7d82352012-04-06 00:47:53 +0200808static enum event_type force_token(const char *str, char **tok);
809
810static enum event_type __read_token(char **tok)
811{
812 char buf[BUFSIZ];
813 int ch, last_ch, quote_ch, next_ch;
814 int i = 0;
815 int tok_size = 0;
816 enum event_type type;
817
818 *tok = NULL;
819
820
821 ch = __read_char();
822 if (ch < 0)
823 return EVENT_NONE;
824
825 type = get_type(ch);
826 if (type == EVENT_NONE)
827 return type;
828
829 buf[i++] = ch;
830
831 switch (type) {
832 case EVENT_NEWLINE:
833 case EVENT_DELIM:
834 *tok = malloc_or_die(2);
835 (*tok)[0] = ch;
836 (*tok)[1] = 0;
837 return type;
838
839 case EVENT_OP:
840 switch (ch) {
841 case '-':
842 next_ch = __peek_char();
843 if (next_ch == '>') {
844 buf[i++] = __read_char();
845 break;
846 }
847 /* fall through */
848 case '+':
849 case '|':
850 case '&':
851 case '>':
852 case '<':
853 last_ch = ch;
854 ch = __peek_char();
855 if (ch != last_ch)
856 goto test_equal;
857 buf[i++] = __read_char();
858 switch (last_ch) {
859 case '>':
860 case '<':
861 goto test_equal;
862 default:
863 break;
864 }
865 break;
866 case '!':
867 case '=':
868 goto test_equal;
869 default: /* what should we do instead? */
870 break;
871 }
872 buf[i] = 0;
873 *tok = strdup(buf);
874 return type;
875
876 test_equal:
877 ch = __peek_char();
878 if (ch == '=')
879 buf[i++] = __read_char();
880 goto out;
881
882 case EVENT_DQUOTE:
883 case EVENT_SQUOTE:
884 /* don't keep quotes */
885 i--;
886 quote_ch = ch;
887 last_ch = 0;
888 concat:
889 do {
890 if (i == (BUFSIZ - 1)) {
891 buf[i] = 0;
Steven Rostedtf7d82352012-04-06 00:47:53 +0200892 tok_size += BUFSIZ;
Namhyung Kimdeba3fb2012-04-09 11:54:30 +0900893
894 if (extend_token(tok, buf, tok_size) < 0)
895 return EVENT_NONE;
Steven Rostedtf7d82352012-04-06 00:47:53 +0200896 i = 0;
897 }
898 last_ch = ch;
899 ch = __read_char();
900 buf[i++] = ch;
901 /* the '\' '\' will cancel itself */
902 if (ch == '\\' && last_ch == '\\')
903 last_ch = 0;
904 } while (ch != quote_ch || last_ch == '\\');
905 /* remove the last quote */
906 i--;
907
908 /*
909 * For strings (double quotes) check the next token.
910 * If it is another string, concatinate the two.
911 */
912 if (type == EVENT_DQUOTE) {
913 unsigned long long save_input_buf_ptr = input_buf_ptr;
914
915 do {
916 ch = __read_char();
917 } while (isspace(ch));
918 if (ch == '"')
919 goto concat;
920 input_buf_ptr = save_input_buf_ptr;
921 }
922
923 goto out;
924
925 case EVENT_ERROR ... EVENT_SPACE:
926 case EVENT_ITEM:
927 default:
928 break;
929 }
930
931 while (get_type(__peek_char()) == type) {
932 if (i == (BUFSIZ - 1)) {
933 buf[i] = 0;
Steven Rostedtf7d82352012-04-06 00:47:53 +0200934 tok_size += BUFSIZ;
Namhyung Kimdeba3fb2012-04-09 11:54:30 +0900935
936 if (extend_token(tok, buf, tok_size) < 0)
937 return EVENT_NONE;
Steven Rostedtf7d82352012-04-06 00:47:53 +0200938 i = 0;
939 }
940 ch = __read_char();
941 buf[i++] = ch;
942 }
943
944 out:
945 buf[i] = 0;
Namhyung Kimdeba3fb2012-04-09 11:54:30 +0900946 if (extend_token(tok, buf, tok_size + i + 1) < 0)
Steven Rostedtf7d82352012-04-06 00:47:53 +0200947 return EVENT_NONE;
948
949 if (type == EVENT_ITEM) {
950 /*
951 * Older versions of the kernel has a bug that
952 * creates invalid symbols and will break the mac80211
953 * parsing. This is a work around to that bug.
954 *
955 * See Linux kernel commit:
956 * 811cb50baf63461ce0bdb234927046131fc7fa8b
957 */
958 if (strcmp(*tok, "LOCAL_PR_FMT") == 0) {
959 free(*tok);
960 *tok = NULL;
961 return force_token("\"\%s\" ", tok);
962 } else if (strcmp(*tok, "STA_PR_FMT") == 0) {
963 free(*tok);
964 *tok = NULL;
965 return force_token("\" sta:%pM\" ", tok);
966 } else if (strcmp(*tok, "VIF_PR_FMT") == 0) {
967 free(*tok);
968 *tok = NULL;
969 return force_token("\" vif:%p(%d)\" ", tok);
970 }
971 }
972
973 return type;
974}
975
976static enum event_type force_token(const char *str, char **tok)
977{
978 const char *save_input_buf;
979 unsigned long long save_input_buf_ptr;
980 unsigned long long save_input_buf_siz;
981 enum event_type type;
982
983 /* save off the current input pointers */
984 save_input_buf = input_buf;
985 save_input_buf_ptr = input_buf_ptr;
986 save_input_buf_siz = input_buf_siz;
987
988 init_input_buf(str, strlen(str));
989
990 type = __read_token(tok);
991
992 /* reset back to original token */
993 input_buf = save_input_buf;
994 input_buf_ptr = save_input_buf_ptr;
995 input_buf_siz = save_input_buf_siz;
996
997 return type;
998}
999
1000static void free_token(char *tok)
1001{
1002 if (tok)
1003 free(tok);
1004}
1005
1006static enum event_type read_token(char **tok)
1007{
1008 enum event_type type;
1009
1010 for (;;) {
1011 type = __read_token(tok);
1012 if (type != EVENT_SPACE)
1013 return type;
1014
1015 free_token(*tok);
1016 }
1017
1018 /* not reached */
1019 *tok = NULL;
1020 return EVENT_NONE;
1021}
1022
1023/**
1024 * pevent_read_token - access to utilites to use the pevent parser
1025 * @tok: The token to return
1026 *
1027 * This will parse tokens from the string given by
1028 * pevent_init_data().
1029 *
1030 * Returns the token type.
1031 */
1032enum event_type pevent_read_token(char **tok)
1033{
1034 return read_token(tok);
1035}
1036
1037/**
1038 * pevent_free_token - free a token returned by pevent_read_token
1039 * @token: the token to free
1040 */
1041void pevent_free_token(char *token)
1042{
1043 free_token(token);
1044}
1045
1046/* no newline */
1047static enum event_type read_token_item(char **tok)
1048{
1049 enum event_type type;
1050
1051 for (;;) {
1052 type = __read_token(tok);
1053 if (type != EVENT_SPACE && type != EVENT_NEWLINE)
1054 return type;
1055 free_token(*tok);
1056 *tok = NULL;
1057 }
1058
1059 /* not reached */
1060 *tok = NULL;
1061 return EVENT_NONE;
1062}
1063
1064static int test_type(enum event_type type, enum event_type expect)
1065{
1066 if (type != expect) {
1067 do_warning("Error: expected type %d but read %d",
1068 expect, type);
1069 return -1;
1070 }
1071 return 0;
1072}
1073
1074static int test_type_token(enum event_type type, const char *token,
1075 enum event_type expect, const char *expect_tok)
1076{
1077 if (type != expect) {
1078 do_warning("Error: expected type %d but read %d",
1079 expect, type);
1080 return -1;
1081 }
1082
1083 if (strcmp(token, expect_tok) != 0) {
1084 do_warning("Error: expected '%s' but read '%s'",
1085 expect_tok, token);
1086 return -1;
1087 }
1088 return 0;
1089}
1090
1091static int __read_expect_type(enum event_type expect, char **tok, int newline_ok)
1092{
1093 enum event_type type;
1094
1095 if (newline_ok)
1096 type = read_token(tok);
1097 else
1098 type = read_token_item(tok);
1099 return test_type(type, expect);
1100}
1101
1102static int read_expect_type(enum event_type expect, char **tok)
1103{
1104 return __read_expect_type(expect, tok, 1);
1105}
1106
1107static int __read_expected(enum event_type expect, const char *str,
1108 int newline_ok)
1109{
1110 enum event_type type;
1111 char *token;
1112 int ret;
1113
1114 if (newline_ok)
1115 type = read_token(&token);
1116 else
1117 type = read_token_item(&token);
1118
1119 ret = test_type_token(type, token, expect, str);
1120
1121 free_token(token);
1122
1123 return ret;
1124}
1125
1126static int read_expected(enum event_type expect, const char *str)
1127{
1128 return __read_expected(expect, str, 1);
1129}
1130
1131static int read_expected_item(enum event_type expect, const char *str)
1132{
1133 return __read_expected(expect, str, 0);
1134}
1135
1136static char *event_read_name(void)
1137{
1138 char *token;
1139
1140 if (read_expected(EVENT_ITEM, "name") < 0)
1141 return NULL;
1142
1143 if (read_expected(EVENT_OP, ":") < 0)
1144 return NULL;
1145
1146 if (read_expect_type(EVENT_ITEM, &token) < 0)
1147 goto fail;
1148
1149 return token;
1150
1151 fail:
1152 free_token(token);
1153 return NULL;
1154}
1155
1156static int event_read_id(void)
1157{
1158 char *token;
1159 int id;
1160
1161 if (read_expected_item(EVENT_ITEM, "ID") < 0)
1162 return -1;
1163
1164 if (read_expected(EVENT_OP, ":") < 0)
1165 return -1;
1166
1167 if (read_expect_type(EVENT_ITEM, &token) < 0)
1168 goto fail;
1169
1170 id = strtoul(token, NULL, 0);
1171 free_token(token);
1172 return id;
1173
1174 fail:
1175 free_token(token);
1176 return -1;
1177}
1178
1179static int field_is_string(struct format_field *field)
1180{
1181 if ((field->flags & FIELD_IS_ARRAY) &&
1182 (strstr(field->type, "char") || strstr(field->type, "u8") ||
1183 strstr(field->type, "s8")))
1184 return 1;
1185
1186 return 0;
1187}
1188
1189static int field_is_dynamic(struct format_field *field)
1190{
1191 if (strncmp(field->type, "__data_loc", 10) == 0)
1192 return 1;
1193
1194 return 0;
1195}
1196
1197static int field_is_long(struct format_field *field)
1198{
1199 /* includes long long */
1200 if (strstr(field->type, "long"))
1201 return 1;
1202
1203 return 0;
1204}
1205
1206static int event_read_fields(struct event_format *event, struct format_field **fields)
1207{
1208 struct format_field *field = NULL;
1209 enum event_type type;
1210 char *token;
1211 char *last_token;
1212 int count = 0;
1213
1214 do {
1215 type = read_token(&token);
1216 if (type == EVENT_NEWLINE) {
1217 free_token(token);
1218 return count;
1219 }
1220
1221 count++;
1222
1223 if (test_type_token(type, token, EVENT_ITEM, "field"))
1224 goto fail;
1225 free_token(token);
1226
1227 type = read_token(&token);
1228 /*
1229 * The ftrace fields may still use the "special" name.
1230 * Just ignore it.
1231 */
1232 if (event->flags & EVENT_FL_ISFTRACE &&
1233 type == EVENT_ITEM && strcmp(token, "special") == 0) {
1234 free_token(token);
1235 type = read_token(&token);
1236 }
1237
1238 if (test_type_token(type, token, EVENT_OP, ":") < 0)
1239 goto fail;
1240
1241 free_token(token);
1242 if (read_expect_type(EVENT_ITEM, &token) < 0)
1243 goto fail;
1244
1245 last_token = token;
1246
1247 field = malloc_or_die(sizeof(*field));
1248 memset(field, 0, sizeof(*field));
1249 field->event = event;
1250
1251 /* read the rest of the type */
1252 for (;;) {
1253 type = read_token(&token);
1254 if (type == EVENT_ITEM ||
1255 (type == EVENT_OP && strcmp(token, "*") == 0) ||
1256 /*
1257 * Some of the ftrace fields are broken and have
1258 * an illegal "." in them.
1259 */
1260 (event->flags & EVENT_FL_ISFTRACE &&
1261 type == EVENT_OP && strcmp(token, ".") == 0)) {
1262
1263 if (strcmp(token, "*") == 0)
1264 field->flags |= FIELD_IS_POINTER;
1265
1266 if (field->type) {
Namhyung Kimd2864472012-04-09 11:54:33 +09001267 char *new_type;
1268 new_type = realloc(field->type,
1269 strlen(field->type) +
1270 strlen(last_token) + 2);
1271 if (!new_type) {
1272 free(last_token);
1273 goto fail;
1274 }
1275 field->type = new_type;
Steven Rostedtf7d82352012-04-06 00:47:53 +02001276 strcat(field->type, " ");
1277 strcat(field->type, last_token);
1278 free(last_token);
1279 } else
1280 field->type = last_token;
1281 last_token = token;
1282 continue;
1283 }
1284
1285 break;
1286 }
1287
1288 if (!field->type) {
1289 die("no type found");
1290 goto fail;
1291 }
1292 field->name = last_token;
1293
1294 if (test_type(type, EVENT_OP))
1295 goto fail;
1296
1297 if (strcmp(token, "[") == 0) {
1298 enum event_type last_type = type;
1299 char *brackets = token;
Namhyung Kimd2864472012-04-09 11:54:33 +09001300 char *new_brackets;
Steven Rostedtf7d82352012-04-06 00:47:53 +02001301 int len;
1302
1303 field->flags |= FIELD_IS_ARRAY;
1304
1305 type = read_token(&token);
1306
1307 if (type == EVENT_ITEM)
1308 field->arraylen = strtoul(token, NULL, 0);
1309 else
1310 field->arraylen = 0;
1311
1312 while (strcmp(token, "]") != 0) {
1313 if (last_type == EVENT_ITEM &&
1314 type == EVENT_ITEM)
1315 len = 2;
1316 else
1317 len = 1;
1318 last_type = type;
1319
Namhyung Kimd2864472012-04-09 11:54:33 +09001320 new_brackets = realloc(brackets,
1321 strlen(brackets) +
1322 strlen(token) + len);
1323 if (!new_brackets) {
1324 free(brackets);
1325 goto fail;
1326 }
1327 brackets = new_brackets;
Steven Rostedtf7d82352012-04-06 00:47:53 +02001328 if (len == 2)
1329 strcat(brackets, " ");
1330 strcat(brackets, token);
1331 /* We only care about the last token */
1332 field->arraylen = strtoul(token, NULL, 0);
1333 free_token(token);
1334 type = read_token(&token);
1335 if (type == EVENT_NONE) {
1336 die("failed to find token");
1337 goto fail;
1338 }
1339 }
1340
1341 free_token(token);
1342
Namhyung Kimd2864472012-04-09 11:54:33 +09001343 new_brackets = realloc(brackets, strlen(brackets) + 2);
1344 if (!new_brackets) {
1345 free(brackets);
1346 goto fail;
1347 }
1348 brackets = new_brackets;
Steven Rostedtf7d82352012-04-06 00:47:53 +02001349 strcat(brackets, "]");
1350
1351 /* add brackets to type */
1352
1353 type = read_token(&token);
1354 /*
1355 * If the next token is not an OP, then it is of
1356 * the format: type [] item;
1357 */
1358 if (type == EVENT_ITEM) {
Namhyung Kimd2864472012-04-09 11:54:33 +09001359 char *new_type;
1360 new_type = realloc(field->type,
1361 strlen(field->type) +
1362 strlen(field->name) +
1363 strlen(brackets) + 2);
1364 if (!new_type) {
1365 free(brackets);
1366 goto fail;
1367 }
1368 field->type = new_type;
Steven Rostedtf7d82352012-04-06 00:47:53 +02001369 strcat(field->type, " ");
1370 strcat(field->type, field->name);
1371 free_token(field->name);
1372 strcat(field->type, brackets);
1373 field->name = token;
1374 type = read_token(&token);
1375 } else {
Namhyung Kimd2864472012-04-09 11:54:33 +09001376 char *new_type;
1377 new_type = realloc(field->type,
1378 strlen(field->type) +
1379 strlen(brackets) + 1);
1380 if (!new_type) {
1381 free(brackets);
1382 goto fail;
1383 }
1384 field->type = new_type;
Steven Rostedtf7d82352012-04-06 00:47:53 +02001385 strcat(field->type, brackets);
1386 }
1387 free(brackets);
1388 }
1389
1390 if (field_is_string(field))
1391 field->flags |= FIELD_IS_STRING;
1392 if (field_is_dynamic(field))
1393 field->flags |= FIELD_IS_DYNAMIC;
1394 if (field_is_long(field))
1395 field->flags |= FIELD_IS_LONG;
1396
1397 if (test_type_token(type, token, EVENT_OP, ";"))
1398 goto fail;
1399 free_token(token);
1400
1401 if (read_expected(EVENT_ITEM, "offset") < 0)
1402 goto fail_expect;
1403
1404 if (read_expected(EVENT_OP, ":") < 0)
1405 goto fail_expect;
1406
1407 if (read_expect_type(EVENT_ITEM, &token))
1408 goto fail;
1409 field->offset = strtoul(token, NULL, 0);
1410 free_token(token);
1411
1412 if (read_expected(EVENT_OP, ";") < 0)
1413 goto fail_expect;
1414
1415 if (read_expected(EVENT_ITEM, "size") < 0)
1416 goto fail_expect;
1417
1418 if (read_expected(EVENT_OP, ":") < 0)
1419 goto fail_expect;
1420
1421 if (read_expect_type(EVENT_ITEM, &token))
1422 goto fail;
1423 field->size = strtoul(token, NULL, 0);
1424 free_token(token);
1425
1426 if (read_expected(EVENT_OP, ";") < 0)
1427 goto fail_expect;
1428
1429 type = read_token(&token);
1430 if (type != EVENT_NEWLINE) {
1431 /* newer versions of the kernel have a "signed" type */
1432 if (test_type_token(type, token, EVENT_ITEM, "signed"))
1433 goto fail;
1434
1435 free_token(token);
1436
1437 if (read_expected(EVENT_OP, ":") < 0)
1438 goto fail_expect;
1439
1440 if (read_expect_type(EVENT_ITEM, &token))
1441 goto fail;
1442
1443 /* add signed type */
1444
1445 free_token(token);
1446 if (read_expected(EVENT_OP, ";") < 0)
1447 goto fail_expect;
1448
1449 if (read_expect_type(EVENT_NEWLINE, &token))
1450 goto fail;
1451 }
1452
1453 free_token(token);
1454
1455 if (field->flags & FIELD_IS_ARRAY) {
1456 if (field->arraylen)
1457 field->elementsize = field->size / field->arraylen;
1458 else if (field->flags & FIELD_IS_STRING)
1459 field->elementsize = 1;
1460 else
1461 field->elementsize = event->pevent->long_size;
1462 } else
1463 field->elementsize = field->size;
1464
1465 *fields = field;
1466 fields = &field->next;
1467
1468 } while (1);
1469
1470 return 0;
1471
1472fail:
1473 free_token(token);
1474fail_expect:
Namhyung Kim57d34dc2012-05-23 11:36:47 +09001475 if (field) {
1476 free(field->type);
1477 free(field->name);
Steven Rostedtf7d82352012-04-06 00:47:53 +02001478 free(field);
Namhyung Kim57d34dc2012-05-23 11:36:47 +09001479 }
Steven Rostedtf7d82352012-04-06 00:47:53 +02001480 return -1;
1481}
1482
1483static int event_read_format(struct event_format *event)
1484{
1485 char *token;
1486 int ret;
1487
1488 if (read_expected_item(EVENT_ITEM, "format") < 0)
1489 return -1;
1490
1491 if (read_expected(EVENT_OP, ":") < 0)
1492 return -1;
1493
1494 if (read_expect_type(EVENT_NEWLINE, &token))
1495 goto fail;
1496 free_token(token);
1497
1498 ret = event_read_fields(event, &event->format.common_fields);
1499 if (ret < 0)
1500 return ret;
1501 event->format.nr_common = ret;
1502
1503 ret = event_read_fields(event, &event->format.fields);
1504 if (ret < 0)
1505 return ret;
1506 event->format.nr_fields = ret;
1507
1508 return 0;
1509
1510 fail:
1511 free_token(token);
1512 return -1;
1513}
1514
1515static enum event_type
1516process_arg_token(struct event_format *event, struct print_arg *arg,
1517 char **tok, enum event_type type);
1518
1519static enum event_type
1520process_arg(struct event_format *event, struct print_arg *arg, char **tok)
1521{
1522 enum event_type type;
1523 char *token;
1524
1525 type = read_token(&token);
1526 *tok = token;
1527
1528 return process_arg_token(event, arg, tok, type);
1529}
1530
1531static enum event_type
1532process_op(struct event_format *event, struct print_arg *arg, char **tok);
1533
1534static enum event_type
1535process_cond(struct event_format *event, struct print_arg *top, char **tok)
1536{
1537 struct print_arg *arg, *left, *right;
1538 enum event_type type;
1539 char *token = NULL;
1540
1541 arg = alloc_arg();
1542 left = alloc_arg();
1543 right = alloc_arg();
1544
1545 arg->type = PRINT_OP;
1546 arg->op.left = left;
1547 arg->op.right = right;
1548
1549 *tok = NULL;
1550 type = process_arg(event, left, &token);
1551
1552 again:
1553 /* Handle other operations in the arguments */
1554 if (type == EVENT_OP && strcmp(token, ":") != 0) {
1555 type = process_op(event, left, &token);
1556 goto again;
1557 }
1558
1559 if (test_type_token(type, token, EVENT_OP, ":"))
1560 goto out_free;
1561
1562 arg->op.op = token;
1563
1564 type = process_arg(event, right, &token);
1565
1566 top->op.right = arg;
1567
1568 *tok = token;
1569 return type;
1570
1571out_free:
1572 /* Top may point to itself */
1573 top->op.right = NULL;
1574 free_token(token);
1575 free_arg(arg);
1576 return EVENT_ERROR;
1577}
1578
1579static enum event_type
1580process_array(struct event_format *event, struct print_arg *top, char **tok)
1581{
1582 struct print_arg *arg;
1583 enum event_type type;
1584 char *token = NULL;
1585
1586 arg = alloc_arg();
1587
1588 *tok = NULL;
1589 type = process_arg(event, arg, &token);
1590 if (test_type_token(type, token, EVENT_OP, "]"))
1591 goto out_free;
1592
1593 top->op.right = arg;
1594
1595 free_token(token);
1596 type = read_token_item(&token);
1597 *tok = token;
1598
1599 return type;
1600
1601out_free:
1602 free_token(*tok);
1603 *tok = NULL;
1604 free_arg(arg);
1605 return EVENT_ERROR;
1606}
1607
1608static int get_op_prio(char *op)
1609{
1610 if (!op[1]) {
1611 switch (op[0]) {
1612 case '~':
1613 case '!':
1614 return 4;
1615 case '*':
1616 case '/':
1617 case '%':
1618 return 6;
1619 case '+':
1620 case '-':
1621 return 7;
1622 /* '>>' and '<<' are 8 */
1623 case '<':
1624 case '>':
1625 return 9;
1626 /* '==' and '!=' are 10 */
1627 case '&':
1628 return 11;
1629 case '^':
1630 return 12;
1631 case '|':
1632 return 13;
1633 case '?':
1634 return 16;
1635 default:
Vaibhav Nagarnaik14ffde02012-04-06 00:48:01 +02001636 do_warning("unknown op '%c'", op[0]);
Steven Rostedtf7d82352012-04-06 00:47:53 +02001637 return -1;
1638 }
1639 } else {
1640 if (strcmp(op, "++") == 0 ||
1641 strcmp(op, "--") == 0) {
1642 return 3;
1643 } else if (strcmp(op, ">>") == 0 ||
1644 strcmp(op, "<<") == 0) {
1645 return 8;
1646 } else if (strcmp(op, ">=") == 0 ||
1647 strcmp(op, "<=") == 0) {
1648 return 9;
1649 } else if (strcmp(op, "==") == 0 ||
1650 strcmp(op, "!=") == 0) {
1651 return 10;
1652 } else if (strcmp(op, "&&") == 0) {
1653 return 14;
1654 } else if (strcmp(op, "||") == 0) {
1655 return 15;
1656 } else {
Vaibhav Nagarnaik14ffde02012-04-06 00:48:01 +02001657 do_warning("unknown op '%s'", op);
Steven Rostedtf7d82352012-04-06 00:47:53 +02001658 return -1;
1659 }
1660 }
1661}
1662
Vaibhav Nagarnaik14ffde02012-04-06 00:48:01 +02001663static int set_op_prio(struct print_arg *arg)
Steven Rostedtf7d82352012-04-06 00:47:53 +02001664{
1665
1666 /* single ops are the greatest */
Vaibhav Nagarnaik14ffde02012-04-06 00:48:01 +02001667 if (!arg->op.left || arg->op.left->type == PRINT_NULL)
Steven Rostedtf7d82352012-04-06 00:47:53 +02001668 arg->op.prio = 0;
Vaibhav Nagarnaik14ffde02012-04-06 00:48:01 +02001669 else
1670 arg->op.prio = get_op_prio(arg->op.op);
Steven Rostedtf7d82352012-04-06 00:47:53 +02001671
Vaibhav Nagarnaik14ffde02012-04-06 00:48:01 +02001672 return arg->op.prio;
Steven Rostedtf7d82352012-04-06 00:47:53 +02001673}
1674
1675/* Note, *tok does not get freed, but will most likely be saved */
1676static enum event_type
1677process_op(struct event_format *event, struct print_arg *arg, char **tok)
1678{
1679 struct print_arg *left, *right = NULL;
1680 enum event_type type;
1681 char *token;
1682
1683 /* the op is passed in via tok */
1684 token = *tok;
1685
1686 if (arg->type == PRINT_OP && !arg->op.left) {
1687 /* handle single op */
1688 if (token[1]) {
1689 die("bad op token %s", token);
1690 goto out_free;
1691 }
1692 switch (token[0]) {
1693 case '~':
1694 case '!':
1695 case '+':
1696 case '-':
1697 break;
1698 default:
1699 do_warning("bad op token %s", token);
1700 goto out_free;
1701
1702 }
1703
1704 /* make an empty left */
1705 left = alloc_arg();
1706 left->type = PRINT_NULL;
1707 arg->op.left = left;
1708
1709 right = alloc_arg();
1710 arg->op.right = right;
1711
1712 /* do not free the token, it belongs to an op */
1713 *tok = NULL;
1714 type = process_arg(event, right, tok);
1715
1716 } else if (strcmp(token, "?") == 0) {
1717
1718 left = alloc_arg();
1719 /* copy the top arg to the left */
1720 *left = *arg;
1721
1722 arg->type = PRINT_OP;
1723 arg->op.op = token;
1724 arg->op.left = left;
1725 arg->op.prio = 0;
1726
1727 type = process_cond(event, arg, tok);
1728
1729 } else if (strcmp(token, ">>") == 0 ||
1730 strcmp(token, "<<") == 0 ||
1731 strcmp(token, "&") == 0 ||
1732 strcmp(token, "|") == 0 ||
1733 strcmp(token, "&&") == 0 ||
1734 strcmp(token, "||") == 0 ||
1735 strcmp(token, "-") == 0 ||
1736 strcmp(token, "+") == 0 ||
1737 strcmp(token, "*") == 0 ||
1738 strcmp(token, "^") == 0 ||
1739 strcmp(token, "/") == 0 ||
1740 strcmp(token, "<") == 0 ||
1741 strcmp(token, ">") == 0 ||
1742 strcmp(token, "==") == 0 ||
1743 strcmp(token, "!=") == 0) {
1744
1745 left = alloc_arg();
1746
1747 /* copy the top arg to the left */
1748 *left = *arg;
1749
1750 arg->type = PRINT_OP;
1751 arg->op.op = token;
1752 arg->op.left = left;
1753
Vaibhav Nagarnaik14ffde02012-04-06 00:48:01 +02001754 if (set_op_prio(arg) == -1) {
1755 event->flags |= EVENT_FL_FAILED;
Namhyung Kimd1de1082012-05-23 11:36:49 +09001756 /* arg->op.op (= token) will be freed at out_free */
1757 arg->op.op = NULL;
Vaibhav Nagarnaik14ffde02012-04-06 00:48:01 +02001758 goto out_free;
1759 }
Steven Rostedtf7d82352012-04-06 00:47:53 +02001760
1761 type = read_token_item(&token);
1762 *tok = token;
1763
1764 /* could just be a type pointer */
1765 if ((strcmp(arg->op.op, "*") == 0) &&
1766 type == EVENT_DELIM && (strcmp(token, ")") == 0)) {
Namhyung Kimd2864472012-04-09 11:54:33 +09001767 char *new_atom;
1768
Steven Rostedtf7d82352012-04-06 00:47:53 +02001769 if (left->type != PRINT_ATOM)
1770 die("bad pointer type");
Namhyung Kimd2864472012-04-09 11:54:33 +09001771 new_atom = realloc(left->atom.atom,
Steven Rostedtf7d82352012-04-06 00:47:53 +02001772 strlen(left->atom.atom) + 3);
Namhyung Kimd2864472012-04-09 11:54:33 +09001773 if (!new_atom)
1774 goto out_free;
1775
1776 left->atom.atom = new_atom;
Steven Rostedtf7d82352012-04-06 00:47:53 +02001777 strcat(left->atom.atom, " *");
1778 free(arg->op.op);
1779 *arg = *left;
1780 free(left);
1781
1782 return type;
1783 }
1784
1785 right = alloc_arg();
1786 type = process_arg_token(event, right, tok, type);
1787 arg->op.right = right;
1788
1789 } else if (strcmp(token, "[") == 0) {
1790
1791 left = alloc_arg();
1792 *left = *arg;
1793
1794 arg->type = PRINT_OP;
1795 arg->op.op = token;
1796 arg->op.left = left;
1797
1798 arg->op.prio = 0;
1799
1800 type = process_array(event, arg, tok);
1801
1802 } else {
1803 do_warning("unknown op '%s'", token);
1804 event->flags |= EVENT_FL_FAILED;
1805 /* the arg is now the left side */
1806 goto out_free;
1807 }
1808
1809 if (type == EVENT_OP && strcmp(*tok, ":") != 0) {
1810 int prio;
1811
1812 /* higher prios need to be closer to the root */
1813 prio = get_op_prio(*tok);
1814
1815 if (prio > arg->op.prio)
1816 return process_op(event, arg, tok);
1817
1818 return process_op(event, right, tok);
1819 }
1820
1821 return type;
1822
1823 out_free:
1824 free_token(token);
1825 *tok = NULL;
1826 return EVENT_ERROR;
1827}
1828
1829static enum event_type
1830process_entry(struct event_format *event __unused, struct print_arg *arg,
1831 char **tok)
1832{
1833 enum event_type type;
1834 char *field;
1835 char *token;
1836
1837 if (read_expected(EVENT_OP, "->") < 0)
1838 goto out_err;
1839
1840 if (read_expect_type(EVENT_ITEM, &token) < 0)
1841 goto out_free;
1842 field = token;
1843
1844 arg->type = PRINT_FIELD;
1845 arg->field.name = field;
1846
Tom Zanussi5205aec2012-04-06 00:47:58 +02001847 if (is_flag_field) {
1848 arg->field.field = pevent_find_any_field(event, arg->field.name);
1849 arg->field.field->flags |= FIELD_IS_FLAG;
1850 is_flag_field = 0;
1851 } else if (is_symbolic_field) {
1852 arg->field.field = pevent_find_any_field(event, arg->field.name);
1853 arg->field.field->flags |= FIELD_IS_SYMBOLIC;
1854 is_symbolic_field = 0;
1855 }
1856
Steven Rostedtf7d82352012-04-06 00:47:53 +02001857 type = read_token(&token);
1858 *tok = token;
1859
1860 return type;
1861
1862 out_free:
1863 free_token(token);
1864 out_err:
1865 *tok = NULL;
1866 return EVENT_ERROR;
1867}
1868
1869static char *arg_eval (struct print_arg *arg);
1870
1871static unsigned long long
1872eval_type_str(unsigned long long val, const char *type, int pointer)
1873{
1874 int sign = 0;
1875 char *ref;
1876 int len;
1877
1878 len = strlen(type);
1879
1880 if (pointer) {
1881
1882 if (type[len-1] != '*') {
1883 do_warning("pointer expected with non pointer type");
1884 return val;
1885 }
1886
1887 ref = malloc_or_die(len);
1888 memcpy(ref, type, len);
1889
1890 /* chop off the " *" */
1891 ref[len - 2] = 0;
1892
1893 val = eval_type_str(val, ref, 0);
1894 free(ref);
1895 return val;
1896 }
1897
1898 /* check if this is a pointer */
1899 if (type[len - 1] == '*')
1900 return val;
1901
1902 /* Try to figure out the arg size*/
1903 if (strncmp(type, "struct", 6) == 0)
1904 /* all bets off */
1905 return val;
1906
1907 if (strcmp(type, "u8") == 0)
1908 return val & 0xff;
1909
1910 if (strcmp(type, "u16") == 0)
1911 return val & 0xffff;
1912
1913 if (strcmp(type, "u32") == 0)
1914 return val & 0xffffffff;
1915
1916 if (strcmp(type, "u64") == 0 ||
1917 strcmp(type, "s64"))
1918 return val;
1919
1920 if (strcmp(type, "s8") == 0)
1921 return (unsigned long long)(char)val & 0xff;
1922
1923 if (strcmp(type, "s16") == 0)
1924 return (unsigned long long)(short)val & 0xffff;
1925
1926 if (strcmp(type, "s32") == 0)
1927 return (unsigned long long)(int)val & 0xffffffff;
1928
1929 if (strncmp(type, "unsigned ", 9) == 0) {
1930 sign = 0;
1931 type += 9;
1932 }
1933
1934 if (strcmp(type, "char") == 0) {
1935 if (sign)
1936 return (unsigned long long)(char)val & 0xff;
1937 else
1938 return val & 0xff;
1939 }
1940
1941 if (strcmp(type, "short") == 0) {
1942 if (sign)
1943 return (unsigned long long)(short)val & 0xffff;
1944 else
1945 return val & 0xffff;
1946 }
1947
1948 if (strcmp(type, "int") == 0) {
1949 if (sign)
1950 return (unsigned long long)(int)val & 0xffffffff;
1951 else
1952 return val & 0xffffffff;
1953 }
1954
1955 return val;
1956}
1957
1958/*
1959 * Try to figure out the type.
1960 */
1961static unsigned long long
1962eval_type(unsigned long long val, struct print_arg *arg, int pointer)
1963{
1964 if (arg->type != PRINT_TYPE)
1965 die("expected type argument");
1966
1967 return eval_type_str(val, arg->typecast.type, pointer);
1968}
1969
Vaibhav Nagarnaikd69afed52012-04-06 00:48:00 +02001970static int arg_num_eval(struct print_arg *arg, long long *val)
Steven Rostedtf7d82352012-04-06 00:47:53 +02001971{
1972 long long left, right;
Vaibhav Nagarnaikd69afed52012-04-06 00:48:00 +02001973 int ret = 1;
Steven Rostedtf7d82352012-04-06 00:47:53 +02001974
1975 switch (arg->type) {
1976 case PRINT_ATOM:
Vaibhav Nagarnaikd69afed52012-04-06 00:48:00 +02001977 *val = strtoll(arg->atom.atom, NULL, 0);
Steven Rostedtf7d82352012-04-06 00:47:53 +02001978 break;
1979 case PRINT_TYPE:
Vaibhav Nagarnaikd69afed52012-04-06 00:48:00 +02001980 ret = arg_num_eval(arg->typecast.item, val);
1981 if (!ret)
1982 break;
1983 *val = eval_type(*val, arg, 0);
Steven Rostedtf7d82352012-04-06 00:47:53 +02001984 break;
1985 case PRINT_OP:
1986 switch (arg->op.op[0]) {
1987 case '|':
Vaibhav Nagarnaikd69afed52012-04-06 00:48:00 +02001988 ret = arg_num_eval(arg->op.left, &left);
1989 if (!ret)
1990 break;
1991 ret = arg_num_eval(arg->op.right, &right);
1992 if (!ret)
1993 break;
Steven Rostedtf7d82352012-04-06 00:47:53 +02001994 if (arg->op.op[1])
Vaibhav Nagarnaikd69afed52012-04-06 00:48:00 +02001995 *val = left || right;
Steven Rostedtf7d82352012-04-06 00:47:53 +02001996 else
Vaibhav Nagarnaikd69afed52012-04-06 00:48:00 +02001997 *val = left | right;
Steven Rostedtf7d82352012-04-06 00:47:53 +02001998 break;
1999 case '&':
Vaibhav Nagarnaikd69afed52012-04-06 00:48:00 +02002000 ret = arg_num_eval(arg->op.left, &left);
2001 if (!ret)
2002 break;
2003 ret = arg_num_eval(arg->op.right, &right);
2004 if (!ret)
2005 break;
Steven Rostedtf7d82352012-04-06 00:47:53 +02002006 if (arg->op.op[1])
Vaibhav Nagarnaikd69afed52012-04-06 00:48:00 +02002007 *val = left && right;
Steven Rostedtf7d82352012-04-06 00:47:53 +02002008 else
Vaibhav Nagarnaikd69afed52012-04-06 00:48:00 +02002009 *val = left & right;
Steven Rostedtf7d82352012-04-06 00:47:53 +02002010 break;
2011 case '<':
Vaibhav Nagarnaikd69afed52012-04-06 00:48:00 +02002012 ret = arg_num_eval(arg->op.left, &left);
2013 if (!ret)
2014 break;
2015 ret = arg_num_eval(arg->op.right, &right);
2016 if (!ret)
2017 break;
Steven Rostedtf7d82352012-04-06 00:47:53 +02002018 switch (arg->op.op[1]) {
2019 case 0:
Vaibhav Nagarnaikd69afed52012-04-06 00:48:00 +02002020 *val = left < right;
Steven Rostedtf7d82352012-04-06 00:47:53 +02002021 break;
2022 case '<':
Vaibhav Nagarnaikd69afed52012-04-06 00:48:00 +02002023 *val = left << right;
Steven Rostedtf7d82352012-04-06 00:47:53 +02002024 break;
2025 case '=':
Vaibhav Nagarnaikd69afed52012-04-06 00:48:00 +02002026 *val = left <= right;
Steven Rostedtf7d82352012-04-06 00:47:53 +02002027 break;
2028 default:
Vaibhav Nagarnaikd69afed52012-04-06 00:48:00 +02002029 do_warning("unknown op '%s'", arg->op.op);
2030 ret = 0;
Steven Rostedtf7d82352012-04-06 00:47:53 +02002031 }
2032 break;
2033 case '>':
Vaibhav Nagarnaikd69afed52012-04-06 00:48:00 +02002034 ret = arg_num_eval(arg->op.left, &left);
2035 if (!ret)
2036 break;
2037 ret = arg_num_eval(arg->op.right, &right);
2038 if (!ret)
2039 break;
Steven Rostedtf7d82352012-04-06 00:47:53 +02002040 switch (arg->op.op[1]) {
2041 case 0:
Vaibhav Nagarnaikd69afed52012-04-06 00:48:00 +02002042 *val = left > right;
Steven Rostedtf7d82352012-04-06 00:47:53 +02002043 break;
2044 case '>':
Vaibhav Nagarnaikd69afed52012-04-06 00:48:00 +02002045 *val = left >> right;
Steven Rostedtf7d82352012-04-06 00:47:53 +02002046 break;
2047 case '=':
Vaibhav Nagarnaikd69afed52012-04-06 00:48:00 +02002048 *val = left >= right;
Steven Rostedtf7d82352012-04-06 00:47:53 +02002049 break;
2050 default:
Vaibhav Nagarnaikd69afed52012-04-06 00:48:00 +02002051 do_warning("unknown op '%s'", arg->op.op);
2052 ret = 0;
Steven Rostedtf7d82352012-04-06 00:47:53 +02002053 }
2054 break;
2055 case '=':
Vaibhav Nagarnaikd69afed52012-04-06 00:48:00 +02002056 ret = arg_num_eval(arg->op.left, &left);
2057 if (!ret)
2058 break;
2059 ret = arg_num_eval(arg->op.right, &right);
2060 if (!ret)
2061 break;
Steven Rostedtf7d82352012-04-06 00:47:53 +02002062
Vaibhav Nagarnaikd69afed52012-04-06 00:48:00 +02002063 if (arg->op.op[1] != '=') {
2064 do_warning("unknown op '%s'", arg->op.op);
2065 ret = 0;
2066 } else
2067 *val = left == right;
Steven Rostedtf7d82352012-04-06 00:47:53 +02002068 break;
2069 case '!':
Vaibhav Nagarnaikd69afed52012-04-06 00:48:00 +02002070 ret = arg_num_eval(arg->op.left, &left);
2071 if (!ret)
2072 break;
2073 ret = arg_num_eval(arg->op.right, &right);
2074 if (!ret)
2075 break;
Steven Rostedtf7d82352012-04-06 00:47:53 +02002076
2077 switch (arg->op.op[1]) {
2078 case '=':
Vaibhav Nagarnaikd69afed52012-04-06 00:48:00 +02002079 *val = left != right;
Steven Rostedtf7d82352012-04-06 00:47:53 +02002080 break;
2081 default:
Vaibhav Nagarnaikd69afed52012-04-06 00:48:00 +02002082 do_warning("unknown op '%s'", arg->op.op);
2083 ret = 0;
Steven Rostedtf7d82352012-04-06 00:47:53 +02002084 }
2085 break;
2086 case '-':
2087 /* check for negative */
2088 if (arg->op.left->type == PRINT_NULL)
2089 left = 0;
2090 else
Vaibhav Nagarnaikd69afed52012-04-06 00:48:00 +02002091 ret = arg_num_eval(arg->op.left, &left);
2092 if (!ret)
2093 break;
2094 ret = arg_num_eval(arg->op.right, &right);
2095 if (!ret)
2096 break;
2097 *val = left - right;
Steven Rostedtf7d82352012-04-06 00:47:53 +02002098 break;
Vaibhav Nagarnaikb4828592012-04-06 00:48:03 +02002099 case '+':
2100 if (arg->op.left->type == PRINT_NULL)
2101 left = 0;
2102 else
2103 ret = arg_num_eval(arg->op.left, &left);
2104 if (!ret)
2105 break;
2106 ret = arg_num_eval(arg->op.right, &right);
2107 if (!ret)
2108 break;
2109 *val = left + right;
2110 break;
Steven Rostedtf7d82352012-04-06 00:47:53 +02002111 default:
Vaibhav Nagarnaikd69afed52012-04-06 00:48:00 +02002112 do_warning("unknown op '%s'", arg->op.op);
2113 ret = 0;
Steven Rostedtf7d82352012-04-06 00:47:53 +02002114 }
2115 break;
2116
2117 case PRINT_NULL:
2118 case PRINT_FIELD ... PRINT_SYMBOL:
2119 case PRINT_STRING:
2120 case PRINT_BSTRING:
2121 default:
Vaibhav Nagarnaikd69afed52012-04-06 00:48:00 +02002122 do_warning("invalid eval type %d", arg->type);
2123 ret = 0;
Steven Rostedtf7d82352012-04-06 00:47:53 +02002124
2125 }
Vaibhav Nagarnaikd69afed52012-04-06 00:48:00 +02002126 return ret;
Steven Rostedtf7d82352012-04-06 00:47:53 +02002127}
2128
2129static char *arg_eval (struct print_arg *arg)
2130{
2131 long long val;
2132 static char buf[20];
2133
2134 switch (arg->type) {
2135 case PRINT_ATOM:
2136 return arg->atom.atom;
2137 case PRINT_TYPE:
2138 return arg_eval(arg->typecast.item);
2139 case PRINT_OP:
Vaibhav Nagarnaikd69afed52012-04-06 00:48:00 +02002140 if (!arg_num_eval(arg, &val))
2141 break;
Steven Rostedtf7d82352012-04-06 00:47:53 +02002142 sprintf(buf, "%lld", val);
2143 return buf;
2144
2145 case PRINT_NULL:
2146 case PRINT_FIELD ... PRINT_SYMBOL:
2147 case PRINT_STRING:
2148 case PRINT_BSTRING:
2149 default:
2150 die("invalid eval type %d", arg->type);
2151 break;
2152 }
2153
2154 return NULL;
2155}
2156
2157static enum event_type
2158process_fields(struct event_format *event, struct print_flag_sym **list, char **tok)
2159{
2160 enum event_type type;
2161 struct print_arg *arg = NULL;
2162 struct print_flag_sym *field;
2163 char *token = *tok;
2164 char *value;
2165
2166 do {
2167 free_token(token);
2168 type = read_token_item(&token);
2169 if (test_type_token(type, token, EVENT_OP, "{"))
2170 break;
2171
2172 arg = alloc_arg();
2173
2174 free_token(token);
2175 type = process_arg(event, arg, &token);
Stefan Hajnoczi00b9da72012-05-23 11:36:42 +09002176
2177 if (type == EVENT_OP)
2178 type = process_op(event, arg, &token);
2179
2180 if (type == EVENT_ERROR)
2181 goto out_free;
2182
Steven Rostedtf7d82352012-04-06 00:47:53 +02002183 if (test_type_token(type, token, EVENT_DELIM, ","))
2184 goto out_free;
2185
2186 field = malloc_or_die(sizeof(*field));
Julia Lawall54a36252012-04-06 00:47:59 +02002187 memset(field, 0, sizeof(*field));
Steven Rostedtf7d82352012-04-06 00:47:53 +02002188
2189 value = arg_eval(arg);
Vaibhav Nagarnaikd69afed52012-04-06 00:48:00 +02002190 if (value == NULL)
2191 goto out_free;
Steven Rostedtf7d82352012-04-06 00:47:53 +02002192 field->value = strdup(value);
Namhyung Kimca638582012-04-09 11:54:31 +09002193 if (field->value == NULL)
2194 goto out_free;
Steven Rostedtf7d82352012-04-06 00:47:53 +02002195
2196 free_arg(arg);
2197 arg = alloc_arg();
2198
2199 free_token(token);
2200 type = process_arg(event, arg, &token);
2201 if (test_type_token(type, token, EVENT_OP, "}"))
2202 goto out_free;
2203
2204 value = arg_eval(arg);
Vaibhav Nagarnaikd69afed52012-04-06 00:48:00 +02002205 if (value == NULL)
2206 goto out_free;
Steven Rostedtf7d82352012-04-06 00:47:53 +02002207 field->str = strdup(value);
Namhyung Kimca638582012-04-09 11:54:31 +09002208 if (field->str == NULL)
2209 goto out_free;
Steven Rostedtf7d82352012-04-06 00:47:53 +02002210 free_arg(arg);
2211 arg = NULL;
2212
2213 *list = field;
2214 list = &field->next;
2215
2216 free_token(token);
2217 type = read_token_item(&token);
2218 } while (type == EVENT_DELIM && strcmp(token, ",") == 0);
2219
2220 *tok = token;
2221 return type;
2222
2223out_free:
2224 free_arg(arg);
2225 free_token(token);
2226 *tok = NULL;
2227
2228 return EVENT_ERROR;
2229}
2230
2231static enum event_type
2232process_flags(struct event_format *event, struct print_arg *arg, char **tok)
2233{
2234 struct print_arg *field;
2235 enum event_type type;
2236 char *token;
2237
2238 memset(arg, 0, sizeof(*arg));
2239 arg->type = PRINT_FLAGS;
2240
2241 field = alloc_arg();
2242
2243 type = process_arg(event, field, &token);
2244
2245 /* Handle operations in the first argument */
2246 while (type == EVENT_OP)
2247 type = process_op(event, field, &token);
2248
2249 if (test_type_token(type, token, EVENT_DELIM, ","))
2250 goto out_free;
2251 free_token(token);
2252
2253 arg->flags.field = field;
2254
2255 type = read_token_item(&token);
2256 if (event_item_type(type)) {
2257 arg->flags.delim = token;
2258 type = read_token_item(&token);
2259 }
2260
2261 if (test_type_token(type, token, EVENT_DELIM, ","))
2262 goto out_free;
2263
2264 type = process_fields(event, &arg->flags.flags, &token);
2265 if (test_type_token(type, token, EVENT_DELIM, ")"))
2266 goto out_free;
2267
2268 free_token(token);
2269 type = read_token_item(tok);
2270 return type;
2271
2272 out_free:
2273 free_token(token);
2274 *tok = NULL;
2275 return EVENT_ERROR;
2276}
2277
2278static enum event_type
2279process_symbols(struct event_format *event, struct print_arg *arg, char **tok)
2280{
2281 struct print_arg *field;
2282 enum event_type type;
2283 char *token;
2284
2285 memset(arg, 0, sizeof(*arg));
2286 arg->type = PRINT_SYMBOL;
2287
2288 field = alloc_arg();
2289
2290 type = process_arg(event, field, &token);
2291 if (test_type_token(type, token, EVENT_DELIM, ","))
2292 goto out_free;
2293
2294 arg->symbol.field = field;
2295
2296 type = process_fields(event, &arg->symbol.symbols, &token);
2297 if (test_type_token(type, token, EVENT_DELIM, ")"))
2298 goto out_free;
2299
2300 free_token(token);
2301 type = read_token_item(tok);
2302 return type;
2303
2304 out_free:
2305 free_token(token);
2306 *tok = NULL;
2307 return EVENT_ERROR;
2308}
2309
2310static enum event_type
Namhyung Kime080e6f2012-06-27 09:41:41 +09002311process_hex(struct event_format *event, struct print_arg *arg, char **tok)
2312{
2313 struct print_arg *field;
2314 enum event_type type;
2315 char *token;
2316
2317 memset(arg, 0, sizeof(*arg));
2318 arg->type = PRINT_HEX;
2319
2320 field = alloc_arg();
2321 type = process_arg(event, field, &token);
2322
2323 if (test_type_token(type, token, EVENT_DELIM, ","))
2324 goto out_free;
2325
2326 arg->hex.field = field;
2327
2328 free_token(token);
2329
2330 field = alloc_arg();
2331 type = process_arg(event, field, &token);
2332
2333 if (test_type_token(type, token, EVENT_DELIM, ")"))
2334 goto out_free;
2335
2336 arg->hex.size = field;
2337
2338 free_token(token);
2339 type = read_token_item(tok);
2340 return type;
2341
2342 out_free:
2343 free_arg(field);
2344 free_token(token);
2345 *tok = NULL;
2346 return EVENT_ERROR;
2347}
2348
2349static enum event_type
Steven Rostedtf7d82352012-04-06 00:47:53 +02002350process_dynamic_array(struct event_format *event, struct print_arg *arg, char **tok)
2351{
2352 struct format_field *field;
2353 enum event_type type;
2354 char *token;
2355
2356 memset(arg, 0, sizeof(*arg));
2357 arg->type = PRINT_DYNAMIC_ARRAY;
2358
2359 /*
2360 * The item within the parenthesis is another field that holds
2361 * the index into where the array starts.
2362 */
2363 type = read_token(&token);
2364 *tok = token;
2365 if (type != EVENT_ITEM)
2366 goto out_free;
2367
2368 /* Find the field */
2369
2370 field = pevent_find_field(event, token);
2371 if (!field)
2372 goto out_free;
2373
2374 arg->dynarray.field = field;
2375 arg->dynarray.index = 0;
2376
2377 if (read_expected(EVENT_DELIM, ")") < 0)
2378 goto out_free;
2379
2380 free_token(token);
2381 type = read_token_item(&token);
2382 *tok = token;
2383 if (type != EVENT_OP || strcmp(token, "[") != 0)
2384 return type;
2385
2386 free_token(token);
2387 arg = alloc_arg();
2388 type = process_arg(event, arg, &token);
2389 if (type == EVENT_ERROR)
Namhyung Kimb3511d02012-05-23 11:36:50 +09002390 goto out_free_arg;
Steven Rostedtf7d82352012-04-06 00:47:53 +02002391
2392 if (!test_type_token(type, token, EVENT_OP, "]"))
Namhyung Kimb3511d02012-05-23 11:36:50 +09002393 goto out_free_arg;
Steven Rostedtf7d82352012-04-06 00:47:53 +02002394
2395 free_token(token);
2396 type = read_token_item(tok);
2397 return type;
2398
Namhyung Kimb3511d02012-05-23 11:36:50 +09002399 out_free_arg:
2400 free_arg(arg);
Steven Rostedtf7d82352012-04-06 00:47:53 +02002401 out_free:
Steven Rostedtf7d82352012-04-06 00:47:53 +02002402 free_token(token);
2403 *tok = NULL;
2404 return EVENT_ERROR;
2405}
2406
2407static enum event_type
2408process_paren(struct event_format *event, struct print_arg *arg, char **tok)
2409{
2410 struct print_arg *item_arg;
2411 enum event_type type;
2412 char *token;
2413
2414 type = process_arg(event, arg, &token);
2415
2416 if (type == EVENT_ERROR)
2417 goto out_free;
2418
2419 if (type == EVENT_OP)
2420 type = process_op(event, arg, &token);
2421
2422 if (type == EVENT_ERROR)
2423 goto out_free;
2424
2425 if (test_type_token(type, token, EVENT_DELIM, ")"))
2426 goto out_free;
2427
2428 free_token(token);
2429 type = read_token_item(&token);
2430
2431 /*
2432 * If the next token is an item or another open paren, then
2433 * this was a typecast.
2434 */
2435 if (event_item_type(type) ||
2436 (type == EVENT_DELIM && strcmp(token, "(") == 0)) {
2437
2438 /* make this a typecast and contine */
2439
2440 /* prevous must be an atom */
2441 if (arg->type != PRINT_ATOM)
2442 die("previous needed to be PRINT_ATOM");
2443
2444 item_arg = alloc_arg();
2445
2446 arg->type = PRINT_TYPE;
2447 arg->typecast.type = arg->atom.atom;
2448 arg->typecast.item = item_arg;
2449 type = process_arg_token(event, item_arg, &token, type);
2450
2451 }
2452
2453 *tok = token;
2454 return type;
2455
2456 out_free:
2457 free_token(token);
2458 *tok = NULL;
2459 return EVENT_ERROR;
2460}
2461
2462
2463static enum event_type
2464process_str(struct event_format *event __unused, struct print_arg *arg, char **tok)
2465{
2466 enum event_type type;
2467 char *token;
2468
2469 if (read_expect_type(EVENT_ITEM, &token) < 0)
2470 goto out_free;
2471
2472 arg->type = PRINT_STRING;
2473 arg->string.string = token;
2474 arg->string.offset = -1;
2475
2476 if (read_expected(EVENT_DELIM, ")") < 0)
2477 goto out_err;
2478
2479 type = read_token(&token);
2480 *tok = token;
2481
2482 return type;
2483
2484 out_free:
2485 free_token(token);
2486 out_err:
2487 *tok = NULL;
2488 return EVENT_ERROR;
2489}
2490
2491static struct pevent_function_handler *
2492find_func_handler(struct pevent *pevent, char *func_name)
2493{
2494 struct pevent_function_handler *func;
2495
2496 for (func = pevent->func_handlers; func; func = func->next) {
2497 if (strcmp(func->name, func_name) == 0)
2498 break;
2499 }
2500
2501 return func;
2502}
2503
2504static void remove_func_handler(struct pevent *pevent, char *func_name)
2505{
2506 struct pevent_function_handler *func;
2507 struct pevent_function_handler **next;
2508
2509 next = &pevent->func_handlers;
2510 while ((func = *next)) {
2511 if (strcmp(func->name, func_name) == 0) {
2512 *next = func->next;
2513 free_func_handle(func);
2514 break;
2515 }
2516 next = &func->next;
2517 }
2518}
2519
2520static enum event_type
2521process_func_handler(struct event_format *event, struct pevent_function_handler *func,
2522 struct print_arg *arg, char **tok)
2523{
2524 struct print_arg **next_arg;
2525 struct print_arg *farg;
2526 enum event_type type;
2527 char *token;
2528 char *test;
2529 int i;
2530
2531 arg->type = PRINT_FUNC;
2532 arg->func.func = func;
2533
2534 *tok = NULL;
2535
2536 next_arg = &(arg->func.args);
2537 for (i = 0; i < func->nr_args; i++) {
2538 farg = alloc_arg();
2539 type = process_arg(event, farg, &token);
2540 if (i < (func->nr_args - 1))
2541 test = ",";
2542 else
2543 test = ")";
2544
2545 if (test_type_token(type, token, EVENT_DELIM, test)) {
2546 free_arg(farg);
2547 free_token(token);
2548 return EVENT_ERROR;
2549 }
2550
2551 *next_arg = farg;
2552 next_arg = &(farg->next);
2553 free_token(token);
2554 }
2555
2556 type = read_token(&token);
2557 *tok = token;
2558
2559 return type;
2560}
2561
2562static enum event_type
2563process_function(struct event_format *event, struct print_arg *arg,
2564 char *token, char **tok)
2565{
2566 struct pevent_function_handler *func;
2567
2568 if (strcmp(token, "__print_flags") == 0) {
2569 free_token(token);
Tom Zanussi5205aec2012-04-06 00:47:58 +02002570 is_flag_field = 1;
Steven Rostedtf7d82352012-04-06 00:47:53 +02002571 return process_flags(event, arg, tok);
2572 }
2573 if (strcmp(token, "__print_symbolic") == 0) {
2574 free_token(token);
Tom Zanussi5205aec2012-04-06 00:47:58 +02002575 is_symbolic_field = 1;
Steven Rostedtf7d82352012-04-06 00:47:53 +02002576 return process_symbols(event, arg, tok);
2577 }
Namhyung Kime080e6f2012-06-27 09:41:41 +09002578 if (strcmp(token, "__print_hex") == 0) {
2579 free_token(token);
2580 return process_hex(event, arg, tok);
2581 }
Steven Rostedtf7d82352012-04-06 00:47:53 +02002582 if (strcmp(token, "__get_str") == 0) {
2583 free_token(token);
2584 return process_str(event, arg, tok);
2585 }
2586 if (strcmp(token, "__get_dynamic_array") == 0) {
2587 free_token(token);
2588 return process_dynamic_array(event, arg, tok);
2589 }
2590
2591 func = find_func_handler(event->pevent, token);
2592 if (func) {
2593 free_token(token);
2594 return process_func_handler(event, func, arg, tok);
2595 }
2596
2597 do_warning("function %s not defined", token);
2598 free_token(token);
2599 return EVENT_ERROR;
2600}
2601
2602static enum event_type
2603process_arg_token(struct event_format *event, struct print_arg *arg,
2604 char **tok, enum event_type type)
2605{
2606 char *token;
2607 char *atom;
2608
2609 token = *tok;
2610
2611 switch (type) {
2612 case EVENT_ITEM:
2613 if (strcmp(token, "REC") == 0) {
2614 free_token(token);
2615 type = process_entry(event, arg, &token);
2616 break;
2617 }
2618 atom = token;
2619 /* test the next token */
2620 type = read_token_item(&token);
2621
2622 /*
2623 * If the next token is a parenthesis, then this
2624 * is a function.
2625 */
2626 if (type == EVENT_DELIM && strcmp(token, "(") == 0) {
2627 free_token(token);
2628 token = NULL;
2629 /* this will free atom. */
2630 type = process_function(event, arg, atom, &token);
2631 break;
2632 }
2633 /* atoms can be more than one token long */
2634 while (type == EVENT_ITEM) {
Namhyung Kimd2864472012-04-09 11:54:33 +09002635 char *new_atom;
2636 new_atom = realloc(atom,
2637 strlen(atom) + strlen(token) + 2);
2638 if (!new_atom) {
2639 free(atom);
2640 *tok = NULL;
2641 free_token(token);
2642 return EVENT_ERROR;
2643 }
2644 atom = new_atom;
Steven Rostedtf7d82352012-04-06 00:47:53 +02002645 strcat(atom, " ");
2646 strcat(atom, token);
2647 free_token(token);
2648 type = read_token_item(&token);
2649 }
2650
2651 arg->type = PRINT_ATOM;
2652 arg->atom.atom = atom;
2653 break;
2654
2655 case EVENT_DQUOTE:
2656 case EVENT_SQUOTE:
2657 arg->type = PRINT_ATOM;
2658 arg->atom.atom = token;
2659 type = read_token_item(&token);
2660 break;
2661 case EVENT_DELIM:
2662 if (strcmp(token, "(") == 0) {
2663 free_token(token);
2664 type = process_paren(event, arg, &token);
2665 break;
2666 }
2667 case EVENT_OP:
2668 /* handle single ops */
2669 arg->type = PRINT_OP;
2670 arg->op.op = token;
2671 arg->op.left = NULL;
2672 type = process_op(event, arg, &token);
2673
2674 /* On error, the op is freed */
2675 if (type == EVENT_ERROR)
2676 arg->op.op = NULL;
2677
2678 /* return error type if errored */
2679 break;
2680
2681 case EVENT_ERROR ... EVENT_NEWLINE:
2682 default:
2683 die("unexpected type %d", type);
2684 }
2685 *tok = token;
2686
2687 return type;
2688}
2689
2690static int event_read_print_args(struct event_format *event, struct print_arg **list)
2691{
2692 enum event_type type = EVENT_ERROR;
2693 struct print_arg *arg;
2694 char *token;
2695 int args = 0;
2696
2697 do {
2698 if (type == EVENT_NEWLINE) {
2699 type = read_token_item(&token);
2700 continue;
2701 }
2702
2703 arg = alloc_arg();
2704
2705 type = process_arg(event, arg, &token);
2706
2707 if (type == EVENT_ERROR) {
2708 free_token(token);
2709 free_arg(arg);
2710 return -1;
2711 }
2712
2713 *list = arg;
2714 args++;
2715
2716 if (type == EVENT_OP) {
2717 type = process_op(event, arg, &token);
2718 free_token(token);
2719 if (type == EVENT_ERROR) {
2720 *list = NULL;
2721 free_arg(arg);
2722 return -1;
2723 }
2724 list = &arg->next;
2725 continue;
2726 }
2727
2728 if (type == EVENT_DELIM && strcmp(token, ",") == 0) {
2729 free_token(token);
2730 *list = arg;
2731 list = &arg->next;
2732 continue;
2733 }
2734 break;
2735 } while (type != EVENT_NONE);
2736
2737 if (type != EVENT_NONE && type != EVENT_ERROR)
2738 free_token(token);
2739
2740 return args;
2741}
2742
2743static int event_read_print(struct event_format *event)
2744{
2745 enum event_type type;
2746 char *token;
2747 int ret;
2748
2749 if (read_expected_item(EVENT_ITEM, "print") < 0)
2750 return -1;
2751
2752 if (read_expected(EVENT_ITEM, "fmt") < 0)
2753 return -1;
2754
2755 if (read_expected(EVENT_OP, ":") < 0)
2756 return -1;
2757
2758 if (read_expect_type(EVENT_DQUOTE, &token) < 0)
2759 goto fail;
2760
2761 concat:
2762 event->print_fmt.format = token;
2763 event->print_fmt.args = NULL;
2764
2765 /* ok to have no arg */
2766 type = read_token_item(&token);
2767
2768 if (type == EVENT_NONE)
2769 return 0;
2770
2771 /* Handle concatenation of print lines */
2772 if (type == EVENT_DQUOTE) {
2773 char *cat;
2774
2775 cat = malloc_or_die(strlen(event->print_fmt.format) +
2776 strlen(token) + 1);
2777 strcpy(cat, event->print_fmt.format);
2778 strcat(cat, token);
2779 free_token(token);
2780 free_token(event->print_fmt.format);
2781 event->print_fmt.format = NULL;
2782 token = cat;
2783 goto concat;
2784 }
2785
2786 if (test_type_token(type, token, EVENT_DELIM, ","))
2787 goto fail;
2788
2789 free_token(token);
2790
2791 ret = event_read_print_args(event, &event->print_fmt.args);
2792 if (ret < 0)
2793 return -1;
2794
2795 return ret;
2796
2797 fail:
2798 free_token(token);
2799 return -1;
2800}
2801
2802/**
2803 * pevent_find_common_field - return a common field by event
2804 * @event: handle for the event
2805 * @name: the name of the common field to return
2806 *
2807 * Returns a common field from the event by the given @name.
2808 * This only searchs the common fields and not all field.
2809 */
2810struct format_field *
2811pevent_find_common_field(struct event_format *event, const char *name)
2812{
2813 struct format_field *format;
2814
2815 for (format = event->format.common_fields;
2816 format; format = format->next) {
2817 if (strcmp(format->name, name) == 0)
2818 break;
2819 }
2820
2821 return format;
2822}
2823
2824/**
2825 * pevent_find_field - find a non-common field
2826 * @event: handle for the event
2827 * @name: the name of the non-common field
2828 *
2829 * Returns a non-common field by the given @name.
2830 * This does not search common fields.
2831 */
2832struct format_field *
2833pevent_find_field(struct event_format *event, const char *name)
2834{
2835 struct format_field *format;
2836
2837 for (format = event->format.fields;
2838 format; format = format->next) {
2839 if (strcmp(format->name, name) == 0)
2840 break;
2841 }
2842
2843 return format;
2844}
2845
2846/**
2847 * pevent_find_any_field - find any field by name
2848 * @event: handle for the event
2849 * @name: the name of the field
2850 *
2851 * Returns a field by the given @name.
2852 * This searchs the common field names first, then
2853 * the non-common ones if a common one was not found.
2854 */
2855struct format_field *
2856pevent_find_any_field(struct event_format *event, const char *name)
2857{
2858 struct format_field *format;
2859
2860 format = pevent_find_common_field(event, name);
2861 if (format)
2862 return format;
2863 return pevent_find_field(event, name);
2864}
2865
2866/**
2867 * pevent_read_number - read a number from data
2868 * @pevent: handle for the pevent
2869 * @ptr: the raw data
2870 * @size: the size of the data that holds the number
2871 *
2872 * Returns the number (converted to host) from the
2873 * raw data.
2874 */
2875unsigned long long pevent_read_number(struct pevent *pevent,
2876 const void *ptr, int size)
2877{
2878 switch (size) {
2879 case 1:
2880 return *(unsigned char *)ptr;
2881 case 2:
2882 return data2host2(pevent, ptr);
2883 case 4:
2884 return data2host4(pevent, ptr);
2885 case 8:
2886 return data2host8(pevent, ptr);
2887 default:
2888 /* BUG! */
2889 return 0;
2890 }
2891}
2892
2893/**
2894 * pevent_read_number_field - read a number from data
2895 * @field: a handle to the field
2896 * @data: the raw data to read
2897 * @value: the value to place the number in
2898 *
2899 * Reads raw data according to a field offset and size,
2900 * and translates it into @value.
2901 *
2902 * Returns 0 on success, -1 otherwise.
2903 */
2904int pevent_read_number_field(struct format_field *field, const void *data,
2905 unsigned long long *value)
2906{
2907 if (!field)
2908 return -1;
2909 switch (field->size) {
2910 case 1:
2911 case 2:
2912 case 4:
2913 case 8:
2914 *value = pevent_read_number(field->event->pevent,
2915 data + field->offset, field->size);
2916 return 0;
2917 default:
2918 return -1;
2919 }
2920}
2921
2922static int get_common_info(struct pevent *pevent,
2923 const char *type, int *offset, int *size)
2924{
2925 struct event_format *event;
2926 struct format_field *field;
2927
2928 /*
2929 * All events should have the same common elements.
2930 * Pick any event to find where the type is;
2931 */
2932 if (!pevent->events)
2933 die("no event_list!");
2934
2935 event = pevent->events[0];
2936 field = pevent_find_common_field(event, type);
2937 if (!field)
Steven Rostedt0866a972012-05-22 14:52:40 +09002938 return -1;
Steven Rostedtf7d82352012-04-06 00:47:53 +02002939
2940 *offset = field->offset;
2941 *size = field->size;
2942
2943 return 0;
2944}
2945
2946static int __parse_common(struct pevent *pevent, void *data,
2947 int *size, int *offset, const char *name)
2948{
2949 int ret;
2950
2951 if (!*size) {
2952 ret = get_common_info(pevent, name, offset, size);
2953 if (ret < 0)
2954 return ret;
2955 }
2956 return pevent_read_number(pevent, data + *offset, *size);
2957}
2958
2959static int trace_parse_common_type(struct pevent *pevent, void *data)
2960{
2961 return __parse_common(pevent, data,
2962 &pevent->type_size, &pevent->type_offset,
2963 "common_type");
2964}
2965
2966static int parse_common_pid(struct pevent *pevent, void *data)
2967{
2968 return __parse_common(pevent, data,
2969 &pevent->pid_size, &pevent->pid_offset,
2970 "common_pid");
2971}
2972
2973static int parse_common_pc(struct pevent *pevent, void *data)
2974{
2975 return __parse_common(pevent, data,
2976 &pevent->pc_size, &pevent->pc_offset,
2977 "common_preempt_count");
2978}
2979
2980static int parse_common_flags(struct pevent *pevent, void *data)
2981{
2982 return __parse_common(pevent, data,
2983 &pevent->flags_size, &pevent->flags_offset,
2984 "common_flags");
2985}
2986
2987static int parse_common_lock_depth(struct pevent *pevent, void *data)
2988{
Steven Rostedt0866a972012-05-22 14:52:40 +09002989 return __parse_common(pevent, data,
2990 &pevent->ld_size, &pevent->ld_offset,
2991 "common_lock_depth");
2992}
Steven Rostedtf7d82352012-04-06 00:47:53 +02002993
Steven Rostedt0866a972012-05-22 14:52:40 +09002994static int parse_common_migrate_disable(struct pevent *pevent, void *data)
2995{
2996 return __parse_common(pevent, data,
2997 &pevent->ld_size, &pevent->ld_offset,
2998 "common_migrate_disable");
Steven Rostedtf7d82352012-04-06 00:47:53 +02002999}
3000
3001static int events_id_cmp(const void *a, const void *b);
3002
3003/**
3004 * pevent_find_event - find an event by given id
3005 * @pevent: a handle to the pevent
3006 * @id: the id of the event
3007 *
3008 * Returns an event that has a given @id.
3009 */
3010struct event_format *pevent_find_event(struct pevent *pevent, int id)
3011{
3012 struct event_format **eventptr;
3013 struct event_format key;
3014 struct event_format *pkey = &key;
3015
3016 /* Check cache first */
3017 if (pevent->last_event && pevent->last_event->id == id)
3018 return pevent->last_event;
3019
3020 key.id = id;
3021
3022 eventptr = bsearch(&pkey, pevent->events, pevent->nr_events,
3023 sizeof(*pevent->events), events_id_cmp);
3024
3025 if (eventptr) {
3026 pevent->last_event = *eventptr;
3027 return *eventptr;
3028 }
3029
3030 return NULL;
3031}
3032
3033/**
3034 * pevent_find_event_by_name - find an event by given name
3035 * @pevent: a handle to the pevent
3036 * @sys: the system name to search for
3037 * @name: the name of the event to search for
3038 *
3039 * This returns an event with a given @name and under the system
3040 * @sys. If @sys is NULL the first event with @name is returned.
3041 */
3042struct event_format *
3043pevent_find_event_by_name(struct pevent *pevent,
3044 const char *sys, const char *name)
3045{
3046 struct event_format *event;
3047 int i;
3048
3049 if (pevent->last_event &&
3050 strcmp(pevent->last_event->name, name) == 0 &&
3051 (!sys || strcmp(pevent->last_event->system, sys) == 0))
3052 return pevent->last_event;
3053
3054 for (i = 0; i < pevent->nr_events; i++) {
3055 event = pevent->events[i];
3056 if (strcmp(event->name, name) == 0) {
3057 if (!sys)
3058 break;
3059 if (strcmp(event->system, sys) == 0)
3060 break;
3061 }
3062 }
3063 if (i == pevent->nr_events)
3064 event = NULL;
3065
3066 pevent->last_event = event;
3067 return event;
3068}
3069
3070static unsigned long long
3071eval_num_arg(void *data, int size, struct event_format *event, struct print_arg *arg)
3072{
3073 struct pevent *pevent = event->pevent;
3074 unsigned long long val = 0;
3075 unsigned long long left, right;
3076 struct print_arg *typearg = NULL;
3077 struct print_arg *larg;
3078 unsigned long offset;
3079 unsigned int field_size;
3080
3081 switch (arg->type) {
3082 case PRINT_NULL:
3083 /* ?? */
3084 return 0;
3085 case PRINT_ATOM:
3086 return strtoull(arg->atom.atom, NULL, 0);
3087 case PRINT_FIELD:
3088 if (!arg->field.field) {
3089 arg->field.field = pevent_find_any_field(event, arg->field.name);
3090 if (!arg->field.field)
3091 die("field %s not found", arg->field.name);
3092 }
3093 /* must be a number */
3094 val = pevent_read_number(pevent, data + arg->field.field->offset,
3095 arg->field.field->size);
3096 break;
3097 case PRINT_FLAGS:
3098 case PRINT_SYMBOL:
Namhyung Kime080e6f2012-06-27 09:41:41 +09003099 case PRINT_HEX:
Steven Rostedtf7d82352012-04-06 00:47:53 +02003100 break;
3101 case PRINT_TYPE:
3102 val = eval_num_arg(data, size, event, arg->typecast.item);
3103 return eval_type(val, arg, 0);
3104 case PRINT_STRING:
3105 case PRINT_BSTRING:
3106 return 0;
3107 case PRINT_FUNC: {
3108 struct trace_seq s;
3109 trace_seq_init(&s);
3110 val = process_defined_func(&s, data, size, event, arg);
3111 trace_seq_destroy(&s);
3112 return val;
3113 }
3114 case PRINT_OP:
3115 if (strcmp(arg->op.op, "[") == 0) {
3116 /*
3117 * Arrays are special, since we don't want
3118 * to read the arg as is.
3119 */
3120 right = eval_num_arg(data, size, event, arg->op.right);
3121
3122 /* handle typecasts */
3123 larg = arg->op.left;
3124 while (larg->type == PRINT_TYPE) {
3125 if (!typearg)
3126 typearg = larg;
3127 larg = larg->typecast.item;
3128 }
3129
3130 /* Default to long size */
3131 field_size = pevent->long_size;
3132
3133 switch (larg->type) {
3134 case PRINT_DYNAMIC_ARRAY:
3135 offset = pevent_read_number(pevent,
3136 data + larg->dynarray.field->offset,
3137 larg->dynarray.field->size);
3138 if (larg->dynarray.field->elementsize)
3139 field_size = larg->dynarray.field->elementsize;
3140 /*
3141 * The actual length of the dynamic array is stored
3142 * in the top half of the field, and the offset
3143 * is in the bottom half of the 32 bit field.
3144 */
3145 offset &= 0xffff;
3146 offset += right;
3147 break;
3148 case PRINT_FIELD:
3149 if (!larg->field.field) {
3150 larg->field.field =
3151 pevent_find_any_field(event, larg->field.name);
3152 if (!larg->field.field)
3153 die("field %s not found", larg->field.name);
3154 }
3155 field_size = larg->field.field->elementsize;
3156 offset = larg->field.field->offset +
3157 right * larg->field.field->elementsize;
3158 break;
3159 default:
3160 goto default_op; /* oops, all bets off */
3161 }
3162 val = pevent_read_number(pevent,
3163 data + offset, field_size);
3164 if (typearg)
3165 val = eval_type(val, typearg, 1);
3166 break;
3167 } else if (strcmp(arg->op.op, "?") == 0) {
3168 left = eval_num_arg(data, size, event, arg->op.left);
3169 arg = arg->op.right;
3170 if (left)
3171 val = eval_num_arg(data, size, event, arg->op.left);
3172 else
3173 val = eval_num_arg(data, size, event, arg->op.right);
3174 break;
3175 }
3176 default_op:
3177 left = eval_num_arg(data, size, event, arg->op.left);
3178 right = eval_num_arg(data, size, event, arg->op.right);
3179 switch (arg->op.op[0]) {
3180 case '!':
3181 switch (arg->op.op[1]) {
3182 case 0:
3183 val = !right;
3184 break;
3185 case '=':
3186 val = left != right;
3187 break;
3188 default:
3189 die("unknown op '%s'", arg->op.op);
3190 }
3191 break;
3192 case '~':
3193 val = ~right;
3194 break;
3195 case '|':
3196 if (arg->op.op[1])
3197 val = left || right;
3198 else
3199 val = left | right;
3200 break;
3201 case '&':
3202 if (arg->op.op[1])
3203 val = left && right;
3204 else
3205 val = left & right;
3206 break;
3207 case '<':
3208 switch (arg->op.op[1]) {
3209 case 0:
3210 val = left < right;
3211 break;
3212 case '<':
3213 val = left << right;
3214 break;
3215 case '=':
3216 val = left <= right;
3217 break;
3218 default:
3219 die("unknown op '%s'", arg->op.op);
3220 }
3221 break;
3222 case '>':
3223 switch (arg->op.op[1]) {
3224 case 0:
3225 val = left > right;
3226 break;
3227 case '>':
3228 val = left >> right;
3229 break;
3230 case '=':
3231 val = left >= right;
3232 break;
3233 default:
3234 die("unknown op '%s'", arg->op.op);
3235 }
3236 break;
3237 case '=':
3238 if (arg->op.op[1] != '=')
3239 die("unknown op '%s'", arg->op.op);
3240 val = left == right;
3241 break;
3242 case '-':
3243 val = left - right;
3244 break;
3245 case '+':
3246 val = left + right;
3247 break;
Steven Rostedt2e7a5fc2012-04-06 00:48:04 +02003248 case '/':
3249 val = left / right;
3250 break;
3251 case '*':
3252 val = left * right;
3253 break;
Steven Rostedtf7d82352012-04-06 00:47:53 +02003254 default:
3255 die("unknown op '%s'", arg->op.op);
3256 }
3257 break;
3258 default: /* not sure what to do there */
3259 return 0;
3260 }
3261 return val;
3262}
3263
3264struct flag {
3265 const char *name;
3266 unsigned long long value;
3267};
3268
3269static const struct flag flags[] = {
3270 { "HI_SOFTIRQ", 0 },
3271 { "TIMER_SOFTIRQ", 1 },
3272 { "NET_TX_SOFTIRQ", 2 },
3273 { "NET_RX_SOFTIRQ", 3 },
3274 { "BLOCK_SOFTIRQ", 4 },
3275 { "BLOCK_IOPOLL_SOFTIRQ", 5 },
3276 { "TASKLET_SOFTIRQ", 6 },
3277 { "SCHED_SOFTIRQ", 7 },
3278 { "HRTIMER_SOFTIRQ", 8 },
3279 { "RCU_SOFTIRQ", 9 },
3280
3281 { "HRTIMER_NORESTART", 0 },
3282 { "HRTIMER_RESTART", 1 },
3283};
3284
3285static unsigned long long eval_flag(const char *flag)
3286{
3287 int i;
3288
3289 /*
3290 * Some flags in the format files do not get converted.
3291 * If the flag is not numeric, see if it is something that
3292 * we already know about.
3293 */
3294 if (isdigit(flag[0]))
3295 return strtoull(flag, NULL, 0);
3296
3297 for (i = 0; i < (int)(sizeof(flags)/sizeof(flags[0])); i++)
3298 if (strcmp(flags[i].name, flag) == 0)
3299 return flags[i].value;
3300
3301 return 0;
3302}
3303
3304static void print_str_to_seq(struct trace_seq *s, const char *format,
3305 int len_arg, const char *str)
3306{
3307 if (len_arg >= 0)
3308 trace_seq_printf(s, format, len_arg, str);
3309 else
3310 trace_seq_printf(s, format, str);
3311}
3312
3313static void print_str_arg(struct trace_seq *s, void *data, int size,
3314 struct event_format *event, const char *format,
3315 int len_arg, struct print_arg *arg)
3316{
3317 struct pevent *pevent = event->pevent;
3318 struct print_flag_sym *flag;
Namhyung Kimb7008072012-06-27 09:41:40 +09003319 struct format_field *field;
Steven Rostedtf7d82352012-04-06 00:47:53 +02003320 unsigned long long val, fval;
3321 unsigned long addr;
3322 char *str;
Namhyung Kime080e6f2012-06-27 09:41:41 +09003323 unsigned char *hex;
Steven Rostedtf7d82352012-04-06 00:47:53 +02003324 int print;
Namhyung Kime080e6f2012-06-27 09:41:41 +09003325 int i, len;
Steven Rostedtf7d82352012-04-06 00:47:53 +02003326
3327 switch (arg->type) {
3328 case PRINT_NULL:
3329 /* ?? */
3330 return;
3331 case PRINT_ATOM:
3332 print_str_to_seq(s, format, len_arg, arg->atom.atom);
3333 return;
3334 case PRINT_FIELD:
Namhyung Kimb7008072012-06-27 09:41:40 +09003335 field = arg->field.field;
3336 if (!field) {
3337 field = pevent_find_any_field(event, arg->field.name);
3338 if (!field)
Steven Rostedtf7d82352012-04-06 00:47:53 +02003339 die("field %s not found", arg->field.name);
Namhyung Kimb7008072012-06-27 09:41:40 +09003340 arg->field.field = field;
Steven Rostedtf7d82352012-04-06 00:47:53 +02003341 }
3342 /* Zero sized fields, mean the rest of the data */
Namhyung Kimb7008072012-06-27 09:41:40 +09003343 len = field->size ? : size - field->offset;
Steven Rostedtf7d82352012-04-06 00:47:53 +02003344
3345 /*
3346 * Some events pass in pointers. If this is not an array
3347 * and the size is the same as long_size, assume that it
3348 * is a pointer.
3349 */
Namhyung Kimb7008072012-06-27 09:41:40 +09003350 if (!(field->flags & FIELD_IS_ARRAY) &&
3351 field->size == pevent->long_size) {
3352 addr = *(unsigned long *)(data + field->offset);
Steven Rostedtf7d82352012-04-06 00:47:53 +02003353 trace_seq_printf(s, "%lx", addr);
3354 break;
3355 }
3356 str = malloc_or_die(len + 1);
Namhyung Kimb7008072012-06-27 09:41:40 +09003357 memcpy(str, data + field->offset, len);
Steven Rostedtf7d82352012-04-06 00:47:53 +02003358 str[len] = 0;
3359 print_str_to_seq(s, format, len_arg, str);
3360 free(str);
3361 break;
3362 case PRINT_FLAGS:
3363 val = eval_num_arg(data, size, event, arg->flags.field);
3364 print = 0;
3365 for (flag = arg->flags.flags; flag; flag = flag->next) {
3366 fval = eval_flag(flag->value);
3367 if (!val && !fval) {
3368 print_str_to_seq(s, format, len_arg, flag->str);
3369 break;
3370 }
3371 if (fval && (val & fval) == fval) {
3372 if (print && arg->flags.delim)
3373 trace_seq_puts(s, arg->flags.delim);
3374 print_str_to_seq(s, format, len_arg, flag->str);
3375 print = 1;
3376 val &= ~fval;
3377 }
3378 }
3379 break;
3380 case PRINT_SYMBOL:
3381 val = eval_num_arg(data, size, event, arg->symbol.field);
3382 for (flag = arg->symbol.symbols; flag; flag = flag->next) {
3383 fval = eval_flag(flag->value);
3384 if (val == fval) {
3385 print_str_to_seq(s, format, len_arg, flag->str);
3386 break;
3387 }
3388 }
3389 break;
Namhyung Kime080e6f2012-06-27 09:41:41 +09003390 case PRINT_HEX:
3391 field = arg->hex.field->field.field;
3392 if (!field) {
3393 str = arg->hex.field->field.name;
3394 field = pevent_find_any_field(event, str);
3395 if (!field)
3396 die("field %s not found", str);
3397 arg->hex.field->field.field = field;
3398 }
3399 hex = data + field->offset;
3400 len = eval_num_arg(data, size, event, arg->hex.size);
3401 for (i = 0; i < len; i++) {
3402 if (i)
3403 trace_seq_putc(s, ' ');
3404 trace_seq_printf(s, "%02x", hex[i]);
3405 }
3406 break;
Steven Rostedtf7d82352012-04-06 00:47:53 +02003407
3408 case PRINT_TYPE:
3409 break;
3410 case PRINT_STRING: {
3411 int str_offset;
3412
3413 if (arg->string.offset == -1) {
3414 struct format_field *f;
3415
3416 f = pevent_find_any_field(event, arg->string.string);
3417 arg->string.offset = f->offset;
3418 }
3419 str_offset = data2host4(pevent, data + arg->string.offset);
3420 str_offset &= 0xffff;
3421 print_str_to_seq(s, format, len_arg, ((char *)data) + str_offset);
3422 break;
3423 }
3424 case PRINT_BSTRING:
Steven Rostedtc2e6dc22011-11-15 18:47:48 -05003425 print_str_to_seq(s, format, len_arg, arg->string.string);
Steven Rostedtf7d82352012-04-06 00:47:53 +02003426 break;
3427 case PRINT_OP:
3428 /*
3429 * The only op for string should be ? :
3430 */
3431 if (arg->op.op[0] != '?')
3432 return;
3433 val = eval_num_arg(data, size, event, arg->op.left);
3434 if (val)
3435 print_str_arg(s, data, size, event,
3436 format, len_arg, arg->op.right->op.left);
3437 else
3438 print_str_arg(s, data, size, event,
3439 format, len_arg, arg->op.right->op.right);
3440 break;
3441 case PRINT_FUNC:
3442 process_defined_func(s, data, size, event, arg);
3443 break;
3444 default:
3445 /* well... */
3446 break;
3447 }
3448}
3449
3450static unsigned long long
3451process_defined_func(struct trace_seq *s, void *data, int size,
3452 struct event_format *event, struct print_arg *arg)
3453{
3454 struct pevent_function_handler *func_handle = arg->func.func;
3455 struct pevent_func_params *param;
3456 unsigned long long *args;
3457 unsigned long long ret;
3458 struct print_arg *farg;
3459 struct trace_seq str;
3460 struct save_str {
3461 struct save_str *next;
3462 char *str;
3463 } *strings = NULL, *string;
3464 int i;
3465
3466 if (!func_handle->nr_args) {
3467 ret = (*func_handle->func)(s, NULL);
3468 goto out;
3469 }
3470
3471 farg = arg->func.args;
3472 param = func_handle->params;
3473
3474 args = malloc_or_die(sizeof(*args) * func_handle->nr_args);
3475 for (i = 0; i < func_handle->nr_args; i++) {
3476 switch (param->type) {
3477 case PEVENT_FUNC_ARG_INT:
3478 case PEVENT_FUNC_ARG_LONG:
3479 case PEVENT_FUNC_ARG_PTR:
3480 args[i] = eval_num_arg(data, size, event, farg);
3481 break;
3482 case PEVENT_FUNC_ARG_STRING:
3483 trace_seq_init(&str);
3484 print_str_arg(&str, data, size, event, "%s", -1, farg);
3485 trace_seq_terminate(&str);
3486 string = malloc_or_die(sizeof(*string));
3487 string->next = strings;
3488 string->str = strdup(str.buffer);
Namhyung Kimca638582012-04-09 11:54:31 +09003489 if (!string->str)
3490 die("malloc str");
3491
Namhyung Kim3831a422012-04-23 13:58:33 +09003492 args[i] = (unsigned long long)string->str;
Steven Rostedtf7d82352012-04-06 00:47:53 +02003493 strings = string;
3494 trace_seq_destroy(&str);
3495 break;
3496 default:
3497 /*
3498 * Something went totally wrong, this is not
3499 * an input error, something in this code broke.
3500 */
3501 die("Unexpected end of arguments\n");
3502 break;
3503 }
3504 farg = farg->next;
Namhyung Kim21c69e72012-05-23 11:36:51 +09003505 param = param->next;
Steven Rostedtf7d82352012-04-06 00:47:53 +02003506 }
3507
3508 ret = (*func_handle->func)(s, args);
3509 free(args);
3510 while (strings) {
3511 string = strings;
3512 strings = string->next;
3513 free(string->str);
3514 free(string);
3515 }
3516
3517 out:
3518 /* TBD : handle return type here */
3519 return ret;
3520}
3521
3522static struct print_arg *make_bprint_args(char *fmt, void *data, int size, struct event_format *event)
3523{
3524 struct pevent *pevent = event->pevent;
3525 struct format_field *field, *ip_field;
3526 struct print_arg *args, *arg, **next;
3527 unsigned long long ip, val;
3528 char *ptr;
3529 void *bptr;
Steven Rostedtc2e6dc22011-11-15 18:47:48 -05003530 int vsize;
Steven Rostedtf7d82352012-04-06 00:47:53 +02003531
3532 field = pevent->bprint_buf_field;
3533 ip_field = pevent->bprint_ip_field;
3534
3535 if (!field) {
3536 field = pevent_find_field(event, "buf");
3537 if (!field)
3538 die("can't find buffer field for binary printk");
3539 ip_field = pevent_find_field(event, "ip");
3540 if (!ip_field)
3541 die("can't find ip field for binary printk");
3542 pevent->bprint_buf_field = field;
3543 pevent->bprint_ip_field = ip_field;
3544 }
3545
3546 ip = pevent_read_number(pevent, data + ip_field->offset, ip_field->size);
3547
3548 /*
3549 * The first arg is the IP pointer.
3550 */
3551 args = alloc_arg();
3552 arg = args;
3553 arg->next = NULL;
3554 next = &arg->next;
3555
3556 arg->type = PRINT_ATOM;
3557 arg->atom.atom = malloc_or_die(32);
3558 sprintf(arg->atom.atom, "%lld", ip);
3559
3560 /* skip the first "%pf : " */
3561 for (ptr = fmt + 6, bptr = data + field->offset;
3562 bptr < data + size && *ptr; ptr++) {
3563 int ls = 0;
3564
3565 if (*ptr == '%') {
3566 process_again:
3567 ptr++;
3568 switch (*ptr) {
3569 case '%':
3570 break;
3571 case 'l':
3572 ls++;
3573 goto process_again;
3574 case 'L':
3575 ls = 2;
3576 goto process_again;
3577 case '0' ... '9':
3578 goto process_again;
Steven Rostedtc2e6dc22011-11-15 18:47:48 -05003579 case '.':
3580 goto process_again;
Steven Rostedtf7d82352012-04-06 00:47:53 +02003581 case 'p':
3582 ls = 1;
3583 /* fall through */
3584 case 'd':
3585 case 'u':
3586 case 'x':
3587 case 'i':
Steven Rostedtc2e6dc22011-11-15 18:47:48 -05003588 switch (ls) {
3589 case 0:
3590 vsize = 4;
3591 break;
3592 case 1:
3593 vsize = pevent->long_size;
3594 break;
3595 case 2:
3596 vsize = 8;
3597 default:
3598 vsize = ls; /* ? */
3599 break;
3600 }
3601 /* fall through */
3602 case '*':
3603 if (*ptr == '*')
3604 vsize = 4;
3605
Steven Rostedtf7d82352012-04-06 00:47:53 +02003606 /* the pointers are always 4 bytes aligned */
3607 bptr = (void *)(((unsigned long)bptr + 3) &
3608 ~3);
Steven Rostedtc2e6dc22011-11-15 18:47:48 -05003609 val = pevent_read_number(pevent, bptr, vsize);
3610 bptr += vsize;
Steven Rostedtf7d82352012-04-06 00:47:53 +02003611 arg = alloc_arg();
3612 arg->next = NULL;
3613 arg->type = PRINT_ATOM;
3614 arg->atom.atom = malloc_or_die(32);
3615 sprintf(arg->atom.atom, "%lld", val);
3616 *next = arg;
3617 next = &arg->next;
Steven Rostedtc2e6dc22011-11-15 18:47:48 -05003618 /*
3619 * The '*' case means that an arg is used as the length.
3620 * We need to continue to figure out for what.
3621 */
3622 if (*ptr == '*')
3623 goto process_again;
3624
Steven Rostedtf7d82352012-04-06 00:47:53 +02003625 break;
3626 case 's':
3627 arg = alloc_arg();
3628 arg->next = NULL;
3629 arg->type = PRINT_BSTRING;
3630 arg->string.string = strdup(bptr);
Namhyung Kimca638582012-04-09 11:54:31 +09003631 if (!arg->string.string)
3632 break;
Steven Rostedtf7d82352012-04-06 00:47:53 +02003633 bptr += strlen(bptr) + 1;
3634 *next = arg;
3635 next = &arg->next;
3636 default:
3637 break;
3638 }
3639 }
3640 }
3641
3642 return args;
3643}
3644
3645static void free_args(struct print_arg *args)
3646{
3647 struct print_arg *next;
3648
3649 while (args) {
3650 next = args->next;
3651
3652 free_arg(args);
3653 args = next;
3654 }
3655}
3656
3657static char *
3658get_bprint_format(void *data, int size __unused, struct event_format *event)
3659{
3660 struct pevent *pevent = event->pevent;
3661 unsigned long long addr;
3662 struct format_field *field;
3663 struct printk_map *printk;
3664 char *format;
3665 char *p;
3666
3667 field = pevent->bprint_fmt_field;
3668
3669 if (!field) {
3670 field = pevent_find_field(event, "fmt");
3671 if (!field)
3672 die("can't find format field for binary printk");
3673 pevent->bprint_fmt_field = field;
3674 }
3675
3676 addr = pevent_read_number(pevent, data + field->offset, field->size);
3677
3678 printk = find_printk(pevent, addr);
3679 if (!printk) {
3680 format = malloc_or_die(45);
3681 sprintf(format, "%%pf : (NO FORMAT FOUND at %llx)\n",
3682 addr);
3683 return format;
3684 }
3685
3686 p = printk->printk;
3687 /* Remove any quotes. */
3688 if (*p == '"')
3689 p++;
3690 format = malloc_or_die(strlen(p) + 10);
3691 sprintf(format, "%s : %s", "%pf", p);
3692 /* remove ending quotes and new line since we will add one too */
3693 p = format + strlen(format) - 1;
3694 if (*p == '"')
3695 *p = 0;
3696
3697 p -= 2;
3698 if (strcmp(p, "\\n") == 0)
3699 *p = 0;
3700
3701 return format;
3702}
3703
3704static void print_mac_arg(struct trace_seq *s, int mac, void *data, int size,
3705 struct event_format *event, struct print_arg *arg)
3706{
3707 unsigned char *buf;
3708 char *fmt = "%.2x:%.2x:%.2x:%.2x:%.2x:%.2x";
3709
3710 if (arg->type == PRINT_FUNC) {
3711 process_defined_func(s, data, size, event, arg);
3712 return;
3713 }
3714
3715 if (arg->type != PRINT_FIELD) {
3716 trace_seq_printf(s, "ARG TYPE NOT FIELD BUT %d",
3717 arg->type);
3718 return;
3719 }
3720
3721 if (mac == 'm')
3722 fmt = "%.2x%.2x%.2x%.2x%.2x%.2x";
3723 if (!arg->field.field) {
3724 arg->field.field =
3725 pevent_find_any_field(event, arg->field.name);
3726 if (!arg->field.field)
3727 die("field %s not found", arg->field.name);
3728 }
3729 if (arg->field.field->size != 6) {
3730 trace_seq_printf(s, "INVALIDMAC");
3731 return;
3732 }
3733 buf = data + arg->field.field->offset;
3734 trace_seq_printf(s, fmt, buf[0], buf[1], buf[2], buf[3], buf[4], buf[5]);
3735}
3736
Namhyung Kim600da3c2012-06-22 17:10:15 +09003737static int is_printable_array(char *p, unsigned int len)
3738{
3739 unsigned int i;
3740
3741 for (i = 0; i < len && p[i]; i++)
3742 if (!isprint(p[i]))
3743 return 0;
3744 return 1;
3745}
3746
Steven Rostedtf7d82352012-04-06 00:47:53 +02003747static void print_event_fields(struct trace_seq *s, void *data, int size,
3748 struct event_format *event)
3749{
3750 struct format_field *field;
3751 unsigned long long val;
3752 unsigned int offset, len, i;
3753
3754 field = event->format.fields;
3755 while (field) {
3756 trace_seq_printf(s, " %s=", field->name);
3757 if (field->flags & FIELD_IS_ARRAY) {
3758 offset = field->offset;
3759 len = field->size;
3760 if (field->flags & FIELD_IS_DYNAMIC) {
3761 val = pevent_read_number(event->pevent, data + offset, len);
3762 offset = val;
3763 len = offset >> 16;
3764 offset &= 0xffff;
3765 }
Namhyung Kim600da3c2012-06-22 17:10:15 +09003766 if (field->flags & FIELD_IS_STRING &&
3767 is_printable_array(data + offset, len)) {
Steven Rostedtf7d82352012-04-06 00:47:53 +02003768 trace_seq_printf(s, "%s", (char *)data + offset);
3769 } else {
3770 trace_seq_puts(s, "ARRAY[");
3771 for (i = 0; i < len; i++) {
3772 if (i)
3773 trace_seq_puts(s, ", ");
3774 trace_seq_printf(s, "%02x",
3775 *((unsigned char *)data + offset + i));
3776 }
3777 trace_seq_putc(s, ']');
Namhyung Kim600da3c2012-06-22 17:10:15 +09003778 field->flags &= ~FIELD_IS_STRING;
Steven Rostedtf7d82352012-04-06 00:47:53 +02003779 }
3780 } else {
3781 val = pevent_read_number(event->pevent, data + field->offset,
3782 field->size);
3783 if (field->flags & FIELD_IS_POINTER) {
3784 trace_seq_printf(s, "0x%llx", val);
3785 } else if (field->flags & FIELD_IS_SIGNED) {
3786 switch (field->size) {
3787 case 4:
3788 /*
3789 * If field is long then print it in hex.
3790 * A long usually stores pointers.
3791 */
3792 if (field->flags & FIELD_IS_LONG)
3793 trace_seq_printf(s, "0x%x", (int)val);
3794 else
3795 trace_seq_printf(s, "%d", (int)val);
3796 break;
3797 case 2:
3798 trace_seq_printf(s, "%2d", (short)val);
3799 break;
3800 case 1:
3801 trace_seq_printf(s, "%1d", (char)val);
3802 break;
3803 default:
3804 trace_seq_printf(s, "%lld", val);
3805 }
3806 } else {
3807 if (field->flags & FIELD_IS_LONG)
3808 trace_seq_printf(s, "0x%llx", val);
3809 else
3810 trace_seq_printf(s, "%llu", val);
3811 }
3812 }
3813 field = field->next;
3814 }
3815}
3816
3817static void pretty_print(struct trace_seq *s, void *data, int size, struct event_format *event)
3818{
3819 struct pevent *pevent = event->pevent;
3820 struct print_fmt *print_fmt = &event->print_fmt;
3821 struct print_arg *arg = print_fmt->args;
3822 struct print_arg *args = NULL;
3823 const char *ptr = print_fmt->format;
3824 unsigned long long val;
3825 struct func_map *func;
3826 const char *saveptr;
3827 char *bprint_fmt = NULL;
3828 char format[32];
3829 int show_func;
3830 int len_as_arg;
3831 int len_arg;
3832 int len;
3833 int ls;
3834
3835 if (event->flags & EVENT_FL_FAILED) {
3836 trace_seq_printf(s, "[FAILED TO PARSE]");
3837 print_event_fields(s, data, size, event);
3838 return;
3839 }
3840
3841 if (event->flags & EVENT_FL_ISBPRINT) {
3842 bprint_fmt = get_bprint_format(data, size, event);
3843 args = make_bprint_args(bprint_fmt, data, size, event);
3844 arg = args;
3845 ptr = bprint_fmt;
3846 }
3847
3848 for (; *ptr; ptr++) {
3849 ls = 0;
3850 if (*ptr == '\\') {
3851 ptr++;
3852 switch (*ptr) {
3853 case 'n':
3854 trace_seq_putc(s, '\n');
3855 break;
3856 case 't':
3857 trace_seq_putc(s, '\t');
3858 break;
3859 case 'r':
3860 trace_seq_putc(s, '\r');
3861 break;
3862 case '\\':
3863 trace_seq_putc(s, '\\');
3864 break;
3865 default:
3866 trace_seq_putc(s, *ptr);
3867 break;
3868 }
3869
3870 } else if (*ptr == '%') {
3871 saveptr = ptr;
3872 show_func = 0;
3873 len_as_arg = 0;
3874 cont_process:
3875 ptr++;
3876 switch (*ptr) {
3877 case '%':
3878 trace_seq_putc(s, '%');
3879 break;
3880 case '#':
3881 /* FIXME: need to handle properly */
3882 goto cont_process;
3883 case 'h':
3884 ls--;
3885 goto cont_process;
3886 case 'l':
3887 ls++;
3888 goto cont_process;
3889 case 'L':
3890 ls = 2;
3891 goto cont_process;
3892 case '*':
3893 /* The argument is the length. */
3894 if (!arg)
3895 die("no argument match");
3896 len_arg = eval_num_arg(data, size, event, arg);
3897 len_as_arg = 1;
3898 arg = arg->next;
3899 goto cont_process;
3900 case '.':
3901 case 'z':
3902 case 'Z':
3903 case '0' ... '9':
3904 goto cont_process;
3905 case 'p':
3906 if (pevent->long_size == 4)
3907 ls = 1;
3908 else
3909 ls = 2;
3910
3911 if (*(ptr+1) == 'F' ||
3912 *(ptr+1) == 'f') {
3913 ptr++;
3914 show_func = *ptr;
3915 } else if (*(ptr+1) == 'M' || *(ptr+1) == 'm') {
3916 print_mac_arg(s, *(ptr+1), data, size, event, arg);
3917 ptr++;
Steven Rostedtaaf05c72012-01-09 15:58:09 -05003918 arg = arg->next;
Steven Rostedtf7d82352012-04-06 00:47:53 +02003919 break;
3920 }
3921
3922 /* fall through */
3923 case 'd':
3924 case 'i':
3925 case 'x':
3926 case 'X':
3927 case 'u':
3928 if (!arg)
3929 die("no argument match");
3930
3931 len = ((unsigned long)ptr + 1) -
3932 (unsigned long)saveptr;
3933
3934 /* should never happen */
3935 if (len > 31)
3936 die("bad format!");
3937
3938 memcpy(format, saveptr, len);
3939 format[len] = 0;
3940
3941 val = eval_num_arg(data, size, event, arg);
3942 arg = arg->next;
3943
3944 if (show_func) {
3945 func = find_func(pevent, val);
3946 if (func) {
3947 trace_seq_puts(s, func->func);
3948 if (show_func == 'F')
3949 trace_seq_printf(s,
3950 "+0x%llx",
3951 val - func->addr);
3952 break;
3953 }
3954 }
Wolfgang Mauererc5b35b72012-03-22 11:18:21 +01003955 if (pevent->long_size == 8 && ls &&
3956 sizeof(long) != 8) {
Steven Rostedtf7d82352012-04-06 00:47:53 +02003957 char *p;
3958
3959 ls = 2;
3960 /* make %l into %ll */
3961 p = strchr(format, 'l');
3962 if (p)
Wolfgang Mauererc5b35b72012-03-22 11:18:21 +01003963 memmove(p+1, p, strlen(p)+1);
Steven Rostedtf7d82352012-04-06 00:47:53 +02003964 else if (strcmp(format, "%p") == 0)
3965 strcpy(format, "0x%llx");
3966 }
3967 switch (ls) {
3968 case -2:
3969 if (len_as_arg)
3970 trace_seq_printf(s, format, len_arg, (char)val);
3971 else
3972 trace_seq_printf(s, format, (char)val);
3973 break;
3974 case -1:
3975 if (len_as_arg)
3976 trace_seq_printf(s, format, len_arg, (short)val);
3977 else
3978 trace_seq_printf(s, format, (short)val);
3979 break;
3980 case 0:
3981 if (len_as_arg)
3982 trace_seq_printf(s, format, len_arg, (int)val);
3983 else
3984 trace_seq_printf(s, format, (int)val);
3985 break;
3986 case 1:
3987 if (len_as_arg)
3988 trace_seq_printf(s, format, len_arg, (long)val);
3989 else
3990 trace_seq_printf(s, format, (long)val);
3991 break;
3992 case 2:
3993 if (len_as_arg)
3994 trace_seq_printf(s, format, len_arg,
3995 (long long)val);
3996 else
3997 trace_seq_printf(s, format, (long long)val);
3998 break;
3999 default:
4000 die("bad count (%d)", ls);
4001 }
4002 break;
4003 case 's':
4004 if (!arg)
4005 die("no matching argument");
4006
4007 len = ((unsigned long)ptr + 1) -
4008 (unsigned long)saveptr;
4009
4010 /* should never happen */
4011 if (len > 31)
4012 die("bad format!");
4013
4014 memcpy(format, saveptr, len);
4015 format[len] = 0;
4016 if (!len_as_arg)
4017 len_arg = -1;
4018 print_str_arg(s, data, size, event,
4019 format, len_arg, arg);
4020 arg = arg->next;
4021 break;
4022 default:
4023 trace_seq_printf(s, ">%c<", *ptr);
4024
4025 }
4026 } else
4027 trace_seq_putc(s, *ptr);
4028 }
4029
4030 if (args) {
4031 free_args(args);
4032 free(bprint_fmt);
4033 }
4034}
4035
4036/**
4037 * pevent_data_lat_fmt - parse the data for the latency format
4038 * @pevent: a handle to the pevent
4039 * @s: the trace_seq to write to
4040 * @data: the raw data to read from
4041 * @size: currently unused.
4042 *
4043 * This parses out the Latency format (interrupts disabled,
4044 * need rescheduling, in hard/soft interrupt, preempt count
4045 * and lock depth) and places it into the trace_seq.
4046 */
4047void pevent_data_lat_fmt(struct pevent *pevent,
Steven Rostedt1c698182012-04-06 00:48:06 +02004048 struct trace_seq *s, struct pevent_record *record)
Steven Rostedtf7d82352012-04-06 00:47:53 +02004049{
4050 static int check_lock_depth = 1;
Steven Rostedt0866a972012-05-22 14:52:40 +09004051 static int check_migrate_disable = 1;
Steven Rostedtf7d82352012-04-06 00:47:53 +02004052 static int lock_depth_exists;
Steven Rostedt0866a972012-05-22 14:52:40 +09004053 static int migrate_disable_exists;
Steven Rostedtf7d82352012-04-06 00:47:53 +02004054 unsigned int lat_flags;
4055 unsigned int pc;
4056 int lock_depth;
Steven Rostedt0866a972012-05-22 14:52:40 +09004057 int migrate_disable;
Steven Rostedtf7d82352012-04-06 00:47:53 +02004058 int hardirq;
4059 int softirq;
4060 void *data = record->data;
4061
4062 lat_flags = parse_common_flags(pevent, data);
4063 pc = parse_common_pc(pevent, data);
4064 /* lock_depth may not always exist */
Steven Rostedtf7d82352012-04-06 00:47:53 +02004065 if (lock_depth_exists)
4066 lock_depth = parse_common_lock_depth(pevent, data);
Steven Rostedt0866a972012-05-22 14:52:40 +09004067 else if (check_lock_depth) {
4068 lock_depth = parse_common_lock_depth(pevent, data);
4069 if (lock_depth < 0)
4070 check_lock_depth = 0;
4071 else
4072 lock_depth_exists = 1;
4073 }
4074
4075 /* migrate_disable may not always exist */
4076 if (migrate_disable_exists)
4077 migrate_disable = parse_common_migrate_disable(pevent, data);
4078 else if (check_migrate_disable) {
4079 migrate_disable = parse_common_migrate_disable(pevent, data);
4080 if (migrate_disable < 0)
4081 check_migrate_disable = 0;
4082 else
4083 migrate_disable_exists = 1;
4084 }
Steven Rostedtf7d82352012-04-06 00:47:53 +02004085
4086 hardirq = lat_flags & TRACE_FLAG_HARDIRQ;
4087 softirq = lat_flags & TRACE_FLAG_SOFTIRQ;
4088
4089 trace_seq_printf(s, "%c%c%c",
4090 (lat_flags & TRACE_FLAG_IRQS_OFF) ? 'd' :
4091 (lat_flags & TRACE_FLAG_IRQS_NOSUPPORT) ?
4092 'X' : '.',
4093 (lat_flags & TRACE_FLAG_NEED_RESCHED) ?
4094 'N' : '.',
4095 (hardirq && softirq) ? 'H' :
4096 hardirq ? 'h' : softirq ? 's' : '.');
4097
4098 if (pc)
4099 trace_seq_printf(s, "%x", pc);
4100 else
4101 trace_seq_putc(s, '.');
4102
Steven Rostedt0866a972012-05-22 14:52:40 +09004103 if (migrate_disable_exists) {
4104 if (migrate_disable < 0)
4105 trace_seq_putc(s, '.');
4106 else
4107 trace_seq_printf(s, "%d", migrate_disable);
4108 }
4109
Steven Rostedtf7d82352012-04-06 00:47:53 +02004110 if (lock_depth_exists) {
4111 if (lock_depth < 0)
4112 trace_seq_putc(s, '.');
4113 else
4114 trace_seq_printf(s, "%d", lock_depth);
4115 }
4116
4117 trace_seq_terminate(s);
4118}
4119
4120/**
4121 * pevent_data_type - parse out the given event type
4122 * @pevent: a handle to the pevent
4123 * @rec: the record to read from
4124 *
4125 * This returns the event id from the @rec.
4126 */
Steven Rostedt1c698182012-04-06 00:48:06 +02004127int pevent_data_type(struct pevent *pevent, struct pevent_record *rec)
Steven Rostedtf7d82352012-04-06 00:47:53 +02004128{
4129 return trace_parse_common_type(pevent, rec->data);
4130}
4131
4132/**
4133 * pevent_data_event_from_type - find the event by a given type
4134 * @pevent: a handle to the pevent
4135 * @type: the type of the event.
4136 *
4137 * This returns the event form a given @type;
4138 */
4139struct event_format *pevent_data_event_from_type(struct pevent *pevent, int type)
4140{
4141 return pevent_find_event(pevent, type);
4142}
4143
4144/**
4145 * pevent_data_pid - parse the PID from raw data
4146 * @pevent: a handle to the pevent
4147 * @rec: the record to parse
4148 *
4149 * This returns the PID from a raw data.
4150 */
Steven Rostedt1c698182012-04-06 00:48:06 +02004151int pevent_data_pid(struct pevent *pevent, struct pevent_record *rec)
Steven Rostedtf7d82352012-04-06 00:47:53 +02004152{
4153 return parse_common_pid(pevent, rec->data);
4154}
4155
4156/**
4157 * pevent_data_comm_from_pid - return the command line from PID
4158 * @pevent: a handle to the pevent
4159 * @pid: the PID of the task to search for
4160 *
4161 * This returns a pointer to the command line that has the given
4162 * @pid.
4163 */
4164const char *pevent_data_comm_from_pid(struct pevent *pevent, int pid)
4165{
4166 const char *comm;
4167
4168 comm = find_cmdline(pevent, pid);
4169 return comm;
4170}
4171
4172/**
4173 * pevent_data_comm_from_pid - parse the data into the print format
4174 * @s: the trace_seq to write to
4175 * @event: the handle to the event
4176 * @cpu: the cpu the event was recorded on
4177 * @data: the raw data
4178 * @size: the size of the raw data
4179 * @nsecs: the timestamp of the event
4180 *
4181 * This parses the raw @data using the given @event information and
4182 * writes the print format into the trace_seq.
4183 */
4184void pevent_event_info(struct trace_seq *s, struct event_format *event,
Steven Rostedt1c698182012-04-06 00:48:06 +02004185 struct pevent_record *record)
Steven Rostedtf7d82352012-04-06 00:47:53 +02004186{
4187 int print_pretty = 1;
4188
4189 if (event->pevent->print_raw)
4190 print_event_fields(s, record->data, record->size, event);
4191 else {
4192
4193 if (event->handler)
4194 print_pretty = event->handler(s, record, event,
4195 event->context);
4196
4197 if (print_pretty)
4198 pretty_print(s, record->data, record->size, event);
4199 }
4200
4201 trace_seq_terminate(s);
4202}
4203
4204void pevent_print_event(struct pevent *pevent, struct trace_seq *s,
Steven Rostedt1c698182012-04-06 00:48:06 +02004205 struct pevent_record *record)
Steven Rostedtf7d82352012-04-06 00:47:53 +02004206{
4207 static char *spaces = " "; /* 20 spaces */
4208 struct event_format *event;
4209 unsigned long secs;
4210 unsigned long usecs;
Steven Rostedt4dc10242012-04-06 00:47:57 +02004211 unsigned long nsecs;
Steven Rostedtf7d82352012-04-06 00:47:53 +02004212 const char *comm;
4213 void *data = record->data;
4214 int type;
4215 int pid;
4216 int len;
Steven Rostedt4dc10242012-04-06 00:47:57 +02004217 int p;
Steven Rostedtf7d82352012-04-06 00:47:53 +02004218
4219 secs = record->ts / NSECS_PER_SEC;
Steven Rostedt4dc10242012-04-06 00:47:57 +02004220 nsecs = record->ts - secs * NSECS_PER_SEC;
Steven Rostedtf7d82352012-04-06 00:47:53 +02004221
4222 if (record->size < 0) {
4223 do_warning("ug! negative record size %d", record->size);
4224 return;
4225 }
4226
4227 type = trace_parse_common_type(pevent, data);
4228
4229 event = pevent_find_event(pevent, type);
4230 if (!event) {
4231 do_warning("ug! no event found for type %d", type);
4232 return;
4233 }
4234
4235 pid = parse_common_pid(pevent, data);
4236 comm = find_cmdline(pevent, pid);
4237
4238 if (pevent->latency_format) {
4239 trace_seq_printf(s, "%8.8s-%-5d %3d",
4240 comm, pid, record->cpu);
4241 pevent_data_lat_fmt(pevent, s, record);
4242 } else
4243 trace_seq_printf(s, "%16s-%-5d [%03d]", comm, pid, record->cpu);
4244
Steven Rostedt4dc10242012-04-06 00:47:57 +02004245 if (pevent->flags & PEVENT_NSEC_OUTPUT) {
4246 usecs = nsecs;
4247 p = 9;
4248 } else {
4249 usecs = (nsecs + 500) / NSECS_PER_USEC;
4250 p = 6;
4251 }
4252
4253 trace_seq_printf(s, " %5lu.%0*lu: %s: ", secs, p, usecs, event->name);
Steven Rostedtf7d82352012-04-06 00:47:53 +02004254
4255 /* Space out the event names evenly. */
4256 len = strlen(event->name);
4257 if (len < 20)
4258 trace_seq_printf(s, "%.*s", 20 - len, spaces);
4259
4260 pevent_event_info(s, event, record);
4261}
4262
4263static int events_id_cmp(const void *a, const void *b)
4264{
4265 struct event_format * const * ea = a;
4266 struct event_format * const * eb = b;
4267
4268 if ((*ea)->id < (*eb)->id)
4269 return -1;
4270
4271 if ((*ea)->id > (*eb)->id)
4272 return 1;
4273
4274 return 0;
4275}
4276
4277static int events_name_cmp(const void *a, const void *b)
4278{
4279 struct event_format * const * ea = a;
4280 struct event_format * const * eb = b;
4281 int res;
4282
4283 res = strcmp((*ea)->name, (*eb)->name);
4284 if (res)
4285 return res;
4286
4287 res = strcmp((*ea)->system, (*eb)->system);
4288 if (res)
4289 return res;
4290
4291 return events_id_cmp(a, b);
4292}
4293
4294static int events_system_cmp(const void *a, const void *b)
4295{
4296 struct event_format * const * ea = a;
4297 struct event_format * const * eb = b;
4298 int res;
4299
4300 res = strcmp((*ea)->system, (*eb)->system);
4301 if (res)
4302 return res;
4303
4304 res = strcmp((*ea)->name, (*eb)->name);
4305 if (res)
4306 return res;
4307
4308 return events_id_cmp(a, b);
4309}
4310
4311struct event_format **pevent_list_events(struct pevent *pevent, enum event_sort_type sort_type)
4312{
4313 struct event_format **events;
4314 int (*sort)(const void *a, const void *b);
4315
4316 events = pevent->sort_events;
4317
4318 if (events && pevent->last_type == sort_type)
4319 return events;
4320
4321 if (!events) {
4322 events = malloc(sizeof(*events) * (pevent->nr_events + 1));
4323 if (!events)
4324 return NULL;
4325
4326 memcpy(events, pevent->events, sizeof(*events) * pevent->nr_events);
4327 events[pevent->nr_events] = NULL;
4328
4329 pevent->sort_events = events;
4330
4331 /* the internal events are sorted by id */
4332 if (sort_type == EVENT_SORT_ID) {
4333 pevent->last_type = sort_type;
4334 return events;
4335 }
4336 }
4337
4338 switch (sort_type) {
4339 case EVENT_SORT_ID:
4340 sort = events_id_cmp;
4341 break;
4342 case EVENT_SORT_NAME:
4343 sort = events_name_cmp;
4344 break;
4345 case EVENT_SORT_SYSTEM:
4346 sort = events_system_cmp;
4347 break;
4348 default:
4349 return events;
4350 }
4351
4352 qsort(events, pevent->nr_events, sizeof(*events), sort);
4353 pevent->last_type = sort_type;
4354
4355 return events;
4356}
4357
4358static struct format_field **
4359get_event_fields(const char *type, const char *name,
4360 int count, struct format_field *list)
4361{
4362 struct format_field **fields;
4363 struct format_field *field;
4364 int i = 0;
4365
4366 fields = malloc_or_die(sizeof(*fields) * (count + 1));
4367 for (field = list; field; field = field->next) {
4368 fields[i++] = field;
4369 if (i == count + 1) {
4370 do_warning("event %s has more %s fields than specified",
4371 name, type);
4372 i--;
4373 break;
4374 }
4375 }
4376
4377 if (i != count)
4378 do_warning("event %s has less %s fields than specified",
4379 name, type);
4380
4381 fields[i] = NULL;
4382
4383 return fields;
4384}
4385
4386/**
4387 * pevent_event_common_fields - return a list of common fields for an event
4388 * @event: the event to return the common fields of.
4389 *
4390 * Returns an allocated array of fields. The last item in the array is NULL.
4391 * The array must be freed with free().
4392 */
4393struct format_field **pevent_event_common_fields(struct event_format *event)
4394{
4395 return get_event_fields("common", event->name,
4396 event->format.nr_common,
4397 event->format.common_fields);
4398}
4399
4400/**
4401 * pevent_event_fields - return a list of event specific fields for an event
4402 * @event: the event to return the fields of.
4403 *
4404 * Returns an allocated array of fields. The last item in the array is NULL.
4405 * The array must be freed with free().
4406 */
4407struct format_field **pevent_event_fields(struct event_format *event)
4408{
4409 return get_event_fields("event", event->name,
4410 event->format.nr_fields,
4411 event->format.fields);
4412}
4413
4414static void print_fields(struct trace_seq *s, struct print_flag_sym *field)
4415{
4416 trace_seq_printf(s, "{ %s, %s }", field->value, field->str);
4417 if (field->next) {
4418 trace_seq_puts(s, ", ");
4419 print_fields(s, field->next);
4420 }
4421}
4422
4423/* for debugging */
4424static void print_args(struct print_arg *args)
4425{
4426 int print_paren = 1;
4427 struct trace_seq s;
4428
4429 switch (args->type) {
4430 case PRINT_NULL:
4431 printf("null");
4432 break;
4433 case PRINT_ATOM:
4434 printf("%s", args->atom.atom);
4435 break;
4436 case PRINT_FIELD:
4437 printf("REC->%s", args->field.name);
4438 break;
4439 case PRINT_FLAGS:
4440 printf("__print_flags(");
4441 print_args(args->flags.field);
4442 printf(", %s, ", args->flags.delim);
4443 trace_seq_init(&s);
4444 print_fields(&s, args->flags.flags);
4445 trace_seq_do_printf(&s);
4446 trace_seq_destroy(&s);
4447 printf(")");
4448 break;
4449 case PRINT_SYMBOL:
4450 printf("__print_symbolic(");
4451 print_args(args->symbol.field);
4452 printf(", ");
4453 trace_seq_init(&s);
4454 print_fields(&s, args->symbol.symbols);
4455 trace_seq_do_printf(&s);
4456 trace_seq_destroy(&s);
4457 printf(")");
4458 break;
Namhyung Kime080e6f2012-06-27 09:41:41 +09004459 case PRINT_HEX:
4460 printf("__print_hex(");
4461 print_args(args->hex.field);
4462 printf(", ");
4463 print_args(args->hex.size);
4464 printf(")");
4465 break;
Steven Rostedtf7d82352012-04-06 00:47:53 +02004466 case PRINT_STRING:
4467 case PRINT_BSTRING:
4468 printf("__get_str(%s)", args->string.string);
4469 break;
4470 case PRINT_TYPE:
4471 printf("(%s)", args->typecast.type);
4472 print_args(args->typecast.item);
4473 break;
4474 case PRINT_OP:
4475 if (strcmp(args->op.op, ":") == 0)
4476 print_paren = 0;
4477 if (print_paren)
4478 printf("(");
4479 print_args(args->op.left);
4480 printf(" %s ", args->op.op);
4481 print_args(args->op.right);
4482 if (print_paren)
4483 printf(")");
4484 break;
4485 default:
4486 /* we should warn... */
4487 return;
4488 }
4489 if (args->next) {
4490 printf("\n");
4491 print_args(args->next);
4492 }
4493}
4494
4495static void parse_header_field(const char *field,
4496 int *offset, int *size, int mandatory)
4497{
4498 unsigned long long save_input_buf_ptr;
4499 unsigned long long save_input_buf_siz;
4500 char *token;
4501 int type;
4502
4503 save_input_buf_ptr = input_buf_ptr;
4504 save_input_buf_siz = input_buf_siz;
4505
4506 if (read_expected(EVENT_ITEM, "field") < 0)
4507 return;
4508 if (read_expected(EVENT_OP, ":") < 0)
4509 return;
4510
4511 /* type */
4512 if (read_expect_type(EVENT_ITEM, &token) < 0)
4513 goto fail;
4514 free_token(token);
4515
4516 /*
4517 * If this is not a mandatory field, then test it first.
4518 */
4519 if (mandatory) {
4520 if (read_expected(EVENT_ITEM, field) < 0)
4521 return;
4522 } else {
4523 if (read_expect_type(EVENT_ITEM, &token) < 0)
4524 goto fail;
4525 if (strcmp(token, field) != 0)
4526 goto discard;
4527 free_token(token);
4528 }
4529
4530 if (read_expected(EVENT_OP, ";") < 0)
4531 return;
4532 if (read_expected(EVENT_ITEM, "offset") < 0)
4533 return;
4534 if (read_expected(EVENT_OP, ":") < 0)
4535 return;
4536 if (read_expect_type(EVENT_ITEM, &token) < 0)
4537 goto fail;
4538 *offset = atoi(token);
4539 free_token(token);
4540 if (read_expected(EVENT_OP, ";") < 0)
4541 return;
4542 if (read_expected(EVENT_ITEM, "size") < 0)
4543 return;
4544 if (read_expected(EVENT_OP, ":") < 0)
4545 return;
4546 if (read_expect_type(EVENT_ITEM, &token) < 0)
4547 goto fail;
4548 *size = atoi(token);
4549 free_token(token);
4550 if (read_expected(EVENT_OP, ";") < 0)
4551 return;
4552 type = read_token(&token);
4553 if (type != EVENT_NEWLINE) {
4554 /* newer versions of the kernel have a "signed" type */
4555 if (type != EVENT_ITEM)
4556 goto fail;
4557
4558 if (strcmp(token, "signed") != 0)
4559 goto fail;
4560
4561 free_token(token);
4562
4563 if (read_expected(EVENT_OP, ":") < 0)
4564 return;
4565
4566 if (read_expect_type(EVENT_ITEM, &token))
4567 goto fail;
4568
4569 free_token(token);
4570 if (read_expected(EVENT_OP, ";") < 0)
4571 return;
4572
4573 if (read_expect_type(EVENT_NEWLINE, &token))
4574 goto fail;
4575 }
4576 fail:
4577 free_token(token);
4578 return;
4579
4580 discard:
4581 input_buf_ptr = save_input_buf_ptr;
4582 input_buf_siz = save_input_buf_siz;
4583 *offset = 0;
4584 *size = 0;
4585 free_token(token);
4586}
4587
4588/**
4589 * pevent_parse_header_page - parse the data stored in the header page
4590 * @pevent: the handle to the pevent
4591 * @buf: the buffer storing the header page format string
4592 * @size: the size of @buf
4593 * @long_size: the long size to use if there is no header
4594 *
4595 * This parses the header page format for information on the
4596 * ring buffer used. The @buf should be copied from
4597 *
4598 * /sys/kernel/debug/tracing/events/header_page
4599 */
4600int pevent_parse_header_page(struct pevent *pevent, char *buf, unsigned long size,
4601 int long_size)
4602{
4603 int ignore;
4604
4605 if (!size) {
4606 /*
4607 * Old kernels did not have header page info.
4608 * Sorry but we just use what we find here in user space.
4609 */
4610 pevent->header_page_ts_size = sizeof(long long);
4611 pevent->header_page_size_size = long_size;
4612 pevent->header_page_data_offset = sizeof(long long) + long_size;
4613 pevent->old_format = 1;
4614 return -1;
4615 }
4616 init_input_buf(buf, size);
4617
4618 parse_header_field("timestamp", &pevent->header_page_ts_offset,
4619 &pevent->header_page_ts_size, 1);
4620 parse_header_field("commit", &pevent->header_page_size_offset,
4621 &pevent->header_page_size_size, 1);
4622 parse_header_field("overwrite", &pevent->header_page_overwrite,
4623 &ignore, 0);
4624 parse_header_field("data", &pevent->header_page_data_offset,
4625 &pevent->header_page_data_size, 1);
4626
4627 return 0;
4628}
4629
4630static int event_matches(struct event_format *event,
4631 int id, const char *sys_name,
4632 const char *event_name)
4633{
4634 if (id >= 0 && id != event->id)
4635 return 0;
4636
4637 if (event_name && (strcmp(event_name, event->name) != 0))
4638 return 0;
4639
4640 if (sys_name && (strcmp(sys_name, event->system) != 0))
4641 return 0;
4642
4643 return 1;
4644}
4645
4646static void free_handler(struct event_handler *handle)
4647{
4648 free((void *)handle->sys_name);
4649 free((void *)handle->event_name);
4650 free(handle);
4651}
4652
4653static int find_event_handle(struct pevent *pevent, struct event_format *event)
4654{
4655 struct event_handler *handle, **next;
4656
4657 for (next = &pevent->handlers; *next;
4658 next = &(*next)->next) {
4659 handle = *next;
4660 if (event_matches(event, handle->id,
4661 handle->sys_name,
4662 handle->event_name))
4663 break;
4664 }
4665
4666 if (!(*next))
4667 return 0;
4668
4669 pr_stat("overriding event (%d) %s:%s with new print handler",
4670 event->id, event->system, event->name);
4671
4672 event->handler = handle->func;
4673 event->context = handle->context;
4674
4675 *next = handle->next;
4676 free_handler(handle);
4677
4678 return 1;
4679}
4680
4681/**
4682 * pevent_parse_event - parse the event format
4683 * @pevent: the handle to the pevent
4684 * @buf: the buffer storing the event format string
4685 * @size: the size of @buf
4686 * @sys: the system the event belongs to
4687 *
4688 * This parses the event format and creates an event structure
4689 * to quickly parse raw data for a given event.
4690 *
4691 * These files currently come from:
4692 *
4693 * /sys/kernel/debug/tracing/events/.../.../format
4694 */
4695int pevent_parse_event(struct pevent *pevent,
4696 const char *buf, unsigned long size,
4697 const char *sys)
4698{
4699 struct event_format *event;
4700 int ret;
4701
4702 init_input_buf(buf, size);
4703
4704 event = alloc_event();
4705 if (!event)
4706 return -ENOMEM;
4707
4708 event->name = event_read_name();
4709 if (!event->name) {
4710 /* Bad event? */
4711 free(event);
4712 return -1;
4713 }
4714
4715 if (strcmp(sys, "ftrace") == 0) {
4716
4717 event->flags |= EVENT_FL_ISFTRACE;
4718
4719 if (strcmp(event->name, "bprint") == 0)
4720 event->flags |= EVENT_FL_ISBPRINT;
4721 }
4722
4723 event->id = event_read_id();
4724 if (event->id < 0)
4725 die("failed to read event id");
4726
4727 event->system = strdup(sys);
Namhyung Kimca638582012-04-09 11:54:31 +09004728 if (!event->system)
4729 die("failed to allocate system");
Steven Rostedtf7d82352012-04-06 00:47:53 +02004730
4731 /* Add pevent to event so that it can be referenced */
4732 event->pevent = pevent;
4733
4734 ret = event_read_format(event);
4735 if (ret < 0) {
4736 do_warning("failed to read event format for %s", event->name);
4737 goto event_failed;
4738 }
4739
4740 /*
4741 * If the event has an override, don't print warnings if the event
4742 * print format fails to parse.
4743 */
4744 if (find_event_handle(pevent, event))
4745 show_warning = 0;
4746
4747 ret = event_read_print(event);
4748 if (ret < 0) {
4749 do_warning("failed to read event print fmt for %s",
4750 event->name);
4751 show_warning = 1;
4752 goto event_failed;
4753 }
4754 show_warning = 1;
4755
4756 add_event(pevent, event);
4757
4758 if (!ret && (event->flags & EVENT_FL_ISFTRACE)) {
4759 struct format_field *field;
4760 struct print_arg *arg, **list;
4761
4762 /* old ftrace had no args */
4763
4764 list = &event->print_fmt.args;
4765 for (field = event->format.fields; field; field = field->next) {
4766 arg = alloc_arg();
4767 *list = arg;
4768 list = &arg->next;
4769 arg->type = PRINT_FIELD;
4770 arg->field.name = strdup(field->name);
Namhyung Kimca638582012-04-09 11:54:31 +09004771 if (!arg->field.name) {
4772 do_warning("failed to allocate field name");
Namhyung Kim4b5632b2012-04-23 13:58:34 +09004773 event->flags |= EVENT_FL_FAILED;
4774 return -1;
Namhyung Kimca638582012-04-09 11:54:31 +09004775 }
Steven Rostedtf7d82352012-04-06 00:47:53 +02004776 arg->field.field = field;
4777 }
4778 return 0;
4779 }
4780
4781#define PRINT_ARGS 0
4782 if (PRINT_ARGS && event->print_fmt.args)
4783 print_args(event->print_fmt.args);
4784
4785 return 0;
4786
4787 event_failed:
4788 event->flags |= EVENT_FL_FAILED;
4789 /* still add it even if it failed */
4790 add_event(pevent, event);
4791 return -1;
4792}
4793
4794int get_field_val(struct trace_seq *s, struct format_field *field,
Steven Rostedt1c698182012-04-06 00:48:06 +02004795 const char *name, struct pevent_record *record,
Steven Rostedtf7d82352012-04-06 00:47:53 +02004796 unsigned long long *val, int err)
4797{
4798 if (!field) {
4799 if (err)
4800 trace_seq_printf(s, "<CANT FIND FIELD %s>", name);
4801 return -1;
4802 }
4803
4804 if (pevent_read_number_field(field, record->data, val)) {
4805 if (err)
4806 trace_seq_printf(s, " %s=INVALID", name);
4807 return -1;
4808 }
4809
4810 return 0;
4811}
4812
4813/**
4814 * pevent_get_field_raw - return the raw pointer into the data field
4815 * @s: The seq to print to on error
4816 * @event: the event that the field is for
4817 * @name: The name of the field
4818 * @record: The record with the field name.
4819 * @len: place to store the field length.
4820 * @err: print default error if failed.
4821 *
4822 * Returns a pointer into record->data of the field and places
4823 * the length of the field in @len.
4824 *
4825 * On failure, it returns NULL.
4826 */
4827void *pevent_get_field_raw(struct trace_seq *s, struct event_format *event,
Steven Rostedt1c698182012-04-06 00:48:06 +02004828 const char *name, struct pevent_record *record,
Steven Rostedtf7d82352012-04-06 00:47:53 +02004829 int *len, int err)
4830{
4831 struct format_field *field;
4832 void *data = record->data;
4833 unsigned offset;
4834 int dummy;
4835
4836 if (!event)
4837 return NULL;
4838
4839 field = pevent_find_field(event, name);
4840
4841 if (!field) {
4842 if (err)
4843 trace_seq_printf(s, "<CANT FIND FIELD %s>", name);
4844 return NULL;
4845 }
4846
4847 /* Allow @len to be NULL */
4848 if (!len)
4849 len = &dummy;
4850
4851 offset = field->offset;
4852 if (field->flags & FIELD_IS_DYNAMIC) {
4853 offset = pevent_read_number(event->pevent,
4854 data + offset, field->size);
4855 *len = offset >> 16;
4856 offset &= 0xffff;
4857 } else
4858 *len = field->size;
4859
4860 return data + offset;
4861}
4862
4863/**
4864 * pevent_get_field_val - find a field and return its value
4865 * @s: The seq to print to on error
4866 * @event: the event that the field is for
4867 * @name: The name of the field
4868 * @record: The record with the field name.
4869 * @val: place to store the value of the field.
4870 * @err: print default error if failed.
4871 *
4872 * Returns 0 on success -1 on field not found.
4873 */
4874int pevent_get_field_val(struct trace_seq *s, struct event_format *event,
Steven Rostedt1c698182012-04-06 00:48:06 +02004875 const char *name, struct pevent_record *record,
Steven Rostedtf7d82352012-04-06 00:47:53 +02004876 unsigned long long *val, int err)
4877{
4878 struct format_field *field;
4879
4880 if (!event)
4881 return -1;
4882
4883 field = pevent_find_field(event, name);
4884
4885 return get_field_val(s, field, name, record, val, err);
4886}
4887
4888/**
4889 * pevent_get_common_field_val - find a common field and return its value
4890 * @s: The seq to print to on error
4891 * @event: the event that the field is for
4892 * @name: The name of the field
4893 * @record: The record with the field name.
4894 * @val: place to store the value of the field.
4895 * @err: print default error if failed.
4896 *
4897 * Returns 0 on success -1 on field not found.
4898 */
4899int pevent_get_common_field_val(struct trace_seq *s, struct event_format *event,
Steven Rostedt1c698182012-04-06 00:48:06 +02004900 const char *name, struct pevent_record *record,
Steven Rostedtf7d82352012-04-06 00:47:53 +02004901 unsigned long long *val, int err)
4902{
4903 struct format_field *field;
4904
4905 if (!event)
4906 return -1;
4907
4908 field = pevent_find_common_field(event, name);
4909
4910 return get_field_val(s, field, name, record, val, err);
4911}
4912
4913/**
4914 * pevent_get_any_field_val - find a any field and return its value
4915 * @s: The seq to print to on error
4916 * @event: the event that the field is for
4917 * @name: The name of the field
4918 * @record: The record with the field name.
4919 * @val: place to store the value of the field.
4920 * @err: print default error if failed.
4921 *
4922 * Returns 0 on success -1 on field not found.
4923 */
4924int pevent_get_any_field_val(struct trace_seq *s, struct event_format *event,
Steven Rostedt1c698182012-04-06 00:48:06 +02004925 const char *name, struct pevent_record *record,
Steven Rostedtf7d82352012-04-06 00:47:53 +02004926 unsigned long long *val, int err)
4927{
4928 struct format_field *field;
4929
4930 if (!event)
4931 return -1;
4932
4933 field = pevent_find_any_field(event, name);
4934
4935 return get_field_val(s, field, name, record, val, err);
4936}
4937
4938/**
4939 * pevent_print_num_field - print a field and a format
4940 * @s: The seq to print to
4941 * @fmt: The printf format to print the field with.
4942 * @event: the event that the field is for
4943 * @name: The name of the field
4944 * @record: The record with the field name.
4945 * @err: print default error if failed.
4946 *
4947 * Returns: 0 on success, -1 field not fould, or 1 if buffer is full.
4948 */
4949int pevent_print_num_field(struct trace_seq *s, const char *fmt,
4950 struct event_format *event, const char *name,
Steven Rostedt1c698182012-04-06 00:48:06 +02004951 struct pevent_record *record, int err)
Steven Rostedtf7d82352012-04-06 00:47:53 +02004952{
4953 struct format_field *field = pevent_find_field(event, name);
4954 unsigned long long val;
4955
4956 if (!field)
4957 goto failed;
4958
4959 if (pevent_read_number_field(field, record->data, &val))
4960 goto failed;
4961
4962 return trace_seq_printf(s, fmt, val);
4963
4964 failed:
4965 if (err)
4966 trace_seq_printf(s, "CAN'T FIND FIELD \"%s\"", name);
4967 return -1;
4968}
4969
4970static void free_func_handle(struct pevent_function_handler *func)
4971{
4972 struct pevent_func_params *params;
4973
4974 free(func->name);
4975
4976 while (func->params) {
4977 params = func->params;
4978 func->params = params->next;
4979 free(params);
4980 }
4981
4982 free(func);
4983}
4984
4985/**
4986 * pevent_register_print_function - register a helper function
4987 * @pevent: the handle to the pevent
4988 * @func: the function to process the helper function
4989 * @name: the name of the helper function
4990 * @parameters: A list of enum pevent_func_arg_type
4991 *
4992 * Some events may have helper functions in the print format arguments.
4993 * This allows a plugin to dynmically create a way to process one
4994 * of these functions.
4995 *
4996 * The @parameters is a variable list of pevent_func_arg_type enums that
4997 * must end with PEVENT_FUNC_ARG_VOID.
4998 */
4999int pevent_register_print_function(struct pevent *pevent,
5000 pevent_func_handler func,
5001 enum pevent_func_arg_type ret_type,
5002 char *name, ...)
5003{
5004 struct pevent_function_handler *func_handle;
5005 struct pevent_func_params **next_param;
5006 struct pevent_func_params *param;
5007 enum pevent_func_arg_type type;
5008 va_list ap;
5009
5010 func_handle = find_func_handler(pevent, name);
5011 if (func_handle) {
5012 /*
5013 * This is most like caused by the users own
5014 * plugins updating the function. This overrides the
5015 * system defaults.
5016 */
5017 pr_stat("override of function helper '%s'", name);
5018 remove_func_handler(pevent, name);
5019 }
5020
5021 func_handle = malloc_or_die(sizeof(*func_handle));
5022 memset(func_handle, 0, sizeof(*func_handle));
5023
5024 func_handle->ret_type = ret_type;
5025 func_handle->name = strdup(name);
5026 func_handle->func = func;
5027 if (!func_handle->name)
5028 die("Failed to allocate function name");
5029
5030 next_param = &(func_handle->params);
5031 va_start(ap, name);
5032 for (;;) {
5033 type = va_arg(ap, enum pevent_func_arg_type);
5034 if (type == PEVENT_FUNC_ARG_VOID)
5035 break;
5036
5037 if (type < 0 || type >= PEVENT_FUNC_ARG_MAX_TYPES) {
5038 warning("Invalid argument type %d", type);
5039 goto out_free;
5040 }
5041
5042 param = malloc_or_die(sizeof(*param));
5043 param->type = type;
5044 param->next = NULL;
5045
5046 *next_param = param;
5047 next_param = &(param->next);
5048
5049 func_handle->nr_args++;
5050 }
5051 va_end(ap);
5052
5053 func_handle->next = pevent->func_handlers;
5054 pevent->func_handlers = func_handle;
5055
5056 return 0;
5057 out_free:
5058 va_end(ap);
5059 free_func_handle(func_handle);
5060 return -1;
5061}
5062
5063/**
5064 * pevent_register_event_handle - register a way to parse an event
5065 * @pevent: the handle to the pevent
5066 * @id: the id of the event to register
5067 * @sys_name: the system name the event belongs to
5068 * @event_name: the name of the event
5069 * @func: the function to call to parse the event information
5070 *
5071 * This function allows a developer to override the parsing of
5072 * a given event. If for some reason the default print format
5073 * is not sufficient, this function will register a function
5074 * for an event to be used to parse the data instead.
5075 *
5076 * If @id is >= 0, then it is used to find the event.
5077 * else @sys_name and @event_name are used.
5078 */
5079int pevent_register_event_handler(struct pevent *pevent,
5080 int id, char *sys_name, char *event_name,
5081 pevent_event_handler_func func,
5082 void *context)
5083{
5084 struct event_format *event;
5085 struct event_handler *handle;
5086
5087 if (id >= 0) {
5088 /* search by id */
5089 event = pevent_find_event(pevent, id);
5090 if (!event)
5091 goto not_found;
5092 if (event_name && (strcmp(event_name, event->name) != 0))
5093 goto not_found;
5094 if (sys_name && (strcmp(sys_name, event->system) != 0))
5095 goto not_found;
5096 } else {
5097 event = pevent_find_event_by_name(pevent, sys_name, event_name);
5098 if (!event)
5099 goto not_found;
5100 }
5101
5102 pr_stat("overriding event (%d) %s:%s with new print handler",
5103 event->id, event->system, event->name);
5104
5105 event->handler = func;
5106 event->context = context;
5107 return 0;
5108
5109 not_found:
5110 /* Save for later use. */
5111 handle = malloc_or_die(sizeof(*handle));
Steven Rostedt42c80132012-04-06 00:48:05 +02005112 memset(handle, 0, sizeof(*handle));
Steven Rostedtf7d82352012-04-06 00:47:53 +02005113 handle->id = id;
5114 if (event_name)
5115 handle->event_name = strdup(event_name);
5116 if (sys_name)
5117 handle->sys_name = strdup(sys_name);
5118
Namhyung Kimca638582012-04-09 11:54:31 +09005119 if ((event_name && !handle->event_name) ||
5120 (sys_name && !handle->sys_name)) {
5121 die("Failed to allocate event/sys name");
5122 }
5123
Steven Rostedtf7d82352012-04-06 00:47:53 +02005124 handle->func = func;
5125 handle->next = pevent->handlers;
5126 pevent->handlers = handle;
5127 handle->context = context;
5128
5129 return -1;
5130}
5131
5132/**
5133 * pevent_alloc - create a pevent handle
5134 */
5135struct pevent *pevent_alloc(void)
5136{
5137 struct pevent *pevent;
5138
5139 pevent = malloc(sizeof(*pevent));
5140 if (!pevent)
5141 return NULL;
5142 memset(pevent, 0, sizeof(*pevent));
5143 pevent->ref_count = 1;
5144
5145 return pevent;
5146}
5147
5148void pevent_ref(struct pevent *pevent)
5149{
5150 pevent->ref_count++;
5151}
5152
5153static void free_format_fields(struct format_field *field)
5154{
5155 struct format_field *next;
5156
5157 while (field) {
5158 next = field->next;
5159 free(field->type);
5160 free(field->name);
5161 free(field);
5162 field = next;
5163 }
5164}
5165
5166static void free_formats(struct format *format)
5167{
5168 free_format_fields(format->common_fields);
5169 free_format_fields(format->fields);
5170}
5171
5172static void free_event(struct event_format *event)
5173{
5174 free(event->name);
5175 free(event->system);
5176
5177 free_formats(&event->format);
5178
5179 free(event->print_fmt.format);
5180 free_args(event->print_fmt.args);
5181
5182 free(event);
5183}
5184
5185/**
5186 * pevent_free - free a pevent handle
5187 * @pevent: the pevent handle to free
5188 */
5189void pevent_free(struct pevent *pevent)
5190{
Steven Rostedta2525a02012-04-06 00:48:02 +02005191 struct cmdline_list *cmdlist, *cmdnext;
5192 struct func_list *funclist, *funcnext;
5193 struct printk_list *printklist, *printknext;
Steven Rostedtf7d82352012-04-06 00:47:53 +02005194 struct pevent_function_handler *func_handler;
5195 struct event_handler *handle;
5196 int i;
5197
Steven Rostedta2525a02012-04-06 00:48:02 +02005198 if (!pevent)
5199 return;
5200
5201 cmdlist = pevent->cmdlist;
5202 funclist = pevent->funclist;
5203 printklist = pevent->printklist;
5204
Steven Rostedtf7d82352012-04-06 00:47:53 +02005205 pevent->ref_count--;
5206 if (pevent->ref_count)
5207 return;
5208
5209 if (pevent->cmdlines) {
5210 for (i = 0; i < pevent->cmdline_count; i++)
5211 free(pevent->cmdlines[i].comm);
5212 free(pevent->cmdlines);
5213 }
5214
5215 while (cmdlist) {
5216 cmdnext = cmdlist->next;
5217 free(cmdlist->comm);
5218 free(cmdlist);
5219 cmdlist = cmdnext;
5220 }
5221
5222 if (pevent->func_map) {
5223 for (i = 0; i < pevent->func_count; i++) {
5224 free(pevent->func_map[i].func);
5225 free(pevent->func_map[i].mod);
5226 }
5227 free(pevent->func_map);
5228 }
5229
5230 while (funclist) {
5231 funcnext = funclist->next;
5232 free(funclist->func);
5233 free(funclist->mod);
5234 free(funclist);
5235 funclist = funcnext;
5236 }
5237
5238 while (pevent->func_handlers) {
5239 func_handler = pevent->func_handlers;
5240 pevent->func_handlers = func_handler->next;
5241 free_func_handle(func_handler);
5242 }
5243
5244 if (pevent->printk_map) {
5245 for (i = 0; i < pevent->printk_count; i++)
5246 free(pevent->printk_map[i].printk);
5247 free(pevent->printk_map);
5248 }
5249
5250 while (printklist) {
5251 printknext = printklist->next;
5252 free(printklist->printk);
5253 free(printklist);
5254 printklist = printknext;
5255 }
5256
5257 for (i = 0; i < pevent->nr_events; i++)
5258 free_event(pevent->events[i]);
5259
5260 while (pevent->handlers) {
5261 handle = pevent->handlers;
5262 pevent->handlers = handle->next;
5263 free_handler(handle);
5264 }
5265
5266 free(pevent->events);
5267 free(pevent->sort_events);
5268
5269 free(pevent);
5270}
5271
5272void pevent_unref(struct pevent *pevent)
5273{
5274 pevent_free(pevent);
5275}