867 lines · 20.7 KB · C
RawDownload
/* * Copyright (C) 2009, 2010 Red Hat Inc, Steven Rostedt <srostedt@redhat.com> * * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License (not later!) * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the * 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,  see <http://www.gnu.org/licenses> * * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */#ifndef _PARSE_EVENTS_H#define _PARSE_EVENTS_H #include <stdbool.h>#include <stdarg.h>#include <regex.h> #ifndef __maybe_unused#define __maybe_unused __attribute__((unused))#endif /* ----------------------- trace_seq ----------------------- */  #ifndef TRACE_SEQ_BUF_SIZE#define TRACE_SEQ_BUF_SIZE 4096#endif #ifndef DEBUG_RECORD#define DEBUG_RECORD 0#endif struct pevent_record {	unsigned long long	ts;	unsigned long long	offset;	long long		missed_events;	/* buffer dropped events before */	int			record_size;	/* size of binary record */	int			size;		/* size of data */	void			*data;	int			cpu;	int			ref_count;	int			locked;		/* Do not free, even if ref_count is zero */	void			*priv;#if DEBUG_RECORD	struct pevent_record	*prev;	struct pevent_record	*next;	long			alloc_addr;#endif}; /* * 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). */ struct trace_seq {	char			*buffer;	unsigned int		buffer_size;	unsigned int		len;	unsigned int		readpos;}; 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, ...)	__attribute__ ((format (printf, 2, 3)));extern int trace_seq_vprintf(struct trace_seq *s, const char *fmt, va_list args)	__attribute__ ((format (printf, 2, 0))); extern int trace_seq_puts(struct trace_seq *s, const char *str);extern int trace_seq_putc(struct trace_seq *s, unsigned char c); extern void trace_seq_terminate(struct trace_seq *s); extern int trace_seq_do_printf(struct trace_seq *s);  /* ----------------------- pevent ----------------------- */ struct pevent;struct event_format; typedef int (*pevent_event_handler_func)(struct trace_seq *s,					 struct pevent_record *record,					 struct event_format *event,					 void *context); typedef int (*pevent_plugin_load_func)(struct pevent *pevent);typedef int (*pevent_plugin_unload_func)(void); struct plugin_option {	struct plugin_option		*next;	void				*handle;	char				*file;	char				*name;	char				*plugin_alias;	char				*description;	char				*value;	void				*priv;	int				set;}; /* * Plugin hooks that can be called: * * PEVENT_PLUGIN_LOADER:  (required) *   The function name to initialized the plugin. * *   int PEVENT_PLUGIN_LOADER(struct pevent *pevent) * * PEVENT_PLUGIN_UNLOADER:  (optional) *   The function called just before unloading * *   int PEVENT_PLUGIN_UNLOADER(void) * * PEVENT_PLUGIN_OPTIONS:  (optional) *   Plugin options that can be set before loading * *   struct plugin_option PEVENT_PLUGIN_OPTIONS[] = { *	{ *		.name = "option-name", *		.plugin_alias = "overide-file-name", (optional) *		.description = "description of option to show users", *	}, *	{ *		.name = NULL, *	}, *   }; * *   Array must end with .name = NULL; * * *   .plugin_alias is used to give a shorter name to access *   the vairable. Useful if a plugin handles more than one event. * * PEVENT_PLUGIN_ALIAS: (optional) *   The name to use for finding options (uses filename if not defined) */#define PEVENT_PLUGIN_LOADER pevent_plugin_loader#define PEVENT_PLUGIN_UNLOADER pevent_plugin_unloader#define PEVENT_PLUGIN_OPTIONS pevent_plugin_options#define PEVENT_PLUGIN_ALIAS pevent_plugin_alias#define _MAKE_STR(x)	#x#define MAKE_STR(x)	_MAKE_STR(x)#define PEVENT_PLUGIN_LOADER_NAME MAKE_STR(PEVENT_PLUGIN_LOADER)#define PEVENT_PLUGIN_UNLOADER_NAME MAKE_STR(PEVENT_PLUGIN_UNLOADER)#define PEVENT_PLUGIN_OPTIONS_NAME MAKE_STR(PEVENT_PLUGIN_OPTIONS)#define PEVENT_PLUGIN_ALIAS_NAME MAKE_STR(PEVENT_PLUGIN_ALIAS) #define NSECS_PER_SEC		1000000000ULL#define NSECS_PER_USEC		1000ULL enum format_flags {	FIELD_IS_ARRAY		= 1,	FIELD_IS_POINTER	= 2,	FIELD_IS_SIGNED		= 4,	FIELD_IS_STRING		= 8,	FIELD_IS_DYNAMIC	= 16,	FIELD_IS_LONG		= 32,	FIELD_IS_FLAG		= 64,	FIELD_IS_SYMBOLIC	= 128,}; struct format_field {	struct format_field	*next;	struct event_format	*event;	char			*type;	char			*name;	int			offset;	int			size;	unsigned int		arraylen;	unsigned int		elementsize;	unsigned long		flags;}; struct format {	int			nr_common;	int			nr_fields;	struct format_field	*common_fields;	struct format_field	*fields;}; struct print_arg_atom {	char			*atom;}; struct print_arg_string {	char			*string;	int			offset;}; struct print_arg_field {	char			*name;	struct format_field	*field;}; struct print_flag_sym {	struct print_flag_sym	*next;	char			*value;	char			*str;}; struct print_arg_typecast {	char 			*type;	struct print_arg	*item;}; struct print_arg_flags {	struct print_arg	*field;	char			*delim;	struct print_flag_sym	*flags;}; struct print_arg_symbol {	struct print_arg	*field;	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;}; struct print_arg; struct print_arg_op {	char			*op;	int			prio;	struct print_arg	*left;	struct print_arg	*right;}; struct pevent_function_handler; struct print_arg_func {	struct pevent_function_handler	*func;	struct print_arg		*args;}; enum print_arg_type {	PRINT_NULL,	PRINT_ATOM,	PRINT_FIELD,	PRINT_FLAGS,	PRINT_SYMBOL,	PRINT_HEX,	PRINT_TYPE,	PRINT_STRING,	PRINT_BSTRING,	PRINT_DYNAMIC_ARRAY,	PRINT_OP,	PRINT_FUNC,}; struct print_arg {	struct print_arg		*next;	enum print_arg_type		type;	union {		struct print_arg_atom		atom;		struct print_arg_field		field;		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_op		op;		struct print_arg_dynarray	dynarray;	};}; struct print_fmt {	char			*format;	struct print_arg	*args;}; struct event_format {	struct pevent		*pevent;	char			*name;	int			id;	int			flags;	struct format		format;	struct print_fmt	print_fmt;	char			*system;	pevent_event_handler_func handler;	void			*context;}; enum {	EVENT_FL_ISFTRACE	= 0x01,	EVENT_FL_ISPRINT	= 0x02,	EVENT_FL_ISBPRINT	= 0x04,	EVENT_FL_ISFUNCENT	= 0x10,	EVENT_FL_ISFUNCRET	= 0x20,	EVENT_FL_NOHANDLE	= 0x40,	EVENT_FL_PRINTRAW	= 0x80, 	EVENT_FL_FAILED		= 0x80000000}; enum event_sort_type {	EVENT_SORT_ID,	EVENT_SORT_NAME,	EVENT_SORT_SYSTEM,}; enum event_type {	EVENT_ERROR,	EVENT_NONE,	EVENT_SPACE,	EVENT_NEWLINE,	EVENT_OP,	EVENT_DELIM,	EVENT_ITEM,	EVENT_DQUOTE,	EVENT_SQUOTE,}; typedef unsigned long long (*pevent_func_handler)(struct trace_seq *s,					     unsigned long long *args); enum pevent_func_arg_type {	PEVENT_FUNC_ARG_VOID,	PEVENT_FUNC_ARG_INT,	PEVENT_FUNC_ARG_LONG,	PEVENT_FUNC_ARG_STRING,	PEVENT_FUNC_ARG_PTR,	PEVENT_FUNC_ARG_MAX_TYPES}; enum pevent_flag {	PEVENT_NSEC_OUTPUT		= 1,	/* output in NSECS */}; #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") #undef _PE#define _PE(__code, __str) PEVENT_ERRNO__ ## __codeenum pevent_errno {	PEVENT_ERRNO__SUCCESS			= 0, 	/*	 * 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 cmdline;struct cmdline_list;struct func_map;struct func_list;struct event_handler; struct pevent {	int ref_count; 	int header_page_ts_offset;	int header_page_ts_size;	int header_page_size_offset;	int header_page_size_size;	int header_page_data_offset;	int header_page_data_size;	int header_page_overwrite; 	int file_bigendian;	int host_bigendian; 	int latency_format; 	int old_format; 	int cpus;	int long_size;	int page_size; 	struct cmdline *cmdlines;	struct cmdline_list *cmdlist;	int cmdline_count; 	struct func_map *func_map;	struct func_list *funclist;	unsigned int func_count; 	struct printk_map *printk_map;	struct printk_list *printklist;	unsigned int printk_count;  	struct event_format **events;	int nr_events;	struct event_format **sort_events;	enum event_sort_type last_type; 	int type_offset;	int type_size; 	int pid_offset;	int pid_size;  	int pc_offset;	int pc_size; 	int flags_offset;	int flags_size; 	int ld_offset;	int ld_size; 	int print_raw; 	int test_filters; 	int flags; 	struct format_field *bprint_ip_field;	struct format_field *bprint_fmt_field;	struct format_field *bprint_buf_field; 	struct event_handler *handlers;	struct pevent_function_handler *func_handlers; 	/* cache */	struct event_format *last_event; 	char *trace_clock;}; static inline void pevent_set_flag(struct pevent *pevent, int flag){	pevent->flags |= flag;} static inline unsigned short__data2host2(struct pevent *pevent, unsigned short data){	unsigned short swap; 	if (pevent->host_bigendian == pevent->file_bigendian)		return data; 	swap = ((data & 0xffULL) << 8) |		((data & (0xffULL << 8)) >> 8); 	return swap;} static inline unsigned int__data2host4(struct pevent *pevent, unsigned int data){	unsigned int swap; 	if (pevent->host_bigendian == pevent->file_bigendian)		return data; 	swap = ((data & 0xffULL) << 24) |		((data & (0xffULL << 8)) << 8) |		((data & (0xffULL << 16)) >> 8) |		((data & (0xffULL << 24)) >> 24); 	return swap;} static inline unsigned long long__data2host8(struct pevent *pevent, unsigned long long data){	unsigned long long swap; 	if (pevent->host_bigendian == pevent->file_bigendian)

Lines 1–500 of 867.