26538b5e932957382e3344349ec6f7ade0bddddf
[lttng-modules.git] / include / lttng / filter.h
1 /* SPDX-License-Identifier: MIT
2 *
3 * lttng/filter.h
4 *
5 * LTTng modules filter header.
6 *
7 * Copyright (C) 2010-2016 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
8 */
9
10 #ifndef _LTTNG_FILTER_H
11 #define _LTTNG_FILTER_H
12
13 #include <linux/kernel.h>
14
15 #include <lttng/events.h>
16 #include <lttng/filter-bytecode.h>
17
18 /* Filter stack length, in number of entries */
19 #define FILTER_STACK_LEN 10 /* includes 2 dummy */
20 #define FILTER_STACK_EMPTY 1
21
22 #define FILTER_MAX_DATA_LEN 65536
23
24 #ifdef DEBUG
25 #define dbg_printk(fmt, args...) \
26 printk(KERN_DEBUG "LTTng: [debug bytecode in %s:%s@%u] " fmt, \
27 __FILE__, __func__, __LINE__, ## args)
28 #else
29 #define dbg_printk(fmt, args...) \
30 do { \
31 /* do nothing but check printf format */ \
32 if (0) \
33 printk(KERN_DEBUG "LTTng: [debug bytecode in %s:%s@%u] " fmt, \
34 __FILE__, __func__, __LINE__, ## args); \
35 } while (0)
36 #endif
37
38 /* Linked bytecode. Child of struct lttng_bytecode_runtime. */
39 struct bytecode_runtime {
40 struct lttng_bytecode_runtime p;
41 size_t data_len;
42 size_t data_alloc_len;
43 char *data;
44 uint16_t len;
45 char code[0];
46 };
47
48 enum entry_type {
49 REG_S64,
50 REG_U64,
51 REG_DOUBLE,
52 REG_STRING,
53 REG_STAR_GLOB_STRING,
54 REG_TYPE_UNKNOWN,
55 REG_PTR,
56 };
57
58 enum load_type {
59 LOAD_ROOT_CONTEXT,
60 LOAD_ROOT_APP_CONTEXT,
61 LOAD_ROOT_PAYLOAD,
62 LOAD_OBJECT,
63 };
64
65 enum object_type {
66 OBJECT_TYPE_S8,
67 OBJECT_TYPE_S16,
68 OBJECT_TYPE_S32,
69 OBJECT_TYPE_S64,
70 OBJECT_TYPE_U8,
71 OBJECT_TYPE_U16,
72 OBJECT_TYPE_U32,
73 OBJECT_TYPE_U64,
74
75 OBJECT_TYPE_DOUBLE,
76 OBJECT_TYPE_STRING,
77 OBJECT_TYPE_STRING_SEQUENCE,
78
79 OBJECT_TYPE_SEQUENCE,
80 OBJECT_TYPE_ARRAY,
81 OBJECT_TYPE_STRUCT,
82 OBJECT_TYPE_VARIANT,
83
84 OBJECT_TYPE_DYNAMIC,
85 };
86
87 struct filter_get_index_data {
88 uint64_t offset; /* in bytes */
89 size_t ctx_index;
90 size_t array_len;
91 struct {
92 size_t len;
93 enum object_type type;
94 bool rev_bo; /* reverse byte order */
95 } elem;
96 };
97
98 /* Validation stack */
99 struct vstack_load {
100 enum load_type type;
101 enum object_type object_type;
102 const struct lttng_event_field *field;
103 bool rev_bo; /* reverse byte order */
104 };
105
106 struct vstack_entry {
107 enum entry_type type;
108 struct vstack_load load;
109 };
110
111 struct vstack {
112 int top; /* top of stack */
113 struct vstack_entry e[FILTER_STACK_LEN];
114 };
115
116 static inline
117 void vstack_init(struct vstack *stack)
118 {
119 stack->top = -1;
120 }
121
122 static inline
123 struct vstack_entry *vstack_ax(struct vstack *stack)
124 {
125 if (unlikely(stack->top < 0))
126 return NULL;
127 return &stack->e[stack->top];
128 }
129
130 static inline
131 struct vstack_entry *vstack_bx(struct vstack *stack)
132 {
133 if (unlikely(stack->top < 1))
134 return NULL;
135 return &stack->e[stack->top - 1];
136 }
137
138 static inline
139 int vstack_push(struct vstack *stack)
140 {
141 if (stack->top >= FILTER_STACK_LEN - 1) {
142 printk(KERN_WARNING "LTTng: filter: Stack full\n");
143 return -EINVAL;
144 }
145 ++stack->top;
146 return 0;
147 }
148
149 static inline
150 int vstack_pop(struct vstack *stack)
151 {
152 if (unlikely(stack->top < 0)) {
153 printk(KERN_WARNING "LTTng: filter: Stack empty\n");
154 return -EINVAL;
155 }
156 stack->top--;
157 return 0;
158 }
159
160 /* Execution stack */
161 enum estack_string_literal_type {
162 ESTACK_STRING_LITERAL_TYPE_NONE,
163 ESTACK_STRING_LITERAL_TYPE_PLAIN,
164 ESTACK_STRING_LITERAL_TYPE_STAR_GLOB,
165 };
166
167 struct load_ptr {
168 enum load_type type;
169 enum object_type object_type;
170 const void *ptr;
171 bool rev_bo;
172 /* Temporary place-holders for contexts. */
173 union {
174 int64_t s64;
175 uint64_t u64;
176 double d;
177 } u;
178 /*
179 * "field" is only needed when nested under a variant, in which
180 * case we cannot specialize the nested operations.
181 */
182 const struct lttng_event_field *field;
183 };
184
185 struct estack_entry {
186 enum entry_type type;
187 union {
188 int64_t v;
189
190 struct {
191 const char *str;
192 const char __user *user_str;
193 size_t seq_len;
194 enum estack_string_literal_type literal_type;
195 int user; /* is string from userspace ? */
196 } s;
197 struct load_ptr ptr;
198 } u;
199 };
200
201 struct estack {
202 int top; /* top of stack */
203 struct estack_entry e[FILTER_STACK_LEN];
204 };
205
206 #define estack_ax_v ax
207 #define estack_bx_v bx
208
209 #define estack_ax_t ax_t
210 #define estack_bx_t bx_t
211
212 #define estack_ax(stack, top) \
213 ({ \
214 BUG_ON((top) <= FILTER_STACK_EMPTY); \
215 &(stack)->e[top]; \
216 })
217
218 #define estack_bx(stack, top) \
219 ({ \
220 BUG_ON((top) <= FILTER_STACK_EMPTY + 1); \
221 &(stack)->e[(top) - 1]; \
222 })
223
224 #define estack_push(stack, top, ax, bx, ax_t, bx_t) \
225 do { \
226 BUG_ON((top) >= FILTER_STACK_LEN - 1); \
227 (stack)->e[(top) - 1].u.v = (bx); \
228 (stack)->e[(top) - 1].type = (bx_t); \
229 (bx) = (ax); \
230 (bx_t) = (ax_t); \
231 ++(top); \
232 } while (0)
233
234 #define estack_pop(stack, top, ax, bx, ax_t, bx_t) \
235 do { \
236 BUG_ON((top) <= FILTER_STACK_EMPTY); \
237 (ax) = (bx); \
238 (ax_t) = (bx_t); \
239 (bx) = (stack)->e[(top) - 2].u.v; \
240 (bx_t) = (stack)->e[(top) - 2].type; \
241 (top)--; \
242 } while (0)
243
244 const char *lttng_filter_print_op(enum filter_op op);
245
246 int lttng_filter_validate_bytecode(struct bytecode_runtime *bytecode);
247 int lttng_filter_specialize_bytecode(const struct lttng_event_desc *event_desc,
248 struct bytecode_runtime *bytecode);
249
250 uint64_t lttng_filter_false(void *filter_data,
251 struct lttng_probe_ctx *lttng_probe_ctx,
252 const char *filter_stack_data);
253 uint64_t lttng_filter_interpret_bytecode(void *filter_data,
254 struct lttng_probe_ctx *lttng_probe_ctx,
255 const char *filter_stack_data);
256
257 #endif /* _LTTNG_FILTER_H */
This page took 0.03365 seconds and 3 git commands to generate.