bt_parser.h revision 1.10
1/*	$OpenBSD: bt_parser.h,v 1.10 2020/09/14 18:45:19 jasper Exp $	*/
2
3/*
4 * Copyright (c) 2019-2020 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 */
36struct bt_probe {
37	const char		*bp_prov;	/* provider */
38	const char		*bp_func;	/* function or time unit */
39	const char		*bp_name;
40	uint32_t		 bp_rate;
41#define bp_unit	bp_func
42};
43
44/*
45 * Filters correspond to predicates performed in kernel.
46 *
47 * When a probe fires the check is performed, if it isn't true no event
48 * is recorded.
49 */
50struct bt_filter {
51	enum bt_operand {
52		B_OP_NONE = 1,
53		B_OP_EQ,
54		B_OP_NE,
55	}			 bf_op;
56	enum  bt_filtervar {
57		B_FV_NONE = 1,
58		B_FV_PID,
59		B_FV_TID
60	}			 bf_var;
61	uint32_t		 bf_val;
62};
63
64TAILQ_HEAD(bt_ruleq, bt_rule);
65
66/*
67 * A rule is the language representation of which 'action' to attach to
68 * which 'probe' under which conditions ('filter').  In other words it
69 * represents the following:
70 *
71 *	probe / filter / { action }
72 */
73struct bt_rule {
74	TAILQ_ENTRY(bt_rule)	 br_next;	/* linkage in global list */
75	struct bt_probe		*br_probe;
76	struct bt_filter	*br_filter;
77	SLIST_HEAD(, bt_stmt)	 br_action;
78
79	enum bt_rtype {
80		 B_RT_BEGIN = 1,
81		 B_RT_END,
82		 B_RT_PROBE,
83	}			 br_type;	/* BEGIN, END or 'probe' */
84
85	uint32_t		 br_pbn;	/* ID assigned by the kernel */
86	void			*br_cookie;
87};
88
89/*
90 * Global variable representation.
91 *
92 * Variables are untyped and also include maps and histograms.
93 */
94struct bt_var {
95	SLIST_ENTRY(bt_var)	 bv_next;	/* linkage in global list */
96	const char		*bv_name;	/* name of the variable */
97	struct bt_arg		*bv_value;	/* corresponding value */
98};
99
100/*
101 * Respresentation of an argument.
102 *
103 * A so called "argument" can be any symbol representing a value or
104 * a combination of those through an operation.
105 */
106struct bt_arg {
107	SLIST_ENTRY(bt_arg)	 ba_next;
108	void			*ba_value;
109	struct bt_arg		*ba_key;	/* key for maps/histograms */
110	enum  bt_argtype {
111		B_AT_STR = 1,			/* C-style string */
112		B_AT_LONG,			/* Number (integer) */
113		B_AT_VAR,			/* global variable (@var) */
114		B_AT_MAP,			/* global map (@map[]) */
115		B_AT_HIST,			/* histogram */
116
117		B_AT_BI_PID,
118		B_AT_BI_TID,
119		B_AT_BI_COMM,
120		B_AT_BI_CPU,
121		B_AT_BI_NSECS,
122		B_AT_BI_KSTACK,
123		B_AT_BI_USTACK,
124		B_AT_BI_ARG0,
125		B_AT_BI_ARG1,
126		B_AT_BI_ARG2,
127		B_AT_BI_ARG3,
128		B_AT_BI_ARG4,
129		B_AT_BI_ARG5,
130		B_AT_BI_ARG6,
131		B_AT_BI_ARG7,
132		B_AT_BI_ARG8,
133		B_AT_BI_ARG9,
134		B_AT_BI_ARGS,
135		B_AT_BI_RETVAL,
136
137		B_AT_MF_COUNT,			/* @map[key] = count() */
138		B_AT_MF_MAX,			/* @map[key] = max(nsecs) */
139		B_AT_MF_MIN,			/* @map[key] = min(pid) */
140		B_AT_MF_SUM,			/* @map[key] = sum(@elapsed) */
141
142		B_AT_OP_ADD,
143		B_AT_OP_MINUS,
144		B_AT_OP_MULT,
145		B_AT_OP_DIVIDE,
146		B_AT_OP_AND,
147		B_AT_OP_OR,
148	}			 ba_type;
149};
150
151#define BA_INITIALIZER(v, t)	{ { NULL }, (void *)(v), NULL, (t) }
152
153/*
154 * Each action associated with a given probe is made of at least one
155 * statement.
156 *
157 * Statements are interpreted linearly in userland to format data
158 * recorded in the form of events.
159 */
160struct bt_stmt {
161	SLIST_ENTRY(bt_stmt)	 bs_next;
162	struct bt_var		*bs_var;	/* for STOREs */
163	SLIST_HEAD(, bt_arg)	 bs_args;
164	enum bt_action {
165		B_AC_BUCKETIZE,			/* @h = hist(42) */
166		B_AC_CLEAR,			/* clear(@map) */
167		B_AC_DELETE,			/* delete(@map[key]) */
168		B_AC_EXIT,			/* exit() */
169		B_AC_INSERT,			/* @map[key] = 42 */
170		B_AC_PRINT,			/* print(@map, 10) */
171		B_AC_PRINTF,			/* printf("hello!\n") */
172		B_AC_STORE,			/* @a = 3 */
173		B_AC_TIME,			/* time("%H:%M:%S  ") */
174		B_AC_ZERO,			/* zero(@map) */
175	}			 bs_act;
176};
177
178struct bt_ruleq		 g_rules;	/* Successfully parsed rules. */
179int			 g_nprobes;	/* # of probes to attach */
180
181int			 btparse(const char *, size_t, const char *, int);
182
183#define ba_new(v, t)	 ba_new0((void *)(v), (t))
184struct bt_arg		*ba_new0(void *, enum bt_argtype);
185
186const char		*bv_name(struct bt_var *);
187
188void			 bm_insert(struct bt_var *, struct bt_arg *,
189			     struct bt_arg *);
190
191#endif /* BT_PARSER_H */
192