blob: f880db45784281dd5210a57b4c85f41d882b6193 [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;
Peter Huewec9bbabe2012-04-24 23:19:40 +02003597 break;
Steven Rostedtc2e6dc22011-11-15 18:47:48 -05003598 default:
3599 vsize = ls; /* ? */
3600 break;
3601 }
3602 /* fall through */
3603 case '*':
3604 if (*ptr == '*')
3605 vsize = 4;
3606
Steven Rostedtf7d82352012-04-06 00:47:53 +02003607 /* the pointers are always 4 bytes aligned */
3608 bptr = (void *)(((unsigned long)bptr + 3) &
3609 ~3);
Steven Rostedtc2e6dc22011-11-15 18:47:48 -05003610 val = pevent_read_number(pevent, bptr, vsize);
3611 bptr += vsize;
Steven Rostedtf7d82352012-04-06 00:47:53 +02003612 arg = alloc_arg();
3613 arg->next = NULL;
3614 arg->type = PRINT_ATOM;
3615 arg->atom.atom = malloc_or_die(32);
3616 sprintf(arg->atom.atom, "%lld", val);
3617 *next = arg;
3618 next = &arg->next;
Steven Rostedtc2e6dc22011-11-15 18:47:48 -05003619 /*
3620 * The '*' case means that an arg is used as the length.
3621 * We need to continue to figure out for what.
3622 */
3623 if (*ptr == '*')
3624 goto process_again;
3625
Steven Rostedtf7d82352012-04-06 00:47:53 +02003626 break;
3627 case 's':
3628 arg = alloc_arg();
3629 arg->next = NULL;
3630 arg->type = PRINT_BSTRING;
3631 arg->string.string = strdup(bptr);
Namhyung Kimca638582012-04-09 11:54:31 +09003632 if (!arg->string.string)
3633 break;
Steven Rostedtf7d82352012-04-06 00:47:53 +02003634 bptr += strlen(bptr) + 1;
3635 *next = arg;
3636 next = &arg->next;
3637 default:
3638 break;
3639 }
3640 }
3641 }
3642
3643 return args;
3644}
3645
3646static void free_args(struct print_arg *args)
3647{
3648 struct print_arg *next;
3649
3650 while (args) {
3651 next = args->next;
3652
3653 free_arg(args);
3654 args = next;
3655 }
3656}
3657
3658static char *
3659get_bprint_format(void *data, int size __unused, struct event_format *event)
3660{
3661 struct pevent *pevent = event->pevent;
3662 unsigned long long addr;
3663 struct format_field *field;
3664 struct printk_map *printk;
3665 char *format;
3666 char *p;
3667
3668 field = pevent->bprint_fmt_field;
3669
3670 if (!field) {
3671 field = pevent_find_field(event, "fmt");
3672 if (!field)
3673 die("can't find format field for binary printk");
3674 pevent->bprint_fmt_field = field;
3675 }
3676
3677 addr = pevent_read_number(pevent, data + field->offset, field->size);
3678
3679 printk = find_printk(pevent, addr);
3680 if (!printk) {
3681 format = malloc_or_die(45);
3682 sprintf(format, "%%pf : (NO FORMAT FOUND at %llx)\n",
3683 addr);
3684 return format;
3685 }
3686
3687 p = printk->printk;
3688 /* Remove any quotes. */
3689 if (*p == '"')
3690 p++;
3691 format = malloc_or_die(strlen(p) + 10);
3692 sprintf(format, "%s : %s", "%pf", p);
3693 /* remove ending quotes and new line since we will add one too */
3694 p = format + strlen(format) - 1;
3695 if (*p == '"')
3696 *p = 0;
3697
3698 p -= 2;
3699 if (strcmp(p, "\\n") == 0)
3700 *p = 0;
3701
3702 return format;
3703}
3704
3705static void print_mac_arg(struct trace_seq *s, int mac, void *data, int size,
3706 struct event_format *event, struct print_arg *arg)
3707{
3708 unsigned char *buf;
3709 char *fmt = "%.2x:%.2x:%.2x:%.2x:%.2x:%.2x";
3710
3711 if (arg->type == PRINT_FUNC) {
3712 process_defined_func(s, data, size, event, arg);
3713 return;
3714 }
3715
3716 if (arg->type != PRINT_FIELD) {
3717 trace_seq_printf(s, "ARG TYPE NOT FIELD BUT %d",
3718 arg->type);
3719 return;
3720 }
3721
3722 if (mac == 'm')
3723 fmt = "%.2x%.2x%.2x%.2x%.2x%.2x";
3724 if (!arg->field.field) {
3725 arg->field.field =
3726 pevent_find_any_field(event, arg->field.name);
3727 if (!arg->field.field)
3728 die("field %s not found", arg->field.name);
3729 }
3730 if (arg->field.field->size != 6) {
3731 trace_seq_printf(s, "INVALIDMAC");
3732 return;
3733 }
3734 buf = data + arg->field.field->offset;
3735 trace_seq_printf(s, fmt, buf[0], buf[1], buf[2], buf[3], buf[4], buf[5]);
3736}
3737
Namhyung Kim600da3c2012-06-22 17:10:15 +09003738static int is_printable_array(char *p, unsigned int len)
3739{
3740 unsigned int i;
3741
3742 for (i = 0; i < len && p[i]; i++)
3743 if (!isprint(p[i]))
3744 return 0;
3745 return 1;
3746}
3747
Steven Rostedtf7d82352012-04-06 00:47:53 +02003748static void print_event_fields(struct trace_seq *s, void *data, int size,
3749 struct event_format *event)
3750{
3751 struct format_field *field;
3752 unsigned long long val;
3753 unsigned int offset, len, i;
3754
3755 field = event->format.fields;
3756 while (field) {
3757 trace_seq_printf(s, " %s=", field->name);
3758 if (field->flags & FIELD_IS_ARRAY) {
3759 offset = field->offset;
3760 len = field->size;
3761 if (field->flags & FIELD_IS_DYNAMIC) {
3762 val = pevent_read_number(event->pevent, data + offset, len);
3763 offset = val;
3764 len = offset >> 16;
3765 offset &= 0xffff;
3766 }
Namhyung Kim600da3c2012-06-22 17:10:15 +09003767 if (field->flags & FIELD_IS_STRING &&
3768 is_printable_array(data + offset, len)) {
Steven Rostedtf7d82352012-04-06 00:47:53 +02003769 trace_seq_printf(s, "%s", (char *)data + offset);
3770 } else {
3771 trace_seq_puts(s, "ARRAY[");
3772 for (i = 0; i < len; i++) {
3773 if (i)
3774 trace_seq_puts(s, ", ");
3775 trace_seq_printf(s, "%02x",
3776 *((unsigned char *)data + offset + i));
3777 }
3778 trace_seq_putc(s, ']');
Namhyung Kim600da3c2012-06-22 17:10:15 +09003779 field->flags &= ~FIELD_IS_STRING;
Steven Rostedtf7d82352012-04-06 00:47:53 +02003780 }
3781 } else {
3782 val = pevent_read_number(event->pevent, data + field->offset,
3783 field->size);
3784 if (field->flags & FIELD_IS_POINTER) {
3785 trace_seq_printf(s, "0x%llx", val);
3786 } else if (field->flags & FIELD_IS_SIGNED) {
3787 switch (field->size) {
3788 case 4:
3789 /*
3790 * If field is long then print it in hex.
3791 * A long usually stores pointers.
3792 */
3793 if (field->flags & FIELD_IS_LONG)
3794 trace_seq_printf(s, "0x%x", (int)val);
3795 else
3796 trace_seq_printf(s, "%d", (int)val);
3797 break;
3798 case 2:
3799 trace_seq_printf(s, "%2d", (short)val);
3800 break;
3801 case 1:
3802 trace_seq_printf(s, "%1d", (char)val);
3803 break;
3804 default:
3805 trace_seq_printf(s, "%lld", val);
3806 }
3807 } else {
3808 if (field->flags & FIELD_IS_LONG)
3809 trace_seq_printf(s, "0x%llx", val);
3810 else
3811 trace_seq_printf(s, "%llu", val);
3812 }
3813 }
3814 field = field->next;
3815 }
3816}
3817
3818static void pretty_print(struct trace_seq *s, void *data, int size, struct event_format *event)
3819{
3820 struct pevent *pevent = event->pevent;
3821 struct print_fmt *print_fmt = &event->print_fmt;
3822 struct print_arg *arg = print_fmt->args;
3823 struct print_arg *args = NULL;
3824 const char *ptr = print_fmt->format;
3825 unsigned long long val;
3826 struct func_map *func;
3827 const char *saveptr;
3828 char *bprint_fmt = NULL;
3829 char format[32];
3830 int show_func;
3831 int len_as_arg;
3832 int len_arg;
3833 int len;
3834 int ls;
3835
3836 if (event->flags & EVENT_FL_FAILED) {
3837 trace_seq_printf(s, "[FAILED TO PARSE]");
3838 print_event_fields(s, data, size, event);
3839 return;
3840 }
3841
3842 if (event->flags & EVENT_FL_ISBPRINT) {
3843 bprint_fmt = get_bprint_format(data, size, event);
3844 args = make_bprint_args(bprint_fmt, data, size, event);
3845 arg = args;
3846 ptr = bprint_fmt;
3847 }
3848
3849 for (; *ptr; ptr++) {
3850 ls = 0;
3851 if (*ptr == '\\') {
3852 ptr++;
3853 switch (*ptr) {
3854 case 'n':
3855 trace_seq_putc(s, '\n');
3856 break;
3857 case 't':
3858 trace_seq_putc(s, '\t');
3859 break;
3860 case 'r':
3861 trace_seq_putc(s, '\r');
3862 break;
3863 case '\\':
3864 trace_seq_putc(s, '\\');
3865 break;
3866 default:
3867 trace_seq_putc(s, *ptr);
3868 break;
3869 }
3870
3871 } else if (*ptr == '%') {
3872 saveptr = ptr;
3873 show_func = 0;
3874 len_as_arg = 0;
3875 cont_process:
3876 ptr++;
3877 switch (*ptr) {
3878 case '%':
3879 trace_seq_putc(s, '%');
3880 break;
3881 case '#':
3882 /* FIXME: need to handle properly */
3883 goto cont_process;
3884 case 'h':
3885 ls--;
3886 goto cont_process;
3887 case 'l':
3888 ls++;
3889 goto cont_process;
3890 case 'L':
3891 ls = 2;
3892 goto cont_process;
3893 case '*':
3894 /* The argument is the length. */
3895 if (!arg)
3896 die("no argument match");
3897 len_arg = eval_num_arg(data, size, event, arg);
3898 len_as_arg = 1;
3899 arg = arg->next;
3900 goto cont_process;
3901 case '.':
3902 case 'z':
3903 case 'Z':
3904 case '0' ... '9':
3905 goto cont_process;
3906 case 'p':
3907 if (pevent->long_size == 4)
3908 ls = 1;
3909 else
3910 ls = 2;
3911
3912 if (*(ptr+1) == 'F' ||
3913 *(ptr+1) == 'f') {
3914 ptr++;
3915 show_func = *ptr;
3916 } else if (*(ptr+1) == 'M' || *(ptr+1) == 'm') {
3917 print_mac_arg(s, *(ptr+1), data, size, event, arg);
3918 ptr++;
Steven Rostedtaaf05c72012-01-09 15:58:09 -05003919 arg = arg->next;
Steven Rostedtf7d82352012-04-06 00:47:53 +02003920 break;
3921 }
3922
3923 /* fall through */
3924 case 'd':
3925 case 'i':
3926 case 'x':
3927 case 'X':
3928 case 'u':
3929 if (!arg)
3930 die("no argument match");
3931
3932 len = ((unsigned long)ptr + 1) -
3933 (unsigned long)saveptr;
3934
3935 /* should never happen */
3936 if (len > 31)
3937 die("bad format!");
3938
3939 memcpy(format, saveptr, len);
3940 format[len] = 0;
3941
3942 val = eval_num_arg(data, size, event, arg);
3943 arg = arg->next;
3944
3945 if (show_func) {
3946 func = find_func(pevent, val);
3947 if (func) {
3948 trace_seq_puts(s, func->func);
3949 if (show_func == 'F')
3950 trace_seq_printf(s,
3951 "+0x%llx",
3952 val - func->addr);
3953 break;
3954 }
3955 }
Wolfgang Mauererc5b35b72012-03-22 11:18:21 +01003956 if (pevent->long_size == 8 && ls &&
3957 sizeof(long) != 8) {
Steven Rostedtf7d82352012-04-06 00:47:53 +02003958 char *p;
3959
3960 ls = 2;
3961 /* make %l into %ll */
3962 p = strchr(format, 'l');
3963 if (p)
Wolfgang Mauererc5b35b72012-03-22 11:18:21 +01003964 memmove(p+1, p, strlen(p)+1);
Steven Rostedtf7d82352012-04-06 00:47:53 +02003965 else if (strcmp(format, "%p") == 0)
3966 strcpy(format, "0x%llx");
3967 }
3968 switch (ls) {
3969 case -2:
3970 if (len_as_arg)
3971 trace_seq_printf(s, format, len_arg, (char)val);
3972 else
3973 trace_seq_printf(s, format, (char)val);
3974 break;
3975 case -1:
3976 if (len_as_arg)
3977 trace_seq_printf(s, format, len_arg, (short)val);
3978 else
3979 trace_seq_printf(s, format, (short)val);
3980 break;
3981 case 0:
3982 if (len_as_arg)
3983 trace_seq_printf(s, format, len_arg, (int)val);
3984 else
3985 trace_seq_printf(s, format, (int)val);
3986 break;
3987 case 1:
3988 if (len_as_arg)
3989 trace_seq_printf(s, format, len_arg, (long)val);
3990 else
3991 trace_seq_printf(s, format, (long)val);
3992 break;
3993 case 2:
3994 if (len_as_arg)
3995 trace_seq_printf(s, format, len_arg,
3996 (long long)val);
3997 else
3998 trace_seq_printf(s, format, (long long)val);
3999 break;
4000 default:
4001 die("bad count (%d)", ls);
4002 }
4003 break;
4004 case 's':
4005 if (!arg)
4006 die("no matching argument");
4007
4008 len = ((unsigned long)ptr + 1) -
4009 (unsigned long)saveptr;
4010
4011 /* should never happen */
4012 if (len > 31)
4013 die("bad format!");
4014
4015 memcpy(format, saveptr, len);
4016 format[len] = 0;
4017 if (!len_as_arg)
4018 len_arg = -1;
4019 print_str_arg(s, data, size, event,
4020 format, len_arg, arg);
4021 arg = arg->next;
4022 break;
4023 default:
4024 trace_seq_printf(s, ">%c<", *ptr);
4025
4026 }
4027 } else
4028 trace_seq_putc(s, *ptr);
4029 }
4030
4031 if (args) {
4032 free_args(args);
4033 free(bprint_fmt);
4034 }
4035}
4036
4037/**
4038 * pevent_data_lat_fmt - parse the data for the latency format
4039 * @pevent: a handle to the pevent
4040 * @s: the trace_seq to write to
Namhyung Kim16e6b8f2012-04-23 13:58:35 +09004041 * @record: the record to read from
Steven Rostedtf7d82352012-04-06 00:47:53 +02004042 *
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
Namhyung Kim16e6b8f2012-04-23 13:58:35 +09004176 * @record: the record to read from
Steven Rostedtf7d82352012-04-06 00:47:53 +02004177 *
4178 * This parses the raw @data using the given @event information and
4179 * writes the print format into the trace_seq.
4180 */
4181void pevent_event_info(struct trace_seq *s, struct event_format *event,
Steven Rostedt1c698182012-04-06 00:48:06 +02004182 struct pevent_record *record)
Steven Rostedtf7d82352012-04-06 00:47:53 +02004183{
4184 int print_pretty = 1;
4185
4186 if (event->pevent->print_raw)
4187 print_event_fields(s, record->data, record->size, event);
4188 else {
4189
4190 if (event->handler)
4191 print_pretty = event->handler(s, record, event,
4192 event->context);
4193
4194 if (print_pretty)
4195 pretty_print(s, record->data, record->size, event);
4196 }
4197
4198 trace_seq_terminate(s);
4199}
4200
4201void pevent_print_event(struct pevent *pevent, struct trace_seq *s,
Steven Rostedt1c698182012-04-06 00:48:06 +02004202 struct pevent_record *record)
Steven Rostedtf7d82352012-04-06 00:47:53 +02004203{
4204 static char *spaces = " "; /* 20 spaces */
4205 struct event_format *event;
4206 unsigned long secs;
4207 unsigned long usecs;
Steven Rostedt4dc10242012-04-06 00:47:57 +02004208 unsigned long nsecs;
Steven Rostedtf7d82352012-04-06 00:47:53 +02004209 const char *comm;
4210 void *data = record->data;
4211 int type;
4212 int pid;
4213 int len;
Steven Rostedt4dc10242012-04-06 00:47:57 +02004214 int p;
Steven Rostedtf7d82352012-04-06 00:47:53 +02004215
4216 secs = record->ts / NSECS_PER_SEC;
Steven Rostedt4dc10242012-04-06 00:47:57 +02004217 nsecs = record->ts - secs * NSECS_PER_SEC;
Steven Rostedtf7d82352012-04-06 00:47:53 +02004218
4219 if (record->size < 0) {
4220 do_warning("ug! negative record size %d", record->size);
4221 return;
4222 }
4223
4224 type = trace_parse_common_type(pevent, data);
4225
4226 event = pevent_find_event(pevent, type);
4227 if (!event) {
4228 do_warning("ug! no event found for type %d", type);
4229 return;
4230 }
4231
4232 pid = parse_common_pid(pevent, data);
4233 comm = find_cmdline(pevent, pid);
4234
4235 if (pevent->latency_format) {
4236 trace_seq_printf(s, "%8.8s-%-5d %3d",
4237 comm, pid, record->cpu);
4238 pevent_data_lat_fmt(pevent, s, record);
4239 } else
4240 trace_seq_printf(s, "%16s-%-5d [%03d]", comm, pid, record->cpu);
4241
Steven Rostedt4dc10242012-04-06 00:47:57 +02004242 if (pevent->flags & PEVENT_NSEC_OUTPUT) {
4243 usecs = nsecs;
4244 p = 9;
4245 } else {
4246 usecs = (nsecs + 500) / NSECS_PER_USEC;
4247 p = 6;
4248 }
4249
4250 trace_seq_printf(s, " %5lu.%0*lu: %s: ", secs, p, usecs, event->name);
Steven Rostedtf7d82352012-04-06 00:47:53 +02004251
4252 /* Space out the event names evenly. */
4253 len = strlen(event->name);
4254 if (len < 20)
4255 trace_seq_printf(s, "%.*s", 20 - len, spaces);
4256
4257 pevent_event_info(s, event, record);
4258}
4259
4260static int events_id_cmp(const void *a, const void *b)
4261{
4262 struct event_format * const * ea = a;
4263 struct event_format * const * eb = b;
4264
4265 if ((*ea)->id < (*eb)->id)
4266 return -1;
4267
4268 if ((*ea)->id > (*eb)->id)
4269 return 1;
4270
4271 return 0;
4272}
4273
4274static int events_name_cmp(const void *a, const void *b)
4275{
4276 struct event_format * const * ea = a;
4277 struct event_format * const * eb = b;
4278 int res;
4279
4280 res = strcmp((*ea)->name, (*eb)->name);
4281 if (res)
4282 return res;
4283
4284 res = strcmp((*ea)->system, (*eb)->system);
4285 if (res)
4286 return res;
4287
4288 return events_id_cmp(a, b);
4289}
4290
4291static int events_system_cmp(const void *a, const void *b)
4292{
4293 struct event_format * const * ea = a;
4294 struct event_format * const * eb = b;
4295 int res;
4296
4297 res = strcmp((*ea)->system, (*eb)->system);
4298 if (res)
4299 return res;
4300
4301 res = strcmp((*ea)->name, (*eb)->name);
4302 if (res)
4303 return res;
4304
4305 return events_id_cmp(a, b);
4306}
4307
4308struct event_format **pevent_list_events(struct pevent *pevent, enum event_sort_type sort_type)
4309{
4310 struct event_format **events;
4311 int (*sort)(const void *a, const void *b);
4312
4313 events = pevent->sort_events;
4314
4315 if (events && pevent->last_type == sort_type)
4316 return events;
4317
4318 if (!events) {
4319 events = malloc(sizeof(*events) * (pevent->nr_events + 1));
4320 if (!events)
4321 return NULL;
4322
4323 memcpy(events, pevent->events, sizeof(*events) * pevent->nr_events);
4324 events[pevent->nr_events] = NULL;
4325
4326 pevent->sort_events = events;
4327
4328 /* the internal events are sorted by id */
4329 if (sort_type == EVENT_SORT_ID) {
4330 pevent->last_type = sort_type;
4331 return events;
4332 }
4333 }
4334
4335 switch (sort_type) {
4336 case EVENT_SORT_ID:
4337 sort = events_id_cmp;
4338 break;
4339 case EVENT_SORT_NAME:
4340 sort = events_name_cmp;
4341 break;
4342 case EVENT_SORT_SYSTEM:
4343 sort = events_system_cmp;
4344 break;
4345 default:
4346 return events;
4347 }
4348
4349 qsort(events, pevent->nr_events, sizeof(*events), sort);
4350 pevent->last_type = sort_type;
4351
4352 return events;
4353}
4354
4355static struct format_field **
4356get_event_fields(const char *type, const char *name,
4357 int count, struct format_field *list)
4358{
4359 struct format_field **fields;
4360 struct format_field *field;
4361 int i = 0;
4362
4363 fields = malloc_or_die(sizeof(*fields) * (count + 1));
4364 for (field = list; field; field = field->next) {
4365 fields[i++] = field;
4366 if (i == count + 1) {
4367 do_warning("event %s has more %s fields than specified",
4368 name, type);
4369 i--;
4370 break;
4371 }
4372 }
4373
4374 if (i != count)
4375 do_warning("event %s has less %s fields than specified",
4376 name, type);
4377
4378 fields[i] = NULL;
4379
4380 return fields;
4381}
4382
4383/**
4384 * pevent_event_common_fields - return a list of common fields for an event
4385 * @event: the event to return the common fields of.
4386 *
4387 * Returns an allocated array of fields. The last item in the array is NULL.
4388 * The array must be freed with free().
4389 */
4390struct format_field **pevent_event_common_fields(struct event_format *event)
4391{
4392 return get_event_fields("common", event->name,
4393 event->format.nr_common,
4394 event->format.common_fields);
4395}
4396
4397/**
4398 * pevent_event_fields - return a list of event specific fields for an event
4399 * @event: the event to return the fields of.
4400 *
4401 * Returns an allocated array of fields. The last item in the array is NULL.
4402 * The array must be freed with free().
4403 */
4404struct format_field **pevent_event_fields(struct event_format *event)
4405{
4406 return get_event_fields("event", event->name,
4407 event->format.nr_fields,
4408 event->format.fields);
4409}
4410
4411static void print_fields(struct trace_seq *s, struct print_flag_sym *field)
4412{
4413 trace_seq_printf(s, "{ %s, %s }", field->value, field->str);
4414 if (field->next) {
4415 trace_seq_puts(s, ", ");
4416 print_fields(s, field->next);
4417 }
4418}
4419
4420/* for debugging */
4421static void print_args(struct print_arg *args)
4422{
4423 int print_paren = 1;
4424 struct trace_seq s;
4425
4426 switch (args->type) {
4427 case PRINT_NULL:
4428 printf("null");
4429 break;
4430 case PRINT_ATOM:
4431 printf("%s", args->atom.atom);
4432 break;
4433 case PRINT_FIELD:
4434 printf("REC->%s", args->field.name);
4435 break;
4436 case PRINT_FLAGS:
4437 printf("__print_flags(");
4438 print_args(args->flags.field);
4439 printf(", %s, ", args->flags.delim);
4440 trace_seq_init(&s);
4441 print_fields(&s, args->flags.flags);
4442 trace_seq_do_printf(&s);
4443 trace_seq_destroy(&s);
4444 printf(")");
4445 break;
4446 case PRINT_SYMBOL:
4447 printf("__print_symbolic(");
4448 print_args(args->symbol.field);
4449 printf(", ");
4450 trace_seq_init(&s);
4451 print_fields(&s, args->symbol.symbols);
4452 trace_seq_do_printf(&s);
4453 trace_seq_destroy(&s);
4454 printf(")");
4455 break;
Namhyung Kime080e6f2012-06-27 09:41:41 +09004456 case PRINT_HEX:
4457 printf("__print_hex(");
4458 print_args(args->hex.field);
4459 printf(", ");
4460 print_args(args->hex.size);
4461 printf(")");
4462 break;
Steven Rostedtf7d82352012-04-06 00:47:53 +02004463 case PRINT_STRING:
4464 case PRINT_BSTRING:
4465 printf("__get_str(%s)", args->string.string);
4466 break;
4467 case PRINT_TYPE:
4468 printf("(%s)", args->typecast.type);
4469 print_args(args->typecast.item);
4470 break;
4471 case PRINT_OP:
4472 if (strcmp(args->op.op, ":") == 0)
4473 print_paren = 0;
4474 if (print_paren)
4475 printf("(");
4476 print_args(args->op.left);
4477 printf(" %s ", args->op.op);
4478 print_args(args->op.right);
4479 if (print_paren)
4480 printf(")");
4481 break;
4482 default:
4483 /* we should warn... */
4484 return;
4485 }
4486 if (args->next) {
4487 printf("\n");
4488 print_args(args->next);
4489 }
4490}
4491
4492static void parse_header_field(const char *field,
4493 int *offset, int *size, int mandatory)
4494{
4495 unsigned long long save_input_buf_ptr;
4496 unsigned long long save_input_buf_siz;
4497 char *token;
4498 int type;
4499
4500 save_input_buf_ptr = input_buf_ptr;
4501 save_input_buf_siz = input_buf_siz;
4502
4503 if (read_expected(EVENT_ITEM, "field") < 0)
4504 return;
4505 if (read_expected(EVENT_OP, ":") < 0)
4506 return;
4507
4508 /* type */
4509 if (read_expect_type(EVENT_ITEM, &token) < 0)
4510 goto fail;
4511 free_token(token);
4512
4513 /*
4514 * If this is not a mandatory field, then test it first.
4515 */
4516 if (mandatory) {
4517 if (read_expected(EVENT_ITEM, field) < 0)
4518 return;
4519 } else {
4520 if (read_expect_type(EVENT_ITEM, &token) < 0)
4521 goto fail;
4522 if (strcmp(token, field) != 0)
4523 goto discard;
4524 free_token(token);
4525 }
4526
4527 if (read_expected(EVENT_OP, ";") < 0)
4528 return;
4529 if (read_expected(EVENT_ITEM, "offset") < 0)
4530 return;
4531 if (read_expected(EVENT_OP, ":") < 0)
4532 return;
4533 if (read_expect_type(EVENT_ITEM, &token) < 0)
4534 goto fail;
4535 *offset = atoi(token);
4536 free_token(token);
4537 if (read_expected(EVENT_OP, ";") < 0)
4538 return;
4539 if (read_expected(EVENT_ITEM, "size") < 0)
4540 return;
4541 if (read_expected(EVENT_OP, ":") < 0)
4542 return;
4543 if (read_expect_type(EVENT_ITEM, &token) < 0)
4544 goto fail;
4545 *size = atoi(token);
4546 free_token(token);
4547 if (read_expected(EVENT_OP, ";") < 0)
4548 return;
4549 type = read_token(&token);
4550 if (type != EVENT_NEWLINE) {
4551 /* newer versions of the kernel have a "signed" type */
4552 if (type != EVENT_ITEM)
4553 goto fail;
4554
4555 if (strcmp(token, "signed") != 0)
4556 goto fail;
4557
4558 free_token(token);
4559
4560 if (read_expected(EVENT_OP, ":") < 0)
4561 return;
4562
4563 if (read_expect_type(EVENT_ITEM, &token))
4564 goto fail;
4565
4566 free_token(token);
4567 if (read_expected(EVENT_OP, ";") < 0)
4568 return;
4569
4570 if (read_expect_type(EVENT_NEWLINE, &token))
4571 goto fail;
4572 }
4573 fail:
4574 free_token(token);
4575 return;
4576
4577 discard:
4578 input_buf_ptr = save_input_buf_ptr;
4579 input_buf_siz = save_input_buf_siz;
4580 *offset = 0;
4581 *size = 0;
4582 free_token(token);
4583}
4584
4585/**
4586 * pevent_parse_header_page - parse the data stored in the header page
4587 * @pevent: the handle to the pevent
4588 * @buf: the buffer storing the header page format string
4589 * @size: the size of @buf
4590 * @long_size: the long size to use if there is no header
4591 *
4592 * This parses the header page format for information on the
4593 * ring buffer used. The @buf should be copied from
4594 *
4595 * /sys/kernel/debug/tracing/events/header_page
4596 */
4597int pevent_parse_header_page(struct pevent *pevent, char *buf, unsigned long size,
4598 int long_size)
4599{
4600 int ignore;
4601
4602 if (!size) {
4603 /*
4604 * Old kernels did not have header page info.
4605 * Sorry but we just use what we find here in user space.
4606 */
4607 pevent->header_page_ts_size = sizeof(long long);
4608 pevent->header_page_size_size = long_size;
4609 pevent->header_page_data_offset = sizeof(long long) + long_size;
4610 pevent->old_format = 1;
4611 return -1;
4612 }
4613 init_input_buf(buf, size);
4614
4615 parse_header_field("timestamp", &pevent->header_page_ts_offset,
4616 &pevent->header_page_ts_size, 1);
4617 parse_header_field("commit", &pevent->header_page_size_offset,
4618 &pevent->header_page_size_size, 1);
4619 parse_header_field("overwrite", &pevent->header_page_overwrite,
4620 &ignore, 0);
4621 parse_header_field("data", &pevent->header_page_data_offset,
4622 &pevent->header_page_data_size, 1);
4623
4624 return 0;
4625}
4626
4627static int event_matches(struct event_format *event,
4628 int id, const char *sys_name,
4629 const char *event_name)
4630{
4631 if (id >= 0 && id != event->id)
4632 return 0;
4633
4634 if (event_name && (strcmp(event_name, event->name) != 0))
4635 return 0;
4636
4637 if (sys_name && (strcmp(sys_name, event->system) != 0))
4638 return 0;
4639
4640 return 1;
4641}
4642
4643static void free_handler(struct event_handler *handle)
4644{
4645 free((void *)handle->sys_name);
4646 free((void *)handle->event_name);
4647 free(handle);
4648}
4649
4650static int find_event_handle(struct pevent *pevent, struct event_format *event)
4651{
4652 struct event_handler *handle, **next;
4653
4654 for (next = &pevent->handlers; *next;
4655 next = &(*next)->next) {
4656 handle = *next;
4657 if (event_matches(event, handle->id,
4658 handle->sys_name,
4659 handle->event_name))
4660 break;
4661 }
4662
4663 if (!(*next))
4664 return 0;
4665
4666 pr_stat("overriding event (%d) %s:%s with new print handler",
4667 event->id, event->system, event->name);
4668
4669 event->handler = handle->func;
4670 event->context = handle->context;
4671
4672 *next = handle->next;
4673 free_handler(handle);
4674
4675 return 1;
4676}
4677
4678/**
4679 * pevent_parse_event - parse the event format
4680 * @pevent: the handle to the pevent
4681 * @buf: the buffer storing the event format string
4682 * @size: the size of @buf
4683 * @sys: the system the event belongs to
4684 *
4685 * This parses the event format and creates an event structure
4686 * to quickly parse raw data for a given event.
4687 *
4688 * These files currently come from:
4689 *
4690 * /sys/kernel/debug/tracing/events/.../.../format
4691 */
4692int pevent_parse_event(struct pevent *pevent,
4693 const char *buf, unsigned long size,
4694 const char *sys)
4695{
4696 struct event_format *event;
4697 int ret;
4698
4699 init_input_buf(buf, size);
4700
4701 event = alloc_event();
4702 if (!event)
4703 return -ENOMEM;
4704
4705 event->name = event_read_name();
4706 if (!event->name) {
4707 /* Bad event? */
4708 free(event);
4709 return -1;
4710 }
4711
4712 if (strcmp(sys, "ftrace") == 0) {
4713
4714 event->flags |= EVENT_FL_ISFTRACE;
4715
4716 if (strcmp(event->name, "bprint") == 0)
4717 event->flags |= EVENT_FL_ISBPRINT;
4718 }
4719
4720 event->id = event_read_id();
4721 if (event->id < 0)
4722 die("failed to read event id");
4723
4724 event->system = strdup(sys);
Namhyung Kimca638582012-04-09 11:54:31 +09004725 if (!event->system)
4726 die("failed to allocate system");
Steven Rostedtf7d82352012-04-06 00:47:53 +02004727
4728 /* Add pevent to event so that it can be referenced */
4729 event->pevent = pevent;
4730
4731 ret = event_read_format(event);
4732 if (ret < 0) {
4733 do_warning("failed to read event format for %s", event->name);
4734 goto event_failed;
4735 }
4736
4737 /*
4738 * If the event has an override, don't print warnings if the event
4739 * print format fails to parse.
4740 */
4741 if (find_event_handle(pevent, event))
4742 show_warning = 0;
4743
4744 ret = event_read_print(event);
4745 if (ret < 0) {
4746 do_warning("failed to read event print fmt for %s",
4747 event->name);
4748 show_warning = 1;
4749 goto event_failed;
4750 }
4751 show_warning = 1;
4752
4753 add_event(pevent, event);
4754
4755 if (!ret && (event->flags & EVENT_FL_ISFTRACE)) {
4756 struct format_field *field;
4757 struct print_arg *arg, **list;
4758
4759 /* old ftrace had no args */
4760
4761 list = &event->print_fmt.args;
4762 for (field = event->format.fields; field; field = field->next) {
4763 arg = alloc_arg();
4764 *list = arg;
4765 list = &arg->next;
4766 arg->type = PRINT_FIELD;
4767 arg->field.name = strdup(field->name);
Namhyung Kimca638582012-04-09 11:54:31 +09004768 if (!arg->field.name) {
4769 do_warning("failed to allocate field name");
Namhyung Kim4b5632b2012-04-23 13:58:34 +09004770 event->flags |= EVENT_FL_FAILED;
4771 return -1;
Namhyung Kimca638582012-04-09 11:54:31 +09004772 }
Steven Rostedtf7d82352012-04-06 00:47:53 +02004773 arg->field.field = field;
4774 }
4775 return 0;
4776 }
4777
4778#define PRINT_ARGS 0
4779 if (PRINT_ARGS && event->print_fmt.args)
4780 print_args(event->print_fmt.args);
4781
4782 return 0;
4783
4784 event_failed:
4785 event->flags |= EVENT_FL_FAILED;
4786 /* still add it even if it failed */
4787 add_event(pevent, event);
4788 return -1;
4789}
4790
4791int get_field_val(struct trace_seq *s, struct format_field *field,
Steven Rostedt1c698182012-04-06 00:48:06 +02004792 const char *name, struct pevent_record *record,
Steven Rostedtf7d82352012-04-06 00:47:53 +02004793 unsigned long long *val, int err)
4794{
4795 if (!field) {
4796 if (err)
4797 trace_seq_printf(s, "<CANT FIND FIELD %s>", name);
4798 return -1;
4799 }
4800
4801 if (pevent_read_number_field(field, record->data, val)) {
4802 if (err)
4803 trace_seq_printf(s, " %s=INVALID", name);
4804 return -1;
4805 }
4806
4807 return 0;
4808}
4809
4810/**
4811 * pevent_get_field_raw - return the raw pointer into the data field
4812 * @s: The seq to print to on error
4813 * @event: the event that the field is for
4814 * @name: The name of the field
4815 * @record: The record with the field name.
4816 * @len: place to store the field length.
4817 * @err: print default error if failed.
4818 *
4819 * Returns a pointer into record->data of the field and places
4820 * the length of the field in @len.
4821 *
4822 * On failure, it returns NULL.
4823 */
4824void *pevent_get_field_raw(struct trace_seq *s, struct event_format *event,
Steven Rostedt1c698182012-04-06 00:48:06 +02004825 const char *name, struct pevent_record *record,
Steven Rostedtf7d82352012-04-06 00:47:53 +02004826 int *len, int err)
4827{
4828 struct format_field *field;
4829 void *data = record->data;
4830 unsigned offset;
4831 int dummy;
4832
4833 if (!event)
4834 return NULL;
4835
4836 field = pevent_find_field(event, name);
4837
4838 if (!field) {
4839 if (err)
4840 trace_seq_printf(s, "<CANT FIND FIELD %s>", name);
4841 return NULL;
4842 }
4843
4844 /* Allow @len to be NULL */
4845 if (!len)
4846 len = &dummy;
4847
4848 offset = field->offset;
4849 if (field->flags & FIELD_IS_DYNAMIC) {
4850 offset = pevent_read_number(event->pevent,
4851 data + offset, field->size);
4852 *len = offset >> 16;
4853 offset &= 0xffff;
4854 } else
4855 *len = field->size;
4856
4857 return data + offset;
4858}
4859
4860/**
4861 * pevent_get_field_val - find a field and return its value
4862 * @s: The seq to print to on error
4863 * @event: the event that the field is for
4864 * @name: The name of the field
4865 * @record: The record with the field name.
4866 * @val: place to store the value of the field.
4867 * @err: print default error if failed.
4868 *
4869 * Returns 0 on success -1 on field not found.
4870 */
4871int pevent_get_field_val(struct trace_seq *s, struct event_format *event,
Steven Rostedt1c698182012-04-06 00:48:06 +02004872 const char *name, struct pevent_record *record,
Steven Rostedtf7d82352012-04-06 00:47:53 +02004873 unsigned long long *val, int err)
4874{
4875 struct format_field *field;
4876
4877 if (!event)
4878 return -1;
4879
4880 field = pevent_find_field(event, name);
4881
4882 return get_field_val(s, field, name, record, val, err);
4883}
4884
4885/**
4886 * pevent_get_common_field_val - find a common field and return its value
4887 * @s: The seq to print to on error
4888 * @event: the event that the field is for
4889 * @name: The name of the field
4890 * @record: The record with the field name.
4891 * @val: place to store the value of the field.
4892 * @err: print default error if failed.
4893 *
4894 * Returns 0 on success -1 on field not found.
4895 */
4896int pevent_get_common_field_val(struct trace_seq *s, struct event_format *event,
Steven Rostedt1c698182012-04-06 00:48:06 +02004897 const char *name, struct pevent_record *record,
Steven Rostedtf7d82352012-04-06 00:47:53 +02004898 unsigned long long *val, int err)
4899{
4900 struct format_field *field;
4901
4902 if (!event)
4903 return -1;
4904
4905 field = pevent_find_common_field(event, name);
4906
4907 return get_field_val(s, field, name, record, val, err);
4908}
4909
4910/**
4911 * pevent_get_any_field_val - find a any field and return its value
4912 * @s: The seq to print to on error
4913 * @event: the event that the field is for
4914 * @name: The name of the field
4915 * @record: The record with the field name.
4916 * @val: place to store the value of the field.
4917 * @err: print default error if failed.
4918 *
4919 * Returns 0 on success -1 on field not found.
4920 */
4921int pevent_get_any_field_val(struct trace_seq *s, struct event_format *event,
Steven Rostedt1c698182012-04-06 00:48:06 +02004922 const char *name, struct pevent_record *record,
Steven Rostedtf7d82352012-04-06 00:47:53 +02004923 unsigned long long *val, int err)
4924{
4925 struct format_field *field;
4926
4927 if (!event)
4928 return -1;
4929
4930 field = pevent_find_any_field(event, name);
4931
4932 return get_field_val(s, field, name, record, val, err);
4933}
4934
4935/**
4936 * pevent_print_num_field - print a field and a format
4937 * @s: The seq to print to
4938 * @fmt: The printf format to print the field with.
4939 * @event: the event that the field is for
4940 * @name: The name of the field
4941 * @record: The record with the field name.
4942 * @err: print default error if failed.
4943 *
Namhyung Kim16e6b8f2012-04-23 13:58:35 +09004944 * Returns: 0 on success, -1 field not found, or 1 if buffer is full.
Steven Rostedtf7d82352012-04-06 00:47:53 +02004945 */
4946int pevent_print_num_field(struct trace_seq *s, const char *fmt,
4947 struct event_format *event, const char *name,
Steven Rostedt1c698182012-04-06 00:48:06 +02004948 struct pevent_record *record, int err)
Steven Rostedtf7d82352012-04-06 00:47:53 +02004949{
4950 struct format_field *field = pevent_find_field(event, name);
4951 unsigned long long val;
4952
4953 if (!field)
4954 goto failed;
4955
4956 if (pevent_read_number_field(field, record->data, &val))
4957 goto failed;
4958
4959 return trace_seq_printf(s, fmt, val);
4960
4961 failed:
4962 if (err)
4963 trace_seq_printf(s, "CAN'T FIND FIELD \"%s\"", name);
4964 return -1;
4965}
4966
4967static void free_func_handle(struct pevent_function_handler *func)
4968{
4969 struct pevent_func_params *params;
4970
4971 free(func->name);
4972
4973 while (func->params) {
4974 params = func->params;
4975 func->params = params->next;
4976 free(params);
4977 }
4978
4979 free(func);
4980}
4981
4982/**
4983 * pevent_register_print_function - register a helper function
4984 * @pevent: the handle to the pevent
4985 * @func: the function to process the helper function
Namhyung Kim16e6b8f2012-04-23 13:58:35 +09004986 * @ret_type: the return type of the helper function
Steven Rostedtf7d82352012-04-06 00:47:53 +02004987 * @name: the name of the helper function
4988 * @parameters: A list of enum pevent_func_arg_type
4989 *
4990 * Some events may have helper functions in the print format arguments.
Namhyung Kim16e6b8f2012-04-23 13:58:35 +09004991 * This allows a plugin to dynamically create a way to process one
Steven Rostedtf7d82352012-04-06 00:47:53 +02004992 * of these functions.
4993 *
4994 * The @parameters is a variable list of pevent_func_arg_type enums that
4995 * must end with PEVENT_FUNC_ARG_VOID.
4996 */
4997int pevent_register_print_function(struct pevent *pevent,
4998 pevent_func_handler func,
4999 enum pevent_func_arg_type ret_type,
5000 char *name, ...)
5001{
5002 struct pevent_function_handler *func_handle;
5003 struct pevent_func_params **next_param;
5004 struct pevent_func_params *param;
5005 enum pevent_func_arg_type type;
5006 va_list ap;
5007
5008 func_handle = find_func_handler(pevent, name);
5009 if (func_handle) {
5010 /*
5011 * This is most like caused by the users own
5012 * plugins updating the function. This overrides the
5013 * system defaults.
5014 */
5015 pr_stat("override of function helper '%s'", name);
5016 remove_func_handler(pevent, name);
5017 }
5018
5019 func_handle = malloc_or_die(sizeof(*func_handle));
5020 memset(func_handle, 0, sizeof(*func_handle));
5021
5022 func_handle->ret_type = ret_type;
5023 func_handle->name = strdup(name);
5024 func_handle->func = func;
5025 if (!func_handle->name)
5026 die("Failed to allocate function name");
5027
5028 next_param = &(func_handle->params);
5029 va_start(ap, name);
5030 for (;;) {
5031 type = va_arg(ap, enum pevent_func_arg_type);
5032 if (type == PEVENT_FUNC_ARG_VOID)
5033 break;
5034
5035 if (type < 0 || type >= PEVENT_FUNC_ARG_MAX_TYPES) {
5036 warning("Invalid argument type %d", type);
5037 goto out_free;
5038 }
5039
5040 param = malloc_or_die(sizeof(*param));
5041 param->type = type;
5042 param->next = NULL;
5043
5044 *next_param = param;
5045 next_param = &(param->next);
5046
5047 func_handle->nr_args++;
5048 }
5049 va_end(ap);
5050
5051 func_handle->next = pevent->func_handlers;
5052 pevent->func_handlers = func_handle;
5053
5054 return 0;
5055 out_free:
5056 va_end(ap);
5057 free_func_handle(func_handle);
5058 return -1;
5059}
5060
5061/**
Namhyung Kim16e6b8f2012-04-23 13:58:35 +09005062 * pevent_register_event_handler - register a way to parse an event
Steven Rostedtf7d82352012-04-06 00:47:53 +02005063 * @pevent: the handle to the pevent
5064 * @id: the id of the event to register
5065 * @sys_name: the system name the event belongs to
5066 * @event_name: the name of the event
5067 * @func: the function to call to parse the event information
Namhyung Kim16e6b8f2012-04-23 13:58:35 +09005068 * @context: the data to be passed to @func
Steven Rostedtf7d82352012-04-06 00:47:53 +02005069 *
5070 * This function allows a developer to override the parsing of
5071 * a given event. If for some reason the default print format
5072 * is not sufficient, this function will register a function
5073 * for an event to be used to parse the data instead.
5074 *
5075 * If @id is >= 0, then it is used to find the event.
5076 * else @sys_name and @event_name are used.
5077 */
5078int pevent_register_event_handler(struct pevent *pevent,
5079 int id, char *sys_name, char *event_name,
5080 pevent_event_handler_func func,
5081 void *context)
5082{
5083 struct event_format *event;
5084 struct event_handler *handle;
5085
5086 if (id >= 0) {
5087 /* search by id */
5088 event = pevent_find_event(pevent, id);
5089 if (!event)
5090 goto not_found;
5091 if (event_name && (strcmp(event_name, event->name) != 0))
5092 goto not_found;
5093 if (sys_name && (strcmp(sys_name, event->system) != 0))
5094 goto not_found;
5095 } else {
5096 event = pevent_find_event_by_name(pevent, sys_name, event_name);
5097 if (!event)
5098 goto not_found;
5099 }
5100
5101 pr_stat("overriding event (%d) %s:%s with new print handler",
5102 event->id, event->system, event->name);
5103
5104 event->handler = func;
5105 event->context = context;
5106 return 0;
5107
5108 not_found:
5109 /* Save for later use. */
5110 handle = malloc_or_die(sizeof(*handle));
Steven Rostedt42c80132012-04-06 00:48:05 +02005111 memset(handle, 0, sizeof(*handle));
Steven Rostedtf7d82352012-04-06 00:47:53 +02005112 handle->id = id;
5113 if (event_name)
5114 handle->event_name = strdup(event_name);
5115 if (sys_name)
5116 handle->sys_name = strdup(sys_name);
5117
Namhyung Kimca638582012-04-09 11:54:31 +09005118 if ((event_name && !handle->event_name) ||
5119 (sys_name && !handle->sys_name)) {
5120 die("Failed to allocate event/sys name");
5121 }
5122
Steven Rostedtf7d82352012-04-06 00:47:53 +02005123 handle->func = func;
5124 handle->next = pevent->handlers;
5125 pevent->handlers = handle;
5126 handle->context = context;
5127
5128 return -1;
5129}
5130
5131/**
5132 * pevent_alloc - create a pevent handle
5133 */
5134struct pevent *pevent_alloc(void)
5135{
5136 struct pevent *pevent;
5137
5138 pevent = malloc(sizeof(*pevent));
5139 if (!pevent)
5140 return NULL;
5141 memset(pevent, 0, sizeof(*pevent));
5142 pevent->ref_count = 1;
5143
5144 return pevent;
5145}
5146
5147void pevent_ref(struct pevent *pevent)
5148{
5149 pevent->ref_count++;
5150}
5151
5152static void free_format_fields(struct format_field *field)
5153{
5154 struct format_field *next;
5155
5156 while (field) {
5157 next = field->next;
5158 free(field->type);
5159 free(field->name);
5160 free(field);
5161 field = next;
5162 }
5163}
5164
5165static void free_formats(struct format *format)
5166{
5167 free_format_fields(format->common_fields);
5168 free_format_fields(format->fields);
5169}
5170
5171static void free_event(struct event_format *event)
5172{
5173 free(event->name);
5174 free(event->system);
5175
5176 free_formats(&event->format);
5177
5178 free(event->print_fmt.format);
5179 free_args(event->print_fmt.args);
5180
5181 free(event);
5182}
5183
5184/**
5185 * pevent_free - free a pevent handle
5186 * @pevent: the pevent handle to free
5187 */
5188void pevent_free(struct pevent *pevent)
5189{
Steven Rostedta2525a02012-04-06 00:48:02 +02005190 struct cmdline_list *cmdlist, *cmdnext;
5191 struct func_list *funclist, *funcnext;
5192 struct printk_list *printklist, *printknext;
Steven Rostedtf7d82352012-04-06 00:47:53 +02005193 struct pevent_function_handler *func_handler;
5194 struct event_handler *handle;
5195 int i;
5196
Steven Rostedta2525a02012-04-06 00:48:02 +02005197 if (!pevent)
5198 return;
5199
5200 cmdlist = pevent->cmdlist;
5201 funclist = pevent->funclist;
5202 printklist = pevent->printklist;
5203
Steven Rostedtf7d82352012-04-06 00:47:53 +02005204 pevent->ref_count--;
5205 if (pevent->ref_count)
5206 return;
5207
5208 if (pevent->cmdlines) {
5209 for (i = 0; i < pevent->cmdline_count; i++)
5210 free(pevent->cmdlines[i].comm);
5211 free(pevent->cmdlines);
5212 }
5213
5214 while (cmdlist) {
5215 cmdnext = cmdlist->next;
5216 free(cmdlist->comm);
5217 free(cmdlist);
5218 cmdlist = cmdnext;
5219 }
5220
5221 if (pevent->func_map) {
5222 for (i = 0; i < pevent->func_count; i++) {
5223 free(pevent->func_map[i].func);
5224 free(pevent->func_map[i].mod);
5225 }
5226 free(pevent->func_map);
5227 }
5228
5229 while (funclist) {
5230 funcnext = funclist->next;
5231 free(funclist->func);
5232 free(funclist->mod);
5233 free(funclist);
5234 funclist = funcnext;
5235 }
5236
5237 while (pevent->func_handlers) {
5238 func_handler = pevent->func_handlers;
5239 pevent->func_handlers = func_handler->next;
5240 free_func_handle(func_handler);
5241 }
5242
5243 if (pevent->printk_map) {
5244 for (i = 0; i < pevent->printk_count; i++)
5245 free(pevent->printk_map[i].printk);
5246 free(pevent->printk_map);
5247 }
5248
5249 while (printklist) {
5250 printknext = printklist->next;
5251 free(printklist->printk);
5252 free(printklist);
5253 printklist = printknext;
5254 }
5255
5256 for (i = 0; i < pevent->nr_events; i++)
5257 free_event(pevent->events[i]);
5258
5259 while (pevent->handlers) {
5260 handle = pevent->handlers;
5261 pevent->handlers = handle->next;
5262 free_handler(handle);
5263 }
5264
5265 free(pevent->events);
5266 free(pevent->sort_events);
5267
5268 free(pevent);
5269}
5270
5271void pevent_unref(struct pevent *pevent)
5272{
5273 pevent_free(pevent);
5274}