aboutsummaryrefslogtreecommitdiff
path: root/tools/lib/traceevent/event-parse.h
diff options
context:
space:
mode:
Diffstat (limited to 'tools/lib/traceevent/event-parse.h')
-rw-r--r--tools/lib/traceevent/event-parse.h194
1 files changed, 167 insertions, 27 deletions
diff --git a/tools/lib/traceevent/event-parse.h b/tools/lib/traceevent/event-parse.h
index ac997bc7b59..7a3873ff9a4 100644
--- a/tools/lib/traceevent/event-parse.h
+++ b/tools/lib/traceevent/event-parse.h
@@ -13,19 +13,20 @@
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
- * License along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ * License along with this program; if not, see <http://www.gnu.org/licenses>
*
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*/
#ifndef _PARSE_EVENTS_H
#define _PARSE_EVENTS_H
+#include <stdbool.h>
#include <stdarg.h>
#include <regex.h>
+#include <string.h>
-#ifndef __unused
-#define __unused __attribute__ ((unused))
+#ifndef __maybe_unused
+#define __maybe_unused __attribute__((unused))
#endif
/* ----------------------- trace_seq ----------------------- */
@@ -49,7 +50,7 @@ struct pevent_record {
int cpu;
int ref_count;
int locked; /* Do not free, even if ref_count is zero */
- void *private;
+ void *priv;
#if DEBUG_RECORD
struct pevent_record *prev;
struct pevent_record *next;
@@ -57,6 +58,12 @@ struct pevent_record {
#endif
};
+enum trace_seq_fail {
+ TRACE_SEQ__GOOD,
+ TRACE_SEQ__BUFFER_POISONED,
+ TRACE_SEQ__MEM_ALLOC_FAILED,
+};
+
/*
* Trace sequences are used to allow a function to call several other functions
* to create a string of data to use (up to a max of PAGE_SIZE).
@@ -67,9 +74,11 @@ struct trace_seq {
unsigned int buffer_size;
unsigned int len;
unsigned int readpos;
+ enum trace_seq_fail state;
};
void trace_seq_init(struct trace_seq *s);
+void trace_seq_reset(struct trace_seq *s);
void trace_seq_destroy(struct trace_seq *s);
extern int trace_seq_printf(struct trace_seq *s, const char *fmt, ...)
@@ -96,17 +105,17 @@ typedef int (*pevent_event_handler_func)(struct trace_seq *s,
void *context);
typedef int (*pevent_plugin_load_func)(struct pevent *pevent);
-typedef int (*pevent_plugin_unload_func)(void);
+typedef int (*pevent_plugin_unload_func)(struct pevent *pevent);
-struct plugin_option {
- struct plugin_option *next;
+struct pevent_plugin_option {
+ struct pevent_plugin_option *next;
void *handle;
char *file;
char *name;
char *plugin_alias;
char *description;
char *value;
- void *private;
+ void *priv;
int set;
};
@@ -121,12 +130,12 @@ struct plugin_option {
* PEVENT_PLUGIN_UNLOADER: (optional)
* The function called just before unloading
*
- * int PEVENT_PLUGIN_UNLOADER(void)
+ * int PEVENT_PLUGIN_UNLOADER(struct pevent *pevent)
*
* PEVENT_PLUGIN_OPTIONS: (optional)
* Plugin options that can be set before loading
*
- * struct plugin_option PEVENT_PLUGIN_OPTIONS[] = {
+ * struct pevent_plugin_option PEVENT_PLUGIN_OPTIONS[] = {
* {
* .name = "option-name",
* .plugin_alias = "overide-file-name", (optional)
@@ -199,6 +208,11 @@ struct print_arg_string {
int offset;
};
+struct print_arg_bitmask {
+ char *bitmask;
+ int offset;
+};
+
struct print_arg_field {
char *name;
struct format_field *field;
@@ -226,6 +240,11 @@ struct print_arg_symbol {
struct print_flag_sym *symbols;
};
+struct print_arg_hex {
+ struct print_arg *field;
+ struct print_arg *size;
+};
+
struct print_arg_dynarray {
struct format_field *field;
struct print_arg *index;
@@ -253,12 +272,14 @@ enum print_arg_type {
PRINT_FIELD,
PRINT_FLAGS,
PRINT_SYMBOL,
+ PRINT_HEX,
PRINT_TYPE,
PRINT_STRING,
PRINT_BSTRING,
PRINT_DYNAMIC_ARRAY,
PRINT_OP,
PRINT_FUNC,
+ PRINT_BITMASK,
};
struct print_arg {
@@ -270,8 +291,10 @@ struct print_arg {
struct print_arg_typecast typecast;
struct print_arg_flags flags;
struct print_arg_symbol symbol;
+ struct print_arg_hex hex;
struct print_arg_func func;
struct print_arg_string string;
+ struct print_arg_bitmask bitmask;
struct print_arg_op op;
struct print_arg_dynarray dynarray;
};
@@ -300,6 +323,8 @@ enum {
EVENT_FL_ISBPRINT = 0x04,
EVENT_FL_ISFUNCENT = 0x10,
EVENT_FL_ISFUNCRET = 0x20,
+ EVENT_FL_NOHANDLE = 0x40,
+ EVENT_FL_PRINTRAW = 0x80,
EVENT_FL_FAILED = 0x80000000
};
@@ -336,7 +361,77 @@ enum pevent_func_arg_type {
enum pevent_flag {
PEVENT_NSEC_OUTPUT = 1, /* output in NSECS */
-};
+ PEVENT_DISABLE_SYS_PLUGINS = 1 << 1,
+ PEVENT_DISABLE_PLUGINS = 1 << 2,
+};
+
+#define PEVENT_ERRORS \
+ _PE(MEM_ALLOC_FAILED, "failed to allocate memory"), \
+ _PE(PARSE_EVENT_FAILED, "failed to parse event"), \
+ _PE(READ_ID_FAILED, "failed to read event id"), \
+ _PE(READ_FORMAT_FAILED, "failed to read event format"), \
+ _PE(READ_PRINT_FAILED, "failed to read event print fmt"), \
+ _PE(OLD_FTRACE_ARG_FAILED,"failed to allocate field name for ftrace"),\
+ _PE(INVALID_ARG_TYPE, "invalid argument type"), \
+ _PE(INVALID_EXP_TYPE, "invalid expression type"), \
+ _PE(INVALID_OP_TYPE, "invalid operator type"), \
+ _PE(INVALID_EVENT_NAME, "invalid event name"), \
+ _PE(EVENT_NOT_FOUND, "no event found"), \
+ _PE(SYNTAX_ERROR, "syntax error"), \
+ _PE(ILLEGAL_RVALUE, "illegal rvalue"), \
+ _PE(ILLEGAL_LVALUE, "illegal lvalue for string comparison"), \
+ _PE(INVALID_REGEX, "regex did not compute"), \
+ _PE(ILLEGAL_STRING_CMP, "illegal comparison for string"), \
+ _PE(ILLEGAL_INTEGER_CMP,"illegal comparison for integer"), \
+ _PE(REPARENT_NOT_OP, "cannot reparent other than OP"), \
+ _PE(REPARENT_FAILED, "failed to reparent filter OP"), \
+ _PE(BAD_FILTER_ARG, "bad arg in filter tree"), \
+ _PE(UNEXPECTED_TYPE, "unexpected type (not a value)"), \
+ _PE(ILLEGAL_TOKEN, "illegal token"), \
+ _PE(INVALID_PAREN, "open parenthesis cannot come here"), \
+ _PE(UNBALANCED_PAREN, "unbalanced number of parenthesis"), \
+ _PE(UNKNOWN_TOKEN, "unknown token"), \
+ _PE(FILTER_NOT_FOUND, "no filter found"), \
+ _PE(NOT_A_NUMBER, "must have number field"), \
+ _PE(NO_FILTER, "no filters exists"), \
+ _PE(FILTER_MISS, "record does not match to filter")
+
+#undef _PE
+#define _PE(__code, __str) PEVENT_ERRNO__ ## __code
+enum pevent_errno {
+ PEVENT_ERRNO__SUCCESS = 0,
+ PEVENT_ERRNO__FILTER_MATCH = PEVENT_ERRNO__SUCCESS,
+
+ /*
+ * Choose an arbitrary negative big number not to clash with standard
+ * errno since SUS requires the errno has distinct positive values.
+ * See 'Issue 6' in the link below.
+ *
+ * http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/errno.h.html
+ */
+ __PEVENT_ERRNO__START = -100000,
+
+ PEVENT_ERRORS,
+
+ __PEVENT_ERRNO__END,
+};
+#undef _PE
+
+struct plugin_list;
+
+#define INVALID_PLUGIN_LIST_OPTION ((char **)((unsigned long)-1))
+
+struct plugin_list *traceevent_load_plugins(struct pevent *pevent);
+void traceevent_unload_plugins(struct plugin_list *plugin_list,
+ struct pevent *pevent);
+char **traceevent_plugin_list_options(void);
+void traceevent_plugin_free_options_list(char **list);
+int traceevent_plugin_add_options(const char *name,
+ struct pevent_plugin_option *options);
+void traceevent_plugin_remove_options(struct pevent_plugin_option *options);
+void traceevent_print_plugins(struct trace_seq *s,
+ const char *prefix, const char *suffix,
+ const struct plugin_list *list);
struct cmdline;
struct cmdline_list;
@@ -364,6 +459,7 @@ struct pevent {
int cpus;
int long_size;
+ int page_size;
struct cmdline *cmdlines;
struct cmdline_list *cmdlist;
@@ -413,6 +509,8 @@ struct pevent {
/* cache */
struct event_format *last_event;
+
+ char *trace_clock;
};
static inline void pevent_set_flag(struct pevent *pevent, int flag)
@@ -480,6 +578,15 @@ __data2host8(struct pevent *pevent, unsigned long long data)
__data2host8(pevent, __val); \
})
+static inline int traceevent_host_bigendian(void)
+{
+ unsigned char str[] = { 0x1, 0x2, 0x3, 0x4 };
+ unsigned int val;
+
+ memcpy(&val, str, 4);
+ return val == 0x01020304;
+}
+
/* taken from kernel/trace/trace.h */
enum trace_flag_type {
TRACE_FLAG_IRQS_OFF = 0x01,
@@ -490,20 +597,26 @@ enum trace_flag_type {
};
int pevent_register_comm(struct pevent *pevent, const char *comm, int pid);
+void pevent_register_trace_clock(struct pevent *pevent, char *trace_clock);
int pevent_register_function(struct pevent *pevent, char *name,
unsigned long long addr, char *mod);
-int pevent_register_print_string(struct pevent *pevent, char *fmt,
+int pevent_register_print_string(struct pevent *pevent, const char *fmt,
unsigned long long addr);
int pevent_pid_is_registered(struct pevent *pevent, int pid);
void pevent_print_event(struct pevent *pevent, struct trace_seq *s,
- struct pevent_record *record);
+ struct pevent_record *record, bool use_trace_clock);
int pevent_parse_header_page(struct pevent *pevent, char *buf, unsigned long size,
int long_size);
-int pevent_parse_event(struct pevent *pevent, const char *buf,
- unsigned long size, const char *sys);
+enum pevent_errno pevent_parse_event(struct pevent *pevent, const char *buf,
+ unsigned long size, const char *sys);
+enum pevent_errno pevent_parse_format(struct pevent *pevent,
+ struct event_format **eventp,
+ const char *buf,
+ unsigned long size, const char *sys);
+void pevent_free_format(struct event_format *event);
void *pevent_get_field_raw(struct trace_seq *s, struct event_format *event,
const char *name, struct pevent_record *record,
@@ -523,12 +636,22 @@ int pevent_print_num_field(struct trace_seq *s, const char *fmt,
struct event_format *event, const char *name,
struct pevent_record *record, int err);
-int pevent_register_event_handler(struct pevent *pevent, int id, char *sys_name, char *event_name,
+int pevent_print_func_field(struct trace_seq *s, const char *fmt,
+ struct event_format *event, const char *name,
+ struct pevent_record *record, int err);
+
+int pevent_register_event_handler(struct pevent *pevent, int id,
+ const char *sys_name, const char *event_name,
pevent_event_handler_func func, void *context);
+int pevent_unregister_event_handler(struct pevent *pevent, int id,
+ const char *sys_name, const char *event_name,
+ pevent_event_handler_func func, void *context);
int pevent_register_print_function(struct pevent *pevent,
pevent_func_handler func,
enum pevent_func_arg_type ret_type,
char *name, ...);
+int pevent_unregister_print_function(struct pevent *pevent,
+ pevent_func_handler func, char *name);
struct format_field *pevent_find_common_field(struct event_format *event, const char *name);
struct format_field *pevent_find_field(struct event_format *event, const char *name);
@@ -554,6 +677,8 @@ int pevent_data_pid(struct pevent *pevent, struct pevent_record *rec);
const char *pevent_data_comm_from_pid(struct pevent *pevent, int pid);
void pevent_event_info(struct trace_seq *s, struct event_format *event,
struct pevent_record *record);
+int pevent_strerror(struct pevent *pevent, enum pevent_errno errnum,
+ char *buf, size_t buflen);
struct event_format **pevent_list_events(struct pevent *pevent, enum event_sort_type);
struct format_field **pevent_event_common_fields(struct event_format *event);
@@ -579,6 +704,16 @@ static inline void pevent_set_long_size(struct pevent *pevent, int long_size)
pevent->long_size = long_size;
}
+static inline int pevent_get_page_size(struct pevent *pevent)
+{
+ return pevent->page_size;
+}
+
+static inline void pevent_set_page_size(struct pevent *pevent, int _page_size)
+{
+ pevent->page_size = _page_size;
+}
+
static inline int pevent_is_file_bigendian(struct pevent *pevent)
{
return pevent->file_bigendian;
@@ -748,18 +883,22 @@ struct filter_type {
struct filter_arg *filter;
};
+#define PEVENT_FILTER_ERROR_BUFSZ 1024
+
struct event_filter {
struct pevent *pevent;
int filters;
struct filter_type *event_filters;
+ char error_buffer[PEVENT_FILTER_ERROR_BUFSZ];
};
struct event_filter *pevent_filter_alloc(struct pevent *pevent);
-#define FILTER_NONE -2
-#define FILTER_NOEXIST -1
-#define FILTER_MISS 0
-#define FILTER_MATCH 1
+/* for backward compatibility */
+#define FILTER_NONE PEVENT_ERRNO__NO_FILTER
+#define FILTER_NOEXIST PEVENT_ERRNO__FILTER_NOT_FOUND
+#define FILTER_MISS PEVENT_ERRNO__FILTER_MISS
+#define FILTER_MATCH PEVENT_ERRNO__FILTER_MATCH
enum filter_trivial_type {
FILTER_TRIVIAL_FALSE,
@@ -767,20 +906,21 @@ enum filter_trivial_type {
FILTER_TRIVIAL_BOTH,
};
-int pevent_filter_add_filter_str(struct event_filter *filter,
- const char *filter_str,
- char **error_str);
+enum pevent_errno pevent_filter_add_filter_str(struct event_filter *filter,
+ const char *filter_str);
+enum pevent_errno pevent_filter_match(struct event_filter *filter,
+ struct pevent_record *record);
-int pevent_filter_match(struct event_filter *filter,
- struct pevent_record *record);
+int pevent_filter_strerror(struct event_filter *filter, enum pevent_errno err,
+ char *buf, size_t buflen);
int pevent_event_filtered(struct event_filter *filter,
int event_id);
void pevent_filter_reset(struct event_filter *filter);
-void pevent_filter_clear_trivial(struct event_filter *filter,
+int pevent_filter_clear_trivial(struct event_filter *filter,
enum filter_trivial_type type);
void pevent_filter_free(struct event_filter *filter);