src/usr.sbin/btrace/bt_parser.h

221 lines
5.6 KiB
C

/* $OpenBSD: bt_parser.h,v 1.25 2023/10/12 15:16:44 cheloha 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 and local 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_TUPLE,
B_VT_MAP,
B_VT_HIST,
} bv_type;
};
/*
* Representation 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_TUPLE, /* tuple (1, 42, "str") */
B_AT_TMEMBER, /* tuple member $t.2 */
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_MODULO,
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 */