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