Edit

IABSD.fr/src/usr.sbin/btrace/bt_parser.h

Branch :

  • Show log

    Commit

  • Author : claudio
    Date : 2021-11-12 16:57:24
    Hash : ca210abe
    Message : Implement the probe variable. Can be used for example with @map[probe] = count(); OK mpi@

  • usr.sbin/btrace/bt_parser.h
  • /*	$OpenBSD: bt_parser.h,v 1.22 2021/11/12 16:57:24 claudio Exp $	*/
    
    /*
     * Copyright (c) 2019-2021 Martin Pieuchot <mpi@openbsd.org>
     *
     * Permission to use, copy, modify, and distribute this software for any
     * purpose with or without fee is hereby granted, provided that the above
     * copyright notice and this permission notice appear in all copies.
     *
     * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
     * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
     * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
     * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
     * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
     * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
     * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
     */
    
    #ifndef BT_PARSER_H
    #define BT_PARSER_H
    
    #ifndef nitems
    #define nitems(_a)	(sizeof((_a)) / sizeof((_a)[0]))
    #endif
    
    /*
     * Probes represent entry points where events can be recorded.
     *
     * Those specified in a given bt(5) script are enabled at runtime. They
     * are represented as:
     *
     *	"provider:function:name"
     * or
     *	"provider:time_unit:rate"
     *
     * Multiple probes can be associated to the same action.
     */
    struct bt_probe {
    	SLIST_ENTRY(bt_probe)	 bp_next;	/* next probe for this rule */
    	const char		*bp_prov;	/* provider */
    	const char		*bp_func;	/* function or time unit */
    	const char		*bp_name;
    	uint32_t		 bp_rate;
    #define bp_unit	bp_func
    	enum bt_ptype {
    		 B_PT_BEGIN = 1,
    		 B_PT_END,
    		 B_PT_PROBE,
    	}			 bp_type;	/* BEGIN, END or 'probe' */
    	void			*bp_cookie;	/* ioctl request */
    	uint32_t		 bp_pbn;	/* ID assigned by the kernel */
    };
    
    
    /*
     * Event filters correspond to checks performed in-kernel.
     */
    struct bt_evtfilter {
    	int			bf_op;
    	enum bt_filtervar {
    		B_FV_NONE = 1,
    		B_FV_PID,
    		B_FV_TID
    	}			 bf_var;
    	uint32_t		 bf_val;
    };
    
    /*
     * Filters, also known as predicates, describe under which set of
     * conditions a rule is executed.
     *
     * They are performed when a rule is evaluated and events might be
     * discarded at runtime.
     */
    struct bt_filter {
    	struct bt_stmt		 *bf_condition;	/* per event condition */
    };
    
    TAILQ_HEAD(bt_ruleq, bt_rule);
    
    /*
     * A rule is the language representation of which 'action' to attach to
     * which 'probe' under which conditions ('filter').  In other words it
     * represents the following:
     *
     *	probe / filter / { action }
     */
    struct bt_rule {
    	TAILQ_ENTRY(bt_rule)	 br_next;	/* linkage in global list */
    	SLIST_HEAD(, bt_probe)	 br_probes;	/* list of probes */
    	struct bt_filter	*br_filter;
    	SLIST_HEAD(, bt_stmt)	 br_action;
    	SLIST_HEAD(, bt_var)	 br_variables;	/* local variables */
    };
    
    /*
     * Global variable representation.
     *
     * Variables are untyped and also include maps and histograms.
     */
    struct bt_var {
    	SLIST_ENTRY(bt_var)	 bv_next;	/* linkage in global list */
    	const char		*bv_name;	/* name of the variable */
    	struct bt_arg		*bv_value;	/* corresponding value */
    	enum bt_vartype	{
    		B_VT_STR = 1,
    		B_VT_LONG,
    		B_VT_MAP,
    		B_VT_HIST,
    	}			 bv_type;
    };
    
    /*
     * Respresentation of an argument.
     *
     * A so called "argument" can be any symbol representing a value or
     * a combination of those through an operation.
     */
    struct bt_arg {
    	SLIST_ENTRY(bt_arg)	 ba_next;
    	void			*ba_value;
    	struct bt_arg		*ba_key;	/* key for maps/histograms */
    	enum bt_argtype {
    		B_AT_STR = 1,			/* C-style string */
    		B_AT_LONG,			/* Number (integer) */
    		B_AT_VAR,			/* global/local variable */
    		B_AT_MAP,			/* global map (@map[]) */
    		B_AT_HIST,			/* histogram */
    		B_AT_NIL,			/* empty value */
    
    		B_AT_BI_PID,
    		B_AT_BI_TID,
    		B_AT_BI_COMM,
    		B_AT_BI_CPU,
    		B_AT_BI_NSECS,
    		B_AT_BI_KSTACK,
    		B_AT_BI_USTACK,
    		B_AT_BI_ARG0,
    		B_AT_BI_ARG1,
    		B_AT_BI_ARG2,
    		B_AT_BI_ARG3,
    		B_AT_BI_ARG4,
    		B_AT_BI_ARG5,
    		B_AT_BI_ARG6,
    		B_AT_BI_ARG7,
    		B_AT_BI_ARG8,
    		B_AT_BI_ARG9,
    		B_AT_BI_ARGS,
    		B_AT_BI_RETVAL,
    		B_AT_BI_PROBE,
    
    		B_AT_FN_STR,			/* str($1); str($1, 3); */
    
    		B_AT_MF_COUNT,			/* @map[key] = count() */
    		B_AT_MF_MAX,			/* @map[key] = max(nsecs) */
    		B_AT_MF_MIN,			/* @map[key] = min(pid) */
    		B_AT_MF_SUM,			/* @map[key] = sum(@elapsed) */
    
    		B_AT_OP_PLUS,
    		B_AT_OP_MINUS,
    		B_AT_OP_MULT,
    		B_AT_OP_DIVIDE,
    		B_AT_OP_BAND,
    		B_AT_OP_XOR,
    		B_AT_OP_BOR,
    		B_AT_OP_EQ,
    		B_AT_OP_NE,
    		B_AT_OP_LE,
    		B_AT_OP_LT,
    		B_AT_OP_GE,
    		B_AT_OP_GT,
    		B_AT_OP_LAND,
    		B_AT_OP_LOR,
    	}			 ba_type;
    };
    
    #define BA_INITIALIZER(v, t)	{ { NULL }, (void *)(v), NULL, (t) }
    
    /*
     * Each action associated with a given probe is made of at least one
     * statement.
     *
     * Statements are interpreted linearly in userland to format data
     * recorded in the form of events.
     */
    struct bt_stmt {
    	SLIST_ENTRY(bt_stmt)	 bs_next;
    	struct bt_var		*bs_var;	/* for STOREs */
    	SLIST_HEAD(, bt_arg)	 bs_args;
    	enum bt_action {
    		B_AC_BUCKETIZE,			/* @h = hist(42) */
    		B_AC_CLEAR,			/* clear(@map) */
    		B_AC_DELETE,			/* delete(@map[key]) */
    		B_AC_EXIT,			/* exit() */
    		B_AC_INSERT,			/* @map[key] = 42 */
    		B_AC_PRINT,			/* print(@map, 10) */
    		B_AC_PRINTF,			/* printf("hello!\n") */
    		B_AC_STORE,			/* @a = 3 */
    		B_AC_TEST,			/* if (@a) */
    		B_AC_TIME,			/* time("%H:%M:%S  ") */
    		B_AC_ZERO,			/* zero(@map) */
    	}			 bs_act;
    };
    
    extern struct bt_ruleq	 g_rules;	/* Successfully parsed rules. */
    extern int		 g_nprobes;	/* # of probes to attach */
    extern struct bt_arg 	 g_nullba;
    extern struct bt_arg	 g_maxba;
    
    int			 btparse(const char *, size_t, const char *, int);
    
    #define ba_new(v, t)	 ba_new0((void *)(v), (t))
    struct bt_arg		*ba_new0(void *, enum bt_argtype);
    
    const char		*bv_name(struct bt_var *);
    
    #endif /* BT_PARSER_H */