~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/tools/lib/traceevent/event-parse.c

Version: ~ [ linux-5.2-rc1 ] ~ [ linux-5.1.2 ] ~ [ linux-5.0.16 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.43 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.119 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.176 ] ~ [ linux-4.8.17 ] ~ [ linux-4.7.10 ] ~ [ linux-4.6.7 ] ~ [ linux-4.5.7 ] ~ [ linux-4.4.179 ] ~ [ linux-4.3.6 ] ~ [ linux-4.2.8 ] ~ [ linux-4.1.52 ] ~ [ linux-4.0.9 ] ~ [ linux-3.19.8 ] ~ [ linux-3.18.139 ] ~ [ linux-3.17.8 ] ~ [ linux-3.16.67 ] ~ [ linux-3.15.10 ] ~ [ linux-3.14.79 ] ~ [ linux-3.13.11 ] ~ [ linux-3.12.74 ] ~ [ linux-3.11.10 ] ~ [ linux-3.10.108 ] ~ [ linux-3.9.11 ] ~ [ linux-3.8.13 ] ~ [ linux-3.7.10 ] ~ [ linux-3.6.11 ] ~ [ linux-3.5.7 ] ~ [ linux-3.4.113 ] ~ [ linux-3.3.8 ] ~ [ linux-3.2.102 ] ~ [ linux-3.1.10 ] ~ [ linux-3.0.101 ] ~ [ linux-2.6.39.4 ] ~ [ linux-2.6.38.8 ] ~ [ linux-2.6.37.6 ] ~ [ linux-2.6.36.4 ] ~ [ linux-2.6.35.14 ] ~ [ linux-2.6.34.15 ] ~ [ linux-2.6.33.20 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.5 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

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

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | Wiki (Japanese) | Wiki (English) | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

osdn.jp