bt_parser.h revision 1.20
1/*	$OpenBSD: bt_parser.h,v 1.20 2021/09/09 09:53:11 mpi Exp $	*/
2
3/*
4 * Copyright (c) 2019-2021 Martin Pieuchot <mpi@openbsd.org>
5 *
6 * Permission to use, copy, modify, and distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
9 *
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 */
18
19#ifndef BT_PARSER_H
20#define BT_PARSER_H
21
22#ifndef nitems
23#define nitems(_a)	(sizeof((_a)) / sizeof((_a)[0]))
24#endif
25
26/*
27 * Probes represent entry points where events can be recorded.
28 *
29 * Those specified in a given bt(5) script are enabled at runtime. They
30 * are represented as:
31 *
32 *	"provider:function:name"
33 * or
34 *	"provider:time_unit:rate"
35 *
36 * Multiple probes can be associated to the same action.
37 */
38struct bt_probe {
39	SLIST_ENTRY(bt_probe)	 bp_next;	/* next probe for this rule */
40	const char		*bp_prov;	/* provider */
41	const char		*bp_func;	/* function or time unit */
42	const char		*bp_name;
43	uint32_t		 bp_rate;
44#define bp_unit	bp_func
45	enum bt_ptype {
46		 B_PT_BEGIN = 1,
47		 B_PT_END,
48		 B_PT_PROBE,
49	}			 bp_type;	/* BEGIN, END or 'probe' */
50	void			*bp_cookie;	/* ioctl request */
51	uint32_t		 bp_pbn;	/* ID assigned by the kernel */
52};
53
54
55/*
56 * Event filters correspond to checks performed in-kernel.
57 */
58struct bt_evtfilter {
59	int			bf_op;
60	enum bt_filtervar {
61		B_FV_NONE = 1,
62		B_FV_PID,
63		B_FV_TID
64	}			 bf_var;
65	uint32_t		 bf_val;
66};
67
68/*
69 * Filters, also known as predicates, describe under which set of
70 * conditions a rule is executed.
71 *
72 * They are performed when a rule is evaluated and events might be
73 * discarded at runtime.
74 */
75struct bt_filter {
76	struct bt_stmt		 *bf_condition;	/* per event condition */
77};
78
79TAILQ_HEAD(bt_ruleq, bt_rule);
80
81/*
82 * A rule is the language representation of which 'action' to attach to
83 * which 'probe' under which conditions ('filter').  In other words it
84 * represents the following:
85 *
86 *	probe / filter / { action }
87 */
88struct bt_rule {
89	TAILQ_ENTRY(bt_rule)	 br_next;	/* linkage in global list */
90	SLIST_HEAD(, bt_probe)	 br_probes;	/* list of probes */
91	struct bt_filter	*br_filter;
92	SLIST_HEAD(, bt_stmt)	 br_action;
93	SLIST_HEAD(, bt_var)	 br_variables;	/* local variables */
94};
95
96/*
97 * Global variable representation.
98 *
99 * Variables are untyped and also include maps and histograms.
100 */
101struct bt_var {
102	SLIST_ENTRY(bt_var)	 bv_next;	/* linkage in global list */
103	const char		*bv_name;	/* name of the variable */
104	struct bt_arg		*bv_value;	/* corresponding value */
105	enum bt_vartype	{
106		B_VT_STR = 1,
107		B_VT_LONG,
108		B_VT_MAP,
109		B_VT_HIST,
110	}			 bv_type;
111};
112
113/*
114 * Respresentation of an argument.
115 *
116 * A so called "argument" can be any symbol representing a value or
117 * a combination of those through an operation.
118 */
119struct bt_arg {
120	SLIST_ENTRY(bt_arg)	 ba_next;
121	void			*ba_value;
122	struct bt_arg		*ba_key;	/* key for maps/histograms */
123	enum bt_argtype {
124		B_AT_STR = 1,			/* C-style string */
125		B_AT_LONG,			/* Number (integer) */
126		B_AT_VAR,			/* global/local variable */
127		B_AT_MAP,			/* global map (@map[]) */
128		B_AT_HIST,			/* histogram */
129		B_AT_NIL,			/* empty value */
130
131		B_AT_BI_PID,
132		B_AT_BI_TID,
133		B_AT_BI_COMM,
134		B_AT_BI_CPU,
135		B_AT_BI_NSECS,
136		B_AT_BI_KSTACK,
137		B_AT_BI_USTACK,
138		B_AT_BI_ARG0,
139		B_AT_BI_ARG1,
140		B_AT_BI_ARG2,
141		B_AT_BI_ARG3,
142		B_AT_BI_ARG4,
143		B_AT_BI_ARG5,
144		B_AT_BI_ARG6,
145		B_AT_BI_ARG7,
146		B_AT_BI_ARG8,
147		B_AT_BI_ARG9,
148		B_AT_BI_ARGS,
149		B_AT_BI_RETVAL,
150
151		B_AT_MF_COUNT,			/* @map[key] = count() */
152		B_AT_MF_MAX,			/* @map[key] = max(nsecs) */
153		B_AT_MF_MIN,			/* @map[key] = min(pid) */
154		B_AT_MF_SUM,			/* @map[key] = sum(@elapsed) */
155
156		B_AT_OP_PLUS,
157		B_AT_OP_MINUS,
158		B_AT_OP_MULT,
159		B_AT_OP_DIVIDE,
160		B_AT_OP_BAND,
161		B_AT_OP_XOR,
162		B_AT_OP_BOR,
163		B_AT_OP_EQ,
164		B_AT_OP_NE,
165		B_AT_OP_LE,
166		B_AT_OP_LT,
167		B_AT_OP_GE,
168		B_AT_OP_GT,
169		B_AT_OP_LAND,
170		B_AT_OP_LOR,
171	}			 ba_type;
172};
173
174#define BA_INITIALIZER(v, t)	{ { NULL }, (void *)(v), NULL, (t) }
175
176/*
177 * Each action associated with a given probe is made of at least one
178 * statement.
179 *
180 * Statements are interpreted linearly in userland to format data
181 * recorded in the form of events.
182 */
183struct bt_stmt {
184	SLIST_ENTRY(bt_stmt)	 bs_next;
185	struct bt_var		*bs_var;	/* for STOREs */
186	SLIST_HEAD(, bt_arg)	 bs_args;
187	enum bt_action {
188		B_AC_BUCKETIZE,			/* @h = hist(42) */
189		B_AC_CLEAR,			/* clear(@map) */
190		B_AC_DELETE,			/* delete(@map[key]) */
191		B_AC_EXIT,			/* exit() */
192		B_AC_INSERT,			/* @map[key] = 42 */
193		B_AC_PRINT,			/* print(@map, 10) */
194		B_AC_PRINTF,			/* printf("hello!\n") */
195		B_AC_STORE,			/* @a = 3 */
196		B_AC_TEST,			/* if (@a) */
197		B_AC_TIME,			/* time("%H:%M:%S  ") */
198		B_AC_ZERO,			/* zero(@map) */
199	}			 bs_act;
200};
201
202extern struct bt_ruleq	 g_rules;	/* Successfully parsed rules. */
203extern int		 g_nprobes;	/* # of probes to attach */
204extern struct bt_arg 	 g_nullba;
205extern struct bt_arg	 g_maxba;
206
207int			 btparse(const char *, size_t, const char *, int);
208
209#define ba_new(v, t)	 ba_new0((void *)(v), (t))
210struct bt_arg		*ba_new0(void *, enum bt_argtype);
211
212const char		*bv_name(struct bt_var *);
213
214#endif /* BT_PARSER_H */
215