1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21#ifndef _PARSE_EVENTS_H
22#define _PARSE_EVENTS_H
23
24#include <stdarg.h>
25#include <regex.h>
26
27#ifndef __maybe_unused
28#define __maybe_unused __attribute__((unused))
29#endif
30
31
32
33
34#ifndef TRACE_SEQ_BUF_SIZE
35#define TRACE_SEQ_BUF_SIZE 4096
36#endif
37
38#ifndef DEBUG_RECORD
39#define DEBUG_RECORD 0
40#endif
41
42struct pevent_record {
43 unsigned long long ts;
44 unsigned long long offset;
45 long long missed_events;
46 int record_size;
47 int size;
48 void *data;
49 int cpu;
50 int ref_count;
51 int locked;
52 void *priv;
53#if DEBUG_RECORD
54 struct pevent_record *prev;
55 struct pevent_record *next;
56 long alloc_addr;
57#endif
58};
59
60
61
62
63
64
65struct trace_seq {
66 char *buffer;
67 unsigned int buffer_size;
68 unsigned int len;
69 unsigned int readpos;
70};
71
72void trace_seq_init(struct trace_seq *s);
73void trace_seq_destroy(struct trace_seq *s);
74
75extern int trace_seq_printf(struct trace_seq *s, const char *fmt, ...)
76 __attribute__ ((format (printf, 2, 3)));
77extern int trace_seq_vprintf(struct trace_seq *s, const char *fmt, va_list args)
78 __attribute__ ((format (printf, 2, 0)));
79
80extern int trace_seq_puts(struct trace_seq *s, const char *str);
81extern int trace_seq_putc(struct trace_seq *s, unsigned char c);
82
83extern void trace_seq_terminate(struct trace_seq *s);
84
85extern int trace_seq_do_printf(struct trace_seq *s);
86
87
88
89
90struct pevent;
91struct event_format;
92
93typedef int (*pevent_event_handler_func)(struct trace_seq *s,
94 struct pevent_record *record,
95 struct event_format *event,
96 void *context);
97
98typedef int (*pevent_plugin_load_func)(struct pevent *pevent);
99typedef int (*pevent_plugin_unload_func)(void);
100
101struct plugin_option {
102 struct plugin_option *next;
103 void *handle;
104 char *file;
105 char *name;
106 char *plugin_alias;
107 char *description;
108 char *value;
109 void *priv;
110 int set;
111};
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149#define PEVENT_PLUGIN_LOADER pevent_plugin_loader
150#define PEVENT_PLUGIN_UNLOADER pevent_plugin_unloader
151#define PEVENT_PLUGIN_OPTIONS pevent_plugin_options
152#define PEVENT_PLUGIN_ALIAS pevent_plugin_alias
153#define _MAKE_STR(x) #x
154#define MAKE_STR(x) _MAKE_STR(x)
155#define PEVENT_PLUGIN_LOADER_NAME MAKE_STR(PEVENT_PLUGIN_LOADER)
156#define PEVENT_PLUGIN_UNLOADER_NAME MAKE_STR(PEVENT_PLUGIN_UNLOADER)
157#define PEVENT_PLUGIN_OPTIONS_NAME MAKE_STR(PEVENT_PLUGIN_OPTIONS)
158#define PEVENT_PLUGIN_ALIAS_NAME MAKE_STR(PEVENT_PLUGIN_ALIAS)
159
160#define NSECS_PER_SEC 1000000000ULL
161#define NSECS_PER_USEC 1000ULL
162
163enum format_flags {
164 FIELD_IS_ARRAY = 1,
165 FIELD_IS_POINTER = 2,
166 FIELD_IS_SIGNED = 4,
167 FIELD_IS_STRING = 8,
168 FIELD_IS_DYNAMIC = 16,
169 FIELD_IS_LONG = 32,
170 FIELD_IS_FLAG = 64,
171 FIELD_IS_SYMBOLIC = 128,
172};
173
174struct format_field {
175 struct format_field *next;
176 struct event_format *event;
177 char *type;
178 char *name;
179 int offset;
180 int size;
181 unsigned int arraylen;
182 unsigned int elementsize;
183 unsigned long flags;
184};
185
186struct format {
187 int nr_common;
188 int nr_fields;
189 struct format_field *common_fields;
190 struct format_field *fields;
191};
192
193struct print_arg_atom {
194 char *atom;
195};
196
197struct print_arg_string {
198 char *string;
199 int offset;
200};
201
202struct print_arg_field {
203 char *name;
204 struct format_field *field;
205};
206
207struct print_flag_sym {
208 struct print_flag_sym *next;
209 char *value;
210 char *str;
211};
212
213struct print_arg_typecast {
214 char *type;
215 struct print_arg *item;
216};
217
218struct print_arg_flags {
219 struct print_arg *field;
220 char *delim;
221 struct print_flag_sym *flags;
222};
223
224struct print_arg_symbol {
225 struct print_arg *field;
226 struct print_flag_sym *symbols;
227};
228
229struct print_arg_hex {
230 struct print_arg *field;
231 struct print_arg *size;
232};
233
234struct print_arg_dynarray {
235 struct format_field *field;
236 struct print_arg *index;
237};
238
239struct print_arg;
240
241struct print_arg_op {
242 char *op;
243 int prio;
244 struct print_arg *left;
245 struct print_arg *right;
246};
247
248struct pevent_function_handler;
249
250struct print_arg_func {
251 struct pevent_function_handler *func;
252 struct print_arg *args;
253};
254
255enum print_arg_type {
256 PRINT_NULL,
257 PRINT_ATOM,
258 PRINT_FIELD,
259 PRINT_FLAGS,
260 PRINT_SYMBOL,
261 PRINT_HEX,
262 PRINT_TYPE,
263 PRINT_STRING,
264 PRINT_BSTRING,
265 PRINT_DYNAMIC_ARRAY,
266 PRINT_OP,
267 PRINT_FUNC,
268};
269
270struct print_arg {
271 struct print_arg *next;
272 enum print_arg_type type;
273 union {
274 struct print_arg_atom atom;
275 struct print_arg_field field;
276 struct print_arg_typecast typecast;
277 struct print_arg_flags flags;
278 struct print_arg_symbol symbol;
279 struct print_arg_hex hex;
280 struct print_arg_func func;
281 struct print_arg_string string;
282 struct print_arg_op op;
283 struct print_arg_dynarray dynarray;
284 };
285};
286
287struct print_fmt {
288 char *format;
289 struct print_arg *args;
290};
291
292struct event_format {
293 struct pevent *pevent;
294 char *name;
295 int id;
296 int flags;
297 struct format format;
298 struct print_fmt print_fmt;
299 char *system;
300 pevent_event_handler_func handler;
301 void *context;
302};
303
304enum {
305 EVENT_FL_ISFTRACE = 0x01,
306 EVENT_FL_ISPRINT = 0x02,
307 EVENT_FL_ISBPRINT = 0x04,
308 EVENT_FL_ISFUNCENT = 0x10,
309 EVENT_FL_ISFUNCRET = 0x20,
310
311 EVENT_FL_FAILED = 0x80000000
312};
313
314enum event_sort_type {
315 EVENT_SORT_ID,
316 EVENT_SORT_NAME,
317 EVENT_SORT_SYSTEM,
318};
319
320enum event_type {
321 EVENT_ERROR,
322 EVENT_NONE,
323 EVENT_SPACE,
324 EVENT_NEWLINE,
325 EVENT_OP,
326 EVENT_DELIM,
327 EVENT_ITEM,
328 EVENT_DQUOTE,
329 EVENT_SQUOTE,
330};
331
332typedef unsigned long long (*pevent_func_handler)(struct trace_seq *s,
333 unsigned long long *args);
334
335enum pevent_func_arg_type {
336 PEVENT_FUNC_ARG_VOID,
337 PEVENT_FUNC_ARG_INT,
338 PEVENT_FUNC_ARG_LONG,
339 PEVENT_FUNC_ARG_STRING,
340 PEVENT_FUNC_ARG_PTR,
341 PEVENT_FUNC_ARG_MAX_TYPES
342};
343
344enum pevent_flag {
345 PEVENT_NSEC_OUTPUT = 1,
346};
347
348#define PEVENT_ERRORS \
349 _PE(MEM_ALLOC_FAILED, "failed to allocate memory"), \
350 _PE(PARSE_EVENT_FAILED, "failed to parse event"), \
351 _PE(READ_ID_FAILED, "failed to read event id"), \
352 _PE(READ_FORMAT_FAILED, "failed to read event format"), \
353 _PE(READ_PRINT_FAILED, "failed to read event print fmt"), \
354 _PE(OLD_FTRACE_ARG_FAILED,"failed to allocate field name for ftrace"),\
355 _PE(INVALID_ARG_TYPE, "invalid argument type")
356
357#undef _PE
358#define _PE(__code, __str) PEVENT_ERRNO__ ## __code
359enum pevent_errno {
360 PEVENT_ERRNO__SUCCESS = 0,
361
362
363
364
365
366
367
368
369 __PEVENT_ERRNO__START = -100000,
370
371 PEVENT_ERRORS,
372
373 __PEVENT_ERRNO__END,
374};
375#undef _PE
376
377struct cmdline;
378struct cmdline_list;
379struct func_map;
380struct func_list;
381struct event_handler;
382
383struct pevent {
384 int ref_count;
385
386 int header_page_ts_offset;
387 int header_page_ts_size;
388 int header_page_size_offset;
389 int header_page_size_size;
390 int header_page_data_offset;
391 int header_page_data_size;
392 int header_page_overwrite;
393
394 int file_bigendian;
395 int host_bigendian;
396
397 int latency_format;
398
399 int old_format;
400
401 int cpus;
402 int long_size;
403
404 struct cmdline *cmdlines;
405 struct cmdline_list *cmdlist;
406 int cmdline_count;
407
408 struct func_map *func_map;
409 struct func_list *funclist;
410 unsigned int func_count;
411
412 struct printk_map *printk_map;
413 struct printk_list *printklist;
414 unsigned int printk_count;
415
416
417 struct event_format **events;
418 int nr_events;
419 struct event_format **sort_events;
420 enum event_sort_type last_type;
421
422 int type_offset;
423 int type_size;
424
425 int pid_offset;
426 int pid_size;
427
428 int pc_offset;
429 int pc_size;
430
431 int flags_offset;
432 int flags_size;
433
434 int ld_offset;
435 int ld_size;
436
437 int print_raw;
438
439 int test_filters;
440
441 int flags;
442
443 struct format_field *bprint_ip_field;
444 struct format_field *bprint_fmt_field;
445 struct format_field *bprint_buf_field;
446
447 struct event_handler *handlers;
448 struct pevent_function_handler *func_handlers;
449
450
451 struct event_format *last_event;
452};
453
454static inline void pevent_set_flag(struct pevent *pevent, int flag)
455{
456 pevent->flags |= flag;
457}
458
459static inline unsigned short
460__data2host2(struct pevent *pevent, unsigned short data)
461{
462 unsigned short swap;
463
464 if (pevent->host_bigendian == pevent->file_bigendian)
465 return data;
466
467 swap = ((data & 0xffULL) << 8) |
468 ((data & (0xffULL << 8)) >> 8);
469
470 return swap;
471}
472
473static inline unsigned int
474__data2host4(struct pevent *pevent, unsigned int data)
475{
476 unsigned int swap;
477
478 if (pevent->host_bigendian == pevent->file_bigendian)
479 return data;
480
481 swap = ((data & 0xffULL) << 24) |
482 ((data & (0xffULL << 8)) << 8) |
483 ((data & (0xffULL << 16)) >> 8) |
484 ((data & (0xffULL << 24)) >> 24);
485
486 return swap;
487}
488
489static inline unsigned long long
490__data2host8(struct pevent *pevent, unsigned long long data)
491{
492 unsigned long long swap;
493
494 if (pevent->host_bigendian == pevent->file_bigendian)
495 return data;
496
497 swap = ((data & 0xffULL) << 56) |
498 ((data & (0xffULL << 8)) << 40) |
499 ((data & (0xffULL << 16)) << 24) |
500 ((data & (0xffULL << 24)) << 8) |
501 ((data & (0xffULL << 32)) >> 8) |
502 ((data & (0xffULL << 40)) >> 24) |
503 ((data & (0xffULL << 48)) >> 40) |
504 ((data & (0xffULL << 56)) >> 56);
505
506 return swap;
507}
508
509#define data2host2(pevent, ptr) __data2host2(pevent, *(unsigned short *)(ptr))
510#define data2host4(pevent, ptr) __data2host4(pevent, *(unsigned int *)(ptr))
511#define data2host8(pevent, ptr) \
512({ \
513 unsigned long long __val; \
514 \
515 memcpy(&__val, (ptr), sizeof(unsigned long long)); \
516 __data2host8(pevent, __val); \
517})
518
519
520enum trace_flag_type {
521 TRACE_FLAG_IRQS_OFF = 0x01,
522 TRACE_FLAG_IRQS_NOSUPPORT = 0x02,
523 TRACE_FLAG_NEED_RESCHED = 0x04,
524 TRACE_FLAG_HARDIRQ = 0x08,
525 TRACE_FLAG_SOFTIRQ = 0x10,
526};
527
528int pevent_register_comm(struct pevent *pevent, const char *comm, int pid);
529int pevent_register_function(struct pevent *pevent, char *name,
530 unsigned long long addr, char *mod);
531int pevent_register_print_string(struct pevent *pevent, char *fmt,
532 unsigned long long addr);
533int pevent_pid_is_registered(struct pevent *pevent, int pid);
534
535void pevent_print_event(struct pevent *pevent, struct trace_seq *s,
536 struct pevent_record *record);
537
538int pevent_parse_header_page(struct pevent *pevent, char *buf, unsigned long size,
539 int long_size);
540
541enum pevent_errno pevent_parse_event(struct pevent *pevent, const char *buf,
542 unsigned long size, const char *sys);
543enum pevent_errno pevent_parse_format(struct event_format **eventp, const char *buf,
544 unsigned long size, const char *sys);
545void pevent_free_format(struct event_format *event);
546
547void *pevent_get_field_raw(struct trace_seq *s, struct event_format *event,
548 const char *name, struct pevent_record *record,
549 int *len, int err);
550
551int pevent_get_field_val(struct trace_seq *s, struct event_format *event,
552 const char *name, struct pevent_record *record,
553 unsigned long long *val, int err);
554int pevent_get_common_field_val(struct trace_seq *s, struct event_format *event,
555 const char *name, struct pevent_record *record,
556 unsigned long long *val, int err);
557int pevent_get_any_field_val(struct trace_seq *s, struct event_format *event,
558 const char *name, struct pevent_record *record,
559 unsigned long long *val, int err);
560
561int pevent_print_num_field(struct trace_seq *s, const char *fmt,
562 struct event_format *event, const char *name,
563 struct pevent_record *record, int err);
564
565int pevent_register_event_handler(struct pevent *pevent, int id, char *sys_name, char *event_name,
566 pevent_event_handler_func func, void *context);
567int pevent_register_print_function(struct pevent *pevent,
568 pevent_func_handler func,
569 enum pevent_func_arg_type ret_type,
570 char *name, ...);
571
572struct format_field *pevent_find_common_field(struct event_format *event, const char *name);
573struct format_field *pevent_find_field(struct event_format *event, const char *name);
574struct format_field *pevent_find_any_field(struct event_format *event, const char *name);
575
576const char *pevent_find_function(struct pevent *pevent, unsigned long long addr);
577unsigned long long
578pevent_find_function_address(struct pevent *pevent, unsigned long long addr);
579unsigned long long pevent_read_number(struct pevent *pevent, const void *ptr, int size);
580int pevent_read_number_field(struct format_field *field, const void *data,
581 unsigned long long *value);
582
583struct event_format *pevent_find_event(struct pevent *pevent, int id);
584
585struct event_format *
586pevent_find_event_by_name(struct pevent *pevent, const char *sys, const char *name);
587
588void pevent_data_lat_fmt(struct pevent *pevent,
589 struct trace_seq *s, struct pevent_record *record);
590int pevent_data_type(struct pevent *pevent, struct pevent_record *rec);
591struct event_format *pevent_data_event_from_type(struct pevent *pevent, int type);
592int pevent_data_pid(struct pevent *pevent, struct pevent_record *rec);
593const char *pevent_data_comm_from_pid(struct pevent *pevent, int pid);
594void pevent_event_info(struct trace_seq *s, struct event_format *event,
595 struct pevent_record *record);
596int pevent_strerror(struct pevent *pevent, enum pevent_errno errnum,
597 char *buf, size_t buflen);
598
599struct event_format **pevent_list_events(struct pevent *pevent, enum event_sort_type);
600struct format_field **pevent_event_common_fields(struct event_format *event);
601struct format_field **pevent_event_fields(struct event_format *event);
602
603static inline int pevent_get_cpus(struct pevent *pevent)
604{
605 return pevent->cpus;
606}
607
608static inline void pevent_set_cpus(struct pevent *pevent, int cpus)
609{
610 pevent->cpus = cpus;
611}
612
613static inline int pevent_get_long_size(struct pevent *pevent)
614{
615 return pevent->long_size;
616}
617
618static inline void pevent_set_long_size(struct pevent *pevent, int long_size)
619{
620 pevent->long_size = long_size;
621}
622
623static inline int pevent_is_file_bigendian(struct pevent *pevent)
624{
625 return pevent->file_bigendian;
626}
627
628static inline void pevent_set_file_bigendian(struct pevent *pevent, int endian)
629{
630 pevent->file_bigendian = endian;
631}
632
633static inline int pevent_is_host_bigendian(struct pevent *pevent)
634{
635 return pevent->host_bigendian;
636}
637
638static inline void pevent_set_host_bigendian(struct pevent *pevent, int endian)
639{
640 pevent->host_bigendian = endian;
641}
642
643static inline int pevent_is_latency_format(struct pevent *pevent)
644{
645 return pevent->latency_format;
646}
647
648static inline void pevent_set_latency_format(struct pevent *pevent, int lat)
649{
650 pevent->latency_format = lat;
651}
652
653struct pevent *pevent_alloc(void);
654void pevent_free(struct pevent *pevent);
655void pevent_ref(struct pevent *pevent);
656void pevent_unref(struct pevent *pevent);
657
658
659void pevent_buffer_init(const char *buf, unsigned long long size);
660enum event_type pevent_read_token(char **tok);
661void pevent_free_token(char *token);
662int pevent_peek_char(void);
663const char *pevent_get_input_buf(void);
664unsigned long long pevent_get_input_buf_ptr(void);
665
666
667void pevent_print_funcs(struct pevent *pevent);
668void pevent_print_printk(struct pevent *pevent);
669
670
671
672enum filter_boolean_type {
673 FILTER_FALSE,
674 FILTER_TRUE,
675};
676
677enum filter_op_type {
678 FILTER_OP_AND = 1,
679 FILTER_OP_OR,
680 FILTER_OP_NOT,
681};
682
683enum filter_cmp_type {
684 FILTER_CMP_NONE,
685 FILTER_CMP_EQ,
686 FILTER_CMP_NE,
687 FILTER_CMP_GT,
688 FILTER_CMP_LT,
689 FILTER_CMP_GE,
690 FILTER_CMP_LE,
691 FILTER_CMP_MATCH,
692 FILTER_CMP_NOT_MATCH,
693 FILTER_CMP_REGEX,
694 FILTER_CMP_NOT_REGEX,
695};
696
697enum filter_exp_type {
698 FILTER_EXP_NONE,
699 FILTER_EXP_ADD,
700 FILTER_EXP_SUB,
701 FILTER_EXP_MUL,
702 FILTER_EXP_DIV,
703 FILTER_EXP_MOD,
704 FILTER_EXP_RSHIFT,
705 FILTER_EXP_LSHIFT,
706 FILTER_EXP_AND,
707 FILTER_EXP_OR,
708 FILTER_EXP_XOR,
709 FILTER_EXP_NOT,
710};
711
712enum filter_arg_type {
713 FILTER_ARG_NONE,
714 FILTER_ARG_BOOLEAN,
715 FILTER_ARG_VALUE,
716 FILTER_ARG_FIELD,
717 FILTER_ARG_EXP,
718 FILTER_ARG_OP,
719 FILTER_ARG_NUM,
720 FILTER_ARG_STR,
721};
722
723enum filter_value_type {
724 FILTER_NUMBER,
725 FILTER_STRING,
726 FILTER_CHAR
727};
728
729struct fliter_arg;
730
731struct filter_arg_boolean {
732 enum filter_boolean_type value;
733};
734
735struct filter_arg_field {
736 struct format_field *field;
737};
738
739struct filter_arg_value {
740 enum filter_value_type type;
741 union {
742 char *str;
743 unsigned long long val;
744 };
745};
746
747struct filter_arg_op {
748 enum filter_op_type type;
749 struct filter_arg *left;
750 struct filter_arg *right;
751};
752
753struct filter_arg_exp {
754 enum filter_exp_type type;
755 struct filter_arg *left;
756 struct filter_arg *right;
757};
758
759struct filter_arg_num {
760 enum filter_cmp_type type;
761 struct filter_arg *left;
762 struct filter_arg *right;
763};
764
765struct filter_arg_str {
766 enum filter_cmp_type type;
767 struct format_field *field;
768 char *val;
769 char *buffer;
770 regex_t reg;
771};
772
773struct filter_arg {
774 enum filter_arg_type type;
775 union {
776 struct filter_arg_boolean boolean;
777 struct filter_arg_field field;
778 struct filter_arg_value value;
779 struct filter_arg_op op;
780 struct filter_arg_exp exp;
781 struct filter_arg_num num;
782 struct filter_arg_str str;
783 };
784};
785
786struct filter_type {
787 int event_id;
788 struct event_format *event;
789 struct filter_arg *filter;
790};
791
792struct event_filter {
793 struct pevent *pevent;
794 int filters;
795 struct filter_type *event_filters;
796};
797
798struct event_filter *pevent_filter_alloc(struct pevent *pevent);
799
800#define FILTER_NONE -2
801#define FILTER_NOEXIST -1
802#define FILTER_MISS 0
803#define FILTER_MATCH 1
804
805enum filter_trivial_type {
806 FILTER_TRIVIAL_FALSE,
807 FILTER_TRIVIAL_TRUE,
808 FILTER_TRIVIAL_BOTH,
809};
810
811int pevent_filter_add_filter_str(struct event_filter *filter,
812 const char *filter_str,
813 char **error_str);
814
815
816int pevent_filter_match(struct event_filter *filter,
817 struct pevent_record *record);
818
819int pevent_event_filtered(struct event_filter *filter,
820 int event_id);
821
822void pevent_filter_reset(struct event_filter *filter);
823
824void pevent_filter_clear_trivial(struct event_filter *filter,
825 enum filter_trivial_type type);
826
827void pevent_filter_free(struct event_filter *filter);
828
829char *pevent_filter_make_string(struct event_filter *filter, int event_id);
830
831int pevent_filter_remove_event(struct event_filter *filter,
832 int event_id);
833
834int pevent_filter_event_has_trivial(struct event_filter *filter,
835 int event_id,
836 enum filter_trivial_type type);
837
838int pevent_filter_copy(struct event_filter *dest, struct event_filter *source);
839
840int pevent_update_trivial(struct event_filter *dest, struct event_filter *source,
841 enum filter_trivial_type type);
842
843int pevent_filter_compare(struct event_filter *filter1, struct event_filter *filter2);
844
845#endif
846