Linux kernel mirror (for testing)
git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel
os
linux
1// SPDX-License-Identifier: LGPL-2.1
2/*
3 * Copyright (C) 2009, 2010 Red Hat Inc, Steven Rostedt <srostedt@redhat.com>
4 *
5 *
6 * The parts for function graph printing was taken and modified from the
7 * Linux Kernel that were written by
8 * - Copyright (C) 2009 Frederic Weisbecker,
9 * Frederic Weisbecker gave his permission to relicense the code to
10 * the Lesser General Public License.
11 */
12#include <inttypes.h>
13#include <stdio.h>
14#include <stdlib.h>
15#include <string.h>
16#include <stdarg.h>
17#include <ctype.h>
18#include <errno.h>
19#include <stdint.h>
20#include <limits.h>
21#include <linux/time64.h>
22
23#include <netinet/in.h>
24#include "event-parse.h"
25
26#include "event-parse-local.h"
27#include "event-utils.h"
28#include "trace-seq.h"
29
30static const char *input_buf;
31static unsigned long long input_buf_ptr;
32static unsigned long long input_buf_siz;
33
34static int is_flag_field;
35static int is_symbolic_field;
36
37static int show_warning = 1;
38
39#define do_warning(fmt, ...) \
40 do { \
41 if (show_warning) \
42 warning(fmt, ##__VA_ARGS__); \
43 } while (0)
44
45#define do_warning_event(event, fmt, ...) \
46 do { \
47 if (!show_warning) \
48 continue; \
49 \
50 if (event) \
51 warning("[%s:%s] " fmt, event->system, \
52 event->name, ##__VA_ARGS__); \
53 else \
54 warning(fmt, ##__VA_ARGS__); \
55 } while (0)
56
57static void init_input_buf(const char *buf, unsigned long long size)
58{
59 input_buf = buf;
60 input_buf_siz = size;
61 input_buf_ptr = 0;
62}
63
64const char *tep_get_input_buf(void)
65{
66 return input_buf;
67}
68
69unsigned long long tep_get_input_buf_ptr(void)
70{
71 return input_buf_ptr;
72}
73
74struct event_handler {
75 struct event_handler *next;
76 int id;
77 const char *sys_name;
78 const char *event_name;
79 tep_event_handler_func func;
80 void *context;
81};
82
83struct func_params {
84 struct func_params *next;
85 enum tep_func_arg_type type;
86};
87
88struct tep_function_handler {
89 struct tep_function_handler *next;
90 enum tep_func_arg_type ret_type;
91 char *name;
92 tep_func_handler func;
93 struct func_params *params;
94 int nr_args;
95};
96
97static unsigned long long
98process_defined_func(struct trace_seq *s, void *data, int size,
99 struct tep_event_format *event, struct tep_print_arg *arg);
100
101static void free_func_handle(struct tep_function_handler *func);
102
103/**
104 * tep_buffer_init - init buffer for parsing
105 * @buf: buffer to parse
106 * @size: the size of the buffer
107 *
108 * For use with tep_read_token(), this initializes the internal
109 * buffer that tep_read_token() will parse.
110 */
111void tep_buffer_init(const char *buf, unsigned long long size)
112{
113 init_input_buf(buf, size);
114}
115
116void breakpoint(void)
117{
118 static int x;
119 x++;
120}
121
122struct tep_print_arg *alloc_arg(void)
123{
124 return calloc(1, sizeof(struct tep_print_arg));
125}
126
127struct cmdline {
128 char *comm;
129 int pid;
130};
131
132static int cmdline_cmp(const void *a, const void *b)
133{
134 const struct cmdline *ca = a;
135 const struct cmdline *cb = b;
136
137 if (ca->pid < cb->pid)
138 return -1;
139 if (ca->pid > cb->pid)
140 return 1;
141
142 return 0;
143}
144
145struct cmdline_list {
146 struct cmdline_list *next;
147 char *comm;
148 int pid;
149};
150
151static int cmdline_init(struct tep_handle *pevent)
152{
153 struct cmdline_list *cmdlist = pevent->cmdlist;
154 struct cmdline_list *item;
155 struct cmdline *cmdlines;
156 int i;
157
158 cmdlines = malloc(sizeof(*cmdlines) * pevent->cmdline_count);
159 if (!cmdlines)
160 return -1;
161
162 i = 0;
163 while (cmdlist) {
164 cmdlines[i].pid = cmdlist->pid;
165 cmdlines[i].comm = cmdlist->comm;
166 i++;
167 item = cmdlist;
168 cmdlist = cmdlist->next;
169 free(item);
170 }
171
172 qsort(cmdlines, pevent->cmdline_count, sizeof(*cmdlines), cmdline_cmp);
173
174 pevent->cmdlines = cmdlines;
175 pevent->cmdlist = NULL;
176
177 return 0;
178}
179
180static const char *find_cmdline(struct tep_handle *pevent, int pid)
181{
182 const struct cmdline *comm;
183 struct cmdline key;
184
185 if (!pid)
186 return "<idle>";
187
188 if (!pevent->cmdlines && cmdline_init(pevent))
189 return "<not enough memory for cmdlines!>";
190
191 key.pid = pid;
192
193 comm = bsearch(&key, pevent->cmdlines, pevent->cmdline_count,
194 sizeof(*pevent->cmdlines), cmdline_cmp);
195
196 if (comm)
197 return comm->comm;
198 return "<...>";
199}
200
201/**
202 * tep_pid_is_registered - return if a pid has a cmdline registered
203 * @pevent: handle for the pevent
204 * @pid: The pid to check if it has a cmdline registered with.
205 *
206 * Returns 1 if the pid has a cmdline mapped to it
207 * 0 otherwise.
208 */
209int tep_pid_is_registered(struct tep_handle *pevent, int pid)
210{
211 const struct cmdline *comm;
212 struct cmdline key;
213
214 if (!pid)
215 return 1;
216
217 if (!pevent->cmdlines && cmdline_init(pevent))
218 return 0;
219
220 key.pid = pid;
221
222 comm = bsearch(&key, pevent->cmdlines, pevent->cmdline_count,
223 sizeof(*pevent->cmdlines), cmdline_cmp);
224
225 if (comm)
226 return 1;
227 return 0;
228}
229
230/*
231 * If the command lines have been converted to an array, then
232 * we must add this pid. This is much slower than when cmdlines
233 * are added before the array is initialized.
234 */
235static int add_new_comm(struct tep_handle *pevent, const char *comm, int pid)
236{
237 struct cmdline *cmdlines = pevent->cmdlines;
238 const struct cmdline *cmdline;
239 struct cmdline key;
240
241 if (!pid)
242 return 0;
243
244 /* avoid duplicates */
245 key.pid = pid;
246
247 cmdline = bsearch(&key, pevent->cmdlines, pevent->cmdline_count,
248 sizeof(*pevent->cmdlines), cmdline_cmp);
249 if (cmdline) {
250 errno = EEXIST;
251 return -1;
252 }
253
254 cmdlines = realloc(cmdlines, sizeof(*cmdlines) * (pevent->cmdline_count + 1));
255 if (!cmdlines) {
256 errno = ENOMEM;
257 return -1;
258 }
259
260 cmdlines[pevent->cmdline_count].comm = strdup(comm);
261 if (!cmdlines[pevent->cmdline_count].comm) {
262 free(cmdlines);
263 errno = ENOMEM;
264 return -1;
265 }
266
267 cmdlines[pevent->cmdline_count].pid = pid;
268
269 if (cmdlines[pevent->cmdline_count].comm)
270 pevent->cmdline_count++;
271
272 qsort(cmdlines, pevent->cmdline_count, sizeof(*cmdlines), cmdline_cmp);
273 pevent->cmdlines = cmdlines;
274
275 return 0;
276}
277
278/**
279 * tep_register_comm - register a pid / comm mapping
280 * @pevent: handle for the pevent
281 * @comm: the command line to register
282 * @pid: the pid to map the command line to
283 *
284 * This adds a mapping to search for command line names with
285 * a given pid. The comm is duplicated.
286 */
287int tep_register_comm(struct tep_handle *pevent, const char *comm, int pid)
288{
289 struct cmdline_list *item;
290
291 if (pevent->cmdlines)
292 return add_new_comm(pevent, comm, pid);
293
294 item = malloc(sizeof(*item));
295 if (!item)
296 return -1;
297
298 if (comm)
299 item->comm = strdup(comm);
300 else
301 item->comm = strdup("<...>");
302 if (!item->comm) {
303 free(item);
304 return -1;
305 }
306 item->pid = pid;
307 item->next = pevent->cmdlist;
308
309 pevent->cmdlist = item;
310 pevent->cmdline_count++;
311
312 return 0;
313}
314
315int tep_register_trace_clock(struct tep_handle *pevent, const char *trace_clock)
316{
317 pevent->trace_clock = strdup(trace_clock);
318 if (!pevent->trace_clock) {
319 errno = ENOMEM;
320 return -1;
321 }
322 return 0;
323}
324
325struct func_map {
326 unsigned long long addr;
327 char *func;
328 char *mod;
329};
330
331struct func_list {
332 struct func_list *next;
333 unsigned long long addr;
334 char *func;
335 char *mod;
336};
337
338static int func_cmp(const void *a, const void *b)
339{
340 const struct func_map *fa = a;
341 const struct func_map *fb = b;
342
343 if (fa->addr < fb->addr)
344 return -1;
345 if (fa->addr > fb->addr)
346 return 1;
347
348 return 0;
349}
350
351/*
352 * We are searching for a record in between, not an exact
353 * match.
354 */
355static int func_bcmp(const void *a, const void *b)
356{
357 const struct func_map *fa = a;
358 const struct func_map *fb = b;
359
360 if ((fa->addr == fb->addr) ||
361
362 (fa->addr > fb->addr &&
363 fa->addr < (fb+1)->addr))
364 return 0;
365
366 if (fa->addr < fb->addr)
367 return -1;
368
369 return 1;
370}
371
372static int func_map_init(struct tep_handle *pevent)
373{
374 struct func_list *funclist;
375 struct func_list *item;
376 struct func_map *func_map;
377 int i;
378
379 func_map = malloc(sizeof(*func_map) * (pevent->func_count + 1));
380 if (!func_map)
381 return -1;
382
383 funclist = pevent->funclist;
384
385 i = 0;
386 while (funclist) {
387 func_map[i].func = funclist->func;
388 func_map[i].addr = funclist->addr;
389 func_map[i].mod = funclist->mod;
390 i++;
391 item = funclist;
392 funclist = funclist->next;
393 free(item);
394 }
395
396 qsort(func_map, pevent->func_count, sizeof(*func_map), func_cmp);
397
398 /*
399 * Add a special record at the end.
400 */
401 func_map[pevent->func_count].func = NULL;
402 func_map[pevent->func_count].addr = 0;
403 func_map[pevent->func_count].mod = NULL;
404
405 pevent->func_map = func_map;
406 pevent->funclist = NULL;
407
408 return 0;
409}
410
411static struct func_map *
412__find_func(struct tep_handle *pevent, unsigned long long addr)
413{
414 struct func_map *func;
415 struct func_map key;
416
417 if (!pevent->func_map)
418 func_map_init(pevent);
419
420 key.addr = addr;
421
422 func = bsearch(&key, pevent->func_map, pevent->func_count,
423 sizeof(*pevent->func_map), func_bcmp);
424
425 return func;
426}
427
428struct func_resolver {
429 tep_func_resolver_t *func;
430 void *priv;
431 struct func_map map;
432};
433
434/**
435 * tep_set_function_resolver - set an alternative function resolver
436 * @pevent: handle for the pevent
437 * @resolver: function to be used
438 * @priv: resolver function private state.
439 *
440 * Some tools may have already a way to resolve kernel functions, allow them to
441 * keep using it instead of duplicating all the entries inside
442 * pevent->funclist.
443 */
444int tep_set_function_resolver(struct tep_handle *pevent,
445 tep_func_resolver_t *func, void *priv)
446{
447 struct func_resolver *resolver = malloc(sizeof(*resolver));
448
449 if (resolver == NULL)
450 return -1;
451
452 resolver->func = func;
453 resolver->priv = priv;
454
455 free(pevent->func_resolver);
456 pevent->func_resolver = resolver;
457
458 return 0;
459}
460
461/**
462 * tep_reset_function_resolver - reset alternative function resolver
463 * @pevent: handle for the pevent
464 *
465 * Stop using whatever alternative resolver was set, use the default
466 * one instead.
467 */
468void tep_reset_function_resolver(struct tep_handle *pevent)
469{
470 free(pevent->func_resolver);
471 pevent->func_resolver = NULL;
472}
473
474static struct func_map *
475find_func(struct tep_handle *pevent, unsigned long long addr)
476{
477 struct func_map *map;
478
479 if (!pevent->func_resolver)
480 return __find_func(pevent, addr);
481
482 map = &pevent->func_resolver->map;
483 map->mod = NULL;
484 map->addr = addr;
485 map->func = pevent->func_resolver->func(pevent->func_resolver->priv,
486 &map->addr, &map->mod);
487 if (map->func == NULL)
488 return NULL;
489
490 return map;
491}
492
493/**
494 * tep_find_function - find a function by a given address
495 * @pevent: handle for the pevent
496 * @addr: the address to find the function with
497 *
498 * Returns a pointer to the function stored that has the given
499 * address. Note, the address does not have to be exact, it
500 * will select the function that would contain the address.
501 */
502const char *tep_find_function(struct tep_handle *pevent, unsigned long long addr)
503{
504 struct func_map *map;
505
506 map = find_func(pevent, addr);
507 if (!map)
508 return NULL;
509
510 return map->func;
511}
512
513/**
514 * tep_find_function_address - find a function address by a given address
515 * @pevent: handle for the pevent
516 * @addr: the address to find the function with
517 *
518 * Returns the address the function starts at. This can be used in
519 * conjunction with tep_find_function to print both the function
520 * name and the function offset.
521 */
522unsigned long long
523tep_find_function_address(struct tep_handle *pevent, unsigned long long addr)
524{
525 struct func_map *map;
526
527 map = find_func(pevent, addr);
528 if (!map)
529 return 0;
530
531 return map->addr;
532}
533
534/**
535 * tep_register_function - register a function with a given address
536 * @pevent: handle for the pevent
537 * @function: the function name to register
538 * @addr: the address the function starts at
539 * @mod: the kernel module the function may be in (NULL for none)
540 *
541 * This registers a function name with an address and module.
542 * The @func passed in is duplicated.
543 */
544int tep_register_function(struct tep_handle *pevent, char *func,
545 unsigned long long addr, char *mod)
546{
547 struct func_list *item = malloc(sizeof(*item));
548
549 if (!item)
550 return -1;
551
552 item->next = pevent->funclist;
553 item->func = strdup(func);
554 if (!item->func)
555 goto out_free;
556
557 if (mod) {
558 item->mod = strdup(mod);
559 if (!item->mod)
560 goto out_free_func;
561 } else
562 item->mod = NULL;
563 item->addr = addr;
564
565 pevent->funclist = item;
566 pevent->func_count++;
567
568 return 0;
569
570out_free_func:
571 free(item->func);
572 item->func = NULL;
573out_free:
574 free(item);
575 errno = ENOMEM;
576 return -1;
577}
578
579/**
580 * tep_print_funcs - print out the stored functions
581 * @pevent: handle for the pevent
582 *
583 * This prints out the stored functions.
584 */
585void tep_print_funcs(struct tep_handle *pevent)
586{
587 int i;
588
589 if (!pevent->func_map)
590 func_map_init(pevent);
591
592 for (i = 0; i < (int)pevent->func_count; i++) {
593 printf("%016llx %s",
594 pevent->func_map[i].addr,
595 pevent->func_map[i].func);
596 if (pevent->func_map[i].mod)
597 printf(" [%s]\n", pevent->func_map[i].mod);
598 else
599 printf("\n");
600 }
601}
602
603struct printk_map {
604 unsigned long long addr;
605 char *printk;
606};
607
608struct printk_list {
609 struct printk_list *next;
610 unsigned long long addr;
611 char *printk;
612};
613
614static int printk_cmp(const void *a, const void *b)
615{
616 const struct printk_map *pa = a;
617 const struct printk_map *pb = b;
618
619 if (pa->addr < pb->addr)
620 return -1;
621 if (pa->addr > pb->addr)
622 return 1;
623
624 return 0;
625}
626
627static int printk_map_init(struct tep_handle *pevent)
628{
629 struct printk_list *printklist;
630 struct printk_list *item;
631 struct printk_map *printk_map;
632 int i;
633
634 printk_map = malloc(sizeof(*printk_map) * (pevent->printk_count + 1));
635 if (!printk_map)
636 return -1;
637
638 printklist = pevent->printklist;
639
640 i = 0;
641 while (printklist) {
642 printk_map[i].printk = printklist->printk;
643 printk_map[i].addr = printklist->addr;
644 i++;
645 item = printklist;
646 printklist = printklist->next;
647 free(item);
648 }
649
650 qsort(printk_map, pevent->printk_count, sizeof(*printk_map), printk_cmp);
651
652 pevent->printk_map = printk_map;
653 pevent->printklist = NULL;
654
655 return 0;
656}
657
658static struct printk_map *
659find_printk(struct tep_handle *pevent, unsigned long long addr)
660{
661 struct printk_map *printk;
662 struct printk_map key;
663
664 if (!pevent->printk_map && printk_map_init(pevent))
665 return NULL;
666
667 key.addr = addr;
668
669 printk = bsearch(&key, pevent->printk_map, pevent->printk_count,
670 sizeof(*pevent->printk_map), printk_cmp);
671
672 return printk;
673}
674
675/**
676 * tep_register_print_string - register a string by its address
677 * @pevent: handle for the pevent
678 * @fmt: the string format to register
679 * @addr: the address the string was located at
680 *
681 * This registers a string by the address it was stored in the kernel.
682 * The @fmt passed in is duplicated.
683 */
684int tep_register_print_string(struct tep_handle *pevent, const char *fmt,
685 unsigned long long addr)
686{
687 struct printk_list *item = malloc(sizeof(*item));
688 char *p;
689
690 if (!item)
691 return -1;
692
693 item->next = pevent->printklist;
694 item->addr = addr;
695
696 /* Strip off quotes and '\n' from the end */
697 if (fmt[0] == '"')
698 fmt++;
699 item->printk = strdup(fmt);
700 if (!item->printk)
701 goto out_free;
702
703 p = item->printk + strlen(item->printk) - 1;
704 if (*p == '"')
705 *p = 0;
706
707 p -= 2;
708 if (strcmp(p, "\\n") == 0)
709 *p = 0;
710
711 pevent->printklist = item;
712 pevent->printk_count++;
713
714 return 0;
715
716out_free:
717 free(item);
718 errno = ENOMEM;
719 return -1;
720}
721
722/**
723 * tep_print_printk - print out the stored strings
724 * @pevent: handle for the pevent
725 *
726 * This prints the string formats that were stored.
727 */
728void tep_print_printk(struct tep_handle *pevent)
729{
730 int i;
731
732 if (!pevent->printk_map)
733 printk_map_init(pevent);
734
735 for (i = 0; i < (int)pevent->printk_count; i++) {
736 printf("%016llx %s\n",
737 pevent->printk_map[i].addr,
738 pevent->printk_map[i].printk);
739 }
740}
741
742static struct tep_event_format *alloc_event(void)
743{
744 return calloc(1, sizeof(struct tep_event_format));
745}
746
747static int add_event(struct tep_handle *pevent, struct tep_event_format *event)
748{
749 int i;
750 struct tep_event_format **events = realloc(pevent->events, sizeof(event) *
751 (pevent->nr_events + 1));
752 if (!events)
753 return -1;
754
755 pevent->events = events;
756
757 for (i = 0; i < pevent->nr_events; i++) {
758 if (pevent->events[i]->id > event->id)
759 break;
760 }
761 if (i < pevent->nr_events)
762 memmove(&pevent->events[i + 1],
763 &pevent->events[i],
764 sizeof(event) * (pevent->nr_events - i));
765
766 pevent->events[i] = event;
767 pevent->nr_events++;
768
769 event->pevent = pevent;
770
771 return 0;
772}
773
774static int event_item_type(enum tep_event_type type)
775{
776 switch (type) {
777 case TEP_EVENT_ITEM ... TEP_EVENT_SQUOTE:
778 return 1;
779 case TEP_EVENT_ERROR ... TEP_EVENT_DELIM:
780 default:
781 return 0;
782 }
783}
784
785static void free_flag_sym(struct tep_print_flag_sym *fsym)
786{
787 struct tep_print_flag_sym *next;
788
789 while (fsym) {
790 next = fsym->next;
791 free(fsym->value);
792 free(fsym->str);
793 free(fsym);
794 fsym = next;
795 }
796}
797
798static void free_arg(struct tep_print_arg *arg)
799{
800 struct tep_print_arg *farg;
801
802 if (!arg)
803 return;
804
805 switch (arg->type) {
806 case TEP_PRINT_ATOM:
807 free(arg->atom.atom);
808 break;
809 case TEP_PRINT_FIELD:
810 free(arg->field.name);
811 break;
812 case TEP_PRINT_FLAGS:
813 free_arg(arg->flags.field);
814 free(arg->flags.delim);
815 free_flag_sym(arg->flags.flags);
816 break;
817 case TEP_PRINT_SYMBOL:
818 free_arg(arg->symbol.field);
819 free_flag_sym(arg->symbol.symbols);
820 break;
821 case TEP_PRINT_HEX:
822 case TEP_PRINT_HEX_STR:
823 free_arg(arg->hex.field);
824 free_arg(arg->hex.size);
825 break;
826 case TEP_PRINT_INT_ARRAY:
827 free_arg(arg->int_array.field);
828 free_arg(arg->int_array.count);
829 free_arg(arg->int_array.el_size);
830 break;
831 case TEP_PRINT_TYPE:
832 free(arg->typecast.type);
833 free_arg(arg->typecast.item);
834 break;
835 case TEP_PRINT_STRING:
836 case TEP_PRINT_BSTRING:
837 free(arg->string.string);
838 break;
839 case TEP_PRINT_BITMASK:
840 free(arg->bitmask.bitmask);
841 break;
842 case TEP_PRINT_DYNAMIC_ARRAY:
843 case TEP_PRINT_DYNAMIC_ARRAY_LEN:
844 free(arg->dynarray.index);
845 break;
846 case TEP_PRINT_OP:
847 free(arg->op.op);
848 free_arg(arg->op.left);
849 free_arg(arg->op.right);
850 break;
851 case TEP_PRINT_FUNC:
852 while (arg->func.args) {
853 farg = arg->func.args;
854 arg->func.args = farg->next;
855 free_arg(farg);
856 }
857 break;
858
859 case TEP_PRINT_NULL:
860 default:
861 break;
862 }
863
864 free(arg);
865}
866
867static enum tep_event_type get_type(int ch)
868{
869 if (ch == '\n')
870 return TEP_EVENT_NEWLINE;
871 if (isspace(ch))
872 return TEP_EVENT_SPACE;
873 if (isalnum(ch) || ch == '_')
874 return TEP_EVENT_ITEM;
875 if (ch == '\'')
876 return TEP_EVENT_SQUOTE;
877 if (ch == '"')
878 return TEP_EVENT_DQUOTE;
879 if (!isprint(ch))
880 return TEP_EVENT_NONE;
881 if (ch == '(' || ch == ')' || ch == ',')
882 return TEP_EVENT_DELIM;
883
884 return TEP_EVENT_OP;
885}
886
887static int __read_char(void)
888{
889 if (input_buf_ptr >= input_buf_siz)
890 return -1;
891
892 return input_buf[input_buf_ptr++];
893}
894
895static int __peek_char(void)
896{
897 if (input_buf_ptr >= input_buf_siz)
898 return -1;
899
900 return input_buf[input_buf_ptr];
901}
902
903/**
904 * tep_peek_char - peek at the next character that will be read
905 *
906 * Returns the next character read, or -1 if end of buffer.
907 */
908int tep_peek_char(void)
909{
910 return __peek_char();
911}
912
913static int extend_token(char **tok, char *buf, int size)
914{
915 char *newtok = realloc(*tok, size);
916
917 if (!newtok) {
918 free(*tok);
919 *tok = NULL;
920 return -1;
921 }
922
923 if (!*tok)
924 strcpy(newtok, buf);
925 else
926 strcat(newtok, buf);
927 *tok = newtok;
928
929 return 0;
930}
931
932static enum tep_event_type force_token(const char *str, char **tok);
933
934static enum tep_event_type __read_token(char **tok)
935{
936 char buf[BUFSIZ];
937 int ch, last_ch, quote_ch, next_ch;
938 int i = 0;
939 int tok_size = 0;
940 enum tep_event_type type;
941
942 *tok = NULL;
943
944
945 ch = __read_char();
946 if (ch < 0)
947 return TEP_EVENT_NONE;
948
949 type = get_type(ch);
950 if (type == TEP_EVENT_NONE)
951 return type;
952
953 buf[i++] = ch;
954
955 switch (type) {
956 case TEP_EVENT_NEWLINE:
957 case TEP_EVENT_DELIM:
958 if (asprintf(tok, "%c", ch) < 0)
959 return TEP_EVENT_ERROR;
960
961 return type;
962
963 case TEP_EVENT_OP:
964 switch (ch) {
965 case '-':
966 next_ch = __peek_char();
967 if (next_ch == '>') {
968 buf[i++] = __read_char();
969 break;
970 }
971 /* fall through */
972 case '+':
973 case '|':
974 case '&':
975 case '>':
976 case '<':
977 last_ch = ch;
978 ch = __peek_char();
979 if (ch != last_ch)
980 goto test_equal;
981 buf[i++] = __read_char();
982 switch (last_ch) {
983 case '>':
984 case '<':
985 goto test_equal;
986 default:
987 break;
988 }
989 break;
990 case '!':
991 case '=':
992 goto test_equal;
993 default: /* what should we do instead? */
994 break;
995 }
996 buf[i] = 0;
997 *tok = strdup(buf);
998 return type;
999
1000 test_equal:
1001 ch = __peek_char();
1002 if (ch == '=')
1003 buf[i++] = __read_char();
1004 goto out;
1005
1006 case TEP_EVENT_DQUOTE:
1007 case TEP_EVENT_SQUOTE:
1008 /* don't keep quotes */
1009 i--;
1010 quote_ch = ch;
1011 last_ch = 0;
1012 concat:
1013 do {
1014 if (i == (BUFSIZ - 1)) {
1015 buf[i] = 0;
1016 tok_size += BUFSIZ;
1017
1018 if (extend_token(tok, buf, tok_size) < 0)
1019 return TEP_EVENT_NONE;
1020 i = 0;
1021 }
1022 last_ch = ch;
1023 ch = __read_char();
1024 buf[i++] = ch;
1025 /* the '\' '\' will cancel itself */
1026 if (ch == '\\' && last_ch == '\\')
1027 last_ch = 0;
1028 } while (ch != quote_ch || last_ch == '\\');
1029 /* remove the last quote */
1030 i--;
1031
1032 /*
1033 * For strings (double quotes) check the next token.
1034 * If it is another string, concatinate the two.
1035 */
1036 if (type == TEP_EVENT_DQUOTE) {
1037 unsigned long long save_input_buf_ptr = input_buf_ptr;
1038
1039 do {
1040 ch = __read_char();
1041 } while (isspace(ch));
1042 if (ch == '"')
1043 goto concat;
1044 input_buf_ptr = save_input_buf_ptr;
1045 }
1046
1047 goto out;
1048
1049 case TEP_EVENT_ERROR ... TEP_EVENT_SPACE:
1050 case TEP_EVENT_ITEM:
1051 default:
1052 break;
1053 }
1054
1055 while (get_type(__peek_char()) == type) {
1056 if (i == (BUFSIZ - 1)) {
1057 buf[i] = 0;
1058 tok_size += BUFSIZ;
1059
1060 if (extend_token(tok, buf, tok_size) < 0)
1061 return TEP_EVENT_NONE;
1062 i = 0;
1063 }
1064 ch = __read_char();
1065 buf[i++] = ch;
1066 }
1067
1068 out:
1069 buf[i] = 0;
1070 if (extend_token(tok, buf, tok_size + i + 1) < 0)
1071 return TEP_EVENT_NONE;
1072
1073 if (type == TEP_EVENT_ITEM) {
1074 /*
1075 * Older versions of the kernel has a bug that
1076 * creates invalid symbols and will break the mac80211
1077 * parsing. This is a work around to that bug.
1078 *
1079 * See Linux kernel commit:
1080 * 811cb50baf63461ce0bdb234927046131fc7fa8b
1081 */
1082 if (strcmp(*tok, "LOCAL_PR_FMT") == 0) {
1083 free(*tok);
1084 *tok = NULL;
1085 return force_token("\"%s\" ", tok);
1086 } else if (strcmp(*tok, "STA_PR_FMT") == 0) {
1087 free(*tok);
1088 *tok = NULL;
1089 return force_token("\" sta:%pM\" ", tok);
1090 } else if (strcmp(*tok, "VIF_PR_FMT") == 0) {
1091 free(*tok);
1092 *tok = NULL;
1093 return force_token("\" vif:%p(%d)\" ", tok);
1094 }
1095 }
1096
1097 return type;
1098}
1099
1100static enum tep_event_type force_token(const char *str, char **tok)
1101{
1102 const char *save_input_buf;
1103 unsigned long long save_input_buf_ptr;
1104 unsigned long long save_input_buf_siz;
1105 enum tep_event_type type;
1106
1107 /* save off the current input pointers */
1108 save_input_buf = input_buf;
1109 save_input_buf_ptr = input_buf_ptr;
1110 save_input_buf_siz = input_buf_siz;
1111
1112 init_input_buf(str, strlen(str));
1113
1114 type = __read_token(tok);
1115
1116 /* reset back to original token */
1117 input_buf = save_input_buf;
1118 input_buf_ptr = save_input_buf_ptr;
1119 input_buf_siz = save_input_buf_siz;
1120
1121 return type;
1122}
1123
1124static void free_token(char *tok)
1125{
1126 if (tok)
1127 free(tok);
1128}
1129
1130static enum tep_event_type read_token(char **tok)
1131{
1132 enum tep_event_type type;
1133
1134 for (;;) {
1135 type = __read_token(tok);
1136 if (type != TEP_EVENT_SPACE)
1137 return type;
1138
1139 free_token(*tok);
1140 }
1141
1142 /* not reached */
1143 *tok = NULL;
1144 return TEP_EVENT_NONE;
1145}
1146
1147/**
1148 * tep_read_token - access to utilites to use the pevent parser
1149 * @tok: The token to return
1150 *
1151 * This will parse tokens from the string given by
1152 * tep_init_data().
1153 *
1154 * Returns the token type.
1155 */
1156enum tep_event_type tep_read_token(char **tok)
1157{
1158 return read_token(tok);
1159}
1160
1161/**
1162 * tep_free_token - free a token returned by tep_read_token
1163 * @token: the token to free
1164 */
1165void tep_free_token(char *token)
1166{
1167 free_token(token);
1168}
1169
1170/* no newline */
1171static enum tep_event_type read_token_item(char **tok)
1172{
1173 enum tep_event_type type;
1174
1175 for (;;) {
1176 type = __read_token(tok);
1177 if (type != TEP_EVENT_SPACE && type != TEP_EVENT_NEWLINE)
1178 return type;
1179 free_token(*tok);
1180 *tok = NULL;
1181 }
1182
1183 /* not reached */
1184 *tok = NULL;
1185 return TEP_EVENT_NONE;
1186}
1187
1188static int test_type(enum tep_event_type type, enum tep_event_type expect)
1189{
1190 if (type != expect) {
1191 do_warning("Error: expected type %d but read %d",
1192 expect, type);
1193 return -1;
1194 }
1195 return 0;
1196}
1197
1198static int test_type_token(enum tep_event_type type, const char *token,
1199 enum tep_event_type expect, const char *expect_tok)
1200{
1201 if (type != expect) {
1202 do_warning("Error: expected type %d but read %d",
1203 expect, type);
1204 return -1;
1205 }
1206
1207 if (strcmp(token, expect_tok) != 0) {
1208 do_warning("Error: expected '%s' but read '%s'",
1209 expect_tok, token);
1210 return -1;
1211 }
1212 return 0;
1213}
1214
1215static int __read_expect_type(enum tep_event_type expect, char **tok, int newline_ok)
1216{
1217 enum tep_event_type type;
1218
1219 if (newline_ok)
1220 type = read_token(tok);
1221 else
1222 type = read_token_item(tok);
1223 return test_type(type, expect);
1224}
1225
1226static int read_expect_type(enum tep_event_type expect, char **tok)
1227{
1228 return __read_expect_type(expect, tok, 1);
1229}
1230
1231static int __read_expected(enum tep_event_type expect, const char *str,
1232 int newline_ok)
1233{
1234 enum tep_event_type type;
1235 char *token;
1236 int ret;
1237
1238 if (newline_ok)
1239 type = read_token(&token);
1240 else
1241 type = read_token_item(&token);
1242
1243 ret = test_type_token(type, token, expect, str);
1244
1245 free_token(token);
1246
1247 return ret;
1248}
1249
1250static int read_expected(enum tep_event_type expect, const char *str)
1251{
1252 return __read_expected(expect, str, 1);
1253}
1254
1255static int read_expected_item(enum tep_event_type expect, const char *str)
1256{
1257 return __read_expected(expect, str, 0);
1258}
1259
1260static char *event_read_name(void)
1261{
1262 char *token;
1263
1264 if (read_expected(TEP_EVENT_ITEM, "name") < 0)
1265 return NULL;
1266
1267 if (read_expected(TEP_EVENT_OP, ":") < 0)
1268 return NULL;
1269
1270 if (read_expect_type(TEP_EVENT_ITEM, &token) < 0)
1271 goto fail;
1272
1273 return token;
1274
1275 fail:
1276 free_token(token);
1277 return NULL;
1278}
1279
1280static int event_read_id(void)
1281{
1282 char *token;
1283 int id;
1284
1285 if (read_expected_item(TEP_EVENT_ITEM, "ID") < 0)
1286 return -1;
1287
1288 if (read_expected(TEP_EVENT_OP, ":") < 0)
1289 return -1;
1290
1291 if (read_expect_type(TEP_EVENT_ITEM, &token) < 0)
1292 goto fail;
1293
1294 id = strtoul(token, NULL, 0);
1295 free_token(token);
1296 return id;
1297
1298 fail:
1299 free_token(token);
1300 return -1;
1301}
1302
1303static int field_is_string(struct tep_format_field *field)
1304{
1305 if ((field->flags & TEP_FIELD_IS_ARRAY) &&
1306 (strstr(field->type, "char") || strstr(field->type, "u8") ||
1307 strstr(field->type, "s8")))
1308 return 1;
1309
1310 return 0;
1311}
1312
1313static int field_is_dynamic(struct tep_format_field *field)
1314{
1315 if (strncmp(field->type, "__data_loc", 10) == 0)
1316 return 1;
1317
1318 return 0;
1319}
1320
1321static int field_is_long(struct tep_format_field *field)
1322{
1323 /* includes long long */
1324 if (strstr(field->type, "long"))
1325 return 1;
1326
1327 return 0;
1328}
1329
1330static unsigned int type_size(const char *name)
1331{
1332 /* This covers all TEP_FIELD_IS_STRING types. */
1333 static struct {
1334 const char *type;
1335 unsigned int size;
1336 } table[] = {
1337 { "u8", 1 },
1338 { "u16", 2 },
1339 { "u32", 4 },
1340 { "u64", 8 },
1341 { "s8", 1 },
1342 { "s16", 2 },
1343 { "s32", 4 },
1344 { "s64", 8 },
1345 { "char", 1 },
1346 { },
1347 };
1348 int i;
1349
1350 for (i = 0; table[i].type; i++) {
1351 if (!strcmp(table[i].type, name))
1352 return table[i].size;
1353 }
1354
1355 return 0;
1356}
1357
1358static int event_read_fields(struct tep_event_format *event, struct tep_format_field **fields)
1359{
1360 struct tep_format_field *field = NULL;
1361 enum tep_event_type type;
1362 char *token;
1363 char *last_token;
1364 int count = 0;
1365
1366 do {
1367 unsigned int size_dynamic = 0;
1368
1369 type = read_token(&token);
1370 if (type == TEP_EVENT_NEWLINE) {
1371 free_token(token);
1372 return count;
1373 }
1374
1375 count++;
1376
1377 if (test_type_token(type, token, TEP_EVENT_ITEM, "field"))
1378 goto fail;
1379 free_token(token);
1380
1381 type = read_token(&token);
1382 /*
1383 * The ftrace fields may still use the "special" name.
1384 * Just ignore it.
1385 */
1386 if (event->flags & TEP_EVENT_FL_ISFTRACE &&
1387 type == TEP_EVENT_ITEM && strcmp(token, "special") == 0) {
1388 free_token(token);
1389 type = read_token(&token);
1390 }
1391
1392 if (test_type_token(type, token, TEP_EVENT_OP, ":") < 0)
1393 goto fail;
1394
1395 free_token(token);
1396 if (read_expect_type(TEP_EVENT_ITEM, &token) < 0)
1397 goto fail;
1398
1399 last_token = token;
1400
1401 field = calloc(1, sizeof(*field));
1402 if (!field)
1403 goto fail;
1404
1405 field->event = event;
1406
1407 /* read the rest of the type */
1408 for (;;) {
1409 type = read_token(&token);
1410 if (type == TEP_EVENT_ITEM ||
1411 (type == TEP_EVENT_OP && strcmp(token, "*") == 0) ||
1412 /*
1413 * Some of the ftrace fields are broken and have
1414 * an illegal "." in them.
1415 */
1416 (event->flags & TEP_EVENT_FL_ISFTRACE &&
1417 type == TEP_EVENT_OP && strcmp(token, ".") == 0)) {
1418
1419 if (strcmp(token, "*") == 0)
1420 field->flags |= TEP_FIELD_IS_POINTER;
1421
1422 if (field->type) {
1423 char *new_type;
1424 new_type = realloc(field->type,
1425 strlen(field->type) +
1426 strlen(last_token) + 2);
1427 if (!new_type) {
1428 free(last_token);
1429 goto fail;
1430 }
1431 field->type = new_type;
1432 strcat(field->type, " ");
1433 strcat(field->type, last_token);
1434 free(last_token);
1435 } else
1436 field->type = last_token;
1437 last_token = token;
1438 continue;
1439 }
1440
1441 break;
1442 }
1443
1444 if (!field->type) {
1445 do_warning_event(event, "%s: no type found", __func__);
1446 goto fail;
1447 }
1448 field->name = field->alias = last_token;
1449
1450 if (test_type(type, TEP_EVENT_OP))
1451 goto fail;
1452
1453 if (strcmp(token, "[") == 0) {
1454 enum tep_event_type last_type = type;
1455 char *brackets = token;
1456 char *new_brackets;
1457 int len;
1458
1459 field->flags |= TEP_FIELD_IS_ARRAY;
1460
1461 type = read_token(&token);
1462
1463 if (type == TEP_EVENT_ITEM)
1464 field->arraylen = strtoul(token, NULL, 0);
1465 else
1466 field->arraylen = 0;
1467
1468 while (strcmp(token, "]") != 0) {
1469 if (last_type == TEP_EVENT_ITEM &&
1470 type == TEP_EVENT_ITEM)
1471 len = 2;
1472 else
1473 len = 1;
1474 last_type = type;
1475
1476 new_brackets = realloc(brackets,
1477 strlen(brackets) +
1478 strlen(token) + len);
1479 if (!new_brackets) {
1480 free(brackets);
1481 goto fail;
1482 }
1483 brackets = new_brackets;
1484 if (len == 2)
1485 strcat(brackets, " ");
1486 strcat(brackets, token);
1487 /* We only care about the last token */
1488 field->arraylen = strtoul(token, NULL, 0);
1489 free_token(token);
1490 type = read_token(&token);
1491 if (type == TEP_EVENT_NONE) {
1492 do_warning_event(event, "failed to find token");
1493 goto fail;
1494 }
1495 }
1496
1497 free_token(token);
1498
1499 new_brackets = realloc(brackets, strlen(brackets) + 2);
1500 if (!new_brackets) {
1501 free(brackets);
1502 goto fail;
1503 }
1504 brackets = new_brackets;
1505 strcat(brackets, "]");
1506
1507 /* add brackets to type */
1508
1509 type = read_token(&token);
1510 /*
1511 * If the next token is not an OP, then it is of
1512 * the format: type [] item;
1513 */
1514 if (type == TEP_EVENT_ITEM) {
1515 char *new_type;
1516 new_type = realloc(field->type,
1517 strlen(field->type) +
1518 strlen(field->name) +
1519 strlen(brackets) + 2);
1520 if (!new_type) {
1521 free(brackets);
1522 goto fail;
1523 }
1524 field->type = new_type;
1525 strcat(field->type, " ");
1526 strcat(field->type, field->name);
1527 size_dynamic = type_size(field->name);
1528 free_token(field->name);
1529 strcat(field->type, brackets);
1530 field->name = field->alias = token;
1531 type = read_token(&token);
1532 } else {
1533 char *new_type;
1534 new_type = realloc(field->type,
1535 strlen(field->type) +
1536 strlen(brackets) + 1);
1537 if (!new_type) {
1538 free(brackets);
1539 goto fail;
1540 }
1541 field->type = new_type;
1542 strcat(field->type, brackets);
1543 }
1544 free(brackets);
1545 }
1546
1547 if (field_is_string(field))
1548 field->flags |= TEP_FIELD_IS_STRING;
1549 if (field_is_dynamic(field))
1550 field->flags |= TEP_FIELD_IS_DYNAMIC;
1551 if (field_is_long(field))
1552 field->flags |= TEP_FIELD_IS_LONG;
1553
1554 if (test_type_token(type, token, TEP_EVENT_OP, ";"))
1555 goto fail;
1556 free_token(token);
1557
1558 if (read_expected(TEP_EVENT_ITEM, "offset") < 0)
1559 goto fail_expect;
1560
1561 if (read_expected(TEP_EVENT_OP, ":") < 0)
1562 goto fail_expect;
1563
1564 if (read_expect_type(TEP_EVENT_ITEM, &token))
1565 goto fail;
1566 field->offset = strtoul(token, NULL, 0);
1567 free_token(token);
1568
1569 if (read_expected(TEP_EVENT_OP, ";") < 0)
1570 goto fail_expect;
1571
1572 if (read_expected(TEP_EVENT_ITEM, "size") < 0)
1573 goto fail_expect;
1574
1575 if (read_expected(TEP_EVENT_OP, ":") < 0)
1576 goto fail_expect;
1577
1578 if (read_expect_type(TEP_EVENT_ITEM, &token))
1579 goto fail;
1580 field->size = strtoul(token, NULL, 0);
1581 free_token(token);
1582
1583 if (read_expected(TEP_EVENT_OP, ";") < 0)
1584 goto fail_expect;
1585
1586 type = read_token(&token);
1587 if (type != TEP_EVENT_NEWLINE) {
1588 /* newer versions of the kernel have a "signed" type */
1589 if (test_type_token(type, token, TEP_EVENT_ITEM, "signed"))
1590 goto fail;
1591
1592 free_token(token);
1593
1594 if (read_expected(TEP_EVENT_OP, ":") < 0)
1595 goto fail_expect;
1596
1597 if (read_expect_type(TEP_EVENT_ITEM, &token))
1598 goto fail;
1599
1600 if (strtoul(token, NULL, 0))
1601 field->flags |= TEP_FIELD_IS_SIGNED;
1602
1603 free_token(token);
1604 if (read_expected(TEP_EVENT_OP, ";") < 0)
1605 goto fail_expect;
1606
1607 if (read_expect_type(TEP_EVENT_NEWLINE, &token))
1608 goto fail;
1609 }
1610
1611 free_token(token);
1612
1613 if (field->flags & TEP_FIELD_IS_ARRAY) {
1614 if (field->arraylen)
1615 field->elementsize = field->size / field->arraylen;
1616 else if (field->flags & TEP_FIELD_IS_DYNAMIC)
1617 field->elementsize = size_dynamic;
1618 else if (field->flags & TEP_FIELD_IS_STRING)
1619 field->elementsize = 1;
1620 else if (field->flags & TEP_FIELD_IS_LONG)
1621 field->elementsize = event->pevent ?
1622 event->pevent->long_size :
1623 sizeof(long);
1624 } else
1625 field->elementsize = field->size;
1626
1627 *fields = field;
1628 fields = &field->next;
1629
1630 } while (1);
1631
1632 return 0;
1633
1634fail:
1635 free_token(token);
1636fail_expect:
1637 if (field) {
1638 free(field->type);
1639 free(field->name);
1640 free(field);
1641 }
1642 return -1;
1643}
1644
1645static int event_read_format(struct tep_event_format *event)
1646{
1647 char *token;
1648 int ret;
1649
1650 if (read_expected_item(TEP_EVENT_ITEM, "format") < 0)
1651 return -1;
1652
1653 if (read_expected(TEP_EVENT_OP, ":") < 0)
1654 return -1;
1655
1656 if (read_expect_type(TEP_EVENT_NEWLINE, &token))
1657 goto fail;
1658 free_token(token);
1659
1660 ret = event_read_fields(event, &event->format.common_fields);
1661 if (ret < 0)
1662 return ret;
1663 event->format.nr_common = ret;
1664
1665 ret = event_read_fields(event, &event->format.fields);
1666 if (ret < 0)
1667 return ret;
1668 event->format.nr_fields = ret;
1669
1670 return 0;
1671
1672 fail:
1673 free_token(token);
1674 return -1;
1675}
1676
1677static enum tep_event_type
1678process_arg_token(struct tep_event_format *event, struct tep_print_arg *arg,
1679 char **tok, enum tep_event_type type);
1680
1681static enum tep_event_type
1682process_arg(struct tep_event_format *event, struct tep_print_arg *arg, char **tok)
1683{
1684 enum tep_event_type type;
1685 char *token;
1686
1687 type = read_token(&token);
1688 *tok = token;
1689
1690 return process_arg_token(event, arg, tok, type);
1691}
1692
1693static enum tep_event_type
1694process_op(struct tep_event_format *event, struct tep_print_arg *arg, char **tok);
1695
1696/*
1697 * For __print_symbolic() and __print_flags, we need to completely
1698 * evaluate the first argument, which defines what to print next.
1699 */
1700static enum tep_event_type
1701process_field_arg(struct tep_event_format *event, struct tep_print_arg *arg, char **tok)
1702{
1703 enum tep_event_type type;
1704
1705 type = process_arg(event, arg, tok);
1706
1707 while (type == TEP_EVENT_OP) {
1708 type = process_op(event, arg, tok);
1709 }
1710
1711 return type;
1712}
1713
1714static enum tep_event_type
1715process_cond(struct tep_event_format *event, struct tep_print_arg *top, char **tok)
1716{
1717 struct tep_print_arg *arg, *left, *right;
1718 enum tep_event_type type;
1719 char *token = NULL;
1720
1721 arg = alloc_arg();
1722 left = alloc_arg();
1723 right = alloc_arg();
1724
1725 if (!arg || !left || !right) {
1726 do_warning_event(event, "%s: not enough memory!", __func__);
1727 /* arg will be freed at out_free */
1728 free_arg(left);
1729 free_arg(right);
1730 goto out_free;
1731 }
1732
1733 arg->type = TEP_PRINT_OP;
1734 arg->op.left = left;
1735 arg->op.right = right;
1736
1737 *tok = NULL;
1738 type = process_arg(event, left, &token);
1739
1740 again:
1741 if (type == TEP_EVENT_ERROR)
1742 goto out_free;
1743
1744 /* Handle other operations in the arguments */
1745 if (type == TEP_EVENT_OP && strcmp(token, ":") != 0) {
1746 type = process_op(event, left, &token);
1747 goto again;
1748 }
1749
1750 if (test_type_token(type, token, TEP_EVENT_OP, ":"))
1751 goto out_free;
1752
1753 arg->op.op = token;
1754
1755 type = process_arg(event, right, &token);
1756
1757 top->op.right = arg;
1758
1759 *tok = token;
1760 return type;
1761
1762out_free:
1763 /* Top may point to itself */
1764 top->op.right = NULL;
1765 free_token(token);
1766 free_arg(arg);
1767 return TEP_EVENT_ERROR;
1768}
1769
1770static enum tep_event_type
1771process_array(struct tep_event_format *event, struct tep_print_arg *top, char **tok)
1772{
1773 struct tep_print_arg *arg;
1774 enum tep_event_type type;
1775 char *token = NULL;
1776
1777 arg = alloc_arg();
1778 if (!arg) {
1779 do_warning_event(event, "%s: not enough memory!", __func__);
1780 /* '*tok' is set to top->op.op. No need to free. */
1781 *tok = NULL;
1782 return TEP_EVENT_ERROR;
1783 }
1784
1785 *tok = NULL;
1786 type = process_arg(event, arg, &token);
1787 if (test_type_token(type, token, TEP_EVENT_OP, "]"))
1788 goto out_free;
1789
1790 top->op.right = arg;
1791
1792 free_token(token);
1793 type = read_token_item(&token);
1794 *tok = token;
1795
1796 return type;
1797
1798out_free:
1799 free_token(token);
1800 free_arg(arg);
1801 return TEP_EVENT_ERROR;
1802}
1803
1804static int get_op_prio(char *op)
1805{
1806 if (!op[1]) {
1807 switch (op[0]) {
1808 case '~':
1809 case '!':
1810 return 4;
1811 case '*':
1812 case '/':
1813 case '%':
1814 return 6;
1815 case '+':
1816 case '-':
1817 return 7;
1818 /* '>>' and '<<' are 8 */
1819 case '<':
1820 case '>':
1821 return 9;
1822 /* '==' and '!=' are 10 */
1823 case '&':
1824 return 11;
1825 case '^':
1826 return 12;
1827 case '|':
1828 return 13;
1829 case '?':
1830 return 16;
1831 default:
1832 do_warning("unknown op '%c'", op[0]);
1833 return -1;
1834 }
1835 } else {
1836 if (strcmp(op, "++") == 0 ||
1837 strcmp(op, "--") == 0) {
1838 return 3;
1839 } else if (strcmp(op, ">>") == 0 ||
1840 strcmp(op, "<<") == 0) {
1841 return 8;
1842 } else if (strcmp(op, ">=") == 0 ||
1843 strcmp(op, "<=") == 0) {
1844 return 9;
1845 } else if (strcmp(op, "==") == 0 ||
1846 strcmp(op, "!=") == 0) {
1847 return 10;
1848 } else if (strcmp(op, "&&") == 0) {
1849 return 14;
1850 } else if (strcmp(op, "||") == 0) {
1851 return 15;
1852 } else {
1853 do_warning("unknown op '%s'", op);
1854 return -1;
1855 }
1856 }
1857}
1858
1859static int set_op_prio(struct tep_print_arg *arg)
1860{
1861
1862 /* single ops are the greatest */
1863 if (!arg->op.left || arg->op.left->type == TEP_PRINT_NULL)
1864 arg->op.prio = 0;
1865 else
1866 arg->op.prio = get_op_prio(arg->op.op);
1867
1868 return arg->op.prio;
1869}
1870
1871/* Note, *tok does not get freed, but will most likely be saved */
1872static enum tep_event_type
1873process_op(struct tep_event_format *event, struct tep_print_arg *arg, char **tok)
1874{
1875 struct tep_print_arg *left, *right = NULL;
1876 enum tep_event_type type;
1877 char *token;
1878
1879 /* the op is passed in via tok */
1880 token = *tok;
1881
1882 if (arg->type == TEP_PRINT_OP && !arg->op.left) {
1883 /* handle single op */
1884 if (token[1]) {
1885 do_warning_event(event, "bad op token %s", token);
1886 goto out_free;
1887 }
1888 switch (token[0]) {
1889 case '~':
1890 case '!':
1891 case '+':
1892 case '-':
1893 break;
1894 default:
1895 do_warning_event(event, "bad op token %s", token);
1896 goto out_free;
1897
1898 }
1899
1900 /* make an empty left */
1901 left = alloc_arg();
1902 if (!left)
1903 goto out_warn_free;
1904
1905 left->type = TEP_PRINT_NULL;
1906 arg->op.left = left;
1907
1908 right = alloc_arg();
1909 if (!right)
1910 goto out_warn_free;
1911
1912 arg->op.right = right;
1913
1914 /* do not free the token, it belongs to an op */
1915 *tok = NULL;
1916 type = process_arg(event, right, tok);
1917
1918 } else if (strcmp(token, "?") == 0) {
1919
1920 left = alloc_arg();
1921 if (!left)
1922 goto out_warn_free;
1923
1924 /* copy the top arg to the left */
1925 *left = *arg;
1926
1927 arg->type = TEP_PRINT_OP;
1928 arg->op.op = token;
1929 arg->op.left = left;
1930 arg->op.prio = 0;
1931
1932 /* it will set arg->op.right */
1933 type = process_cond(event, arg, tok);
1934
1935 } else if (strcmp(token, ">>") == 0 ||
1936 strcmp(token, "<<") == 0 ||
1937 strcmp(token, "&") == 0 ||
1938 strcmp(token, "|") == 0 ||
1939 strcmp(token, "&&") == 0 ||
1940 strcmp(token, "||") == 0 ||
1941 strcmp(token, "-") == 0 ||
1942 strcmp(token, "+") == 0 ||
1943 strcmp(token, "*") == 0 ||
1944 strcmp(token, "^") == 0 ||
1945 strcmp(token, "/") == 0 ||
1946 strcmp(token, "%") == 0 ||
1947 strcmp(token, "<") == 0 ||
1948 strcmp(token, ">") == 0 ||
1949 strcmp(token, "<=") == 0 ||
1950 strcmp(token, ">=") == 0 ||
1951 strcmp(token, "==") == 0 ||
1952 strcmp(token, "!=") == 0) {
1953
1954 left = alloc_arg();
1955 if (!left)
1956 goto out_warn_free;
1957
1958 /* copy the top arg to the left */
1959 *left = *arg;
1960
1961 arg->type = TEP_PRINT_OP;
1962 arg->op.op = token;
1963 arg->op.left = left;
1964 arg->op.right = NULL;
1965
1966 if (set_op_prio(arg) == -1) {
1967 event->flags |= TEP_EVENT_FL_FAILED;
1968 /* arg->op.op (= token) will be freed at out_free */
1969 arg->op.op = NULL;
1970 goto out_free;
1971 }
1972
1973 type = read_token_item(&token);
1974 *tok = token;
1975
1976 /* could just be a type pointer */
1977 if ((strcmp(arg->op.op, "*") == 0) &&
1978 type == TEP_EVENT_DELIM && (strcmp(token, ")") == 0)) {
1979 char *new_atom;
1980
1981 if (left->type != TEP_PRINT_ATOM) {
1982 do_warning_event(event, "bad pointer type");
1983 goto out_free;
1984 }
1985 new_atom = realloc(left->atom.atom,
1986 strlen(left->atom.atom) + 3);
1987 if (!new_atom)
1988 goto out_warn_free;
1989
1990 left->atom.atom = new_atom;
1991 strcat(left->atom.atom, " *");
1992 free(arg->op.op);
1993 *arg = *left;
1994 free(left);
1995
1996 return type;
1997 }
1998
1999 right = alloc_arg();
2000 if (!right)
2001 goto out_warn_free;
2002
2003 type = process_arg_token(event, right, tok, type);
2004 if (type == TEP_EVENT_ERROR) {
2005 free_arg(right);
2006 /* token was freed in process_arg_token() via *tok */
2007 token = NULL;
2008 goto out_free;
2009 }
2010
2011 if (right->type == TEP_PRINT_OP &&
2012 get_op_prio(arg->op.op) < get_op_prio(right->op.op)) {
2013 struct tep_print_arg tmp;
2014
2015 /* rotate ops according to the priority */
2016 arg->op.right = right->op.left;
2017
2018 tmp = *arg;
2019 *arg = *right;
2020 *right = tmp;
2021
2022 arg->op.left = right;
2023 } else {
2024 arg->op.right = right;
2025 }
2026
2027 } else if (strcmp(token, "[") == 0) {
2028
2029 left = alloc_arg();
2030 if (!left)
2031 goto out_warn_free;
2032
2033 *left = *arg;
2034
2035 arg->type = TEP_PRINT_OP;
2036 arg->op.op = token;
2037 arg->op.left = left;
2038
2039 arg->op.prio = 0;
2040
2041 /* it will set arg->op.right */
2042 type = process_array(event, arg, tok);
2043
2044 } else {
2045 do_warning_event(event, "unknown op '%s'", token);
2046 event->flags |= TEP_EVENT_FL_FAILED;
2047 /* the arg is now the left side */
2048 goto out_free;
2049 }
2050
2051 if (type == TEP_EVENT_OP && strcmp(*tok, ":") != 0) {
2052 int prio;
2053
2054 /* higher prios need to be closer to the root */
2055 prio = get_op_prio(*tok);
2056
2057 if (prio > arg->op.prio)
2058 return process_op(event, arg, tok);
2059
2060 return process_op(event, right, tok);
2061 }
2062
2063 return type;
2064
2065out_warn_free:
2066 do_warning_event(event, "%s: not enough memory!", __func__);
2067out_free:
2068 free_token(token);
2069 *tok = NULL;
2070 return TEP_EVENT_ERROR;
2071}
2072
2073static enum tep_event_type
2074process_entry(struct tep_event_format *event __maybe_unused, struct tep_print_arg *arg,
2075 char **tok)
2076{
2077 enum tep_event_type type;
2078 char *field;
2079 char *token;
2080
2081 if (read_expected(TEP_EVENT_OP, "->") < 0)
2082 goto out_err;
2083
2084 if (read_expect_type(TEP_EVENT_ITEM, &token) < 0)
2085 goto out_free;
2086 field = token;
2087
2088 arg->type = TEP_PRINT_FIELD;
2089 arg->field.name = field;
2090
2091 if (is_flag_field) {
2092 arg->field.field = tep_find_any_field(event, arg->field.name);
2093 arg->field.field->flags |= TEP_FIELD_IS_FLAG;
2094 is_flag_field = 0;
2095 } else if (is_symbolic_field) {
2096 arg->field.field = tep_find_any_field(event, arg->field.name);
2097 arg->field.field->flags |= TEP_FIELD_IS_SYMBOLIC;
2098 is_symbolic_field = 0;
2099 }
2100
2101 type = read_token(&token);
2102 *tok = token;
2103
2104 return type;
2105
2106 out_free:
2107 free_token(token);
2108 out_err:
2109 *tok = NULL;
2110 return TEP_EVENT_ERROR;
2111}
2112
2113static int alloc_and_process_delim(struct tep_event_format *event, char *next_token,
2114 struct tep_print_arg **print_arg)
2115{
2116 struct tep_print_arg *field;
2117 enum tep_event_type type;
2118 char *token;
2119 int ret = 0;
2120
2121 field = alloc_arg();
2122 if (!field) {
2123 do_warning_event(event, "%s: not enough memory!", __func__);
2124 errno = ENOMEM;
2125 return -1;
2126 }
2127
2128 type = process_arg(event, field, &token);
2129
2130 if (test_type_token(type, token, TEP_EVENT_DELIM, next_token)) {
2131 errno = EINVAL;
2132 ret = -1;
2133 free_arg(field);
2134 goto out_free_token;
2135 }
2136
2137 *print_arg = field;
2138
2139out_free_token:
2140 free_token(token);
2141
2142 return ret;
2143}
2144
2145static char *arg_eval (struct tep_print_arg *arg);
2146
2147static unsigned long long
2148eval_type_str(unsigned long long val, const char *type, int pointer)
2149{
2150 int sign = 0;
2151 char *ref;
2152 int len;
2153
2154 len = strlen(type);
2155
2156 if (pointer) {
2157
2158 if (type[len-1] != '*') {
2159 do_warning("pointer expected with non pointer type");
2160 return val;
2161 }
2162
2163 ref = malloc(len);
2164 if (!ref) {
2165 do_warning("%s: not enough memory!", __func__);
2166 return val;
2167 }
2168 memcpy(ref, type, len);
2169
2170 /* chop off the " *" */
2171 ref[len - 2] = 0;
2172
2173 val = eval_type_str(val, ref, 0);
2174 free(ref);
2175 return val;
2176 }
2177
2178 /* check if this is a pointer */
2179 if (type[len - 1] == '*')
2180 return val;
2181
2182 /* Try to figure out the arg size*/
2183 if (strncmp(type, "struct", 6) == 0)
2184 /* all bets off */
2185 return val;
2186
2187 if (strcmp(type, "u8") == 0)
2188 return val & 0xff;
2189
2190 if (strcmp(type, "u16") == 0)
2191 return val & 0xffff;
2192
2193 if (strcmp(type, "u32") == 0)
2194 return val & 0xffffffff;
2195
2196 if (strcmp(type, "u64") == 0 ||
2197 strcmp(type, "s64"))
2198 return val;
2199
2200 if (strcmp(type, "s8") == 0)
2201 return (unsigned long long)(char)val & 0xff;
2202
2203 if (strcmp(type, "s16") == 0)
2204 return (unsigned long long)(short)val & 0xffff;
2205
2206 if (strcmp(type, "s32") == 0)
2207 return (unsigned long long)(int)val & 0xffffffff;
2208
2209 if (strncmp(type, "unsigned ", 9) == 0) {
2210 sign = 0;
2211 type += 9;
2212 }
2213
2214 if (strcmp(type, "char") == 0) {
2215 if (sign)
2216 return (unsigned long long)(char)val & 0xff;
2217 else
2218 return val & 0xff;
2219 }
2220
2221 if (strcmp(type, "short") == 0) {
2222 if (sign)
2223 return (unsigned long long)(short)val & 0xffff;
2224 else
2225 return val & 0xffff;
2226 }
2227
2228 if (strcmp(type, "int") == 0) {
2229 if (sign)
2230 return (unsigned long long)(int)val & 0xffffffff;
2231 else
2232 return val & 0xffffffff;
2233 }
2234
2235 return val;
2236}
2237
2238/*
2239 * Try to figure out the type.
2240 */
2241static unsigned long long
2242eval_type(unsigned long long val, struct tep_print_arg *arg, int pointer)
2243{
2244 if (arg->type != TEP_PRINT_TYPE) {
2245 do_warning("expected type argument");
2246 return 0;
2247 }
2248
2249 return eval_type_str(val, arg->typecast.type, pointer);
2250}
2251
2252static int arg_num_eval(struct tep_print_arg *arg, long long *val)
2253{
2254 long long left, right;
2255 int ret = 1;
2256
2257 switch (arg->type) {
2258 case TEP_PRINT_ATOM:
2259 *val = strtoll(arg->atom.atom, NULL, 0);
2260 break;
2261 case TEP_PRINT_TYPE:
2262 ret = arg_num_eval(arg->typecast.item, val);
2263 if (!ret)
2264 break;
2265 *val = eval_type(*val, arg, 0);
2266 break;
2267 case TEP_PRINT_OP:
2268 switch (arg->op.op[0]) {
2269 case '|':
2270 ret = arg_num_eval(arg->op.left, &left);
2271 if (!ret)
2272 break;
2273 ret = arg_num_eval(arg->op.right, &right);
2274 if (!ret)
2275 break;
2276 if (arg->op.op[1])
2277 *val = left || right;
2278 else
2279 *val = left | right;
2280 break;
2281 case '&':
2282 ret = arg_num_eval(arg->op.left, &left);
2283 if (!ret)
2284 break;
2285 ret = arg_num_eval(arg->op.right, &right);
2286 if (!ret)
2287 break;
2288 if (arg->op.op[1])
2289 *val = left && right;
2290 else
2291 *val = left & right;
2292 break;
2293 case '<':
2294 ret = arg_num_eval(arg->op.left, &left);
2295 if (!ret)
2296 break;
2297 ret = arg_num_eval(arg->op.right, &right);
2298 if (!ret)
2299 break;
2300 switch (arg->op.op[1]) {
2301 case 0:
2302 *val = left < right;
2303 break;
2304 case '<':
2305 *val = left << right;
2306 break;
2307 case '=':
2308 *val = left <= right;
2309 break;
2310 default:
2311 do_warning("unknown op '%s'", arg->op.op);
2312 ret = 0;
2313 }
2314 break;
2315 case '>':
2316 ret = arg_num_eval(arg->op.left, &left);
2317 if (!ret)
2318 break;
2319 ret = arg_num_eval(arg->op.right, &right);
2320 if (!ret)
2321 break;
2322 switch (arg->op.op[1]) {
2323 case 0:
2324 *val = left > right;
2325 break;
2326 case '>':
2327 *val = left >> right;
2328 break;
2329 case '=':
2330 *val = left >= right;
2331 break;
2332 default:
2333 do_warning("unknown op '%s'", arg->op.op);
2334 ret = 0;
2335 }
2336 break;
2337 case '=':
2338 ret = arg_num_eval(arg->op.left, &left);
2339 if (!ret)
2340 break;
2341 ret = arg_num_eval(arg->op.right, &right);
2342 if (!ret)
2343 break;
2344
2345 if (arg->op.op[1] != '=') {
2346 do_warning("unknown op '%s'", arg->op.op);
2347 ret = 0;
2348 } else
2349 *val = left == right;
2350 break;
2351 case '!':
2352 ret = arg_num_eval(arg->op.left, &left);
2353 if (!ret)
2354 break;
2355 ret = arg_num_eval(arg->op.right, &right);
2356 if (!ret)
2357 break;
2358
2359 switch (arg->op.op[1]) {
2360 case '=':
2361 *val = left != right;
2362 break;
2363 default:
2364 do_warning("unknown op '%s'", arg->op.op);
2365 ret = 0;
2366 }
2367 break;
2368 case '-':
2369 /* check for negative */
2370 if (arg->op.left->type == TEP_PRINT_NULL)
2371 left = 0;
2372 else
2373 ret = arg_num_eval(arg->op.left, &left);
2374 if (!ret)
2375 break;
2376 ret = arg_num_eval(arg->op.right, &right);
2377 if (!ret)
2378 break;
2379 *val = left - right;
2380 break;
2381 case '+':
2382 if (arg->op.left->type == TEP_PRINT_NULL)
2383 left = 0;
2384 else
2385 ret = arg_num_eval(arg->op.left, &left);
2386 if (!ret)
2387 break;
2388 ret = arg_num_eval(arg->op.right, &right);
2389 if (!ret)
2390 break;
2391 *val = left + right;
2392 break;
2393 case '~':
2394 ret = arg_num_eval(arg->op.right, &right);
2395 if (!ret)
2396 break;
2397 *val = ~right;
2398 break;
2399 default:
2400 do_warning("unknown op '%s'", arg->op.op);
2401 ret = 0;
2402 }
2403 break;
2404
2405 case TEP_PRINT_NULL:
2406 case TEP_PRINT_FIELD ... TEP_PRINT_SYMBOL:
2407 case TEP_PRINT_STRING:
2408 case TEP_PRINT_BSTRING:
2409 case TEP_PRINT_BITMASK:
2410 default:
2411 do_warning("invalid eval type %d", arg->type);
2412 ret = 0;
2413
2414 }
2415 return ret;
2416}
2417
2418static char *arg_eval (struct tep_print_arg *arg)
2419{
2420 long long val;
2421 static char buf[20];
2422
2423 switch (arg->type) {
2424 case TEP_PRINT_ATOM:
2425 return arg->atom.atom;
2426 case TEP_PRINT_TYPE:
2427 return arg_eval(arg->typecast.item);
2428 case TEP_PRINT_OP:
2429 if (!arg_num_eval(arg, &val))
2430 break;
2431 sprintf(buf, "%lld", val);
2432 return buf;
2433
2434 case TEP_PRINT_NULL:
2435 case TEP_PRINT_FIELD ... TEP_PRINT_SYMBOL:
2436 case TEP_PRINT_STRING:
2437 case TEP_PRINT_BSTRING:
2438 case TEP_PRINT_BITMASK:
2439 default:
2440 do_warning("invalid eval type %d", arg->type);
2441 break;
2442 }
2443
2444 return NULL;
2445}
2446
2447static enum tep_event_type
2448process_fields(struct tep_event_format *event, struct tep_print_flag_sym **list, char **tok)
2449{
2450 enum tep_event_type type;
2451 struct tep_print_arg *arg = NULL;
2452 struct tep_print_flag_sym *field;
2453 char *token = *tok;
2454 char *value;
2455
2456 do {
2457 free_token(token);
2458 type = read_token_item(&token);
2459 if (test_type_token(type, token, TEP_EVENT_OP, "{"))
2460 break;
2461
2462 arg = alloc_arg();
2463 if (!arg)
2464 goto out_free;
2465
2466 free_token(token);
2467 type = process_arg(event, arg, &token);
2468
2469 if (type == TEP_EVENT_OP)
2470 type = process_op(event, arg, &token);
2471
2472 if (type == TEP_EVENT_ERROR)
2473 goto out_free;
2474
2475 if (test_type_token(type, token, TEP_EVENT_DELIM, ","))
2476 goto out_free;
2477
2478 field = calloc(1, sizeof(*field));
2479 if (!field)
2480 goto out_free;
2481
2482 value = arg_eval(arg);
2483 if (value == NULL)
2484 goto out_free_field;
2485 field->value = strdup(value);
2486 if (field->value == NULL)
2487 goto out_free_field;
2488
2489 free_arg(arg);
2490 arg = alloc_arg();
2491 if (!arg)
2492 goto out_free;
2493
2494 free_token(token);
2495 type = process_arg(event, arg, &token);
2496 if (test_type_token(type, token, TEP_EVENT_OP, "}"))
2497 goto out_free_field;
2498
2499 value = arg_eval(arg);
2500 if (value == NULL)
2501 goto out_free_field;
2502 field->str = strdup(value);
2503 if (field->str == NULL)
2504 goto out_free_field;
2505 free_arg(arg);
2506 arg = NULL;
2507
2508 *list = field;
2509 list = &field->next;
2510
2511 free_token(token);
2512 type = read_token_item(&token);
2513 } while (type == TEP_EVENT_DELIM && strcmp(token, ",") == 0);
2514
2515 *tok = token;
2516 return type;
2517
2518out_free_field:
2519 free_flag_sym(field);
2520out_free:
2521 free_arg(arg);
2522 free_token(token);
2523 *tok = NULL;
2524
2525 return TEP_EVENT_ERROR;
2526}
2527
2528static enum tep_event_type
2529process_flags(struct tep_event_format *event, struct tep_print_arg *arg, char **tok)
2530{
2531 struct tep_print_arg *field;
2532 enum tep_event_type type;
2533 char *token = NULL;
2534
2535 memset(arg, 0, sizeof(*arg));
2536 arg->type = TEP_PRINT_FLAGS;
2537
2538 field = alloc_arg();
2539 if (!field) {
2540 do_warning_event(event, "%s: not enough memory!", __func__);
2541 goto out_free;
2542 }
2543
2544 type = process_field_arg(event, field, &token);
2545
2546 /* Handle operations in the first argument */
2547 while (type == TEP_EVENT_OP)
2548 type = process_op(event, field, &token);
2549
2550 if (test_type_token(type, token, TEP_EVENT_DELIM, ","))
2551 goto out_free_field;
2552 free_token(token);
2553
2554 arg->flags.field = field;
2555
2556 type = read_token_item(&token);
2557 if (event_item_type(type)) {
2558 arg->flags.delim = token;
2559 type = read_token_item(&token);
2560 }
2561
2562 if (test_type_token(type, token, TEP_EVENT_DELIM, ","))
2563 goto out_free;
2564
2565 type = process_fields(event, &arg->flags.flags, &token);
2566 if (test_type_token(type, token, TEP_EVENT_DELIM, ")"))
2567 goto out_free;
2568
2569 free_token(token);
2570 type = read_token_item(tok);
2571 return type;
2572
2573out_free_field:
2574 free_arg(field);
2575out_free:
2576 free_token(token);
2577 *tok = NULL;
2578 return TEP_EVENT_ERROR;
2579}
2580
2581static enum tep_event_type
2582process_symbols(struct tep_event_format *event, struct tep_print_arg *arg, char **tok)
2583{
2584 struct tep_print_arg *field;
2585 enum tep_event_type type;
2586 char *token = NULL;
2587
2588 memset(arg, 0, sizeof(*arg));
2589 arg->type = TEP_PRINT_SYMBOL;
2590
2591 field = alloc_arg();
2592 if (!field) {
2593 do_warning_event(event, "%s: not enough memory!", __func__);
2594 goto out_free;
2595 }
2596
2597 type = process_field_arg(event, field, &token);
2598
2599 if (test_type_token(type, token, TEP_EVENT_DELIM, ","))
2600 goto out_free_field;
2601
2602 arg->symbol.field = field;
2603
2604 type = process_fields(event, &arg->symbol.symbols, &token);
2605 if (test_type_token(type, token, TEP_EVENT_DELIM, ")"))
2606 goto out_free;
2607
2608 free_token(token);
2609 type = read_token_item(tok);
2610 return type;
2611
2612out_free_field:
2613 free_arg(field);
2614out_free:
2615 free_token(token);
2616 *tok = NULL;
2617 return TEP_EVENT_ERROR;
2618}
2619
2620static enum tep_event_type
2621process_hex_common(struct tep_event_format *event, struct tep_print_arg *arg,
2622 char **tok, enum tep_print_arg_type type)
2623{
2624 memset(arg, 0, sizeof(*arg));
2625 arg->type = type;
2626
2627 if (alloc_and_process_delim(event, ",", &arg->hex.field))
2628 goto out;
2629
2630 if (alloc_and_process_delim(event, ")", &arg->hex.size))
2631 goto free_field;
2632
2633 return read_token_item(tok);
2634
2635free_field:
2636 free_arg(arg->hex.field);
2637 arg->hex.field = NULL;
2638out:
2639 *tok = NULL;
2640 return TEP_EVENT_ERROR;
2641}
2642
2643static enum tep_event_type
2644process_hex(struct tep_event_format *event, struct tep_print_arg *arg, char **tok)
2645{
2646 return process_hex_common(event, arg, tok, TEP_PRINT_HEX);
2647}
2648
2649static enum tep_event_type
2650process_hex_str(struct tep_event_format *event, struct tep_print_arg *arg,
2651 char **tok)
2652{
2653 return process_hex_common(event, arg, tok, TEP_PRINT_HEX_STR);
2654}
2655
2656static enum tep_event_type
2657process_int_array(struct tep_event_format *event, struct tep_print_arg *arg, char **tok)
2658{
2659 memset(arg, 0, sizeof(*arg));
2660 arg->type = TEP_PRINT_INT_ARRAY;
2661
2662 if (alloc_and_process_delim(event, ",", &arg->int_array.field))
2663 goto out;
2664
2665 if (alloc_and_process_delim(event, ",", &arg->int_array.count))
2666 goto free_field;
2667
2668 if (alloc_and_process_delim(event, ")", &arg->int_array.el_size))
2669 goto free_size;
2670
2671 return read_token_item(tok);
2672
2673free_size:
2674 free_arg(arg->int_array.count);
2675 arg->int_array.count = NULL;
2676free_field:
2677 free_arg(arg->int_array.field);
2678 arg->int_array.field = NULL;
2679out:
2680 *tok = NULL;
2681 return TEP_EVENT_ERROR;
2682}
2683
2684static enum tep_event_type
2685process_dynamic_array(struct tep_event_format *event, struct tep_print_arg *arg, char **tok)
2686{
2687 struct tep_format_field *field;
2688 enum tep_event_type type;
2689 char *token;
2690
2691 memset(arg, 0, sizeof(*arg));
2692 arg->type = TEP_PRINT_DYNAMIC_ARRAY;
2693
2694 /*
2695 * The item within the parenthesis is another field that holds
2696 * the index into where the array starts.
2697 */
2698 type = read_token(&token);
2699 *tok = token;
2700 if (type != TEP_EVENT_ITEM)
2701 goto out_free;
2702
2703 /* Find the field */
2704
2705 field = tep_find_field(event, token);
2706 if (!field)
2707 goto out_free;
2708
2709 arg->dynarray.field = field;
2710 arg->dynarray.index = 0;
2711
2712 if (read_expected(TEP_EVENT_DELIM, ")") < 0)
2713 goto out_free;
2714
2715 free_token(token);
2716 type = read_token_item(&token);
2717 *tok = token;
2718 if (type != TEP_EVENT_OP || strcmp(token, "[") != 0)
2719 return type;
2720
2721 free_token(token);
2722 arg = alloc_arg();
2723 if (!arg) {
2724 do_warning_event(event, "%s: not enough memory!", __func__);
2725 *tok = NULL;
2726 return TEP_EVENT_ERROR;
2727 }
2728
2729 type = process_arg(event, arg, &token);
2730 if (type == TEP_EVENT_ERROR)
2731 goto out_free_arg;
2732
2733 if (!test_type_token(type, token, TEP_EVENT_OP, "]"))
2734 goto out_free_arg;
2735
2736 free_token(token);
2737 type = read_token_item(tok);
2738 return type;
2739
2740 out_free_arg:
2741 free_arg(arg);
2742 out_free:
2743 free_token(token);
2744 *tok = NULL;
2745 return TEP_EVENT_ERROR;
2746}
2747
2748static enum tep_event_type
2749process_dynamic_array_len(struct tep_event_format *event, struct tep_print_arg *arg,
2750 char **tok)
2751{
2752 struct tep_format_field *field;
2753 enum tep_event_type type;
2754 char *token;
2755
2756 if (read_expect_type(TEP_EVENT_ITEM, &token) < 0)
2757 goto out_free;
2758
2759 arg->type = TEP_PRINT_DYNAMIC_ARRAY_LEN;
2760
2761 /* Find the field */
2762 field = tep_find_field(event, token);
2763 if (!field)
2764 goto out_free;
2765
2766 arg->dynarray.field = field;
2767 arg->dynarray.index = 0;
2768
2769 if (read_expected(TEP_EVENT_DELIM, ")") < 0)
2770 goto out_err;
2771
2772 type = read_token(&token);
2773 *tok = token;
2774
2775 return type;
2776
2777 out_free:
2778 free_token(token);
2779 out_err:
2780 *tok = NULL;
2781 return TEP_EVENT_ERROR;
2782}
2783
2784static enum tep_event_type
2785process_paren(struct tep_event_format *event, struct tep_print_arg *arg, char **tok)
2786{
2787 struct tep_print_arg *item_arg;
2788 enum tep_event_type type;
2789 char *token;
2790
2791 type = process_arg(event, arg, &token);
2792
2793 if (type == TEP_EVENT_ERROR)
2794 goto out_free;
2795
2796 if (type == TEP_EVENT_OP)
2797 type = process_op(event, arg, &token);
2798
2799 if (type == TEP_EVENT_ERROR)
2800 goto out_free;
2801
2802 if (test_type_token(type, token, TEP_EVENT_DELIM, ")"))
2803 goto out_free;
2804
2805 free_token(token);
2806 type = read_token_item(&token);
2807
2808 /*
2809 * If the next token is an item or another open paren, then
2810 * this was a typecast.
2811 */
2812 if (event_item_type(type) ||
2813 (type == TEP_EVENT_DELIM && strcmp(token, "(") == 0)) {
2814
2815 /* make this a typecast and contine */
2816
2817 /* prevous must be an atom */
2818 if (arg->type != TEP_PRINT_ATOM) {
2819 do_warning_event(event, "previous needed to be TEP_PRINT_ATOM");
2820 goto out_free;
2821 }
2822
2823 item_arg = alloc_arg();
2824 if (!item_arg) {
2825 do_warning_event(event, "%s: not enough memory!",
2826 __func__);
2827 goto out_free;
2828 }
2829
2830 arg->type = TEP_PRINT_TYPE;
2831 arg->typecast.type = arg->atom.atom;
2832 arg->typecast.item = item_arg;
2833 type = process_arg_token(event, item_arg, &token, type);
2834
2835 }
2836
2837 *tok = token;
2838 return type;
2839
2840 out_free:
2841 free_token(token);
2842 *tok = NULL;
2843 return TEP_EVENT_ERROR;
2844}
2845
2846
2847static enum tep_event_type
2848process_str(struct tep_event_format *event __maybe_unused, struct tep_print_arg *arg,
2849 char **tok)
2850{
2851 enum tep_event_type type;
2852 char *token;
2853
2854 if (read_expect_type(TEP_EVENT_ITEM, &token) < 0)
2855 goto out_free;
2856
2857 arg->type = TEP_PRINT_STRING;
2858 arg->string.string = token;
2859 arg->string.offset = -1;
2860
2861 if (read_expected(TEP_EVENT_DELIM, ")") < 0)
2862 goto out_err;
2863
2864 type = read_token(&token);
2865 *tok = token;
2866
2867 return type;
2868
2869 out_free:
2870 free_token(token);
2871 out_err:
2872 *tok = NULL;
2873 return TEP_EVENT_ERROR;
2874}
2875
2876static enum tep_event_type
2877process_bitmask(struct tep_event_format *event __maybe_unused, struct tep_print_arg *arg,
2878 char **tok)
2879{
2880 enum tep_event_type type;
2881 char *token;
2882
2883 if (read_expect_type(TEP_EVENT_ITEM, &token) < 0)
2884 goto out_free;
2885
2886 arg->type = TEP_PRINT_BITMASK;
2887 arg->bitmask.bitmask = token;
2888 arg->bitmask.offset = -1;
2889
2890 if (read_expected(TEP_EVENT_DELIM, ")") < 0)
2891 goto out_err;
2892
2893 type = read_token(&token);
2894 *tok = token;
2895
2896 return type;
2897
2898 out_free:
2899 free_token(token);
2900 out_err:
2901 *tok = NULL;
2902 return TEP_EVENT_ERROR;
2903}
2904
2905static struct tep_function_handler *
2906find_func_handler(struct tep_handle *pevent, char *func_name)
2907{
2908 struct tep_function_handler *func;
2909
2910 if (!pevent)
2911 return NULL;
2912
2913 for (func = pevent->func_handlers; func; func = func->next) {
2914 if (strcmp(func->name, func_name) == 0)
2915 break;
2916 }
2917
2918 return func;
2919}
2920
2921static void remove_func_handler(struct tep_handle *pevent, char *func_name)
2922{
2923 struct tep_function_handler *func;
2924 struct tep_function_handler **next;
2925
2926 next = &pevent->func_handlers;
2927 while ((func = *next)) {
2928 if (strcmp(func->name, func_name) == 0) {
2929 *next = func->next;
2930 free_func_handle(func);
2931 break;
2932 }
2933 next = &func->next;
2934 }
2935}
2936
2937static enum tep_event_type
2938process_func_handler(struct tep_event_format *event, struct tep_function_handler *func,
2939 struct tep_print_arg *arg, char **tok)
2940{
2941 struct tep_print_arg **next_arg;
2942 struct tep_print_arg *farg;
2943 enum tep_event_type type;
2944 char *token;
2945 int i;
2946
2947 arg->type = TEP_PRINT_FUNC;
2948 arg->func.func = func;
2949
2950 *tok = NULL;
2951
2952 next_arg = &(arg->func.args);
2953 for (i = 0; i < func->nr_args; i++) {
2954 farg = alloc_arg();
2955 if (!farg) {
2956 do_warning_event(event, "%s: not enough memory!",
2957 __func__);
2958 return TEP_EVENT_ERROR;
2959 }
2960
2961 type = process_arg(event, farg, &token);
2962 if (i < (func->nr_args - 1)) {
2963 if (type != TEP_EVENT_DELIM || strcmp(token, ",") != 0) {
2964 do_warning_event(event,
2965 "Error: function '%s()' expects %d arguments but event %s only uses %d",
2966 func->name, func->nr_args,
2967 event->name, i + 1);
2968 goto err;
2969 }
2970 } else {
2971 if (type != TEP_EVENT_DELIM || strcmp(token, ")") != 0) {
2972 do_warning_event(event,
2973 "Error: function '%s()' only expects %d arguments but event %s has more",
2974 func->name, func->nr_args, event->name);
2975 goto err;
2976 }
2977 }
2978
2979 *next_arg = farg;
2980 next_arg = &(farg->next);
2981 free_token(token);
2982 }
2983
2984 type = read_token(&token);
2985 *tok = token;
2986
2987 return type;
2988
2989err:
2990 free_arg(farg);
2991 free_token(token);
2992 return TEP_EVENT_ERROR;
2993}
2994
2995static enum tep_event_type
2996process_function(struct tep_event_format *event, struct tep_print_arg *arg,
2997 char *token, char **tok)
2998{
2999 struct tep_function_handler *func;
3000
3001 if (strcmp(token, "__print_flags") == 0) {
3002 free_token(token);
3003 is_flag_field = 1;
3004 return process_flags(event, arg, tok);
3005 }
3006 if (strcmp(token, "__print_symbolic") == 0) {
3007 free_token(token);
3008 is_symbolic_field = 1;
3009 return process_symbols(event, arg, tok);
3010 }
3011 if (strcmp(token, "__print_hex") == 0) {
3012 free_token(token);
3013 return process_hex(event, arg, tok);
3014 }
3015 if (strcmp(token, "__print_hex_str") == 0) {
3016 free_token(token);
3017 return process_hex_str(event, arg, tok);
3018 }
3019 if (strcmp(token, "__print_array") == 0) {
3020 free_token(token);
3021 return process_int_array(event, arg, tok);
3022 }
3023 if (strcmp(token, "__get_str") == 0) {
3024 free_token(token);
3025 return process_str(event, arg, tok);
3026 }
3027 if (strcmp(token, "__get_bitmask") == 0) {
3028 free_token(token);
3029 return process_bitmask(event, arg, tok);
3030 }
3031 if (strcmp(token, "__get_dynamic_array") == 0) {
3032 free_token(token);
3033 return process_dynamic_array(event, arg, tok);
3034 }
3035 if (strcmp(token, "__get_dynamic_array_len") == 0) {
3036 free_token(token);
3037 return process_dynamic_array_len(event, arg, tok);
3038 }
3039
3040 func = find_func_handler(event->pevent, token);
3041 if (func) {
3042 free_token(token);
3043 return process_func_handler(event, func, arg, tok);
3044 }
3045
3046 do_warning_event(event, "function %s not defined", token);
3047 free_token(token);
3048 return TEP_EVENT_ERROR;
3049}
3050
3051static enum tep_event_type
3052process_arg_token(struct tep_event_format *event, struct tep_print_arg *arg,
3053 char **tok, enum tep_event_type type)
3054{
3055 char *token;
3056 char *atom;
3057
3058 token = *tok;
3059
3060 switch (type) {
3061 case TEP_EVENT_ITEM:
3062 if (strcmp(token, "REC") == 0) {
3063 free_token(token);
3064 type = process_entry(event, arg, &token);
3065 break;
3066 }
3067 atom = token;
3068 /* test the next token */
3069 type = read_token_item(&token);
3070
3071 /*
3072 * If the next token is a parenthesis, then this
3073 * is a function.
3074 */
3075 if (type == TEP_EVENT_DELIM && strcmp(token, "(") == 0) {
3076 free_token(token);
3077 token = NULL;
3078 /* this will free atom. */
3079 type = process_function(event, arg, atom, &token);
3080 break;
3081 }
3082 /* atoms can be more than one token long */
3083 while (type == TEP_EVENT_ITEM) {
3084 char *new_atom;
3085 new_atom = realloc(atom,
3086 strlen(atom) + strlen(token) + 2);
3087 if (!new_atom) {
3088 free(atom);
3089 *tok = NULL;
3090 free_token(token);
3091 return TEP_EVENT_ERROR;
3092 }
3093 atom = new_atom;
3094 strcat(atom, " ");
3095 strcat(atom, token);
3096 free_token(token);
3097 type = read_token_item(&token);
3098 }
3099
3100 arg->type = TEP_PRINT_ATOM;
3101 arg->atom.atom = atom;
3102 break;
3103
3104 case TEP_EVENT_DQUOTE:
3105 case TEP_EVENT_SQUOTE:
3106 arg->type = TEP_PRINT_ATOM;
3107 arg->atom.atom = token;
3108 type = read_token_item(&token);
3109 break;
3110 case TEP_EVENT_DELIM:
3111 if (strcmp(token, "(") == 0) {
3112 free_token(token);
3113 type = process_paren(event, arg, &token);
3114 break;
3115 }
3116 case TEP_EVENT_OP:
3117 /* handle single ops */
3118 arg->type = TEP_PRINT_OP;
3119 arg->op.op = token;
3120 arg->op.left = NULL;
3121 type = process_op(event, arg, &token);
3122
3123 /* On error, the op is freed */
3124 if (type == TEP_EVENT_ERROR)
3125 arg->op.op = NULL;
3126
3127 /* return error type if errored */
3128 break;
3129
3130 case TEP_EVENT_ERROR ... TEP_EVENT_NEWLINE:
3131 default:
3132 do_warning_event(event, "unexpected type %d", type);
3133 return TEP_EVENT_ERROR;
3134 }
3135 *tok = token;
3136
3137 return type;
3138}
3139
3140static int event_read_print_args(struct tep_event_format *event, struct tep_print_arg **list)
3141{
3142 enum tep_event_type type = TEP_EVENT_ERROR;
3143 struct tep_print_arg *arg;
3144 char *token;
3145 int args = 0;
3146
3147 do {
3148 if (type == TEP_EVENT_NEWLINE) {
3149 type = read_token_item(&token);
3150 continue;
3151 }
3152
3153 arg = alloc_arg();
3154 if (!arg) {
3155 do_warning_event(event, "%s: not enough memory!",
3156 __func__);
3157 return -1;
3158 }
3159
3160 type = process_arg(event, arg, &token);
3161
3162 if (type == TEP_EVENT_ERROR) {
3163 free_token(token);
3164 free_arg(arg);
3165 return -1;
3166 }
3167
3168 *list = arg;
3169 args++;
3170
3171 if (type == TEP_EVENT_OP) {
3172 type = process_op(event, arg, &token);
3173 free_token(token);
3174 if (type == TEP_EVENT_ERROR) {
3175 *list = NULL;
3176 free_arg(arg);
3177 return -1;
3178 }
3179 list = &arg->next;
3180 continue;
3181 }
3182
3183 if (type == TEP_EVENT_DELIM && strcmp(token, ",") == 0) {
3184 free_token(token);
3185 *list = arg;
3186 list = &arg->next;
3187 continue;
3188 }
3189 break;
3190 } while (type != TEP_EVENT_NONE);
3191
3192 if (type != TEP_EVENT_NONE && type != TEP_EVENT_ERROR)
3193 free_token(token);
3194
3195 return args;
3196}
3197
3198static int event_read_print(struct tep_event_format *event)
3199{
3200 enum tep_event_type type;
3201 char *token;
3202 int ret;
3203
3204 if (read_expected_item(TEP_EVENT_ITEM, "print") < 0)
3205 return -1;
3206
3207 if (read_expected(TEP_EVENT_ITEM, "fmt") < 0)
3208 return -1;
3209
3210 if (read_expected(TEP_EVENT_OP, ":") < 0)
3211 return -1;
3212
3213 if (read_expect_type(TEP_EVENT_DQUOTE, &token) < 0)
3214 goto fail;
3215
3216 concat:
3217 event->print_fmt.format = token;
3218 event->print_fmt.args = NULL;
3219
3220 /* ok to have no arg */
3221 type = read_token_item(&token);
3222
3223 if (type == TEP_EVENT_NONE)
3224 return 0;
3225
3226 /* Handle concatenation of print lines */
3227 if (type == TEP_EVENT_DQUOTE) {
3228 char *cat;
3229
3230 if (asprintf(&cat, "%s%s", event->print_fmt.format, token) < 0)
3231 goto fail;
3232 free_token(token);
3233 free_token(event->print_fmt.format);
3234 event->print_fmt.format = NULL;
3235 token = cat;
3236 goto concat;
3237 }
3238
3239 if (test_type_token(type, token, TEP_EVENT_DELIM, ","))
3240 goto fail;
3241
3242 free_token(token);
3243
3244 ret = event_read_print_args(event, &event->print_fmt.args);
3245 if (ret < 0)
3246 return -1;
3247
3248 return ret;
3249
3250 fail:
3251 free_token(token);
3252 return -1;
3253}
3254
3255/**
3256 * tep_find_common_field - return a common field by event
3257 * @event: handle for the event
3258 * @name: the name of the common field to return
3259 *
3260 * Returns a common field from the event by the given @name.
3261 * This only searchs the common fields and not all field.
3262 */
3263struct tep_format_field *
3264tep_find_common_field(struct tep_event_format *event, const char *name)
3265{
3266 struct tep_format_field *format;
3267
3268 for (format = event->format.common_fields;
3269 format; format = format->next) {
3270 if (strcmp(format->name, name) == 0)
3271 break;
3272 }
3273
3274 return format;
3275}
3276
3277/**
3278 * tep_find_field - find a non-common field
3279 * @event: handle for the event
3280 * @name: the name of the non-common field
3281 *
3282 * Returns a non-common field by the given @name.
3283 * This does not search common fields.
3284 */
3285struct tep_format_field *
3286tep_find_field(struct tep_event_format *event, const char *name)
3287{
3288 struct tep_format_field *format;
3289
3290 for (format = event->format.fields;
3291 format; format = format->next) {
3292 if (strcmp(format->name, name) == 0)
3293 break;
3294 }
3295
3296 return format;
3297}
3298
3299/**
3300 * tep_find_any_field - find any field by name
3301 * @event: handle for the event
3302 * @name: the name of the field
3303 *
3304 * Returns a field by the given @name.
3305 * This searchs the common field names first, then
3306 * the non-common ones if a common one was not found.
3307 */
3308struct tep_format_field *
3309tep_find_any_field(struct tep_event_format *event, const char *name)
3310{
3311 struct tep_format_field *format;
3312
3313 format = tep_find_common_field(event, name);
3314 if (format)
3315 return format;
3316 return tep_find_field(event, name);
3317}
3318
3319/**
3320 * tep_read_number - read a number from data
3321 * @pevent: handle for the pevent
3322 * @ptr: the raw data
3323 * @size: the size of the data that holds the number
3324 *
3325 * Returns the number (converted to host) from the
3326 * raw data.
3327 */
3328unsigned long long tep_read_number(struct tep_handle *pevent,
3329 const void *ptr, int size)
3330{
3331 switch (size) {
3332 case 1:
3333 return *(unsigned char *)ptr;
3334 case 2:
3335 return tep_data2host2(pevent, ptr);
3336 case 4:
3337 return tep_data2host4(pevent, ptr);
3338 case 8:
3339 return tep_data2host8(pevent, ptr);
3340 default:
3341 /* BUG! */
3342 return 0;
3343 }
3344}
3345
3346/**
3347 * tep_read_number_field - read a number from data
3348 * @field: a handle to the field
3349 * @data: the raw data to read
3350 * @value: the value to place the number in
3351 *
3352 * Reads raw data according to a field offset and size,
3353 * and translates it into @value.
3354 *
3355 * Returns 0 on success, -1 otherwise.
3356 */
3357int tep_read_number_field(struct tep_format_field *field, const void *data,
3358 unsigned long long *value)
3359{
3360 if (!field)
3361 return -1;
3362 switch (field->size) {
3363 case 1:
3364 case 2:
3365 case 4:
3366 case 8:
3367 *value = tep_read_number(field->event->pevent,
3368 data + field->offset, field->size);
3369 return 0;
3370 default:
3371 return -1;
3372 }
3373}
3374
3375static int get_common_info(struct tep_handle *pevent,
3376 const char *type, int *offset, int *size)
3377{
3378 struct tep_event_format *event;
3379 struct tep_format_field *field;
3380
3381 /*
3382 * All events should have the same common elements.
3383 * Pick any event to find where the type is;
3384 */
3385 if (!pevent->events) {
3386 do_warning("no event_list!");
3387 return -1;
3388 }
3389
3390 event = pevent->events[0];
3391 field = tep_find_common_field(event, type);
3392 if (!field)
3393 return -1;
3394
3395 *offset = field->offset;
3396 *size = field->size;
3397
3398 return 0;
3399}
3400
3401static int __parse_common(struct tep_handle *pevent, void *data,
3402 int *size, int *offset, const char *name)
3403{
3404 int ret;
3405
3406 if (!*size) {
3407 ret = get_common_info(pevent, name, offset, size);
3408 if (ret < 0)
3409 return ret;
3410 }
3411 return tep_read_number(pevent, data + *offset, *size);
3412}
3413
3414static int trace_parse_common_type(struct tep_handle *pevent, void *data)
3415{
3416 return __parse_common(pevent, data,
3417 &pevent->type_size, &pevent->type_offset,
3418 "common_type");
3419}
3420
3421static int parse_common_pid(struct tep_handle *pevent, void *data)
3422{
3423 return __parse_common(pevent, data,
3424 &pevent->pid_size, &pevent->pid_offset,
3425 "common_pid");
3426}
3427
3428static int parse_common_pc(struct tep_handle *pevent, void *data)
3429{
3430 return __parse_common(pevent, data,
3431 &pevent->pc_size, &pevent->pc_offset,
3432 "common_preempt_count");
3433}
3434
3435static int parse_common_flags(struct tep_handle *pevent, void *data)
3436{
3437 return __parse_common(pevent, data,
3438 &pevent->flags_size, &pevent->flags_offset,
3439 "common_flags");
3440}
3441
3442static int parse_common_lock_depth(struct tep_handle *pevent, void *data)
3443{
3444 return __parse_common(pevent, data,
3445 &pevent->ld_size, &pevent->ld_offset,
3446 "common_lock_depth");
3447}
3448
3449static int parse_common_migrate_disable(struct tep_handle *pevent, void *data)
3450{
3451 return __parse_common(pevent, data,
3452 &pevent->ld_size, &pevent->ld_offset,
3453 "common_migrate_disable");
3454}
3455
3456static int events_id_cmp(const void *a, const void *b);
3457
3458/**
3459 * tep_find_event - find an event by given id
3460 * @pevent: a handle to the pevent
3461 * @id: the id of the event
3462 *
3463 * Returns an event that has a given @id.
3464 */
3465struct tep_event_format *tep_find_event(struct tep_handle *pevent, int id)
3466{
3467 struct tep_event_format **eventptr;
3468 struct tep_event_format key;
3469 struct tep_event_format *pkey = &key;
3470
3471 /* Check cache first */
3472 if (pevent->last_event && pevent->last_event->id == id)
3473 return pevent->last_event;
3474
3475 key.id = id;
3476
3477 eventptr = bsearch(&pkey, pevent->events, pevent->nr_events,
3478 sizeof(*pevent->events), events_id_cmp);
3479
3480 if (eventptr) {
3481 pevent->last_event = *eventptr;
3482 return *eventptr;
3483 }
3484
3485 return NULL;
3486}
3487
3488/**
3489 * tep_find_event_by_name - find an event by given name
3490 * @pevent: a handle to the pevent
3491 * @sys: the system name to search for
3492 * @name: the name of the event to search for
3493 *
3494 * This returns an event with a given @name and under the system
3495 * @sys. If @sys is NULL the first event with @name is returned.
3496 */
3497struct tep_event_format *
3498tep_find_event_by_name(struct tep_handle *pevent,
3499 const char *sys, const char *name)
3500{
3501 struct tep_event_format *event;
3502 int i;
3503
3504 if (pevent->last_event &&
3505 strcmp(pevent->last_event->name, name) == 0 &&
3506 (!sys || strcmp(pevent->last_event->system, sys) == 0))
3507 return pevent->last_event;
3508
3509 for (i = 0; i < pevent->nr_events; i++) {
3510 event = pevent->events[i];
3511 if (strcmp(event->name, name) == 0) {
3512 if (!sys)
3513 break;
3514 if (strcmp(event->system, sys) == 0)
3515 break;
3516 }
3517 }
3518 if (i == pevent->nr_events)
3519 event = NULL;
3520
3521 pevent->last_event = event;
3522 return event;
3523}
3524
3525static unsigned long long
3526eval_num_arg(void *data, int size, struct tep_event_format *event, struct tep_print_arg *arg)
3527{
3528 struct tep_handle *pevent = event->pevent;
3529 unsigned long long val = 0;
3530 unsigned long long left, right;
3531 struct tep_print_arg *typearg = NULL;
3532 struct tep_print_arg *larg;
3533 unsigned long offset;
3534 unsigned int field_size;
3535
3536 switch (arg->type) {
3537 case TEP_PRINT_NULL:
3538 /* ?? */
3539 return 0;
3540 case TEP_PRINT_ATOM:
3541 return strtoull(arg->atom.atom, NULL, 0);
3542 case TEP_PRINT_FIELD:
3543 if (!arg->field.field) {
3544 arg->field.field = tep_find_any_field(event, arg->field.name);
3545 if (!arg->field.field)
3546 goto out_warning_field;
3547
3548 }
3549 /* must be a number */
3550 val = tep_read_number(pevent, data + arg->field.field->offset,
3551 arg->field.field->size);
3552 break;
3553 case TEP_PRINT_FLAGS:
3554 case TEP_PRINT_SYMBOL:
3555 case TEP_PRINT_INT_ARRAY:
3556 case TEP_PRINT_HEX:
3557 case TEP_PRINT_HEX_STR:
3558 break;
3559 case TEP_PRINT_TYPE:
3560 val = eval_num_arg(data, size, event, arg->typecast.item);
3561 return eval_type(val, arg, 0);
3562 case TEP_PRINT_STRING:
3563 case TEP_PRINT_BSTRING:
3564 case TEP_PRINT_BITMASK:
3565 return 0;
3566 case TEP_PRINT_FUNC: {
3567 struct trace_seq s;
3568 trace_seq_init(&s);
3569 val = process_defined_func(&s, data, size, event, arg);
3570 trace_seq_destroy(&s);
3571 return val;
3572 }
3573 case TEP_PRINT_OP:
3574 if (strcmp(arg->op.op, "[") == 0) {
3575 /*
3576 * Arrays are special, since we don't want
3577 * to read the arg as is.
3578 */
3579 right = eval_num_arg(data, size, event, arg->op.right);
3580
3581 /* handle typecasts */
3582 larg = arg->op.left;
3583 while (larg->type == TEP_PRINT_TYPE) {
3584 if (!typearg)
3585 typearg = larg;
3586 larg = larg->typecast.item;
3587 }
3588
3589 /* Default to long size */
3590 field_size = pevent->long_size;
3591
3592 switch (larg->type) {
3593 case TEP_PRINT_DYNAMIC_ARRAY:
3594 offset = tep_read_number(pevent,
3595 data + larg->dynarray.field->offset,
3596 larg->dynarray.field->size);
3597 if (larg->dynarray.field->elementsize)
3598 field_size = larg->dynarray.field->elementsize;
3599 /*
3600 * The actual length of the dynamic array is stored
3601 * in the top half of the field, and the offset
3602 * is in the bottom half of the 32 bit field.
3603 */
3604 offset &= 0xffff;
3605 offset += right;
3606 break;
3607 case TEP_PRINT_FIELD:
3608 if (!larg->field.field) {
3609 larg->field.field =
3610 tep_find_any_field(event, larg->field.name);
3611 if (!larg->field.field) {
3612 arg = larg;
3613 goto out_warning_field;
3614 }
3615 }
3616 field_size = larg->field.field->elementsize;
3617 offset = larg->field.field->offset +
3618 right * larg->field.field->elementsize;
3619 break;
3620 default:
3621 goto default_op; /* oops, all bets off */
3622 }
3623 val = tep_read_number(pevent,
3624 data + offset, field_size);
3625 if (typearg)
3626 val = eval_type(val, typearg, 1);
3627 break;
3628 } else if (strcmp(arg->op.op, "?") == 0) {
3629 left = eval_num_arg(data, size, event, arg->op.left);
3630 arg = arg->op.right;
3631 if (left)
3632 val = eval_num_arg(data, size, event, arg->op.left);
3633 else
3634 val = eval_num_arg(data, size, event, arg->op.right);
3635 break;
3636 }
3637 default_op:
3638 left = eval_num_arg(data, size, event, arg->op.left);
3639 right = eval_num_arg(data, size, event, arg->op.right);
3640 switch (arg->op.op[0]) {
3641 case '!':
3642 switch (arg->op.op[1]) {
3643 case 0:
3644 val = !right;
3645 break;
3646 case '=':
3647 val = left != right;
3648 break;
3649 default:
3650 goto out_warning_op;
3651 }
3652 break;
3653 case '~':
3654 val = ~right;
3655 break;
3656 case '|':
3657 if (arg->op.op[1])
3658 val = left || right;
3659 else
3660 val = left | right;
3661 break;
3662 case '&':
3663 if (arg->op.op[1])
3664 val = left && right;
3665 else
3666 val = left & right;
3667 break;
3668 case '<':
3669 switch (arg->op.op[1]) {
3670 case 0:
3671 val = left < right;
3672 break;
3673 case '<':
3674 val = left << right;
3675 break;
3676 case '=':
3677 val = left <= right;
3678 break;
3679 default:
3680 goto out_warning_op;
3681 }
3682 break;
3683 case '>':
3684 switch (arg->op.op[1]) {
3685 case 0:
3686 val = left > right;
3687 break;
3688 case '>':
3689 val = left >> right;
3690 break;
3691 case '=':
3692 val = left >= right;
3693 break;
3694 default:
3695 goto out_warning_op;
3696 }
3697 break;
3698 case '=':
3699 if (arg->op.op[1] != '=')
3700 goto out_warning_op;
3701
3702 val = left == right;
3703 break;
3704 case '-':
3705 val = left - right;
3706 break;
3707 case '+':
3708 val = left + right;
3709 break;
3710 case '/':
3711 val = left / right;
3712 break;
3713 case '%':
3714 val = left % right;
3715 break;
3716 case '*':
3717 val = left * right;
3718 break;
3719 default:
3720 goto out_warning_op;
3721 }
3722 break;
3723 case TEP_PRINT_DYNAMIC_ARRAY_LEN:
3724 offset = tep_read_number(pevent,
3725 data + arg->dynarray.field->offset,
3726 arg->dynarray.field->size);
3727 /*
3728 * The total allocated length of the dynamic array is
3729 * stored in the top half of the field, and the offset
3730 * is in the bottom half of the 32 bit field.
3731 */
3732 val = (unsigned long long)(offset >> 16);
3733 break;
3734 case TEP_PRINT_DYNAMIC_ARRAY:
3735 /* Without [], we pass the address to the dynamic data */
3736 offset = tep_read_number(pevent,
3737 data + arg->dynarray.field->offset,
3738 arg->dynarray.field->size);
3739 /*
3740 * The total allocated length of the dynamic array is
3741 * stored in the top half of the field, and the offset
3742 * is in the bottom half of the 32 bit field.
3743 */
3744 offset &= 0xffff;
3745 val = (unsigned long long)((unsigned long)data + offset);
3746 break;
3747 default: /* not sure what to do there */
3748 return 0;
3749 }
3750 return val;
3751
3752out_warning_op:
3753 do_warning_event(event, "%s: unknown op '%s'", __func__, arg->op.op);
3754 return 0;
3755
3756out_warning_field:
3757 do_warning_event(event, "%s: field %s not found",
3758 __func__, arg->field.name);
3759 return 0;
3760}
3761
3762struct flag {
3763 const char *name;
3764 unsigned long long value;
3765};
3766
3767static const struct flag flags[] = {
3768 { "HI_SOFTIRQ", 0 },
3769 { "TIMER_SOFTIRQ", 1 },
3770 { "NET_TX_SOFTIRQ", 2 },
3771 { "NET_RX_SOFTIRQ", 3 },
3772 { "BLOCK_SOFTIRQ", 4 },
3773 { "IRQ_POLL_SOFTIRQ", 5 },
3774 { "TASKLET_SOFTIRQ", 6 },
3775 { "SCHED_SOFTIRQ", 7 },
3776 { "HRTIMER_SOFTIRQ", 8 },
3777 { "RCU_SOFTIRQ", 9 },
3778
3779 { "HRTIMER_NORESTART", 0 },
3780 { "HRTIMER_RESTART", 1 },
3781};
3782
3783static long long eval_flag(const char *flag)
3784{
3785 int i;
3786
3787 /*
3788 * Some flags in the format files do not get converted.
3789 * If the flag is not numeric, see if it is something that
3790 * we already know about.
3791 */
3792 if (isdigit(flag[0]))
3793 return strtoull(flag, NULL, 0);
3794
3795 for (i = 0; i < (int)(sizeof(flags)/sizeof(flags[0])); i++)
3796 if (strcmp(flags[i].name, flag) == 0)
3797 return flags[i].value;
3798
3799 return -1LL;
3800}
3801
3802static void print_str_to_seq(struct trace_seq *s, const char *format,
3803 int len_arg, const char *str)
3804{
3805 if (len_arg >= 0)
3806 trace_seq_printf(s, format, len_arg, str);
3807 else
3808 trace_seq_printf(s, format, str);
3809}
3810
3811static void print_bitmask_to_seq(struct tep_handle *pevent,
3812 struct trace_seq *s, const char *format,
3813 int len_arg, const void *data, int size)
3814{
3815 int nr_bits = size * 8;
3816 int str_size = (nr_bits + 3) / 4;
3817 int len = 0;
3818 char buf[3];
3819 char *str;
3820 int index;
3821 int i;
3822
3823 /*
3824 * The kernel likes to put in commas every 32 bits, we
3825 * can do the same.
3826 */
3827 str_size += (nr_bits - 1) / 32;
3828
3829 str = malloc(str_size + 1);
3830 if (!str) {
3831 do_warning("%s: not enough memory!", __func__);
3832 return;
3833 }
3834 str[str_size] = 0;
3835
3836 /* Start out with -2 for the two chars per byte */
3837 for (i = str_size - 2; i >= 0; i -= 2) {
3838 /*
3839 * data points to a bit mask of size bytes.
3840 * In the kernel, this is an array of long words, thus
3841 * endianess is very important.
3842 */
3843 if (pevent->file_bigendian)
3844 index = size - (len + 1);
3845 else
3846 index = len;
3847
3848 snprintf(buf, 3, "%02x", *((unsigned char *)data + index));
3849 memcpy(str + i, buf, 2);
3850 len++;
3851 if (!(len & 3) && i > 0) {
3852 i--;
3853 str[i] = ',';
3854 }
3855 }
3856
3857 if (len_arg >= 0)
3858 trace_seq_printf(s, format, len_arg, str);
3859 else
3860 trace_seq_printf(s, format, str);
3861
3862 free(str);
3863}
3864
3865static void print_str_arg(struct trace_seq *s, void *data, int size,
3866 struct tep_event_format *event, const char *format,
3867 int len_arg, struct tep_print_arg *arg)
3868{
3869 struct tep_handle *pevent = event->pevent;
3870 struct tep_print_flag_sym *flag;
3871 struct tep_format_field *field;
3872 struct printk_map *printk;
3873 long long val, fval;
3874 unsigned long long addr;
3875 char *str;
3876 unsigned char *hex;
3877 int print;
3878 int i, len;
3879
3880 switch (arg->type) {
3881 case TEP_PRINT_NULL:
3882 /* ?? */
3883 return;
3884 case TEP_PRINT_ATOM:
3885 print_str_to_seq(s, format, len_arg, arg->atom.atom);
3886 return;
3887 case TEP_PRINT_FIELD:
3888 field = arg->field.field;
3889 if (!field) {
3890 field = tep_find_any_field(event, arg->field.name);
3891 if (!field) {
3892 str = arg->field.name;
3893 goto out_warning_field;
3894 }
3895 arg->field.field = field;
3896 }
3897 /* Zero sized fields, mean the rest of the data */
3898 len = field->size ? : size - field->offset;
3899
3900 /*
3901 * Some events pass in pointers. If this is not an array
3902 * and the size is the same as long_size, assume that it
3903 * is a pointer.
3904 */
3905 if (!(field->flags & TEP_FIELD_IS_ARRAY) &&
3906 field->size == pevent->long_size) {
3907
3908 /* Handle heterogeneous recording and processing
3909 * architectures
3910 *
3911 * CASE I:
3912 * Traces recorded on 32-bit devices (32-bit
3913 * addressing) and processed on 64-bit devices:
3914 * In this case, only 32 bits should be read.
3915 *
3916 * CASE II:
3917 * Traces recorded on 64 bit devices and processed
3918 * on 32-bit devices:
3919 * In this case, 64 bits must be read.
3920 */
3921 addr = (pevent->long_size == 8) ?
3922 *(unsigned long long *)(data + field->offset) :
3923 (unsigned long long)*(unsigned int *)(data + field->offset);
3924
3925 /* Check if it matches a print format */
3926 printk = find_printk(pevent, addr);
3927 if (printk)
3928 trace_seq_puts(s, printk->printk);
3929 else
3930 trace_seq_printf(s, "%llx", addr);
3931 break;
3932 }
3933 str = malloc(len + 1);
3934 if (!str) {
3935 do_warning_event(event, "%s: not enough memory!",
3936 __func__);
3937 return;
3938 }
3939 memcpy(str, data + field->offset, len);
3940 str[len] = 0;
3941 print_str_to_seq(s, format, len_arg, str);
3942 free(str);
3943 break;
3944 case TEP_PRINT_FLAGS:
3945 val = eval_num_arg(data, size, event, arg->flags.field);
3946 print = 0;
3947 for (flag = arg->flags.flags; flag; flag = flag->next) {
3948 fval = eval_flag(flag->value);
3949 if (!val && fval < 0) {
3950 print_str_to_seq(s, format, len_arg, flag->str);
3951 break;
3952 }
3953 if (fval > 0 && (val & fval) == fval) {
3954 if (print && arg->flags.delim)
3955 trace_seq_puts(s, arg->flags.delim);
3956 print_str_to_seq(s, format, len_arg, flag->str);
3957 print = 1;
3958 val &= ~fval;
3959 }
3960 }
3961 if (val) {
3962 if (print && arg->flags.delim)
3963 trace_seq_puts(s, arg->flags.delim);
3964 trace_seq_printf(s, "0x%llx", val);
3965 }
3966 break;
3967 case TEP_PRINT_SYMBOL:
3968 val = eval_num_arg(data, size, event, arg->symbol.field);
3969 for (flag = arg->symbol.symbols; flag; flag = flag->next) {
3970 fval = eval_flag(flag->value);
3971 if (val == fval) {
3972 print_str_to_seq(s, format, len_arg, flag->str);
3973 break;
3974 }
3975 }
3976 if (!flag)
3977 trace_seq_printf(s, "0x%llx", val);
3978 break;
3979 case TEP_PRINT_HEX:
3980 case TEP_PRINT_HEX_STR:
3981 if (arg->hex.field->type == TEP_PRINT_DYNAMIC_ARRAY) {
3982 unsigned long offset;
3983 offset = tep_read_number(pevent,
3984 data + arg->hex.field->dynarray.field->offset,
3985 arg->hex.field->dynarray.field->size);
3986 hex = data + (offset & 0xffff);
3987 } else {
3988 field = arg->hex.field->field.field;
3989 if (!field) {
3990 str = arg->hex.field->field.name;
3991 field = tep_find_any_field(event, str);
3992 if (!field)
3993 goto out_warning_field;
3994 arg->hex.field->field.field = field;
3995 }
3996 hex = data + field->offset;
3997 }
3998 len = eval_num_arg(data, size, event, arg->hex.size);
3999 for (i = 0; i < len; i++) {
4000 if (i && arg->type == TEP_PRINT_HEX)
4001 trace_seq_putc(s, ' ');
4002 trace_seq_printf(s, "%02x", hex[i]);
4003 }
4004 break;
4005
4006 case TEP_PRINT_INT_ARRAY: {
4007 void *num;
4008 int el_size;
4009
4010 if (arg->int_array.field->type == TEP_PRINT_DYNAMIC_ARRAY) {
4011 unsigned long offset;
4012 struct tep_format_field *field =
4013 arg->int_array.field->dynarray.field;
4014 offset = tep_read_number(pevent,
4015 data + field->offset,
4016 field->size);
4017 num = data + (offset & 0xffff);
4018 } else {
4019 field = arg->int_array.field->field.field;
4020 if (!field) {
4021 str = arg->int_array.field->field.name;
4022 field = tep_find_any_field(event, str);
4023 if (!field)
4024 goto out_warning_field;
4025 arg->int_array.field->field.field = field;
4026 }
4027 num = data + field->offset;
4028 }
4029 len = eval_num_arg(data, size, event, arg->int_array.count);
4030 el_size = eval_num_arg(data, size, event,
4031 arg->int_array.el_size);
4032 for (i = 0; i < len; i++) {
4033 if (i)
4034 trace_seq_putc(s, ' ');
4035
4036 if (el_size == 1) {
4037 trace_seq_printf(s, "%u", *(uint8_t *)num);
4038 } else if (el_size == 2) {
4039 trace_seq_printf(s, "%u", *(uint16_t *)num);
4040 } else if (el_size == 4) {
4041 trace_seq_printf(s, "%u", *(uint32_t *)num);
4042 } else if (el_size == 8) {
4043 trace_seq_printf(s, "%"PRIu64, *(uint64_t *)num);
4044 } else {
4045 trace_seq_printf(s, "BAD SIZE:%d 0x%x",
4046 el_size, *(uint8_t *)num);
4047 el_size = 1;
4048 }
4049
4050 num += el_size;
4051 }
4052 break;
4053 }
4054 case TEP_PRINT_TYPE:
4055 break;
4056 case TEP_PRINT_STRING: {
4057 int str_offset;
4058
4059 if (arg->string.offset == -1) {
4060 struct tep_format_field *f;
4061
4062 f = tep_find_any_field(event, arg->string.string);
4063 arg->string.offset = f->offset;
4064 }
4065 str_offset = tep_data2host4(pevent, data + arg->string.offset);
4066 str_offset &= 0xffff;
4067 print_str_to_seq(s, format, len_arg, ((char *)data) + str_offset);
4068 break;
4069 }
4070 case TEP_PRINT_BSTRING:
4071 print_str_to_seq(s, format, len_arg, arg->string.string);
4072 break;
4073 case TEP_PRINT_BITMASK: {
4074 int bitmask_offset;
4075 int bitmask_size;
4076
4077 if (arg->bitmask.offset == -1) {
4078 struct tep_format_field *f;
4079
4080 f = tep_find_any_field(event, arg->bitmask.bitmask);
4081 arg->bitmask.offset = f->offset;
4082 }
4083 bitmask_offset = tep_data2host4(pevent, data + arg->bitmask.offset);
4084 bitmask_size = bitmask_offset >> 16;
4085 bitmask_offset &= 0xffff;
4086 print_bitmask_to_seq(pevent, s, format, len_arg,
4087 data + bitmask_offset, bitmask_size);
4088 break;
4089 }
4090 case TEP_PRINT_OP:
4091 /*
4092 * The only op for string should be ? :
4093 */
4094 if (arg->op.op[0] != '?')
4095 return;
4096 val = eval_num_arg(data, size, event, arg->op.left);
4097 if (val)
4098 print_str_arg(s, data, size, event,
4099 format, len_arg, arg->op.right->op.left);
4100 else
4101 print_str_arg(s, data, size, event,
4102 format, len_arg, arg->op.right->op.right);
4103 break;
4104 case TEP_PRINT_FUNC:
4105 process_defined_func(s, data, size, event, arg);
4106 break;
4107 default:
4108 /* well... */
4109 break;
4110 }
4111
4112 return;
4113
4114out_warning_field:
4115 do_warning_event(event, "%s: field %s not found",
4116 __func__, arg->field.name);
4117}
4118
4119static unsigned long long
4120process_defined_func(struct trace_seq *s, void *data, int size,
4121 struct tep_event_format *event, struct tep_print_arg *arg)
4122{
4123 struct tep_function_handler *func_handle = arg->func.func;
4124 struct func_params *param;
4125 unsigned long long *args;
4126 unsigned long long ret;
4127 struct tep_print_arg *farg;
4128 struct trace_seq str;
4129 struct save_str {
4130 struct save_str *next;
4131 char *str;
4132 } *strings = NULL, *string;
4133 int i;
4134
4135 if (!func_handle->nr_args) {
4136 ret = (*func_handle->func)(s, NULL);
4137 goto out;
4138 }
4139
4140 farg = arg->func.args;
4141 param = func_handle->params;
4142
4143 ret = ULLONG_MAX;
4144 args = malloc(sizeof(*args) * func_handle->nr_args);
4145 if (!args)
4146 goto out;
4147
4148 for (i = 0; i < func_handle->nr_args; i++) {
4149 switch (param->type) {
4150 case TEP_FUNC_ARG_INT:
4151 case TEP_FUNC_ARG_LONG:
4152 case TEP_FUNC_ARG_PTR:
4153 args[i] = eval_num_arg(data, size, event, farg);
4154 break;
4155 case TEP_FUNC_ARG_STRING:
4156 trace_seq_init(&str);
4157 print_str_arg(&str, data, size, event, "%s", -1, farg);
4158 trace_seq_terminate(&str);
4159 string = malloc(sizeof(*string));
4160 if (!string) {
4161 do_warning_event(event, "%s(%d): malloc str",
4162 __func__, __LINE__);
4163 goto out_free;
4164 }
4165 string->next = strings;
4166 string->str = strdup(str.buffer);
4167 if (!string->str) {
4168 free(string);
4169 do_warning_event(event, "%s(%d): malloc str",
4170 __func__, __LINE__);
4171 goto out_free;
4172 }
4173 args[i] = (uintptr_t)string->str;
4174 strings = string;
4175 trace_seq_destroy(&str);
4176 break;
4177 default:
4178 /*
4179 * Something went totally wrong, this is not
4180 * an input error, something in this code broke.
4181 */
4182 do_warning_event(event, "Unexpected end of arguments\n");
4183 goto out_free;
4184 }
4185 farg = farg->next;
4186 param = param->next;
4187 }
4188
4189 ret = (*func_handle->func)(s, args);
4190out_free:
4191 free(args);
4192 while (strings) {
4193 string = strings;
4194 strings = string->next;
4195 free(string->str);
4196 free(string);
4197 }
4198
4199 out:
4200 /* TBD : handle return type here */
4201 return ret;
4202}
4203
4204static void free_args(struct tep_print_arg *args)
4205{
4206 struct tep_print_arg *next;
4207
4208 while (args) {
4209 next = args->next;
4210
4211 free_arg(args);
4212 args = next;
4213 }
4214}
4215
4216static struct tep_print_arg *make_bprint_args(char *fmt, void *data, int size, struct tep_event_format *event)
4217{
4218 struct tep_handle *pevent = event->pevent;
4219 struct tep_format_field *field, *ip_field;
4220 struct tep_print_arg *args, *arg, **next;
4221 unsigned long long ip, val;
4222 char *ptr;
4223 void *bptr;
4224 int vsize;
4225
4226 field = pevent->bprint_buf_field;
4227 ip_field = pevent->bprint_ip_field;
4228
4229 if (!field) {
4230 field = tep_find_field(event, "buf");
4231 if (!field) {
4232 do_warning_event(event, "can't find buffer field for binary printk");
4233 return NULL;
4234 }
4235 ip_field = tep_find_field(event, "ip");
4236 if (!ip_field) {
4237 do_warning_event(event, "can't find ip field for binary printk");
4238 return NULL;
4239 }
4240 pevent->bprint_buf_field = field;
4241 pevent->bprint_ip_field = ip_field;
4242 }
4243
4244 ip = tep_read_number(pevent, data + ip_field->offset, ip_field->size);
4245
4246 /*
4247 * The first arg is the IP pointer.
4248 */
4249 args = alloc_arg();
4250 if (!args) {
4251 do_warning_event(event, "%s(%d): not enough memory!",
4252 __func__, __LINE__);
4253 return NULL;
4254 }
4255 arg = args;
4256 arg->next = NULL;
4257 next = &arg->next;
4258
4259 arg->type = TEP_PRINT_ATOM;
4260
4261 if (asprintf(&arg->atom.atom, "%lld", ip) < 0)
4262 goto out_free;
4263
4264 /* skip the first "%ps: " */
4265 for (ptr = fmt + 5, bptr = data + field->offset;
4266 bptr < data + size && *ptr; ptr++) {
4267 int ls = 0;
4268
4269 if (*ptr == '%') {
4270 process_again:
4271 ptr++;
4272 switch (*ptr) {
4273 case '%':
4274 break;
4275 case 'l':
4276 ls++;
4277 goto process_again;
4278 case 'L':
4279 ls = 2;
4280 goto process_again;
4281 case '0' ... '9':
4282 goto process_again;
4283 case '.':
4284 goto process_again;
4285 case 'z':
4286 case 'Z':
4287 ls = 1;
4288 goto process_again;
4289 case 'p':
4290 ls = 1;
4291 if (isalnum(ptr[1])) {
4292 ptr++;
4293 /* Check for special pointers */
4294 switch (*ptr) {
4295 case 's':
4296 case 'S':
4297 case 'f':
4298 case 'F':
4299 break;
4300 default:
4301 /*
4302 * Older kernels do not process
4303 * dereferenced pointers.
4304 * Only process if the pointer
4305 * value is a printable.
4306 */
4307 if (isprint(*(char *)bptr))
4308 goto process_string;
4309 }
4310 }
4311 /* fall through */
4312 case 'd':
4313 case 'u':
4314 case 'x':
4315 case 'i':
4316 switch (ls) {
4317 case 0:
4318 vsize = 4;
4319 break;
4320 case 1:
4321 vsize = pevent->long_size;
4322 break;
4323 case 2:
4324 vsize = 8;
4325 break;
4326 default:
4327 vsize = ls; /* ? */
4328 break;
4329 }
4330 /* fall through */
4331 case '*':
4332 if (*ptr == '*')
4333 vsize = 4;
4334
4335 /* the pointers are always 4 bytes aligned */
4336 bptr = (void *)(((unsigned long)bptr + 3) &
4337 ~3);
4338 val = tep_read_number(pevent, bptr, vsize);
4339 bptr += vsize;
4340 arg = alloc_arg();
4341 if (!arg) {
4342 do_warning_event(event, "%s(%d): not enough memory!",
4343 __func__, __LINE__);
4344 goto out_free;
4345 }
4346 arg->next = NULL;
4347 arg->type = TEP_PRINT_ATOM;
4348 if (asprintf(&arg->atom.atom, "%lld", val) < 0) {
4349 free(arg);
4350 goto out_free;
4351 }
4352 *next = arg;
4353 next = &arg->next;
4354 /*
4355 * The '*' case means that an arg is used as the length.
4356 * We need to continue to figure out for what.
4357 */
4358 if (*ptr == '*')
4359 goto process_again;
4360
4361 break;
4362 case 's':
4363 process_string:
4364 arg = alloc_arg();
4365 if (!arg) {
4366 do_warning_event(event, "%s(%d): not enough memory!",
4367 __func__, __LINE__);
4368 goto out_free;
4369 }
4370 arg->next = NULL;
4371 arg->type = TEP_PRINT_BSTRING;
4372 arg->string.string = strdup(bptr);
4373 if (!arg->string.string)
4374 goto out_free;
4375 bptr += strlen(bptr) + 1;
4376 *next = arg;
4377 next = &arg->next;
4378 default:
4379 break;
4380 }
4381 }
4382 }
4383
4384 return args;
4385
4386out_free:
4387 free_args(args);
4388 return NULL;
4389}
4390
4391static char *
4392get_bprint_format(void *data, int size __maybe_unused,
4393 struct tep_event_format *event)
4394{
4395 struct tep_handle *pevent = event->pevent;
4396 unsigned long long addr;
4397 struct tep_format_field *field;
4398 struct printk_map *printk;
4399 char *format;
4400
4401 field = pevent->bprint_fmt_field;
4402
4403 if (!field) {
4404 field = tep_find_field(event, "fmt");
4405 if (!field) {
4406 do_warning_event(event, "can't find format field for binary printk");
4407 return NULL;
4408 }
4409 pevent->bprint_fmt_field = field;
4410 }
4411
4412 addr = tep_read_number(pevent, data + field->offset, field->size);
4413
4414 printk = find_printk(pevent, addr);
4415 if (!printk) {
4416 if (asprintf(&format, "%%pf: (NO FORMAT FOUND at %llx)\n", addr) < 0)
4417 return NULL;
4418 return format;
4419 }
4420
4421 if (asprintf(&format, "%s: %s", "%pf", printk->printk) < 0)
4422 return NULL;
4423
4424 return format;
4425}
4426
4427static void print_mac_arg(struct trace_seq *s, int mac, void *data, int size,
4428 struct tep_event_format *event, struct tep_print_arg *arg)
4429{
4430 unsigned char *buf;
4431 const char *fmt = "%.2x:%.2x:%.2x:%.2x:%.2x:%.2x";
4432
4433 if (arg->type == TEP_PRINT_FUNC) {
4434 process_defined_func(s, data, size, event, arg);
4435 return;
4436 }
4437
4438 if (arg->type != TEP_PRINT_FIELD) {
4439 trace_seq_printf(s, "ARG TYPE NOT FIELD BUT %d",
4440 arg->type);
4441 return;
4442 }
4443
4444 if (mac == 'm')
4445 fmt = "%.2x%.2x%.2x%.2x%.2x%.2x";
4446 if (!arg->field.field) {
4447 arg->field.field =
4448 tep_find_any_field(event, arg->field.name);
4449 if (!arg->field.field) {
4450 do_warning_event(event, "%s: field %s not found",
4451 __func__, arg->field.name);
4452 return;
4453 }
4454 }
4455 if (arg->field.field->size != 6) {
4456 trace_seq_printf(s, "INVALIDMAC");
4457 return;
4458 }
4459 buf = data + arg->field.field->offset;
4460 trace_seq_printf(s, fmt, buf[0], buf[1], buf[2], buf[3], buf[4], buf[5]);
4461}
4462
4463static void print_ip4_addr(struct trace_seq *s, char i, unsigned char *buf)
4464{
4465 const char *fmt;
4466
4467 if (i == 'i')
4468 fmt = "%03d.%03d.%03d.%03d";
4469 else
4470 fmt = "%d.%d.%d.%d";
4471
4472 trace_seq_printf(s, fmt, buf[0], buf[1], buf[2], buf[3]);
4473}
4474
4475static inline bool ipv6_addr_v4mapped(const struct in6_addr *a)
4476{
4477 return ((unsigned long)(a->s6_addr32[0] | a->s6_addr32[1]) |
4478 (unsigned long)(a->s6_addr32[2] ^ htonl(0x0000ffff))) == 0UL;
4479}
4480
4481static inline bool ipv6_addr_is_isatap(const struct in6_addr *addr)
4482{
4483 return (addr->s6_addr32[2] | htonl(0x02000000)) == htonl(0x02005EFE);
4484}
4485
4486static void print_ip6c_addr(struct trace_seq *s, unsigned char *addr)
4487{
4488 int i, j, range;
4489 unsigned char zerolength[8];
4490 int longest = 1;
4491 int colonpos = -1;
4492 uint16_t word;
4493 uint8_t hi, lo;
4494 bool needcolon = false;
4495 bool useIPv4;
4496 struct in6_addr in6;
4497
4498 memcpy(&in6, addr, sizeof(struct in6_addr));
4499
4500 useIPv4 = ipv6_addr_v4mapped(&in6) || ipv6_addr_is_isatap(&in6);
4501
4502 memset(zerolength, 0, sizeof(zerolength));
4503
4504 if (useIPv4)
4505 range = 6;
4506 else
4507 range = 8;
4508
4509 /* find position of longest 0 run */
4510 for (i = 0; i < range; i++) {
4511 for (j = i; j < range; j++) {
4512 if (in6.s6_addr16[j] != 0)
4513 break;
4514 zerolength[i]++;
4515 }
4516 }
4517 for (i = 0; i < range; i++) {
4518 if (zerolength[i] > longest) {
4519 longest = zerolength[i];
4520 colonpos = i;
4521 }
4522 }
4523 if (longest == 1) /* don't compress a single 0 */
4524 colonpos = -1;
4525
4526 /* emit address */
4527 for (i = 0; i < range; i++) {
4528 if (i == colonpos) {
4529 if (needcolon || i == 0)
4530 trace_seq_printf(s, ":");
4531 trace_seq_printf(s, ":");
4532 needcolon = false;
4533 i += longest - 1;
4534 continue;
4535 }
4536 if (needcolon) {
4537 trace_seq_printf(s, ":");
4538 needcolon = false;
4539 }
4540 /* hex u16 without leading 0s */
4541 word = ntohs(in6.s6_addr16[i]);
4542 hi = word >> 8;
4543 lo = word & 0xff;
4544 if (hi)
4545 trace_seq_printf(s, "%x%02x", hi, lo);
4546 else
4547 trace_seq_printf(s, "%x", lo);
4548
4549 needcolon = true;
4550 }
4551
4552 if (useIPv4) {
4553 if (needcolon)
4554 trace_seq_printf(s, ":");
4555 print_ip4_addr(s, 'I', &in6.s6_addr[12]);
4556 }
4557
4558 return;
4559}
4560
4561static void print_ip6_addr(struct trace_seq *s, char i, unsigned char *buf)
4562{
4563 int j;
4564
4565 for (j = 0; j < 16; j += 2) {
4566 trace_seq_printf(s, "%02x%02x", buf[j], buf[j+1]);
4567 if (i == 'I' && j < 14)
4568 trace_seq_printf(s, ":");
4569 }
4570}
4571
4572/*
4573 * %pi4 print an IPv4 address with leading zeros
4574 * %pI4 print an IPv4 address without leading zeros
4575 * %pi6 print an IPv6 address without colons
4576 * %pI6 print an IPv6 address with colons
4577 * %pI6c print an IPv6 address in compressed form with colons
4578 * %pISpc print an IP address based on sockaddr; p adds port.
4579 */
4580static int print_ipv4_arg(struct trace_seq *s, const char *ptr, char i,
4581 void *data, int size, struct tep_event_format *event,
4582 struct tep_print_arg *arg)
4583{
4584 unsigned char *buf;
4585
4586 if (arg->type == TEP_PRINT_FUNC) {
4587 process_defined_func(s, data, size, event, arg);
4588 return 0;
4589 }
4590
4591 if (arg->type != TEP_PRINT_FIELD) {
4592 trace_seq_printf(s, "ARG TYPE NOT FIELD BUT %d", arg->type);
4593 return 0;
4594 }
4595
4596 if (!arg->field.field) {
4597 arg->field.field =
4598 tep_find_any_field(event, arg->field.name);
4599 if (!arg->field.field) {
4600 do_warning("%s: field %s not found",
4601 __func__, arg->field.name);
4602 return 0;
4603 }
4604 }
4605
4606 buf = data + arg->field.field->offset;
4607
4608 if (arg->field.field->size != 4) {
4609 trace_seq_printf(s, "INVALIDIPv4");
4610 return 0;
4611 }
4612 print_ip4_addr(s, i, buf);
4613
4614 return 0;
4615}
4616
4617static int print_ipv6_arg(struct trace_seq *s, const char *ptr, char i,
4618 void *data, int size, struct tep_event_format *event,
4619 struct tep_print_arg *arg)
4620{
4621 char have_c = 0;
4622 unsigned char *buf;
4623 int rc = 0;
4624
4625 /* pI6c */
4626 if (i == 'I' && *ptr == 'c') {
4627 have_c = 1;
4628 ptr++;
4629 rc++;
4630 }
4631
4632 if (arg->type == TEP_PRINT_FUNC) {
4633 process_defined_func(s, data, size, event, arg);
4634 return rc;
4635 }
4636
4637 if (arg->type != TEP_PRINT_FIELD) {
4638 trace_seq_printf(s, "ARG TYPE NOT FIELD BUT %d", arg->type);
4639 return rc;
4640 }
4641
4642 if (!arg->field.field) {
4643 arg->field.field =
4644 tep_find_any_field(event, arg->field.name);
4645 if (!arg->field.field) {
4646 do_warning("%s: field %s not found",
4647 __func__, arg->field.name);
4648 return rc;
4649 }
4650 }
4651
4652 buf = data + arg->field.field->offset;
4653
4654 if (arg->field.field->size != 16) {
4655 trace_seq_printf(s, "INVALIDIPv6");
4656 return rc;
4657 }
4658
4659 if (have_c)
4660 print_ip6c_addr(s, buf);
4661 else
4662 print_ip6_addr(s, i, buf);
4663
4664 return rc;
4665}
4666
4667static int print_ipsa_arg(struct trace_seq *s, const char *ptr, char i,
4668 void *data, int size, struct tep_event_format *event,
4669 struct tep_print_arg *arg)
4670{
4671 char have_c = 0, have_p = 0;
4672 unsigned char *buf;
4673 struct sockaddr_storage *sa;
4674 int rc = 0;
4675
4676 /* pISpc */
4677 if (i == 'I') {
4678 if (*ptr == 'p') {
4679 have_p = 1;
4680 ptr++;
4681 rc++;
4682 }
4683 if (*ptr == 'c') {
4684 have_c = 1;
4685 ptr++;
4686 rc++;
4687 }
4688 }
4689
4690 if (arg->type == TEP_PRINT_FUNC) {
4691 process_defined_func(s, data, size, event, arg);
4692 return rc;
4693 }
4694
4695 if (arg->type != TEP_PRINT_FIELD) {
4696 trace_seq_printf(s, "ARG TYPE NOT FIELD BUT %d", arg->type);
4697 return rc;
4698 }
4699
4700 if (!arg->field.field) {
4701 arg->field.field =
4702 tep_find_any_field(event, arg->field.name);
4703 if (!arg->field.field) {
4704 do_warning("%s: field %s not found",
4705 __func__, arg->field.name);
4706 return rc;
4707 }
4708 }
4709
4710 sa = (struct sockaddr_storage *) (data + arg->field.field->offset);
4711
4712 if (sa->ss_family == AF_INET) {
4713 struct sockaddr_in *sa4 = (struct sockaddr_in *) sa;
4714
4715 if (arg->field.field->size < sizeof(struct sockaddr_in)) {
4716 trace_seq_printf(s, "INVALIDIPv4");
4717 return rc;
4718 }
4719
4720 print_ip4_addr(s, i, (unsigned char *) &sa4->sin_addr);
4721 if (have_p)
4722 trace_seq_printf(s, ":%d", ntohs(sa4->sin_port));
4723
4724
4725 } else if (sa->ss_family == AF_INET6) {
4726 struct sockaddr_in6 *sa6 = (struct sockaddr_in6 *) sa;
4727
4728 if (arg->field.field->size < sizeof(struct sockaddr_in6)) {
4729 trace_seq_printf(s, "INVALIDIPv6");
4730 return rc;
4731 }
4732
4733 if (have_p)
4734 trace_seq_printf(s, "[");
4735
4736 buf = (unsigned char *) &sa6->sin6_addr;
4737 if (have_c)
4738 print_ip6c_addr(s, buf);
4739 else
4740 print_ip6_addr(s, i, buf);
4741
4742 if (have_p)
4743 trace_seq_printf(s, "]:%d", ntohs(sa6->sin6_port));
4744 }
4745
4746 return rc;
4747}
4748
4749static int print_ip_arg(struct trace_seq *s, const char *ptr,
4750 void *data, int size, struct tep_event_format *event,
4751 struct tep_print_arg *arg)
4752{
4753 char i = *ptr; /* 'i' or 'I' */
4754 char ver;
4755 int rc = 0;
4756
4757 ptr++;
4758 rc++;
4759
4760 ver = *ptr;
4761 ptr++;
4762 rc++;
4763
4764 switch (ver) {
4765 case '4':
4766 rc += print_ipv4_arg(s, ptr, i, data, size, event, arg);
4767 break;
4768 case '6':
4769 rc += print_ipv6_arg(s, ptr, i, data, size, event, arg);
4770 break;
4771 case 'S':
4772 rc += print_ipsa_arg(s, ptr, i, data, size, event, arg);
4773 break;
4774 default:
4775 return 0;
4776 }
4777
4778 return rc;
4779}
4780
4781static int is_printable_array(char *p, unsigned int len)
4782{
4783 unsigned int i;
4784
4785 for (i = 0; i < len && p[i]; i++)
4786 if (!isprint(p[i]) && !isspace(p[i]))
4787 return 0;
4788 return 1;
4789}
4790
4791void tep_print_field(struct trace_seq *s, void *data,
4792 struct tep_format_field *field)
4793{
4794 unsigned long long val;
4795 unsigned int offset, len, i;
4796 struct tep_handle *pevent = field->event->pevent;
4797
4798 if (field->flags & TEP_FIELD_IS_ARRAY) {
4799 offset = field->offset;
4800 len = field->size;
4801 if (field->flags & TEP_FIELD_IS_DYNAMIC) {
4802 val = tep_read_number(pevent, data + offset, len);
4803 offset = val;
4804 len = offset >> 16;
4805 offset &= 0xffff;
4806 }
4807 if (field->flags & TEP_FIELD_IS_STRING &&
4808 is_printable_array(data + offset, len)) {
4809 trace_seq_printf(s, "%s", (char *)data + offset);
4810 } else {
4811 trace_seq_puts(s, "ARRAY[");
4812 for (i = 0; i < len; i++) {
4813 if (i)
4814 trace_seq_puts(s, ", ");
4815 trace_seq_printf(s, "%02x",
4816 *((unsigned char *)data + offset + i));
4817 }
4818 trace_seq_putc(s, ']');
4819 field->flags &= ~TEP_FIELD_IS_STRING;
4820 }
4821 } else {
4822 val = tep_read_number(pevent, data + field->offset,
4823 field->size);
4824 if (field->flags & TEP_FIELD_IS_POINTER) {
4825 trace_seq_printf(s, "0x%llx", val);
4826 } else if (field->flags & TEP_FIELD_IS_SIGNED) {
4827 switch (field->size) {
4828 case 4:
4829 /*
4830 * If field is long then print it in hex.
4831 * A long usually stores pointers.
4832 */
4833 if (field->flags & TEP_FIELD_IS_LONG)
4834 trace_seq_printf(s, "0x%x", (int)val);
4835 else
4836 trace_seq_printf(s, "%d", (int)val);
4837 break;
4838 case 2:
4839 trace_seq_printf(s, "%2d", (short)val);
4840 break;
4841 case 1:
4842 trace_seq_printf(s, "%1d", (char)val);
4843 break;
4844 default:
4845 trace_seq_printf(s, "%lld", val);
4846 }
4847 } else {
4848 if (field->flags & TEP_FIELD_IS_LONG)
4849 trace_seq_printf(s, "0x%llx", val);
4850 else
4851 trace_seq_printf(s, "%llu", val);
4852 }
4853 }
4854}
4855
4856void tep_print_fields(struct trace_seq *s, void *data,
4857 int size __maybe_unused, struct tep_event_format *event)
4858{
4859 struct tep_format_field *field;
4860
4861 field = event->format.fields;
4862 while (field) {
4863 trace_seq_printf(s, " %s=", field->name);
4864 tep_print_field(s, data, field);
4865 field = field->next;
4866 }
4867}
4868
4869static void pretty_print(struct trace_seq *s, void *data, int size, struct tep_event_format *event)
4870{
4871 struct tep_handle *pevent = event->pevent;
4872 struct tep_print_fmt *print_fmt = &event->print_fmt;
4873 struct tep_print_arg *arg = print_fmt->args;
4874 struct tep_print_arg *args = NULL;
4875 const char *ptr = print_fmt->format;
4876 unsigned long long val;
4877 struct func_map *func;
4878 const char *saveptr;
4879 struct trace_seq p;
4880 char *bprint_fmt = NULL;
4881 char format[32];
4882 int show_func;
4883 int len_as_arg;
4884 int len_arg;
4885 int len;
4886 int ls;
4887
4888 if (event->flags & TEP_EVENT_FL_FAILED) {
4889 trace_seq_printf(s, "[FAILED TO PARSE]");
4890 tep_print_fields(s, data, size, event);
4891 return;
4892 }
4893
4894 if (event->flags & TEP_EVENT_FL_ISBPRINT) {
4895 bprint_fmt = get_bprint_format(data, size, event);
4896 args = make_bprint_args(bprint_fmt, data, size, event);
4897 arg = args;
4898 ptr = bprint_fmt;
4899 }
4900
4901 for (; *ptr; ptr++) {
4902 ls = 0;
4903 if (*ptr == '\\') {
4904 ptr++;
4905 switch (*ptr) {
4906 case 'n':
4907 trace_seq_putc(s, '\n');
4908 break;
4909 case 't':
4910 trace_seq_putc(s, '\t');
4911 break;
4912 case 'r':
4913 trace_seq_putc(s, '\r');
4914 break;
4915 case '\\':
4916 trace_seq_putc(s, '\\');
4917 break;
4918 default:
4919 trace_seq_putc(s, *ptr);
4920 break;
4921 }
4922
4923 } else if (*ptr == '%') {
4924 saveptr = ptr;
4925 show_func = 0;
4926 len_as_arg = 0;
4927 cont_process:
4928 ptr++;
4929 switch (*ptr) {
4930 case '%':
4931 trace_seq_putc(s, '%');
4932 break;
4933 case '#':
4934 /* FIXME: need to handle properly */
4935 goto cont_process;
4936 case 'h':
4937 ls--;
4938 goto cont_process;
4939 case 'l':
4940 ls++;
4941 goto cont_process;
4942 case 'L':
4943 ls = 2;
4944 goto cont_process;
4945 case '*':
4946 /* The argument is the length. */
4947 if (!arg) {
4948 do_warning_event(event, "no argument match");
4949 event->flags |= TEP_EVENT_FL_FAILED;
4950 goto out_failed;
4951 }
4952 len_arg = eval_num_arg(data, size, event, arg);
4953 len_as_arg = 1;
4954 arg = arg->next;
4955 goto cont_process;
4956 case '.':
4957 case 'z':
4958 case 'Z':
4959 case '0' ... '9':
4960 case '-':
4961 goto cont_process;
4962 case 'p':
4963 if (pevent->long_size == 4)
4964 ls = 1;
4965 else
4966 ls = 2;
4967
4968 if (isalnum(ptr[1]))
4969 ptr++;
4970
4971 if (arg->type == TEP_PRINT_BSTRING) {
4972 trace_seq_puts(s, arg->string.string);
4973 break;
4974 }
4975
4976 if (*ptr == 'F' || *ptr == 'f' ||
4977 *ptr == 'S' || *ptr == 's') {
4978 show_func = *ptr;
4979 } else if (*ptr == 'M' || *ptr == 'm') {
4980 print_mac_arg(s, *ptr, data, size, event, arg);
4981 arg = arg->next;
4982 break;
4983 } else if (*ptr == 'I' || *ptr == 'i') {
4984 int n;
4985
4986 n = print_ip_arg(s, ptr, data, size, event, arg);
4987 if (n > 0) {
4988 ptr += n - 1;
4989 arg = arg->next;
4990 break;
4991 }
4992 }
4993
4994 /* fall through */
4995 case 'd':
4996 case 'i':
4997 case 'x':
4998 case 'X':
4999 case 'u':
5000 if (!arg) {
5001 do_warning_event(event, "no argument match");
5002 event->flags |= TEP_EVENT_FL_FAILED;
5003 goto out_failed;
5004 }
5005
5006 len = ((unsigned long)ptr + 1) -
5007 (unsigned long)saveptr;
5008
5009 /* should never happen */
5010 if (len > 31) {
5011 do_warning_event(event, "bad format!");
5012 event->flags |= TEP_EVENT_FL_FAILED;
5013 len = 31;
5014 }
5015
5016 memcpy(format, saveptr, len);
5017 format[len] = 0;
5018
5019 val = eval_num_arg(data, size, event, arg);
5020 arg = arg->next;
5021
5022 if (show_func) {
5023 func = find_func(pevent, val);
5024 if (func) {
5025 trace_seq_puts(s, func->func);
5026 if (show_func == 'F')
5027 trace_seq_printf(s,
5028 "+0x%llx",
5029 val - func->addr);
5030 break;
5031 }
5032 }
5033 if (pevent->long_size == 8 && ls == 1 &&
5034 sizeof(long) != 8) {
5035 char *p;
5036
5037 /* make %l into %ll */
5038 if (ls == 1 && (p = strchr(format, 'l')))
5039 memmove(p+1, p, strlen(p)+1);
5040 else if (strcmp(format, "%p") == 0)
5041 strcpy(format, "0x%llx");
5042 ls = 2;
5043 }
5044 switch (ls) {
5045 case -2:
5046 if (len_as_arg)
5047 trace_seq_printf(s, format, len_arg, (char)val);
5048 else
5049 trace_seq_printf(s, format, (char)val);
5050 break;
5051 case -1:
5052 if (len_as_arg)
5053 trace_seq_printf(s, format, len_arg, (short)val);
5054 else
5055 trace_seq_printf(s, format, (short)val);
5056 break;
5057 case 0:
5058 if (len_as_arg)
5059 trace_seq_printf(s, format, len_arg, (int)val);
5060 else
5061 trace_seq_printf(s, format, (int)val);
5062 break;
5063 case 1:
5064 if (len_as_arg)
5065 trace_seq_printf(s, format, len_arg, (long)val);
5066 else
5067 trace_seq_printf(s, format, (long)val);
5068 break;
5069 case 2:
5070 if (len_as_arg)
5071 trace_seq_printf(s, format, len_arg,
5072 (long long)val);
5073 else
5074 trace_seq_printf(s, format, (long long)val);
5075 break;
5076 default:
5077 do_warning_event(event, "bad count (%d)", ls);
5078 event->flags |= TEP_EVENT_FL_FAILED;
5079 }
5080 break;
5081 case 's':
5082 if (!arg) {
5083 do_warning_event(event, "no matching argument");
5084 event->flags |= TEP_EVENT_FL_FAILED;
5085 goto out_failed;
5086 }
5087
5088 len = ((unsigned long)ptr + 1) -
5089 (unsigned long)saveptr;
5090
5091 /* should never happen */
5092 if (len > 31) {
5093 do_warning_event(event, "bad format!");
5094 event->flags |= TEP_EVENT_FL_FAILED;
5095 len = 31;
5096 }
5097
5098 memcpy(format, saveptr, len);
5099 format[len] = 0;
5100 if (!len_as_arg)
5101 len_arg = -1;
5102 /* Use helper trace_seq */
5103 trace_seq_init(&p);
5104 print_str_arg(&p, data, size, event,
5105 format, len_arg, arg);
5106 trace_seq_terminate(&p);
5107 trace_seq_puts(s, p.buffer);
5108 trace_seq_destroy(&p);
5109 arg = arg->next;
5110 break;
5111 default:
5112 trace_seq_printf(s, ">%c<", *ptr);
5113
5114 }
5115 } else
5116 trace_seq_putc(s, *ptr);
5117 }
5118
5119 if (event->flags & TEP_EVENT_FL_FAILED) {
5120out_failed:
5121 trace_seq_printf(s, "[FAILED TO PARSE]");
5122 }
5123
5124 if (args) {
5125 free_args(args);
5126 free(bprint_fmt);
5127 }
5128}
5129
5130/**
5131 * tep_data_lat_fmt - parse the data for the latency format
5132 * @pevent: a handle to the pevent
5133 * @s: the trace_seq to write to
5134 * @record: the record to read from
5135 *
5136 * This parses out the Latency format (interrupts disabled,
5137 * need rescheduling, in hard/soft interrupt, preempt count
5138 * and lock depth) and places it into the trace_seq.
5139 */
5140void tep_data_lat_fmt(struct tep_handle *pevent,
5141 struct trace_seq *s, struct tep_record *record)
5142{
5143 static int check_lock_depth = 1;
5144 static int check_migrate_disable = 1;
5145 static int lock_depth_exists;
5146 static int migrate_disable_exists;
5147 unsigned int lat_flags;
5148 unsigned int pc;
5149 int lock_depth;
5150 int migrate_disable;
5151 int hardirq;
5152 int softirq;
5153 void *data = record->data;
5154
5155 lat_flags = parse_common_flags(pevent, data);
5156 pc = parse_common_pc(pevent, data);
5157 /* lock_depth may not always exist */
5158 if (lock_depth_exists)
5159 lock_depth = parse_common_lock_depth(pevent, data);
5160 else if (check_lock_depth) {
5161 lock_depth = parse_common_lock_depth(pevent, data);
5162 if (lock_depth < 0)
5163 check_lock_depth = 0;
5164 else
5165 lock_depth_exists = 1;
5166 }
5167
5168 /* migrate_disable may not always exist */
5169 if (migrate_disable_exists)
5170 migrate_disable = parse_common_migrate_disable(pevent, data);
5171 else if (check_migrate_disable) {
5172 migrate_disable = parse_common_migrate_disable(pevent, data);
5173 if (migrate_disable < 0)
5174 check_migrate_disable = 0;
5175 else
5176 migrate_disable_exists = 1;
5177 }
5178
5179 hardirq = lat_flags & TRACE_FLAG_HARDIRQ;
5180 softirq = lat_flags & TRACE_FLAG_SOFTIRQ;
5181
5182 trace_seq_printf(s, "%c%c%c",
5183 (lat_flags & TRACE_FLAG_IRQS_OFF) ? 'd' :
5184 (lat_flags & TRACE_FLAG_IRQS_NOSUPPORT) ?
5185 'X' : '.',
5186 (lat_flags & TRACE_FLAG_NEED_RESCHED) ?
5187 'N' : '.',
5188 (hardirq && softirq) ? 'H' :
5189 hardirq ? 'h' : softirq ? 's' : '.');
5190
5191 if (pc)
5192 trace_seq_printf(s, "%x", pc);
5193 else
5194 trace_seq_putc(s, '.');
5195
5196 if (migrate_disable_exists) {
5197 if (migrate_disable < 0)
5198 trace_seq_putc(s, '.');
5199 else
5200 trace_seq_printf(s, "%d", migrate_disable);
5201 }
5202
5203 if (lock_depth_exists) {
5204 if (lock_depth < 0)
5205 trace_seq_putc(s, '.');
5206 else
5207 trace_seq_printf(s, "%d", lock_depth);
5208 }
5209
5210 trace_seq_terminate(s);
5211}
5212
5213/**
5214 * tep_data_type - parse out the given event type
5215 * @pevent: a handle to the pevent
5216 * @rec: the record to read from
5217 *
5218 * This returns the event id from the @rec.
5219 */
5220int tep_data_type(struct tep_handle *pevent, struct tep_record *rec)
5221{
5222 return trace_parse_common_type(pevent, rec->data);
5223}
5224
5225/**
5226 * tep_data_event_from_type - find the event by a given type
5227 * @pevent: a handle to the pevent
5228 * @type: the type of the event.
5229 *
5230 * This returns the event form a given @type;
5231 */
5232struct tep_event_format *tep_data_event_from_type(struct tep_handle *pevent, int type)
5233{
5234 return tep_find_event(pevent, type);
5235}
5236
5237/**
5238 * tep_data_pid - parse the PID from record
5239 * @pevent: a handle to the pevent
5240 * @rec: the record to parse
5241 *
5242 * This returns the PID from a record.
5243 */
5244int tep_data_pid(struct tep_handle *pevent, struct tep_record *rec)
5245{
5246 return parse_common_pid(pevent, rec->data);
5247}
5248
5249/**
5250 * tep_data_preempt_count - parse the preempt count from the record
5251 * @pevent: a handle to the pevent
5252 * @rec: the record to parse
5253 *
5254 * This returns the preempt count from a record.
5255 */
5256int tep_data_preempt_count(struct tep_handle *pevent, struct tep_record *rec)
5257{
5258 return parse_common_pc(pevent, rec->data);
5259}
5260
5261/**
5262 * tep_data_flags - parse the latency flags from the record
5263 * @pevent: a handle to the pevent
5264 * @rec: the record to parse
5265 *
5266 * This returns the latency flags from a record.
5267 *
5268 * Use trace_flag_type enum for the flags (see event-parse.h).
5269 */
5270int tep_data_flags(struct tep_handle *pevent, struct tep_record *rec)
5271{
5272 return parse_common_flags(pevent, rec->data);
5273}
5274
5275/**
5276 * tep_data_comm_from_pid - return the command line from PID
5277 * @pevent: a handle to the pevent
5278 * @pid: the PID of the task to search for
5279 *
5280 * This returns a pointer to the command line that has the given
5281 * @pid.
5282 */
5283const char *tep_data_comm_from_pid(struct tep_handle *pevent, int pid)
5284{
5285 const char *comm;
5286
5287 comm = find_cmdline(pevent, pid);
5288 return comm;
5289}
5290
5291static struct cmdline *
5292pid_from_cmdlist(struct tep_handle *pevent, const char *comm, struct cmdline *next)
5293{
5294 struct cmdline_list *cmdlist = (struct cmdline_list *)next;
5295
5296 if (cmdlist)
5297 cmdlist = cmdlist->next;
5298 else
5299 cmdlist = pevent->cmdlist;
5300
5301 while (cmdlist && strcmp(cmdlist->comm, comm) != 0)
5302 cmdlist = cmdlist->next;
5303
5304 return (struct cmdline *)cmdlist;
5305}
5306
5307/**
5308 * tep_data_pid_from_comm - return the pid from a given comm
5309 * @pevent: a handle to the pevent
5310 * @comm: the cmdline to find the pid from
5311 * @next: the cmdline structure to find the next comm
5312 *
5313 * This returns the cmdline structure that holds a pid for a given
5314 * comm, or NULL if none found. As there may be more than one pid for
5315 * a given comm, the result of this call can be passed back into
5316 * a recurring call in the @next paramater, and then it will find the
5317 * next pid.
5318 * Also, it does a linear seach, so it may be slow.
5319 */
5320struct cmdline *tep_data_pid_from_comm(struct tep_handle *pevent, const char *comm,
5321 struct cmdline *next)
5322{
5323 struct cmdline *cmdline;
5324
5325 /*
5326 * If the cmdlines have not been converted yet, then use
5327 * the list.
5328 */
5329 if (!pevent->cmdlines)
5330 return pid_from_cmdlist(pevent, comm, next);
5331
5332 if (next) {
5333 /*
5334 * The next pointer could have been still from
5335 * a previous call before cmdlines were created
5336 */
5337 if (next < pevent->cmdlines ||
5338 next >= pevent->cmdlines + pevent->cmdline_count)
5339 next = NULL;
5340 else
5341 cmdline = next++;
5342 }
5343
5344 if (!next)
5345 cmdline = pevent->cmdlines;
5346
5347 while (cmdline < pevent->cmdlines + pevent->cmdline_count) {
5348 if (strcmp(cmdline->comm, comm) == 0)
5349 return cmdline;
5350 cmdline++;
5351 }
5352 return NULL;
5353}
5354
5355/**
5356 * tep_cmdline_pid - return the pid associated to a given cmdline
5357 * @cmdline: The cmdline structure to get the pid from
5358 *
5359 * Returns the pid for a give cmdline. If @cmdline is NULL, then
5360 * -1 is returned.
5361 */
5362int tep_cmdline_pid(struct tep_handle *pevent, struct cmdline *cmdline)
5363{
5364 struct cmdline_list *cmdlist = (struct cmdline_list *)cmdline;
5365
5366 if (!cmdline)
5367 return -1;
5368
5369 /*
5370 * If cmdlines have not been created yet, or cmdline is
5371 * not part of the array, then treat it as a cmdlist instead.
5372 */
5373 if (!pevent->cmdlines ||
5374 cmdline < pevent->cmdlines ||
5375 cmdline >= pevent->cmdlines + pevent->cmdline_count)
5376 return cmdlist->pid;
5377
5378 return cmdline->pid;
5379}
5380
5381/**
5382 * tep_event_info - parse the data into the print format
5383 * @s: the trace_seq to write to
5384 * @event: the handle to the event
5385 * @record: the record to read from
5386 *
5387 * This parses the raw @data using the given @event information and
5388 * writes the print format into the trace_seq.
5389 */
5390void tep_event_info(struct trace_seq *s, struct tep_event_format *event,
5391 struct tep_record *record)
5392{
5393 int print_pretty = 1;
5394
5395 if (event->pevent->print_raw || (event->flags & TEP_EVENT_FL_PRINTRAW))
5396 tep_print_fields(s, record->data, record->size, event);
5397 else {
5398
5399 if (event->handler && !(event->flags & TEP_EVENT_FL_NOHANDLE))
5400 print_pretty = event->handler(s, record, event,
5401 event->context);
5402
5403 if (print_pretty)
5404 pretty_print(s, record->data, record->size, event);
5405 }
5406
5407 trace_seq_terminate(s);
5408}
5409
5410static bool is_timestamp_in_us(char *trace_clock, bool use_trace_clock)
5411{
5412 if (!use_trace_clock)
5413 return true;
5414
5415 if (!strcmp(trace_clock, "local") || !strcmp(trace_clock, "global")
5416 || !strcmp(trace_clock, "uptime") || !strcmp(trace_clock, "perf"))
5417 return true;
5418
5419 /* trace_clock is setting in tsc or counter mode */
5420 return false;
5421}
5422
5423/**
5424 * tep_find_event_by_record - return the event from a given record
5425 * @pevent: a handle to the pevent
5426 * @record: The record to get the event from
5427 *
5428 * Returns the associated event for a given record, or NULL if non is
5429 * is found.
5430 */
5431struct tep_event_format *
5432tep_find_event_by_record(struct tep_handle *pevent, struct tep_record *record)
5433{
5434 int type;
5435
5436 if (record->size < 0) {
5437 do_warning("ug! negative record size %d", record->size);
5438 return NULL;
5439 }
5440
5441 type = trace_parse_common_type(pevent, record->data);
5442
5443 return tep_find_event(pevent, type);
5444}
5445
5446/**
5447 * tep_print_event_task - Write the event task comm, pid and CPU
5448 * @pevent: a handle to the pevent
5449 * @s: the trace_seq to write to
5450 * @event: the handle to the record's event
5451 * @record: The record to get the event from
5452 *
5453 * Writes the tasks comm, pid and CPU to @s.
5454 */
5455void tep_print_event_task(struct tep_handle *pevent, struct trace_seq *s,
5456 struct tep_event_format *event,
5457 struct tep_record *record)
5458{
5459 void *data = record->data;
5460 const char *comm;
5461 int pid;
5462
5463 pid = parse_common_pid(pevent, data);
5464 comm = find_cmdline(pevent, pid);
5465
5466 if (pevent->latency_format) {
5467 trace_seq_printf(s, "%8.8s-%-5d %3d",
5468 comm, pid, record->cpu);
5469 } else
5470 trace_seq_printf(s, "%16s-%-5d [%03d]", comm, pid, record->cpu);
5471}
5472
5473/**
5474 * tep_print_event_time - Write the event timestamp
5475 * @pevent: a handle to the pevent
5476 * @s: the trace_seq to write to
5477 * @event: the handle to the record's event
5478 * @record: The record to get the event from
5479 * @use_trace_clock: Set to parse according to the @pevent->trace_clock
5480 *
5481 * Writes the timestamp of the record into @s.
5482 */
5483void tep_print_event_time(struct tep_handle *pevent, struct trace_seq *s,
5484 struct tep_event_format *event,
5485 struct tep_record *record,
5486 bool use_trace_clock)
5487{
5488 unsigned long secs;
5489 unsigned long usecs;
5490 unsigned long nsecs;
5491 int p;
5492 bool use_usec_format;
5493
5494 use_usec_format = is_timestamp_in_us(pevent->trace_clock,
5495 use_trace_clock);
5496 if (use_usec_format) {
5497 secs = record->ts / NSEC_PER_SEC;
5498 nsecs = record->ts - secs * NSEC_PER_SEC;
5499 }
5500
5501 if (pevent->latency_format) {
5502 tep_data_lat_fmt(pevent, s, record);
5503 }
5504
5505 if (use_usec_format) {
5506 if (pevent->flags & TEP_NSEC_OUTPUT) {
5507 usecs = nsecs;
5508 p = 9;
5509 } else {
5510 usecs = (nsecs + 500) / NSEC_PER_USEC;
5511 /* To avoid usecs larger than 1 sec */
5512 if (usecs >= USEC_PER_SEC) {
5513 usecs -= USEC_PER_SEC;
5514 secs++;
5515 }
5516 p = 6;
5517 }
5518
5519 trace_seq_printf(s, " %5lu.%0*lu:", secs, p, usecs);
5520 } else
5521 trace_seq_printf(s, " %12llu:", record->ts);
5522}
5523
5524/**
5525 * tep_print_event_data - Write the event data section
5526 * @pevent: a handle to the pevent
5527 * @s: the trace_seq to write to
5528 * @event: the handle to the record's event
5529 * @record: The record to get the event from
5530 *
5531 * Writes the parsing of the record's data to @s.
5532 */
5533void tep_print_event_data(struct tep_handle *pevent, struct trace_seq *s,
5534 struct tep_event_format *event,
5535 struct tep_record *record)
5536{
5537 static const char *spaces = " "; /* 20 spaces */
5538 int len;
5539
5540 trace_seq_printf(s, " %s: ", event->name);
5541
5542 /* Space out the event names evenly. */
5543 len = strlen(event->name);
5544 if (len < 20)
5545 trace_seq_printf(s, "%.*s", 20 - len, spaces);
5546
5547 tep_event_info(s, event, record);
5548}
5549
5550void tep_print_event(struct tep_handle *pevent, struct trace_seq *s,
5551 struct tep_record *record, bool use_trace_clock)
5552{
5553 struct tep_event_format *event;
5554
5555 event = tep_find_event_by_record(pevent, record);
5556 if (!event) {
5557 int i;
5558 int type = trace_parse_common_type(pevent, record->data);
5559
5560 do_warning("ug! no event found for type %d", type);
5561 trace_seq_printf(s, "[UNKNOWN TYPE %d]", type);
5562 for (i = 0; i < record->size; i++)
5563 trace_seq_printf(s, " %02x",
5564 ((unsigned char *)record->data)[i]);
5565 return;
5566 }
5567
5568 tep_print_event_task(pevent, s, event, record);
5569 tep_print_event_time(pevent, s, event, record, use_trace_clock);
5570 tep_print_event_data(pevent, s, event, record);
5571}
5572
5573static int events_id_cmp(const void *a, const void *b)
5574{
5575 struct tep_event_format * const * ea = a;
5576 struct tep_event_format * const * eb = b;
5577
5578 if ((*ea)->id < (*eb)->id)
5579 return -1;
5580
5581 if ((*ea)->id > (*eb)->id)
5582 return 1;
5583
5584 return 0;
5585}
5586
5587static int events_name_cmp(const void *a, const void *b)
5588{
5589 struct tep_event_format * const * ea = a;
5590 struct tep_event_format * const * eb = b;
5591 int res;
5592
5593 res = strcmp((*ea)->name, (*eb)->name);
5594 if (res)
5595 return res;
5596
5597 res = strcmp((*ea)->system, (*eb)->system);
5598 if (res)
5599 return res;
5600
5601 return events_id_cmp(a, b);
5602}
5603
5604static int events_system_cmp(const void *a, const void *b)
5605{
5606 struct tep_event_format * const * ea = a;
5607 struct tep_event_format * const * eb = b;
5608 int res;
5609
5610 res = strcmp((*ea)->system, (*eb)->system);
5611 if (res)
5612 return res;
5613
5614 res = strcmp((*ea)->name, (*eb)->name);
5615 if (res)
5616 return res;
5617
5618 return events_id_cmp(a, b);
5619}
5620
5621struct tep_event_format **tep_list_events(struct tep_handle *pevent, enum tep_event_sort_type sort_type)
5622{
5623 struct tep_event_format **events;
5624 int (*sort)(const void *a, const void *b);
5625
5626 events = pevent->sort_events;
5627
5628 if (events && pevent->last_type == sort_type)
5629 return events;
5630
5631 if (!events) {
5632 events = malloc(sizeof(*events) * (pevent->nr_events + 1));
5633 if (!events)
5634 return NULL;
5635
5636 memcpy(events, pevent->events, sizeof(*events) * pevent->nr_events);
5637 events[pevent->nr_events] = NULL;
5638
5639 pevent->sort_events = events;
5640
5641 /* the internal events are sorted by id */
5642 if (sort_type == TEP_EVENT_SORT_ID) {
5643 pevent->last_type = sort_type;
5644 return events;
5645 }
5646 }
5647
5648 switch (sort_type) {
5649 case TEP_EVENT_SORT_ID:
5650 sort = events_id_cmp;
5651 break;
5652 case TEP_EVENT_SORT_NAME:
5653 sort = events_name_cmp;
5654 break;
5655 case TEP_EVENT_SORT_SYSTEM:
5656 sort = events_system_cmp;
5657 break;
5658 default:
5659 return events;
5660 }
5661
5662 qsort(events, pevent->nr_events, sizeof(*events), sort);
5663 pevent->last_type = sort_type;
5664
5665 return events;
5666}
5667
5668static struct tep_format_field **
5669get_event_fields(const char *type, const char *name,
5670 int count, struct tep_format_field *list)
5671{
5672 struct tep_format_field **fields;
5673 struct tep_format_field *field;
5674 int i = 0;
5675
5676 fields = malloc(sizeof(*fields) * (count + 1));
5677 if (!fields)
5678 return NULL;
5679
5680 for (field = list; field; field = field->next) {
5681 fields[i++] = field;
5682 if (i == count + 1) {
5683 do_warning("event %s has more %s fields than specified",
5684 name, type);
5685 i--;
5686 break;
5687 }
5688 }
5689
5690 if (i != count)
5691 do_warning("event %s has less %s fields than specified",
5692 name, type);
5693
5694 fields[i] = NULL;
5695
5696 return fields;
5697}
5698
5699/**
5700 * tep_event_common_fields - return a list of common fields for an event
5701 * @event: the event to return the common fields of.
5702 *
5703 * Returns an allocated array of fields. The last item in the array is NULL.
5704 * The array must be freed with free().
5705 */
5706struct tep_format_field **tep_event_common_fields(struct tep_event_format *event)
5707{
5708 return get_event_fields("common", event->name,
5709 event->format.nr_common,
5710 event->format.common_fields);
5711}
5712
5713/**
5714 * tep_event_fields - return a list of event specific fields for an event
5715 * @event: the event to return the fields of.
5716 *
5717 * Returns an allocated array of fields. The last item in the array is NULL.
5718 * The array must be freed with free().
5719 */
5720struct tep_format_field **tep_event_fields(struct tep_event_format *event)
5721{
5722 return get_event_fields("event", event->name,
5723 event->format.nr_fields,
5724 event->format.fields);
5725}
5726
5727static void print_fields(struct trace_seq *s, struct tep_print_flag_sym *field)
5728{
5729 trace_seq_printf(s, "{ %s, %s }", field->value, field->str);
5730 if (field->next) {
5731 trace_seq_puts(s, ", ");
5732 print_fields(s, field->next);
5733 }
5734}
5735
5736/* for debugging */
5737static void print_args(struct tep_print_arg *args)
5738{
5739 int print_paren = 1;
5740 struct trace_seq s;
5741
5742 switch (args->type) {
5743 case TEP_PRINT_NULL:
5744 printf("null");
5745 break;
5746 case TEP_PRINT_ATOM:
5747 printf("%s", args->atom.atom);
5748 break;
5749 case TEP_PRINT_FIELD:
5750 printf("REC->%s", args->field.name);
5751 break;
5752 case TEP_PRINT_FLAGS:
5753 printf("__print_flags(");
5754 print_args(args->flags.field);
5755 printf(", %s, ", args->flags.delim);
5756 trace_seq_init(&s);
5757 print_fields(&s, args->flags.flags);
5758 trace_seq_do_printf(&s);
5759 trace_seq_destroy(&s);
5760 printf(")");
5761 break;
5762 case TEP_PRINT_SYMBOL:
5763 printf("__print_symbolic(");
5764 print_args(args->symbol.field);
5765 printf(", ");
5766 trace_seq_init(&s);
5767 print_fields(&s, args->symbol.symbols);
5768 trace_seq_do_printf(&s);
5769 trace_seq_destroy(&s);
5770 printf(")");
5771 break;
5772 case TEP_PRINT_HEX:
5773 printf("__print_hex(");
5774 print_args(args->hex.field);
5775 printf(", ");
5776 print_args(args->hex.size);
5777 printf(")");
5778 break;
5779 case TEP_PRINT_HEX_STR:
5780 printf("__print_hex_str(");
5781 print_args(args->hex.field);
5782 printf(", ");
5783 print_args(args->hex.size);
5784 printf(")");
5785 break;
5786 case TEP_PRINT_INT_ARRAY:
5787 printf("__print_array(");
5788 print_args(args->int_array.field);
5789 printf(", ");
5790 print_args(args->int_array.count);
5791 printf(", ");
5792 print_args(args->int_array.el_size);
5793 printf(")");
5794 break;
5795 case TEP_PRINT_STRING:
5796 case TEP_PRINT_BSTRING:
5797 printf("__get_str(%s)", args->string.string);
5798 break;
5799 case TEP_PRINT_BITMASK:
5800 printf("__get_bitmask(%s)", args->bitmask.bitmask);
5801 break;
5802 case TEP_PRINT_TYPE:
5803 printf("(%s)", args->typecast.type);
5804 print_args(args->typecast.item);
5805 break;
5806 case TEP_PRINT_OP:
5807 if (strcmp(args->op.op, ":") == 0)
5808 print_paren = 0;
5809 if (print_paren)
5810 printf("(");
5811 print_args(args->op.left);
5812 printf(" %s ", args->op.op);
5813 print_args(args->op.right);
5814 if (print_paren)
5815 printf(")");
5816 break;
5817 default:
5818 /* we should warn... */
5819 return;
5820 }
5821 if (args->next) {
5822 printf("\n");
5823 print_args(args->next);
5824 }
5825}
5826
5827static void parse_header_field(const char *field,
5828 int *offset, int *size, int mandatory)
5829{
5830 unsigned long long save_input_buf_ptr;
5831 unsigned long long save_input_buf_siz;
5832 char *token;
5833 int type;
5834
5835 save_input_buf_ptr = input_buf_ptr;
5836 save_input_buf_siz = input_buf_siz;
5837
5838 if (read_expected(TEP_EVENT_ITEM, "field") < 0)
5839 return;
5840 if (read_expected(TEP_EVENT_OP, ":") < 0)
5841 return;
5842
5843 /* type */
5844 if (read_expect_type(TEP_EVENT_ITEM, &token) < 0)
5845 goto fail;
5846 free_token(token);
5847
5848 /*
5849 * If this is not a mandatory field, then test it first.
5850 */
5851 if (mandatory) {
5852 if (read_expected(TEP_EVENT_ITEM, field) < 0)
5853 return;
5854 } else {
5855 if (read_expect_type(TEP_EVENT_ITEM, &token) < 0)
5856 goto fail;
5857 if (strcmp(token, field) != 0)
5858 goto discard;
5859 free_token(token);
5860 }
5861
5862 if (read_expected(TEP_EVENT_OP, ";") < 0)
5863 return;
5864 if (read_expected(TEP_EVENT_ITEM, "offset") < 0)
5865 return;
5866 if (read_expected(TEP_EVENT_OP, ":") < 0)
5867 return;
5868 if (read_expect_type(TEP_EVENT_ITEM, &token) < 0)
5869 goto fail;
5870 *offset = atoi(token);
5871 free_token(token);
5872 if (read_expected(TEP_EVENT_OP, ";") < 0)
5873 return;
5874 if (read_expected(TEP_EVENT_ITEM, "size") < 0)
5875 return;
5876 if (read_expected(TEP_EVENT_OP, ":") < 0)
5877 return;
5878 if (read_expect_type(TEP_EVENT_ITEM, &token) < 0)
5879 goto fail;
5880 *size = atoi(token);
5881 free_token(token);
5882 if (read_expected(TEP_EVENT_OP, ";") < 0)
5883 return;
5884 type = read_token(&token);
5885 if (type != TEP_EVENT_NEWLINE) {
5886 /* newer versions of the kernel have a "signed" type */
5887 if (type != TEP_EVENT_ITEM)
5888 goto fail;
5889
5890 if (strcmp(token, "signed") != 0)
5891 goto fail;
5892
5893 free_token(token);
5894
5895 if (read_expected(TEP_EVENT_OP, ":") < 0)
5896 return;
5897
5898 if (read_expect_type(TEP_EVENT_ITEM, &token))
5899 goto fail;
5900
5901 free_token(token);
5902 if (read_expected(TEP_EVENT_OP, ";") < 0)
5903 return;
5904
5905 if (read_expect_type(TEP_EVENT_NEWLINE, &token))
5906 goto fail;
5907 }
5908 fail:
5909 free_token(token);
5910 return;
5911
5912 discard:
5913 input_buf_ptr = save_input_buf_ptr;
5914 input_buf_siz = save_input_buf_siz;
5915 *offset = 0;
5916 *size = 0;
5917 free_token(token);
5918}
5919
5920/**
5921 * tep_parse_header_page - parse the data stored in the header page
5922 * @pevent: the handle to the pevent
5923 * @buf: the buffer storing the header page format string
5924 * @size: the size of @buf
5925 * @long_size: the long size to use if there is no header
5926 *
5927 * This parses the header page format for information on the
5928 * ring buffer used. The @buf should be copied from
5929 *
5930 * /sys/kernel/debug/tracing/events/header_page
5931 */
5932int tep_parse_header_page(struct tep_handle *pevent, char *buf, unsigned long size,
5933 int long_size)
5934{
5935 int ignore;
5936
5937 if (!size) {
5938 /*
5939 * Old kernels did not have header page info.
5940 * Sorry but we just use what we find here in user space.
5941 */
5942 pevent->header_page_ts_size = sizeof(long long);
5943 pevent->header_page_size_size = long_size;
5944 pevent->header_page_data_offset = sizeof(long long) + long_size;
5945 pevent->old_format = 1;
5946 return -1;
5947 }
5948 init_input_buf(buf, size);
5949
5950 parse_header_field("timestamp", &pevent->header_page_ts_offset,
5951 &pevent->header_page_ts_size, 1);
5952 parse_header_field("commit", &pevent->header_page_size_offset,
5953 &pevent->header_page_size_size, 1);
5954 parse_header_field("overwrite", &pevent->header_page_overwrite,
5955 &ignore, 0);
5956 parse_header_field("data", &pevent->header_page_data_offset,
5957 &pevent->header_page_data_size, 1);
5958
5959 return 0;
5960}
5961
5962static int event_matches(struct tep_event_format *event,
5963 int id, const char *sys_name,
5964 const char *event_name)
5965{
5966 if (id >= 0 && id != event->id)
5967 return 0;
5968
5969 if (event_name && (strcmp(event_name, event->name) != 0))
5970 return 0;
5971
5972 if (sys_name && (strcmp(sys_name, event->system) != 0))
5973 return 0;
5974
5975 return 1;
5976}
5977
5978static void free_handler(struct event_handler *handle)
5979{
5980 free((void *)handle->sys_name);
5981 free((void *)handle->event_name);
5982 free(handle);
5983}
5984
5985static int find_event_handle(struct tep_handle *pevent, struct tep_event_format *event)
5986{
5987 struct event_handler *handle, **next;
5988
5989 for (next = &pevent->handlers; *next;
5990 next = &(*next)->next) {
5991 handle = *next;
5992 if (event_matches(event, handle->id,
5993 handle->sys_name,
5994 handle->event_name))
5995 break;
5996 }
5997
5998 if (!(*next))
5999 return 0;
6000
6001 pr_stat("overriding event (%d) %s:%s with new print handler",
6002 event->id, event->system, event->name);
6003
6004 event->handler = handle->func;
6005 event->context = handle->context;
6006
6007 *next = handle->next;
6008 free_handler(handle);
6009
6010 return 1;
6011}
6012
6013/**
6014 * __tep_parse_format - parse the event format
6015 * @buf: the buffer storing the event format string
6016 * @size: the size of @buf
6017 * @sys: the system the event belongs to
6018 *
6019 * This parses the event format and creates an event structure
6020 * to quickly parse raw data for a given event.
6021 *
6022 * These files currently come from:
6023 *
6024 * /sys/kernel/debug/tracing/events/.../.../format
6025 */
6026enum tep_errno __tep_parse_format(struct tep_event_format **eventp,
6027 struct tep_handle *pevent, const char *buf,
6028 unsigned long size, const char *sys)
6029{
6030 struct tep_event_format *event;
6031 int ret;
6032
6033 init_input_buf(buf, size);
6034
6035 *eventp = event = alloc_event();
6036 if (!event)
6037 return TEP_ERRNO__MEM_ALLOC_FAILED;
6038
6039 event->name = event_read_name();
6040 if (!event->name) {
6041 /* Bad event? */
6042 ret = TEP_ERRNO__MEM_ALLOC_FAILED;
6043 goto event_alloc_failed;
6044 }
6045
6046 if (strcmp(sys, "ftrace") == 0) {
6047 event->flags |= TEP_EVENT_FL_ISFTRACE;
6048
6049 if (strcmp(event->name, "bprint") == 0)
6050 event->flags |= TEP_EVENT_FL_ISBPRINT;
6051 }
6052
6053 event->id = event_read_id();
6054 if (event->id < 0) {
6055 ret = TEP_ERRNO__READ_ID_FAILED;
6056 /*
6057 * This isn't an allocation error actually.
6058 * But as the ID is critical, just bail out.
6059 */
6060 goto event_alloc_failed;
6061 }
6062
6063 event->system = strdup(sys);
6064 if (!event->system) {
6065 ret = TEP_ERRNO__MEM_ALLOC_FAILED;
6066 goto event_alloc_failed;
6067 }
6068
6069 /* Add pevent to event so that it can be referenced */
6070 event->pevent = pevent;
6071
6072 ret = event_read_format(event);
6073 if (ret < 0) {
6074 ret = TEP_ERRNO__READ_FORMAT_FAILED;
6075 goto event_parse_failed;
6076 }
6077
6078 /*
6079 * If the event has an override, don't print warnings if the event
6080 * print format fails to parse.
6081 */
6082 if (pevent && find_event_handle(pevent, event))
6083 show_warning = 0;
6084
6085 ret = event_read_print(event);
6086 show_warning = 1;
6087
6088 if (ret < 0) {
6089 ret = TEP_ERRNO__READ_PRINT_FAILED;
6090 goto event_parse_failed;
6091 }
6092
6093 if (!ret && (event->flags & TEP_EVENT_FL_ISFTRACE)) {
6094 struct tep_format_field *field;
6095 struct tep_print_arg *arg, **list;
6096
6097 /* old ftrace had no args */
6098 list = &event->print_fmt.args;
6099 for (field = event->format.fields; field; field = field->next) {
6100 arg = alloc_arg();
6101 if (!arg) {
6102 event->flags |= TEP_EVENT_FL_FAILED;
6103 return TEP_ERRNO__OLD_FTRACE_ARG_FAILED;
6104 }
6105 arg->type = TEP_PRINT_FIELD;
6106 arg->field.name = strdup(field->name);
6107 if (!arg->field.name) {
6108 event->flags |= TEP_EVENT_FL_FAILED;
6109 free_arg(arg);
6110 return TEP_ERRNO__OLD_FTRACE_ARG_FAILED;
6111 }
6112 arg->field.field = field;
6113 *list = arg;
6114 list = &arg->next;
6115 }
6116 return 0;
6117 }
6118
6119 return 0;
6120
6121 event_parse_failed:
6122 event->flags |= TEP_EVENT_FL_FAILED;
6123 return ret;
6124
6125 event_alloc_failed:
6126 free(event->system);
6127 free(event->name);
6128 free(event);
6129 *eventp = NULL;
6130 return ret;
6131}
6132
6133static enum tep_errno
6134__parse_event(struct tep_handle *pevent,
6135 struct tep_event_format **eventp,
6136 const char *buf, unsigned long size,
6137 const char *sys)
6138{
6139 int ret = __tep_parse_format(eventp, pevent, buf, size, sys);
6140 struct tep_event_format *event = *eventp;
6141
6142 if (event == NULL)
6143 return ret;
6144
6145 if (pevent && add_event(pevent, event)) {
6146 ret = TEP_ERRNO__MEM_ALLOC_FAILED;
6147 goto event_add_failed;
6148 }
6149
6150#define PRINT_ARGS 0
6151 if (PRINT_ARGS && event->print_fmt.args)
6152 print_args(event->print_fmt.args);
6153
6154 return 0;
6155
6156event_add_failed:
6157 tep_free_format(event);
6158 return ret;
6159}
6160
6161/**
6162 * tep_parse_format - parse the event format
6163 * @pevent: the handle to the pevent
6164 * @eventp: returned format
6165 * @buf: the buffer storing the event format string
6166 * @size: the size of @buf
6167 * @sys: the system the event belongs to
6168 *
6169 * This parses the event format and creates an event structure
6170 * to quickly parse raw data for a given event.
6171 *
6172 * These files currently come from:
6173 *
6174 * /sys/kernel/debug/tracing/events/.../.../format
6175 */
6176enum tep_errno tep_parse_format(struct tep_handle *pevent,
6177 struct tep_event_format **eventp,
6178 const char *buf,
6179 unsigned long size, const char *sys)
6180{
6181 return __parse_event(pevent, eventp, buf, size, sys);
6182}
6183
6184/**
6185 * tep_parse_event - parse the event format
6186 * @pevent: the handle to the pevent
6187 * @buf: the buffer storing the event format string
6188 * @size: the size of @buf
6189 * @sys: the system the event belongs to
6190 *
6191 * This parses the event format and creates an event structure
6192 * to quickly parse raw data for a given event.
6193 *
6194 * These files currently come from:
6195 *
6196 * /sys/kernel/debug/tracing/events/.../.../format
6197 */
6198enum tep_errno tep_parse_event(struct tep_handle *pevent, const char *buf,
6199 unsigned long size, const char *sys)
6200{
6201 struct tep_event_format *event = NULL;
6202 return __parse_event(pevent, &event, buf, size, sys);
6203}
6204
6205int get_field_val(struct trace_seq *s, struct tep_format_field *field,
6206 const char *name, struct tep_record *record,
6207 unsigned long long *val, int err)
6208{
6209 if (!field) {
6210 if (err)
6211 trace_seq_printf(s, "<CANT FIND FIELD %s>", name);
6212 return -1;
6213 }
6214
6215 if (tep_read_number_field(field, record->data, val)) {
6216 if (err)
6217 trace_seq_printf(s, " %s=INVALID", name);
6218 return -1;
6219 }
6220
6221 return 0;
6222}
6223
6224/**
6225 * tep_get_field_raw - return the raw pointer into the data field
6226 * @s: The seq to print to on error
6227 * @event: the event that the field is for
6228 * @name: The name of the field
6229 * @record: The record with the field name.
6230 * @len: place to store the field length.
6231 * @err: print default error if failed.
6232 *
6233 * Returns a pointer into record->data of the field and places
6234 * the length of the field in @len.
6235 *
6236 * On failure, it returns NULL.
6237 */
6238void *tep_get_field_raw(struct trace_seq *s, struct tep_event_format *event,
6239 const char *name, struct tep_record *record,
6240 int *len, int err)
6241{
6242 struct tep_format_field *field;
6243 void *data = record->data;
6244 unsigned offset;
6245 int dummy;
6246
6247 if (!event)
6248 return NULL;
6249
6250 field = tep_find_field(event, name);
6251
6252 if (!field) {
6253 if (err)
6254 trace_seq_printf(s, "<CANT FIND FIELD %s>", name);
6255 return NULL;
6256 }
6257
6258 /* Allow @len to be NULL */
6259 if (!len)
6260 len = &dummy;
6261
6262 offset = field->offset;
6263 if (field->flags & TEP_FIELD_IS_DYNAMIC) {
6264 offset = tep_read_number(event->pevent,
6265 data + offset, field->size);
6266 *len = offset >> 16;
6267 offset &= 0xffff;
6268 } else
6269 *len = field->size;
6270
6271 return data + offset;
6272}
6273
6274/**
6275 * tep_get_field_val - find a field and return its value
6276 * @s: The seq to print to on error
6277 * @event: the event that the field is for
6278 * @name: The name of the field
6279 * @record: The record with the field name.
6280 * @val: place to store the value of the field.
6281 * @err: print default error if failed.
6282 *
6283 * Returns 0 on success -1 on field not found.
6284 */
6285int tep_get_field_val(struct trace_seq *s, struct tep_event_format *event,
6286 const char *name, struct tep_record *record,
6287 unsigned long long *val, int err)
6288{
6289 struct tep_format_field *field;
6290
6291 if (!event)
6292 return -1;
6293
6294 field = tep_find_field(event, name);
6295
6296 return get_field_val(s, field, name, record, val, err);
6297}
6298
6299/**
6300 * tep_get_common_field_val - find a common field and return its value
6301 * @s: The seq to print to on error
6302 * @event: the event that the field is for
6303 * @name: The name of the field
6304 * @record: The record with the field name.
6305 * @val: place to store the value of the field.
6306 * @err: print default error if failed.
6307 *
6308 * Returns 0 on success -1 on field not found.
6309 */
6310int tep_get_common_field_val(struct trace_seq *s, struct tep_event_format *event,
6311 const char *name, struct tep_record *record,
6312 unsigned long long *val, int err)
6313{
6314 struct tep_format_field *field;
6315
6316 if (!event)
6317 return -1;
6318
6319 field = tep_find_common_field(event, name);
6320
6321 return get_field_val(s, field, name, record, val, err);
6322}
6323
6324/**
6325 * tep_get_any_field_val - find a any field and return its value
6326 * @s: The seq to print to on error
6327 * @event: the event that the field is for
6328 * @name: The name of the field
6329 * @record: The record with the field name.
6330 * @val: place to store the value of the field.
6331 * @err: print default error if failed.
6332 *
6333 * Returns 0 on success -1 on field not found.
6334 */
6335int tep_get_any_field_val(struct trace_seq *s, struct tep_event_format *event,
6336 const char *name, struct tep_record *record,
6337 unsigned long long *val, int err)
6338{
6339 struct tep_format_field *field;
6340
6341 if (!event)
6342 return -1;
6343
6344 field = tep_find_any_field(event, name);
6345
6346 return get_field_val(s, field, name, record, val, err);
6347}
6348
6349/**
6350 * tep_print_num_field - print a field and a format
6351 * @s: The seq to print to
6352 * @fmt: The printf format to print the field with.
6353 * @event: the event that the field is for
6354 * @name: The name of the field
6355 * @record: The record with the field name.
6356 * @err: print default error if failed.
6357 *
6358 * Returns: 0 on success, -1 field not found, or 1 if buffer is full.
6359 */
6360int tep_print_num_field(struct trace_seq *s, const char *fmt,
6361 struct tep_event_format *event, const char *name,
6362 struct tep_record *record, int err)
6363{
6364 struct tep_format_field *field = tep_find_field(event, name);
6365 unsigned long long val;
6366
6367 if (!field)
6368 goto failed;
6369
6370 if (tep_read_number_field(field, record->data, &val))
6371 goto failed;
6372
6373 return trace_seq_printf(s, fmt, val);
6374
6375 failed:
6376 if (err)
6377 trace_seq_printf(s, "CAN'T FIND FIELD \"%s\"", name);
6378 return -1;
6379}
6380
6381/**
6382 * tep_print_func_field - print a field and a format for function pointers
6383 * @s: The seq to print to
6384 * @fmt: The printf format to print the field with.
6385 * @event: the event that the field is for
6386 * @name: The name of the field
6387 * @record: The record with the field name.
6388 * @err: print default error if failed.
6389 *
6390 * Returns: 0 on success, -1 field not found, or 1 if buffer is full.
6391 */
6392int tep_print_func_field(struct trace_seq *s, const char *fmt,
6393 struct tep_event_format *event, const char *name,
6394 struct tep_record *record, int err)
6395{
6396 struct tep_format_field *field = tep_find_field(event, name);
6397 struct tep_handle *pevent = event->pevent;
6398 unsigned long long val;
6399 struct func_map *func;
6400 char tmp[128];
6401
6402 if (!field)
6403 goto failed;
6404
6405 if (tep_read_number_field(field, record->data, &val))
6406 goto failed;
6407
6408 func = find_func(pevent, val);
6409
6410 if (func)
6411 snprintf(tmp, 128, "%s/0x%llx", func->func, func->addr - val);
6412 else
6413 sprintf(tmp, "0x%08llx", val);
6414
6415 return trace_seq_printf(s, fmt, tmp);
6416
6417 failed:
6418 if (err)
6419 trace_seq_printf(s, "CAN'T FIND FIELD \"%s\"", name);
6420 return -1;
6421}
6422
6423static void free_func_handle(struct tep_function_handler *func)
6424{
6425 struct func_params *params;
6426
6427 free(func->name);
6428
6429 while (func->params) {
6430 params = func->params;
6431 func->params = params->next;
6432 free(params);
6433 }
6434
6435 free(func);
6436}
6437
6438/**
6439 * tep_register_print_function - register a helper function
6440 * @pevent: the handle to the pevent
6441 * @func: the function to process the helper function
6442 * @ret_type: the return type of the helper function
6443 * @name: the name of the helper function
6444 * @parameters: A list of enum tep_func_arg_type
6445 *
6446 * Some events may have helper functions in the print format arguments.
6447 * This allows a plugin to dynamically create a way to process one
6448 * of these functions.
6449 *
6450 * The @parameters is a variable list of tep_func_arg_type enums that
6451 * must end with TEP_FUNC_ARG_VOID.
6452 */
6453int tep_register_print_function(struct tep_handle *pevent,
6454 tep_func_handler func,
6455 enum tep_func_arg_type ret_type,
6456 char *name, ...)
6457{
6458 struct tep_function_handler *func_handle;
6459 struct func_params **next_param;
6460 struct func_params *param;
6461 enum tep_func_arg_type type;
6462 va_list ap;
6463 int ret;
6464
6465 func_handle = find_func_handler(pevent, name);
6466 if (func_handle) {
6467 /*
6468 * This is most like caused by the users own
6469 * plugins updating the function. This overrides the
6470 * system defaults.
6471 */
6472 pr_stat("override of function helper '%s'", name);
6473 remove_func_handler(pevent, name);
6474 }
6475
6476 func_handle = calloc(1, sizeof(*func_handle));
6477 if (!func_handle) {
6478 do_warning("Failed to allocate function handler");
6479 return TEP_ERRNO__MEM_ALLOC_FAILED;
6480 }
6481
6482 func_handle->ret_type = ret_type;
6483 func_handle->name = strdup(name);
6484 func_handle->func = func;
6485 if (!func_handle->name) {
6486 do_warning("Failed to allocate function name");
6487 free(func_handle);
6488 return TEP_ERRNO__MEM_ALLOC_FAILED;
6489 }
6490
6491 next_param = &(func_handle->params);
6492 va_start(ap, name);
6493 for (;;) {
6494 type = va_arg(ap, enum tep_func_arg_type);
6495 if (type == TEP_FUNC_ARG_VOID)
6496 break;
6497
6498 if (type >= TEP_FUNC_ARG_MAX_TYPES) {
6499 do_warning("Invalid argument type %d", type);
6500 ret = TEP_ERRNO__INVALID_ARG_TYPE;
6501 goto out_free;
6502 }
6503
6504 param = malloc(sizeof(*param));
6505 if (!param) {
6506 do_warning("Failed to allocate function param");
6507 ret = TEP_ERRNO__MEM_ALLOC_FAILED;
6508 goto out_free;
6509 }
6510 param->type = type;
6511 param->next = NULL;
6512
6513 *next_param = param;
6514 next_param = &(param->next);
6515
6516 func_handle->nr_args++;
6517 }
6518 va_end(ap);
6519
6520 func_handle->next = pevent->func_handlers;
6521 pevent->func_handlers = func_handle;
6522
6523 return 0;
6524 out_free:
6525 va_end(ap);
6526 free_func_handle(func_handle);
6527 return ret;
6528}
6529
6530/**
6531 * tep_unregister_print_function - unregister a helper function
6532 * @pevent: the handle to the pevent
6533 * @func: the function to process the helper function
6534 * @name: the name of the helper function
6535 *
6536 * This function removes existing print handler for function @name.
6537 *
6538 * Returns 0 if the handler was removed successully, -1 otherwise.
6539 */
6540int tep_unregister_print_function(struct tep_handle *pevent,
6541 tep_func_handler func, char *name)
6542{
6543 struct tep_function_handler *func_handle;
6544
6545 func_handle = find_func_handler(pevent, name);
6546 if (func_handle && func_handle->func == func) {
6547 remove_func_handler(pevent, name);
6548 return 0;
6549 }
6550 return -1;
6551}
6552
6553static struct tep_event_format *search_event(struct tep_handle *pevent, int id,
6554 const char *sys_name,
6555 const char *event_name)
6556{
6557 struct tep_event_format *event;
6558
6559 if (id >= 0) {
6560 /* search by id */
6561 event = tep_find_event(pevent, id);
6562 if (!event)
6563 return NULL;
6564 if (event_name && (strcmp(event_name, event->name) != 0))
6565 return NULL;
6566 if (sys_name && (strcmp(sys_name, event->system) != 0))
6567 return NULL;
6568 } else {
6569 event = tep_find_event_by_name(pevent, sys_name, event_name);
6570 if (!event)
6571 return NULL;
6572 }
6573 return event;
6574}
6575
6576/**
6577 * tep_register_event_handler - register a way to parse an event
6578 * @pevent: the handle to the pevent
6579 * @id: the id of the event to register
6580 * @sys_name: the system name the event belongs to
6581 * @event_name: the name of the event
6582 * @func: the function to call to parse the event information
6583 * @context: the data to be passed to @func
6584 *
6585 * This function allows a developer to override the parsing of
6586 * a given event. If for some reason the default print format
6587 * is not sufficient, this function will register a function
6588 * for an event to be used to parse the data instead.
6589 *
6590 * If @id is >= 0, then it is used to find the event.
6591 * else @sys_name and @event_name are used.
6592 */
6593int tep_register_event_handler(struct tep_handle *pevent, int id,
6594 const char *sys_name, const char *event_name,
6595 tep_event_handler_func func, void *context)
6596{
6597 struct tep_event_format *event;
6598 struct event_handler *handle;
6599
6600 event = search_event(pevent, id, sys_name, event_name);
6601 if (event == NULL)
6602 goto not_found;
6603
6604 pr_stat("overriding event (%d) %s:%s with new print handler",
6605 event->id, event->system, event->name);
6606
6607 event->handler = func;
6608 event->context = context;
6609 return 0;
6610
6611 not_found:
6612 /* Save for later use. */
6613 handle = calloc(1, sizeof(*handle));
6614 if (!handle) {
6615 do_warning("Failed to allocate event handler");
6616 return TEP_ERRNO__MEM_ALLOC_FAILED;
6617 }
6618
6619 handle->id = id;
6620 if (event_name)
6621 handle->event_name = strdup(event_name);
6622 if (sys_name)
6623 handle->sys_name = strdup(sys_name);
6624
6625 if ((event_name && !handle->event_name) ||
6626 (sys_name && !handle->sys_name)) {
6627 do_warning("Failed to allocate event/sys name");
6628 free((void *)handle->event_name);
6629 free((void *)handle->sys_name);
6630 free(handle);
6631 return TEP_ERRNO__MEM_ALLOC_FAILED;
6632 }
6633
6634 handle->func = func;
6635 handle->next = pevent->handlers;
6636 pevent->handlers = handle;
6637 handle->context = context;
6638
6639 return -1;
6640}
6641
6642static int handle_matches(struct event_handler *handler, int id,
6643 const char *sys_name, const char *event_name,
6644 tep_event_handler_func func, void *context)
6645{
6646 if (id >= 0 && id != handler->id)
6647 return 0;
6648
6649 if (event_name && (strcmp(event_name, handler->event_name) != 0))
6650 return 0;
6651
6652 if (sys_name && (strcmp(sys_name, handler->sys_name) != 0))
6653 return 0;
6654
6655 if (func != handler->func || context != handler->context)
6656 return 0;
6657
6658 return 1;
6659}
6660
6661/**
6662 * tep_unregister_event_handler - unregister an existing event handler
6663 * @pevent: the handle to the pevent
6664 * @id: the id of the event to unregister
6665 * @sys_name: the system name the handler belongs to
6666 * @event_name: the name of the event handler
6667 * @func: the function to call to parse the event information
6668 * @context: the data to be passed to @func
6669 *
6670 * This function removes existing event handler (parser).
6671 *
6672 * If @id is >= 0, then it is used to find the event.
6673 * else @sys_name and @event_name are used.
6674 *
6675 * Returns 0 if handler was removed successfully, -1 if event was not found.
6676 */
6677int tep_unregister_event_handler(struct tep_handle *pevent, int id,
6678 const char *sys_name, const char *event_name,
6679 tep_event_handler_func func, void *context)
6680{
6681 struct tep_event_format *event;
6682 struct event_handler *handle;
6683 struct event_handler **next;
6684
6685 event = search_event(pevent, id, sys_name, event_name);
6686 if (event == NULL)
6687 goto not_found;
6688
6689 if (event->handler == func && event->context == context) {
6690 pr_stat("removing override handler for event (%d) %s:%s. Going back to default handler.",
6691 event->id, event->system, event->name);
6692
6693 event->handler = NULL;
6694 event->context = NULL;
6695 return 0;
6696 }
6697
6698not_found:
6699 for (next = &pevent->handlers; *next; next = &(*next)->next) {
6700 handle = *next;
6701 if (handle_matches(handle, id, sys_name, event_name,
6702 func, context))
6703 break;
6704 }
6705
6706 if (!(*next))
6707 return -1;
6708
6709 *next = handle->next;
6710 free_handler(handle);
6711
6712 return 0;
6713}
6714
6715/**
6716 * tep_alloc - create a pevent handle
6717 */
6718struct tep_handle *tep_alloc(void)
6719{
6720 struct tep_handle *pevent = calloc(1, sizeof(*pevent));
6721
6722 if (pevent)
6723 pevent->ref_count = 1;
6724
6725 return pevent;
6726}
6727
6728void tep_ref(struct tep_handle *pevent)
6729{
6730 pevent->ref_count++;
6731}
6732
6733void tep_free_format_field(struct tep_format_field *field)
6734{
6735 free(field->type);
6736 if (field->alias != field->name)
6737 free(field->alias);
6738 free(field->name);
6739 free(field);
6740}
6741
6742static void free_format_fields(struct tep_format_field *field)
6743{
6744 struct tep_format_field *next;
6745
6746 while (field) {
6747 next = field->next;
6748 tep_free_format_field(field);
6749 field = next;
6750 }
6751}
6752
6753static void free_formats(struct tep_format *format)
6754{
6755 free_format_fields(format->common_fields);
6756 free_format_fields(format->fields);
6757}
6758
6759void tep_free_format(struct tep_event_format *event)
6760{
6761 free(event->name);
6762 free(event->system);
6763
6764 free_formats(&event->format);
6765
6766 free(event->print_fmt.format);
6767 free_args(event->print_fmt.args);
6768
6769 free(event);
6770}
6771
6772/**
6773 * tep_free - free a pevent handle
6774 * @pevent: the pevent handle to free
6775 */
6776void tep_free(struct tep_handle *pevent)
6777{
6778 struct cmdline_list *cmdlist, *cmdnext;
6779 struct func_list *funclist, *funcnext;
6780 struct printk_list *printklist, *printknext;
6781 struct tep_function_handler *func_handler;
6782 struct event_handler *handle;
6783 int i;
6784
6785 if (!pevent)
6786 return;
6787
6788 cmdlist = pevent->cmdlist;
6789 funclist = pevent->funclist;
6790 printklist = pevent->printklist;
6791
6792 pevent->ref_count--;
6793 if (pevent->ref_count)
6794 return;
6795
6796 if (pevent->cmdlines) {
6797 for (i = 0; i < pevent->cmdline_count; i++)
6798 free(pevent->cmdlines[i].comm);
6799 free(pevent->cmdlines);
6800 }
6801
6802 while (cmdlist) {
6803 cmdnext = cmdlist->next;
6804 free(cmdlist->comm);
6805 free(cmdlist);
6806 cmdlist = cmdnext;
6807 }
6808
6809 if (pevent->func_map) {
6810 for (i = 0; i < (int)pevent->func_count; i++) {
6811 free(pevent->func_map[i].func);
6812 free(pevent->func_map[i].mod);
6813 }
6814 free(pevent->func_map);
6815 }
6816
6817 while (funclist) {
6818 funcnext = funclist->next;
6819 free(funclist->func);
6820 free(funclist->mod);
6821 free(funclist);
6822 funclist = funcnext;
6823 }
6824
6825 while (pevent->func_handlers) {
6826 func_handler = pevent->func_handlers;
6827 pevent->func_handlers = func_handler->next;
6828 free_func_handle(func_handler);
6829 }
6830
6831 if (pevent->printk_map) {
6832 for (i = 0; i < (int)pevent->printk_count; i++)
6833 free(pevent->printk_map[i].printk);
6834 free(pevent->printk_map);
6835 }
6836
6837 while (printklist) {
6838 printknext = printklist->next;
6839 free(printklist->printk);
6840 free(printklist);
6841 printklist = printknext;
6842 }
6843
6844 for (i = 0; i < pevent->nr_events; i++)
6845 tep_free_format(pevent->events[i]);
6846
6847 while (pevent->handlers) {
6848 handle = pevent->handlers;
6849 pevent->handlers = handle->next;
6850 free_handler(handle);
6851 }
6852
6853 free(pevent->trace_clock);
6854 free(pevent->events);
6855 free(pevent->sort_events);
6856 free(pevent->func_resolver);
6857
6858 free(pevent);
6859}
6860
6861void tep_unref(struct tep_handle *pevent)
6862{
6863 tep_free(pevent);
6864}