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