Filter: specialize 'and' and 'or' ops.
[lttng-ust.git] / liblttng-ust / lttng-filter.c
1 /*
2 * lttng-filter.c
3 *
4 * LTTng UST filter code.
5 *
6 * Copyright (C) 2010-2012 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
7 *
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; only
11 * version 2.1 of the License.
12 *
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21 */
22
23 #include <errno.h>
24 #include <stdio.h>
25 #include <helper.h>
26 #include <lttng/ust-events.h>
27 #include <stdint.h>
28 #include <errno.h>
29 #include <string.h>
30 #include <inttypes.h>
31 #include <limits.h>
32 #include <usterr-signal-safe.h>
33 #include "filter-bytecode.h"
34
35 #define NR_REG 2
36
37 #ifndef min_t
38 #define min_t(type, a, b) \
39 ((type) (a) < (type) (b) ? (type) (a) : (type) (b))
40 #endif
41
42 #ifndef likely
43 #define likely(x) __builtin_expect(!!(x), 1)
44 #endif
45
46 #ifndef unlikely
47 #define unlikely(x) __builtin_expect(!!(x), 0)
48 #endif
49
50 #ifdef DEBUG
51 #define dbg_printf(fmt, args...) printf("[debug bytecode] " fmt, ## args)
52 #else
53 #define dbg_printf(fmt, args...) \
54 do { \
55 /* do nothing but check printf format */ \
56 if (0) \
57 printf("[debug bytecode] " fmt, ## args); \
58 } while (0)
59 #endif
60
61 /* Linked bytecode */
62 struct bytecode_runtime {
63 uint16_t len;
64 char data[0];
65 };
66
67 enum reg_type {
68 REG_S64,
69 REG_DOUBLE,
70 REG_STRING,
71 REG_TYPE_UNKNOWN,
72 };
73
74 /* Validation registers */
75 struct vreg {
76 enum reg_type type;
77 int literal; /* is string literal ? */
78 };
79
80 /* Execution registers */
81 struct reg {
82 enum reg_type type;
83 int64_t v;
84 double d;
85
86 const char *str;
87 size_t seq_len;
88 int literal; /* is string literal ? */
89 };
90
91 static const char *opnames[] = {
92 [ FILTER_OP_UNKNOWN ] = "UNKNOWN",
93
94 [ FILTER_OP_RETURN ] = "RETURN",
95
96 /* binary */
97 [ FILTER_OP_MUL ] = "MUL",
98 [ FILTER_OP_DIV ] = "DIV",
99 [ FILTER_OP_MOD ] = "MOD",
100 [ FILTER_OP_PLUS ] = "PLUS",
101 [ FILTER_OP_MINUS ] = "MINUS",
102 [ FILTER_OP_RSHIFT ] = "RSHIFT",
103 [ FILTER_OP_LSHIFT ] = "LSHIFT",
104 [ FILTER_OP_BIN_AND ] = "BIN_AND",
105 [ FILTER_OP_BIN_OR ] = "BIN_OR",
106 [ FILTER_OP_BIN_XOR ] = "BIN_XOR",
107
108 /* binary comparators */
109 [ FILTER_OP_EQ ] = "EQ",
110 [ FILTER_OP_NE ] = "NE",
111 [ FILTER_OP_GT ] = "GT",
112 [ FILTER_OP_LT ] = "LT",
113 [ FILTER_OP_GE ] = "GE",
114 [ FILTER_OP_LE ] = "LE",
115
116 /* string binary comparators */
117 [ FILTER_OP_EQ_STRING ] = "EQ_STRING",
118 [ FILTER_OP_NE_STRING ] = "NE_STRING",
119 [ FILTER_OP_GT_STRING ] = "GT_STRING",
120 [ FILTER_OP_LT_STRING ] = "LT_STRING",
121 [ FILTER_OP_GE_STRING ] = "GE_STRING",
122 [ FILTER_OP_LE_STRING ] = "LE_STRING",
123
124 /* s64 binary comparators */
125 [ FILTER_OP_EQ_S64 ] = "EQ_S64",
126 [ FILTER_OP_NE_S64 ] = "NE_S64",
127 [ FILTER_OP_GT_S64 ] = "GT_S64",
128 [ FILTER_OP_LT_S64 ] = "LT_S64",
129 [ FILTER_OP_GE_S64 ] = "GE_S64",
130 [ FILTER_OP_LE_S64 ] = "LE_S64",
131
132 /* double binary comparators */
133 [ FILTER_OP_EQ_DOUBLE ] = "EQ_DOUBLE",
134 [ FILTER_OP_NE_DOUBLE ] = "NE_DOUBLE",
135 [ FILTER_OP_GT_DOUBLE ] = "GT_DOUBLE",
136 [ FILTER_OP_LT_DOUBLE ] = "LT_DOUBLE",
137 [ FILTER_OP_GE_DOUBLE ] = "GE_DOUBLE",
138 [ FILTER_OP_LE_DOUBLE ] = "LE_DOUBLE",
139
140
141 /* unary */
142 [ FILTER_OP_UNARY_PLUS ] = "UNARY_PLUS",
143 [ FILTER_OP_UNARY_MINUS ] = "UNARY_MINUS",
144 [ FILTER_OP_UNARY_NOT ] = "UNARY_NOT",
145 [ FILTER_OP_UNARY_PLUS_S64 ] = "UNARY_PLUS_S64",
146 [ FILTER_OP_UNARY_MINUS_S64 ] = "UNARY_MINUS_S64",
147 [ FILTER_OP_UNARY_NOT_S64 ] = "UNARY_NOT_S64",
148 [ FILTER_OP_UNARY_PLUS_DOUBLE ] = "UNARY_PLUS_DOUBLE",
149 [ FILTER_OP_UNARY_MINUS_DOUBLE ] = "UNARY_MINUS_DOUBLE",
150 [ FILTER_OP_UNARY_NOT_DOUBLE ] = "UNARY_NOT_DOUBLE",
151
152 /* logical */
153 [ FILTER_OP_AND ] = "AND",
154 [ FILTER_OP_OR ] = "OR",
155 [ FILTER_OP_AND_S64 ] = "AND_S64",
156 [ FILTER_OP_OR_S64 ] = "OR_S64",
157 [ FILTER_OP_AND_DOUBLE ] = "AND_DOUBLE",
158 [ FILTER_OP_OR_DOUBLE ] = "OR_DOUBLE",
159
160 /* load */
161 [ FILTER_OP_LOAD_FIELD_REF ] = "LOAD_FIELD_REF",
162 [ FILTER_OP_LOAD_FIELD_REF_STRING ] = "LOAD_FIELD_REF_STRING",
163 [ FILTER_OP_LOAD_FIELD_REF_SEQUENCE ] = "LOAD_FIELD_REF_SEQUENCE",
164 [ FILTER_OP_LOAD_FIELD_REF_S64 ] = "LOAD_FIELD_REF_S64",
165 [ FILTER_OP_LOAD_FIELD_REF_DOUBLE ] = "LOAD_FIELD_REF_DOUBLE",
166
167 [ FILTER_OP_LOAD_STRING ] = "LOAD_STRING",
168 [ FILTER_OP_LOAD_S64 ] = "LOAD_S64",
169 [ FILTER_OP_LOAD_DOUBLE ] = "LOAD_DOUBLE",
170 };
171
172 static
173 const char *print_op(enum filter_op op)
174 {
175 if (op >= NR_FILTER_OPS)
176 return "UNKNOWN";
177 else
178 return opnames[op];
179 }
180
181 /*
182 * -1: wildcard found.
183 * -2: unknown escape char.
184 * 0: normal char.
185 */
186
187 static
188 int parse_char(const char **p)
189 {
190 switch (**p) {
191 case '\\':
192 (*p)++;
193 switch (**p) {
194 case '\\':
195 case '*':
196 return 0;
197 default:
198 return -2;
199 }
200 case '*':
201 return -1;
202 default:
203 return 0;
204 }
205 }
206
207 static
208 int reg_strcmp(struct reg reg[NR_REG], const char *cmp_type)
209 {
210 const char *p = reg[REG_R0].str, *q = reg[REG_R1].str;
211 int ret;
212 int diff;
213
214 for (;;) {
215 int escaped_r0 = 0;
216
217 if (unlikely(p - reg[REG_R0].str > reg[REG_R0].seq_len || *p == '\0')) {
218 if (q - reg[REG_R1].str > reg[REG_R1].seq_len || *q == '\0')
219 diff = 0;
220 else
221 diff = -1;
222 break;
223 }
224 if (unlikely(q - reg[REG_R1].str > reg[REG_R1].seq_len || *q == '\0')) {
225 if (p - reg[REG_R0].str > reg[REG_R0].seq_len || *p == '\0')
226 diff = 0;
227 else
228 diff = 1;
229 break;
230 }
231 if (reg[REG_R0].literal) {
232 ret = parse_char(&p);
233 if (ret == -1) {
234 return 0;
235 } else if (ret == -2) {
236 escaped_r0 = 1;
237 }
238 /* else compare both char */
239 }
240 if (reg[REG_R1].literal) {
241 ret = parse_char(&q);
242 if (ret == -1) {
243 return 0;
244 } else if (ret == -2) {
245 if (!escaped_r0)
246 return -1;
247 } else {
248 if (escaped_r0)
249 return 1;
250 }
251 } else {
252 if (escaped_r0)
253 return 1;
254 }
255 diff = *p - *q;
256 if (diff != 0)
257 break;
258 p++;
259 q++;
260 }
261 return diff;
262 }
263
264 static
265 int lttng_filter_false(void *filter_data,
266 const char *filter_stack_data)
267 {
268 return 0;
269 }
270
271 #ifdef INTERPRETER_USE_SWITCH
272
273 /*
274 * Fallback for compilers that do not support taking address of labels.
275 */
276
277 #define START_OP \
278 start_pc = &bytecode->data[0]; \
279 for (pc = next_pc = start_pc; pc - start_pc < bytecode->len; \
280 pc = next_pc) { \
281 dbg_printf("Executing op %s (%u)\n", \
282 print_op((unsigned int) *(filter_opcode_t *) pc), \
283 (unsigned int) *(filter_opcode_t *) pc); \
284 switch (*(filter_opcode_t *) pc) {
285
286 #define OP(name) case name
287
288 #define PO break
289
290 #define END_OP } \
291 }
292
293 #else
294
295 /*
296 * Dispatch-table based interpreter.
297 */
298
299 #define START_OP \
300 start_pc = &bytecode->data[0]; \
301 pc = next_pc = start_pc; \
302 if (unlikely(pc - start_pc >= bytecode->len)) \
303 goto end; \
304 goto *dispatch[*(filter_opcode_t *) pc];
305
306 #define OP(name) \
307 LABEL_##name
308
309 #define PO \
310 pc = next_pc; \
311 goto *dispatch[*(filter_opcode_t *) pc];
312
313 #define END_OP
314
315 #endif
316
317 static
318 int lttng_filter_interpret_bytecode(void *filter_data,
319 const char *filter_stack_data)
320 {
321 struct bytecode_runtime *bytecode = filter_data;
322 void *pc, *next_pc, *start_pc;
323 int ret = -EINVAL;
324 int retval = 0;
325 struct reg reg[NR_REG];
326 #ifndef INTERPRETER_USE_SWITCH
327 static void *dispatch[NR_FILTER_OPS] = {
328 [ FILTER_OP_UNKNOWN ] = &&LABEL_FILTER_OP_UNKNOWN,
329
330 [ FILTER_OP_RETURN ] = &&LABEL_FILTER_OP_RETURN,
331
332 /* binary */
333 [ FILTER_OP_MUL ] = &&LABEL_FILTER_OP_MUL,
334 [ FILTER_OP_DIV ] = &&LABEL_FILTER_OP_DIV,
335 [ FILTER_OP_MOD ] = &&LABEL_FILTER_OP_MOD,
336 [ FILTER_OP_PLUS ] = &&LABEL_FILTER_OP_PLUS,
337 [ FILTER_OP_MINUS ] = &&LABEL_FILTER_OP_MINUS,
338 [ FILTER_OP_RSHIFT ] = &&LABEL_FILTER_OP_RSHIFT,
339 [ FILTER_OP_LSHIFT ] = &&LABEL_FILTER_OP_LSHIFT,
340 [ FILTER_OP_BIN_AND ] = &&LABEL_FILTER_OP_BIN_AND,
341 [ FILTER_OP_BIN_OR ] = &&LABEL_FILTER_OP_BIN_OR,
342 [ FILTER_OP_BIN_XOR ] = &&LABEL_FILTER_OP_BIN_XOR,
343
344 /* binary comparators */
345 [ FILTER_OP_EQ ] = &&LABEL_FILTER_OP_EQ,
346 [ FILTER_OP_NE ] = &&LABEL_FILTER_OP_NE,
347 [ FILTER_OP_GT ] = &&LABEL_FILTER_OP_GT,
348 [ FILTER_OP_LT ] = &&LABEL_FILTER_OP_LT,
349 [ FILTER_OP_GE ] = &&LABEL_FILTER_OP_GE,
350 [ FILTER_OP_LE ] = &&LABEL_FILTER_OP_LE,
351
352 /* string binary comparator */
353 [ FILTER_OP_EQ_STRING ] = &&LABEL_FILTER_OP_EQ_STRING,
354 [ FILTER_OP_NE_STRING ] = &&LABEL_FILTER_OP_NE_STRING,
355 [ FILTER_OP_GT_STRING ] = &&LABEL_FILTER_OP_GT_STRING,
356 [ FILTER_OP_LT_STRING ] = &&LABEL_FILTER_OP_LT_STRING,
357 [ FILTER_OP_GE_STRING ] = &&LABEL_FILTER_OP_GE_STRING,
358 [ FILTER_OP_LE_STRING ] = &&LABEL_FILTER_OP_LE_STRING,
359
360 /* s64 binary comparator */
361 [ FILTER_OP_EQ_S64 ] = &&LABEL_FILTER_OP_EQ_S64,
362 [ FILTER_OP_NE_S64 ] = &&LABEL_FILTER_OP_NE_S64,
363 [ FILTER_OP_GT_S64 ] = &&LABEL_FILTER_OP_GT_S64,
364 [ FILTER_OP_LT_S64 ] = &&LABEL_FILTER_OP_LT_S64,
365 [ FILTER_OP_GE_S64 ] = &&LABEL_FILTER_OP_GE_S64,
366 [ FILTER_OP_LE_S64 ] = &&LABEL_FILTER_OP_LE_S64,
367
368 /* double binary comparator */
369 [ FILTER_OP_EQ_DOUBLE ] = &&LABEL_FILTER_OP_EQ_DOUBLE,
370 [ FILTER_OP_NE_DOUBLE ] = &&LABEL_FILTER_OP_NE_DOUBLE,
371 [ FILTER_OP_GT_DOUBLE ] = &&LABEL_FILTER_OP_GT_DOUBLE,
372 [ FILTER_OP_LT_DOUBLE ] = &&LABEL_FILTER_OP_LT_DOUBLE,
373 [ FILTER_OP_GE_DOUBLE ] = &&LABEL_FILTER_OP_GE_DOUBLE,
374 [ FILTER_OP_LE_DOUBLE ] = &&LABEL_FILTER_OP_LE_DOUBLE,
375
376 /* unary */
377 [ FILTER_OP_UNARY_PLUS ] = &&LABEL_FILTER_OP_UNARY_PLUS,
378 [ FILTER_OP_UNARY_MINUS ] = &&LABEL_FILTER_OP_UNARY_MINUS,
379 [ FILTER_OP_UNARY_NOT ] = &&LABEL_FILTER_OP_UNARY_NOT,
380 [ FILTER_OP_UNARY_PLUS_S64 ] = &&LABEL_FILTER_OP_UNARY_PLUS_S64,
381 [ FILTER_OP_UNARY_MINUS_S64 ] = &&LABEL_FILTER_OP_UNARY_MINUS_S64,
382 [ FILTER_OP_UNARY_NOT_S64 ] = &&LABEL_FILTER_OP_UNARY_NOT_S64,
383 [ FILTER_OP_UNARY_PLUS_DOUBLE ] = &&LABEL_FILTER_OP_UNARY_PLUS_DOUBLE,
384 [ FILTER_OP_UNARY_MINUS_DOUBLE ] = &&LABEL_FILTER_OP_UNARY_MINUS_DOUBLE,
385 [ FILTER_OP_UNARY_NOT_DOUBLE ] = &&LABEL_FILTER_OP_UNARY_NOT_DOUBLE,
386
387 /* logical */
388 [ FILTER_OP_AND ] = &&LABEL_FILTER_OP_AND,
389 [ FILTER_OP_OR ] = &&LABEL_FILTER_OP_OR,
390 [ FILTER_OP_AND_S64 ] = &&LABEL_FILTER_OP_AND_S64,
391 [ FILTER_OP_OR_S64 ] = &&LABEL_FILTER_OP_OR_S64,
392 [ FILTER_OP_AND_DOUBLE ] = &&LABEL_FILTER_OP_AND_DOUBLE,
393 [ FILTER_OP_OR_DOUBLE ] = &&LABEL_FILTER_OP_OR_DOUBLE,
394
395 /* load */
396 [ FILTER_OP_LOAD_FIELD_REF ] = &&LABEL_FILTER_OP_LOAD_FIELD_REF,
397 [ FILTER_OP_LOAD_FIELD_REF_STRING ] = &&LABEL_FILTER_OP_LOAD_FIELD_REF_STRING,
398 [ FILTER_OP_LOAD_FIELD_REF_SEQUENCE ] = &&LABEL_FILTER_OP_LOAD_FIELD_REF_SEQUENCE,
399 [ FILTER_OP_LOAD_FIELD_REF_S64 ] = &&LABEL_FILTER_OP_LOAD_FIELD_REF_S64,
400 [ FILTER_OP_LOAD_FIELD_REF_DOUBLE ] = &&LABEL_FILTER_OP_LOAD_FIELD_REF_DOUBLE,
401
402 [ FILTER_OP_LOAD_STRING ] = &&LABEL_FILTER_OP_LOAD_STRING,
403 [ FILTER_OP_LOAD_S64 ] = &&LABEL_FILTER_OP_LOAD_S64,
404 [ FILTER_OP_LOAD_DOUBLE ] = &&LABEL_FILTER_OP_LOAD_DOUBLE,
405 };
406 #endif /* #ifndef INTERPRETER_USE_SWITCH */
407
408 START_OP
409
410 OP(FILTER_OP_UNKNOWN):
411 OP(FILTER_OP_LOAD_FIELD_REF):
412 #ifdef INTERPRETER_USE_SWITCH
413 default:
414 #endif /* INTERPRETER_USE_SWITCH */
415 ERR("unknown bytecode op %u\n",
416 (unsigned int) *(filter_opcode_t *) pc);
417 ret = -EINVAL;
418 goto end;
419
420 OP(FILTER_OP_RETURN):
421 retval = !!reg[0].v;
422 ret = 0;
423 goto end;
424
425 /* binary */
426 OP(FILTER_OP_MUL):
427 OP(FILTER_OP_DIV):
428 OP(FILTER_OP_MOD):
429 OP(FILTER_OP_PLUS):
430 OP(FILTER_OP_MINUS):
431 OP(FILTER_OP_RSHIFT):
432 OP(FILTER_OP_LSHIFT):
433 OP(FILTER_OP_BIN_AND):
434 OP(FILTER_OP_BIN_OR):
435 OP(FILTER_OP_BIN_XOR):
436 ERR("unsupported bytecode op %u\n",
437 (unsigned int) *(filter_opcode_t *) pc);
438 ret = -EINVAL;
439 goto end;
440
441 OP(FILTER_OP_EQ):
442 OP(FILTER_OP_NE):
443 OP(FILTER_OP_GT):
444 OP(FILTER_OP_LT):
445 OP(FILTER_OP_GE):
446 OP(FILTER_OP_LE):
447 ERR("unsupported non-specialized bytecode op %u\n",
448 (unsigned int) *(filter_opcode_t *) pc);
449 ret = -EINVAL;
450 goto end;
451
452 OP(FILTER_OP_EQ_STRING):
453 {
454 reg[REG_R0].v = (reg_strcmp(reg, "==") == 0);
455 reg[REG_R0].type = REG_S64;
456 next_pc += sizeof(struct binary_op);
457 PO;
458 }
459 OP(FILTER_OP_NE_STRING):
460 {
461 reg[REG_R0].v = (reg_strcmp(reg, "!=") != 0);
462 reg[REG_R0].type = REG_S64;
463 next_pc += sizeof(struct binary_op);
464 PO;
465 }
466 OP(FILTER_OP_GT_STRING):
467 {
468 reg[REG_R0].v = (reg_strcmp(reg, ">") > 0);
469 reg[REG_R0].type = REG_S64;
470 next_pc += sizeof(struct binary_op);
471 PO;
472 }
473 OP(FILTER_OP_LT_STRING):
474 {
475 reg[REG_R0].v = (reg_strcmp(reg, "<") < 0);
476 reg[REG_R0].type = REG_S64;
477 next_pc += sizeof(struct binary_op);
478 PO;
479 }
480 OP(FILTER_OP_GE_STRING):
481 {
482 reg[REG_R0].v = (reg_strcmp(reg, ">=") >= 0);
483 reg[REG_R0].type = REG_S64;
484 next_pc += sizeof(struct binary_op);
485 PO;
486 }
487 OP(FILTER_OP_LE_STRING):
488 {
489 reg[REG_R0].v = (reg_strcmp(reg, "<=") <= 0);
490 reg[REG_R0].type = REG_S64;
491 next_pc += sizeof(struct binary_op);
492 PO;
493 }
494
495 OP(FILTER_OP_EQ_S64):
496 {
497 reg[REG_R0].v = (reg[REG_R0].v == reg[REG_R1].v);
498 reg[REG_R0].type = REG_S64;
499 next_pc += sizeof(struct binary_op);
500 PO;
501 }
502 OP(FILTER_OP_NE_S64):
503 {
504 reg[REG_R0].v = (reg[REG_R0].v != reg[REG_R1].v);
505 reg[REG_R0].type = REG_S64;
506 next_pc += sizeof(struct binary_op);
507 PO;
508 }
509 OP(FILTER_OP_GT_S64):
510 {
511 reg[REG_R0].v = (reg[REG_R0].v > reg[REG_R1].v);
512 reg[REG_R0].type = REG_S64;
513 next_pc += sizeof(struct binary_op);
514 PO;
515 }
516 OP(FILTER_OP_LT_S64):
517 {
518 reg[REG_R0].v = (reg[REG_R0].v < reg[REG_R1].v);
519 reg[REG_R0].type = REG_S64;
520 next_pc += sizeof(struct binary_op);
521 PO;
522 }
523 OP(FILTER_OP_GE_S64):
524 {
525 reg[REG_R0].v = (reg[REG_R0].v >= reg[REG_R1].v);
526 reg[REG_R0].type = REG_S64;
527 next_pc += sizeof(struct binary_op);
528 PO;
529 }
530 OP(FILTER_OP_LE_S64):
531 {
532 reg[REG_R0].v = (reg[REG_R0].v <= reg[REG_R1].v);
533 reg[REG_R0].type = REG_S64;
534 next_pc += sizeof(struct binary_op);
535 PO;
536 }
537
538 OP(FILTER_OP_EQ_DOUBLE):
539 {
540 if (unlikely(reg[REG_R0].type == REG_S64))
541 reg[REG_R0].d = (double) reg[REG_R0].v;
542 else if (unlikely(reg[REG_R1].type == REG_S64))
543 reg[REG_R1].d = (double) reg[REG_R1].v;
544 reg[REG_R0].v = (reg[REG_R0].d == reg[REG_R1].d);
545 reg[REG_R0].type = REG_S64;
546 next_pc += sizeof(struct binary_op);
547 PO;
548 }
549 OP(FILTER_OP_NE_DOUBLE):
550 {
551 if (unlikely(reg[REG_R0].type == REG_S64))
552 reg[REG_R0].d = (double) reg[REG_R0].v;
553 else if (unlikely(reg[REG_R1].type == REG_S64))
554 reg[REG_R1].d = (double) reg[REG_R1].v;
555 reg[REG_R0].v = (reg[REG_R0].d != reg[REG_R1].d);
556 reg[REG_R0].type = REG_S64;
557 next_pc += sizeof(struct binary_op);
558 PO;
559 }
560 OP(FILTER_OP_GT_DOUBLE):
561 {
562 if (unlikely(reg[REG_R0].type == REG_S64))
563 reg[REG_R0].d = (double) reg[REG_R0].v;
564 else if (unlikely(reg[REG_R1].type == REG_S64))
565 reg[REG_R1].d = (double) reg[REG_R1].v;
566 reg[REG_R0].v = (reg[REG_R0].d > reg[REG_R1].d);
567 reg[REG_R0].type = REG_S64;
568 next_pc += sizeof(struct binary_op);
569 PO;
570 }
571 OP(FILTER_OP_LT_DOUBLE):
572 {
573 if (unlikely(reg[REG_R0].type == REG_S64))
574 reg[REG_R0].d = (double) reg[REG_R0].v;
575 else if (unlikely(reg[REG_R1].type == REG_S64))
576 reg[REG_R1].d = (double) reg[REG_R1].v;
577 reg[REG_R0].v = (reg[REG_R0].d < reg[REG_R1].d);
578 reg[REG_R0].type = REG_S64;
579 next_pc += sizeof(struct binary_op);
580 PO;
581 }
582 OP(FILTER_OP_GE_DOUBLE):
583 {
584 if (unlikely(reg[REG_R0].type == REG_S64))
585 reg[REG_R0].d = (double) reg[REG_R0].v;
586 else if (unlikely(reg[REG_R1].type == REG_S64))
587 reg[REG_R1].d = (double) reg[REG_R1].v;
588 reg[REG_R0].v = (reg[REG_R0].d >= reg[REG_R1].d);
589 reg[REG_R0].type = REG_S64;
590 next_pc += sizeof(struct binary_op);
591 PO;
592 }
593 OP(FILTER_OP_LE_DOUBLE):
594 {
595 if (unlikely(reg[REG_R0].type == REG_S64))
596 reg[REG_R0].d = (double) reg[REG_R0].v;
597 else if (unlikely(reg[REG_R1].type == REG_S64))
598 reg[REG_R1].d = (double) reg[REG_R1].v;
599 reg[REG_R0].v = (reg[REG_R0].d <= reg[REG_R1].d);
600 reg[REG_R0].type = REG_S64;
601 next_pc += sizeof(struct binary_op);
602 PO;
603 }
604
605 /* unary */
606 OP(FILTER_OP_UNARY_PLUS):
607 OP(FILTER_OP_UNARY_MINUS):
608 OP(FILTER_OP_UNARY_NOT):
609 ERR("unsupported non-specialized bytecode op %u\n",
610 (unsigned int) *(filter_opcode_t *) pc);
611 ret = -EINVAL;
612 goto end;
613
614
615 OP(FILTER_OP_UNARY_PLUS_S64):
616 OP(FILTER_OP_UNARY_PLUS_DOUBLE):
617 {
618 next_pc += sizeof(struct unary_op);
619 PO;
620 }
621 OP(FILTER_OP_UNARY_MINUS_S64):
622 {
623 struct unary_op *insn = (struct unary_op *) pc;
624
625 reg[insn->reg].v = -reg[insn->reg].v;
626 next_pc += sizeof(struct unary_op);
627 PO;
628 }
629 OP(FILTER_OP_UNARY_MINUS_DOUBLE):
630 {
631 struct unary_op *insn = (struct unary_op *) pc;
632
633 reg[insn->reg].d = -reg[insn->reg].d;
634 next_pc += sizeof(struct unary_op);
635 PO;
636 }
637 OP(FILTER_OP_UNARY_NOT_S64):
638 {
639 struct unary_op *insn = (struct unary_op *) pc;
640
641 reg[insn->reg].v = !reg[insn->reg].v;
642 next_pc += sizeof(struct unary_op);
643 PO;
644 }
645 OP(FILTER_OP_UNARY_NOT_DOUBLE):
646 {
647 struct unary_op *insn = (struct unary_op *) pc;
648
649 reg[insn->reg].d = !reg[insn->reg].d;
650 next_pc += sizeof(struct unary_op);
651 PO;
652 }
653
654 /* logical */
655 OP(FILTER_OP_AND):
656 OP(FILTER_OP_OR):
657 ERR("unsupported non-specialized bytecode op %u\n",
658 (unsigned int) *(filter_opcode_t *) pc);
659 ret = -EINVAL;
660 goto end;
661
662 OP(FILTER_OP_AND_S64):
663 {
664 struct logical_op *insn = (struct logical_op *) pc;
665
666 /* If REG_R0 is 0, skip and evaluate to 0 */
667 if (unlikely(reg[REG_R0].v == 0)) {
668 dbg_printf("Jumping to bytecode offset %u\n",
669 (unsigned int) insn->skip_offset);
670 next_pc = start_pc + insn->skip_offset;
671 } else {
672 next_pc += sizeof(struct logical_op);
673 }
674 PO;
675 }
676 OP(FILTER_OP_OR_S64):
677 {
678 struct logical_op *insn = (struct logical_op *) pc;
679
680 /* If REG_R0 is nonzero, skip and evaluate to 1 */
681
682 if (unlikely(reg[REG_R0].v != 0)) {
683 reg[REG_R0].v = 1;
684 dbg_printf("Jumping to bytecode offset %u\n",
685 (unsigned int) insn->skip_offset);
686 next_pc = start_pc + insn->skip_offset;
687 } else {
688 next_pc += sizeof(struct logical_op);
689 }
690 PO;
691 }
692
693 OP(FILTER_OP_AND_DOUBLE):
694 {
695 struct logical_op *insn = (struct logical_op *) pc;
696
697 /* If REG_R0 is 0, skip and evaluate to 0 */
698 if ((reg[REG_R0].type == REG_DOUBLE && unlikely(reg[REG_R0].d == 0.0))
699 || (reg[REG_R0].type == REG_S64 && unlikely(reg[REG_R0].v == 0))) {
700 dbg_printf("Jumping to bytecode offset %u\n",
701 (unsigned int) insn->skip_offset);
702 next_pc = start_pc + insn->skip_offset;
703 } else {
704 next_pc += sizeof(struct logical_op);
705 }
706 PO;
707 }
708 OP(FILTER_OP_OR_DOUBLE):
709 {
710 struct logical_op *insn = (struct logical_op *) pc;
711
712 /* If REG_R0 is nonzero, skip and evaluate to 1 (in double) */
713 if ((reg[REG_R0].type == REG_DOUBLE && unlikely(reg[REG_R0].d != 0.0))
714 || (reg[REG_R0].type == REG_S64 && unlikely(reg[REG_R0].v != 0))) {
715 reg[REG_R0].d = 1.0;
716 dbg_printf("Jumping to bytecode offset %u\n",
717 (unsigned int) insn->skip_offset);
718 next_pc = start_pc + insn->skip_offset;
719 } else {
720 next_pc += sizeof(struct logical_op);
721 }
722 PO;
723 }
724
725 /* load */
726 OP(FILTER_OP_LOAD_FIELD_REF_STRING):
727 {
728 struct load_op *insn = (struct load_op *) pc;
729 struct field_ref *ref = (struct field_ref *) insn->data;
730
731 dbg_printf("load field ref offset %u type string\n",
732 ref->offset);
733 reg[insn->reg].str =
734 *(const char * const *) &filter_stack_data[ref->offset];
735 reg[insn->reg].type = REG_STRING;
736 reg[insn->reg].seq_len = UINT_MAX;
737 reg[insn->reg].literal = 0;
738 dbg_printf("ref load string %s\n", reg[insn->reg].str);
739 next_pc += sizeof(struct load_op) + sizeof(struct field_ref);
740 PO;
741 }
742
743 OP(FILTER_OP_LOAD_FIELD_REF_SEQUENCE):
744 {
745 struct load_op *insn = (struct load_op *) pc;
746 struct field_ref *ref = (struct field_ref *) insn->data;
747
748 dbg_printf("load field ref offset %u type sequence\n",
749 ref->offset);
750 reg[insn->reg].seq_len =
751 *(unsigned long *) &filter_stack_data[ref->offset];
752 reg[insn->reg].str =
753 *(const char **) (&filter_stack_data[ref->offset
754 + sizeof(unsigned long)]);
755 reg[insn->reg].type = REG_STRING;
756 reg[insn->reg].literal = 0;
757 next_pc += sizeof(struct load_op) + sizeof(struct field_ref);
758 PO;
759 }
760
761 OP(FILTER_OP_LOAD_FIELD_REF_S64):
762 {
763 struct load_op *insn = (struct load_op *) pc;
764 struct field_ref *ref = (struct field_ref *) insn->data;
765
766 dbg_printf("load field ref offset %u type s64\n",
767 ref->offset);
768 memcpy(&reg[insn->reg].v, &filter_stack_data[ref->offset],
769 sizeof(struct literal_numeric));
770 reg[insn->reg].type = REG_S64;
771 reg[insn->reg].literal = 0;
772 dbg_printf("ref load s64 %" PRIi64 "\n", reg[insn->reg].v);
773 next_pc += sizeof(struct load_op) + sizeof(struct field_ref);
774 PO;
775 }
776
777 OP(FILTER_OP_LOAD_FIELD_REF_DOUBLE):
778 {
779 struct load_op *insn = (struct load_op *) pc;
780 struct field_ref *ref = (struct field_ref *) insn->data;
781
782 dbg_printf("load field ref offset %u type double\n",
783 ref->offset);
784 memcpy(&reg[insn->reg].d, &filter_stack_data[ref->offset],
785 sizeof(struct literal_double));
786 reg[insn->reg].type = REG_DOUBLE;
787 reg[insn->reg].literal = 0;
788 dbg_printf("ref load double %g\n", reg[insn->reg].d);
789 next_pc += sizeof(struct load_op) + sizeof(struct field_ref);
790 PO;
791 }
792
793 OP(FILTER_OP_LOAD_STRING):
794 {
795 struct load_op *insn = (struct load_op *) pc;
796
797 dbg_printf("load string %s\n", insn->data);
798 reg[insn->reg].str = insn->data;
799 reg[insn->reg].type = REG_STRING;
800 reg[insn->reg].seq_len = UINT_MAX;
801 reg[insn->reg].literal = 1;
802 next_pc += sizeof(struct load_op) + strlen(insn->data) + 1;
803 PO;
804 }
805
806 OP(FILTER_OP_LOAD_S64):
807 {
808 struct load_op *insn = (struct load_op *) pc;
809
810 memcpy(&reg[insn->reg].v, insn->data,
811 sizeof(struct literal_numeric));
812 dbg_printf("load s64 %" PRIi64 "\n", reg[insn->reg].v);
813 reg[insn->reg].type = REG_S64;
814 reg[insn->reg].literal = 1;
815 next_pc += sizeof(struct load_op)
816 + sizeof(struct literal_numeric);
817 PO;
818 }
819
820 OP(FILTER_OP_LOAD_DOUBLE):
821 {
822 struct load_op *insn = (struct load_op *) pc;
823
824 memcpy(&reg[insn->reg].d, insn->data,
825 sizeof(struct literal_double));
826 dbg_printf("load s64 %g\n", reg[insn->reg].d);
827 reg[insn->reg].type = REG_DOUBLE;
828 reg[insn->reg].literal = 1;
829 next_pc += sizeof(struct load_op)
830 + sizeof(struct literal_double);
831 PO;
832 }
833
834 END_OP
835 end:
836 /* return 0 (discard) on error */
837 if (ret)
838 return 0;
839 return retval;
840 }
841
842 #undef START_OP
843 #undef OP
844 #undef PO
845 #undef END_OP
846
847 static
848 int bin_op_compare_check(struct vreg reg[NR_REG], const char *str)
849 {
850 switch (reg[REG_R0].type) {
851 default:
852 goto error_unknown;
853
854 case REG_STRING:
855 switch (reg[REG_R1].type) {
856 default:
857 goto error_unknown;
858
859 case REG_STRING:
860 break;
861 case REG_S64:
862 case REG_DOUBLE:
863 goto error_mismatch;
864 }
865 break;
866 case REG_S64:
867 case REG_DOUBLE:
868 switch (reg[REG_R1].type) {
869 default:
870 goto error_unknown;
871
872 case REG_STRING:
873 goto error_mismatch;
874
875 case REG_S64:
876 case REG_DOUBLE:
877 break;
878 }
879 break;
880 }
881 return 0;
882
883 error_unknown:
884
885 return -EINVAL;
886 error_mismatch:
887 ERR("type mismatch for '%s' binary operator\n", str);
888 return -EINVAL;
889 }
890
891 static
892 int lttng_filter_validate_bytecode(struct bytecode_runtime *bytecode)
893 {
894 void *pc, *next_pc, *start_pc;
895 int ret = -EINVAL;
896 struct vreg reg[NR_REG];
897 int i;
898
899 for (i = 0; i < NR_REG; i++) {
900 reg[i].type = REG_TYPE_UNKNOWN;
901 reg[i].literal = 0;
902 }
903
904 start_pc = &bytecode->data[0];
905 for (pc = next_pc = start_pc; pc - start_pc < bytecode->len;
906 pc = next_pc) {
907 if (unlikely(pc >= start_pc + bytecode->len)) {
908 ERR("filter bytecode overflow\n");
909 ret = -EINVAL;
910 goto end;
911 }
912 dbg_printf("Validating op %s (%u)\n",
913 print_op((unsigned int) *(filter_opcode_t *) pc),
914 (unsigned int) *(filter_opcode_t *) pc);
915 switch (*(filter_opcode_t *) pc) {
916 case FILTER_OP_UNKNOWN:
917 default:
918 ERR("unknown bytecode op %u\n",
919 (unsigned int) *(filter_opcode_t *) pc);
920 ret = -EINVAL;
921 goto end;
922
923 case FILTER_OP_RETURN:
924 ret = 0;
925 goto end;
926
927 /* binary */
928 case FILTER_OP_MUL:
929 case FILTER_OP_DIV:
930 case FILTER_OP_MOD:
931 case FILTER_OP_PLUS:
932 case FILTER_OP_MINUS:
933 case FILTER_OP_RSHIFT:
934 case FILTER_OP_LSHIFT:
935 case FILTER_OP_BIN_AND:
936 case FILTER_OP_BIN_OR:
937 case FILTER_OP_BIN_XOR:
938 ERR("unsupported bytecode op %u\n",
939 (unsigned int) *(filter_opcode_t *) pc);
940 ret = -EINVAL;
941 goto end;
942
943 case FILTER_OP_EQ:
944 {
945 ret = bin_op_compare_check(reg, "==");
946 if (ret)
947 goto end;
948 reg[REG_R0].type = REG_S64;
949 next_pc += sizeof(struct binary_op);
950 break;
951 }
952 case FILTER_OP_NE:
953 {
954 ret = bin_op_compare_check(reg, "!=");
955 if (ret)
956 goto end;
957 reg[REG_R0].type = REG_S64;
958 next_pc += sizeof(struct binary_op);
959 break;
960 }
961 case FILTER_OP_GT:
962 {
963 ret = bin_op_compare_check(reg, ">");
964 if (ret)
965 goto end;
966 reg[REG_R0].type = REG_S64;
967 next_pc += sizeof(struct binary_op);
968 break;
969 }
970 case FILTER_OP_LT:
971 {
972 ret = bin_op_compare_check(reg, "<");
973 if (ret)
974 goto end;
975 reg[REG_R0].type = REG_S64;
976 next_pc += sizeof(struct binary_op);
977 break;
978 }
979 case FILTER_OP_GE:
980 {
981 ret = bin_op_compare_check(reg, ">=");
982 if (ret)
983 goto end;
984 reg[REG_R0].type = REG_S64;
985 next_pc += sizeof(struct binary_op);
986 break;
987 }
988 case FILTER_OP_LE:
989 {
990 ret = bin_op_compare_check(reg, "<=");
991 if (ret)
992 goto end;
993 reg[REG_R0].type = REG_S64;
994 next_pc += sizeof(struct binary_op);
995 break;
996 }
997
998 case FILTER_OP_EQ_STRING:
999 case FILTER_OP_NE_STRING:
1000 case FILTER_OP_GT_STRING:
1001 case FILTER_OP_LT_STRING:
1002 case FILTER_OP_GE_STRING:
1003 case FILTER_OP_LE_STRING:
1004 {
1005 if (reg[REG_R0].type != REG_STRING
1006 || reg[REG_R1].type != REG_STRING) {
1007 ERR("Unexpected register type for string comparator\n");
1008 ret = -EINVAL;
1009 goto end;
1010 }
1011 reg[REG_R0].type = REG_S64;
1012 next_pc += sizeof(struct binary_op);
1013 break;
1014 }
1015
1016 case FILTER_OP_EQ_S64:
1017 case FILTER_OP_NE_S64:
1018 case FILTER_OP_GT_S64:
1019 case FILTER_OP_LT_S64:
1020 case FILTER_OP_GE_S64:
1021 case FILTER_OP_LE_S64:
1022 {
1023 if (reg[REG_R0].type != REG_S64
1024 || reg[REG_R1].type != REG_S64) {
1025 ERR("Unexpected register type for s64 comparator\n");
1026 ret = -EINVAL;
1027 goto end;
1028 }
1029 reg[REG_R0].type = REG_S64;
1030 next_pc += sizeof(struct binary_op);
1031 break;
1032 }
1033
1034 case FILTER_OP_EQ_DOUBLE:
1035 case FILTER_OP_NE_DOUBLE:
1036 case FILTER_OP_GT_DOUBLE:
1037 case FILTER_OP_LT_DOUBLE:
1038 case FILTER_OP_GE_DOUBLE:
1039 case FILTER_OP_LE_DOUBLE:
1040 {
1041 if ((reg[REG_R0].type != REG_DOUBLE && reg[REG_R0].type != REG_S64)
1042 || (reg[REG_R1].type != REG_DOUBLE && reg[REG_R1].type != REG_S64)) {
1043 ERR("Unexpected register type for double comparator\n");
1044 ret = -EINVAL;
1045 goto end;
1046 }
1047 if (reg[REG_R0].type != REG_DOUBLE && reg[REG_R1].type != REG_DOUBLE) {
1048 ERR("Double operator should have at least one double register\n");
1049 ret = -EINVAL;
1050 goto end;
1051 }
1052 reg[REG_R0].type = REG_DOUBLE;
1053 next_pc += sizeof(struct binary_op);
1054 break;
1055 }
1056
1057 /* unary */
1058 case FILTER_OP_UNARY_PLUS:
1059 case FILTER_OP_UNARY_MINUS:
1060 case FILTER_OP_UNARY_NOT:
1061 {
1062 struct unary_op *insn = (struct unary_op *) pc;
1063
1064 if (unlikely(insn->reg >= REG_ERROR)) {
1065 ERR("invalid register %u\n",
1066 (unsigned int) insn->reg);
1067 ret = -EINVAL;
1068 goto end;
1069 }
1070 switch (reg[insn->reg].type) {
1071 default:
1072 ERR("unknown register type\n");
1073 ret = -EINVAL;
1074 goto end;
1075
1076 case REG_STRING:
1077 ERR("Unary op can only be applied to numeric or floating point registers\n");
1078 ret = -EINVAL;
1079 goto end;
1080 case REG_S64:
1081 break;
1082 case REG_DOUBLE:
1083 break;
1084 }
1085 next_pc += sizeof(struct unary_op);
1086 break;
1087 }
1088
1089 case FILTER_OP_UNARY_PLUS_S64:
1090 case FILTER_OP_UNARY_MINUS_S64:
1091 case FILTER_OP_UNARY_NOT_S64:
1092 {
1093 struct unary_op *insn = (struct unary_op *) pc;
1094
1095 if (unlikely(insn->reg >= REG_ERROR)) {
1096 ERR("invalid register %u\n",
1097 (unsigned int) insn->reg);
1098 ret = -EINVAL;
1099 goto end;
1100 }
1101 if (reg[insn->reg].type != REG_S64) {
1102 ERR("Invalid register type\n");
1103 ret = -EINVAL;
1104 goto end;
1105 }
1106 next_pc += sizeof(struct unary_op);
1107 break;
1108 }
1109
1110 case FILTER_OP_UNARY_PLUS_DOUBLE:
1111 case FILTER_OP_UNARY_MINUS_DOUBLE:
1112 case FILTER_OP_UNARY_NOT_DOUBLE:
1113 {
1114 struct unary_op *insn = (struct unary_op *) pc;
1115
1116 if (unlikely(insn->reg >= REG_ERROR)) {
1117 ERR("invalid register %u\n",
1118 (unsigned int) insn->reg);
1119 ret = -EINVAL;
1120 goto end;
1121 }
1122 if (reg[insn->reg].type != REG_DOUBLE) {
1123 ERR("Invalid register type\n");
1124 ret = -EINVAL;
1125 goto end;
1126 }
1127 next_pc += sizeof(struct unary_op);
1128 break;
1129 }
1130
1131 /* logical */
1132 case FILTER_OP_AND:
1133 case FILTER_OP_OR:
1134 case FILTER_OP_AND_S64:
1135 case FILTER_OP_OR_S64:
1136 case FILTER_OP_AND_DOUBLE:
1137 case FILTER_OP_OR_DOUBLE:
1138 {
1139 struct logical_op *insn = (struct logical_op *) pc;
1140
1141 if (unlikely(reg[REG_R0].type == REG_TYPE_UNKNOWN
1142 || reg[REG_R1].type == REG_TYPE_UNKNOWN
1143 || reg[REG_R0].type == REG_STRING
1144 || reg[REG_R1].type == REG_STRING)) {
1145 ERR("Logical comparator can only be applied to numeric and floating point registers\n");
1146 ret = -EINVAL;
1147 goto end;
1148 }
1149
1150 dbg_printf("Validate jumping to bytecode offset %u\n",
1151 (unsigned int) insn->skip_offset);
1152 if (unlikely(start_pc + insn->skip_offset <= pc)) {
1153 ERR("Loops are not allowed in bytecode\n");
1154 ret = -EINVAL;
1155 goto end;
1156 }
1157 if (insn->op == FILTER_OP_AND_S64
1158 || insn->op == FILTER_OP_OR_S64) {
1159 if (reg[REG_R0].type != REG_S64
1160 || reg[REG_R1].type != REG_S64) {
1161 ret = -EINVAL;
1162 goto end;
1163 }
1164 }
1165 if (insn->op == FILTER_OP_AND_DOUBLE
1166 || insn->op == FILTER_OP_OR_DOUBLE) {
1167 if (reg[REG_R0].type != REG_DOUBLE
1168 && reg[REG_R1].type != REG_DOUBLE) {
1169 ERR("Double operator should have at least one double register\n");
1170 ret = -EINVAL;
1171 goto end;
1172 }
1173 }
1174 switch(reg[REG_R0].type) {
1175 default:
1176 case REG_STRING:
1177 ERR("unknown register type\n");
1178 ret = -EINVAL;
1179 goto end;
1180
1181 case REG_S64:
1182 if (reg[REG_R1].type == REG_S64) {
1183 reg[REG_R0].type = REG_S64;
1184 } else {
1185 reg[REG_R0].type = REG_DOUBLE;
1186 }
1187 break;
1188 case REG_DOUBLE:
1189 reg[REG_R0].type = REG_DOUBLE;
1190 break;
1191 }
1192 next_pc += sizeof(struct logical_op);
1193 break;
1194 }
1195
1196 /* load */
1197 case FILTER_OP_LOAD_FIELD_REF:
1198 {
1199 ERR("Unknown field ref type\n");
1200 ret = -EINVAL;
1201 goto end;
1202 }
1203 case FILTER_OP_LOAD_FIELD_REF_STRING:
1204 case FILTER_OP_LOAD_FIELD_REF_SEQUENCE:
1205 {
1206 struct load_op *insn = (struct load_op *) pc;
1207 struct field_ref *ref = (struct field_ref *) insn->data;
1208
1209 if (unlikely(insn->reg >= REG_ERROR)) {
1210 ERR("invalid register %u\n",
1211 (unsigned int) insn->reg);
1212 ret = -EINVAL;
1213 goto end;
1214 }
1215 dbg_printf("Validate load field ref offset %u type string\n",
1216 ref->offset);
1217 reg[insn->reg].type = REG_STRING;
1218 reg[insn->reg].literal = 0;
1219 next_pc += sizeof(struct load_op) + sizeof(struct field_ref);
1220 break;
1221 }
1222 case FILTER_OP_LOAD_FIELD_REF_S64:
1223 {
1224 struct load_op *insn = (struct load_op *) pc;
1225 struct field_ref *ref = (struct field_ref *) insn->data;
1226
1227 if (unlikely(insn->reg >= REG_ERROR)) {
1228 ERR("invalid register %u\n",
1229 (unsigned int) insn->reg);
1230 ret = -EINVAL;
1231 goto end;
1232 }
1233 dbg_printf("Validate load field ref offset %u type s64\n",
1234 ref->offset);
1235 reg[insn->reg].type = REG_S64;
1236 reg[insn->reg].literal = 0;
1237 next_pc += sizeof(struct load_op) + sizeof(struct field_ref);
1238 break;
1239 }
1240 case FILTER_OP_LOAD_FIELD_REF_DOUBLE:
1241 {
1242 struct load_op *insn = (struct load_op *) pc;
1243 struct field_ref *ref = (struct field_ref *) insn->data;
1244
1245 if (unlikely(insn->reg >= REG_ERROR)) {
1246 ERR("invalid register %u\n",
1247 (unsigned int) insn->reg);
1248 ret = -EINVAL;
1249 goto end;
1250 }
1251 dbg_printf("Validate load field ref offset %u type double\n",
1252 ref->offset);
1253 reg[insn->reg].type = REG_DOUBLE;
1254 reg[insn->reg].literal = 0;
1255 next_pc += sizeof(struct load_op) + sizeof(struct field_ref);
1256 break;
1257 }
1258
1259 case FILTER_OP_LOAD_STRING:
1260 {
1261 struct load_op *insn = (struct load_op *) pc;
1262
1263 if (unlikely(insn->reg >= REG_ERROR)) {
1264 ERR("invalid register %u\n",
1265 (unsigned int) insn->reg);
1266 ret = -EINVAL;
1267 goto end;
1268 }
1269 reg[insn->reg].type = REG_STRING;
1270 reg[insn->reg].literal = 1;
1271 next_pc += sizeof(struct load_op) + strlen(insn->data) + 1;
1272 break;
1273 }
1274
1275 case FILTER_OP_LOAD_S64:
1276 {
1277 struct load_op *insn = (struct load_op *) pc;
1278
1279 if (unlikely(insn->reg >= REG_ERROR)) {
1280 ERR("invalid register %u\n",
1281 (unsigned int) insn->reg);
1282 ret = -EINVAL;
1283 goto end;
1284 }
1285 reg[insn->reg].type = REG_S64;
1286 reg[insn->reg].literal = 1;
1287 next_pc += sizeof(struct load_op)
1288 + sizeof(struct literal_numeric);
1289 break;
1290 }
1291
1292 case FILTER_OP_LOAD_DOUBLE:
1293 {
1294 struct load_op *insn = (struct load_op *) pc;
1295
1296 if (unlikely(insn->reg >= REG_ERROR)) {
1297 ERR("invalid register %u\n",
1298 (unsigned int) insn->reg);
1299 ret = -EINVAL;
1300 goto end;
1301 }
1302 reg[insn->reg].type = REG_DOUBLE;
1303 reg[insn->reg].literal = 1;
1304 next_pc += sizeof(struct load_op)
1305 + sizeof(struct literal_double);
1306 break;
1307 }
1308 }
1309 }
1310 end:
1311 return ret;
1312 }
1313
1314 static
1315 int lttng_filter_specialize_bytecode(struct bytecode_runtime *bytecode)
1316 {
1317 void *pc, *next_pc, *start_pc;
1318 int ret = -EINVAL;
1319 struct vreg reg[NR_REG];
1320 int i;
1321
1322 for (i = 0; i < NR_REG; i++) {
1323 reg[i].type = REG_TYPE_UNKNOWN;
1324 reg[i].literal = 0;
1325 }
1326
1327 start_pc = &bytecode->data[0];
1328 for (pc = next_pc = start_pc; pc - start_pc < bytecode->len;
1329 pc = next_pc) {
1330 switch (*(filter_opcode_t *) pc) {
1331 case FILTER_OP_UNKNOWN:
1332 default:
1333 ERR("unknown bytecode op %u\n",
1334 (unsigned int) *(filter_opcode_t *) pc);
1335 ret = -EINVAL;
1336 goto end;
1337
1338 case FILTER_OP_RETURN:
1339 ret = 0;
1340 goto end;
1341
1342 /* binary */
1343 case FILTER_OP_MUL:
1344 case FILTER_OP_DIV:
1345 case FILTER_OP_MOD:
1346 case FILTER_OP_PLUS:
1347 case FILTER_OP_MINUS:
1348 case FILTER_OP_RSHIFT:
1349 case FILTER_OP_LSHIFT:
1350 case FILTER_OP_BIN_AND:
1351 case FILTER_OP_BIN_OR:
1352 case FILTER_OP_BIN_XOR:
1353 ERR("unsupported bytecode op %u\n",
1354 (unsigned int) *(filter_opcode_t *) pc);
1355 ret = -EINVAL;
1356 goto end;
1357
1358 case FILTER_OP_EQ:
1359 {
1360 struct binary_op *insn = (struct binary_op *) pc;
1361
1362 switch(reg[REG_R0].type) {
1363 default:
1364 ERR("unknown register type\n");
1365 ret = -EINVAL;
1366 goto end;
1367
1368 case REG_STRING:
1369 insn->op = FILTER_OP_EQ_STRING;
1370 break;
1371 case REG_S64:
1372 if (reg[REG_R1].type == REG_S64)
1373 insn->op = FILTER_OP_EQ_S64;
1374 else
1375 insn->op = FILTER_OP_EQ_DOUBLE;
1376 break;
1377 case REG_DOUBLE:
1378 insn->op = FILTER_OP_EQ_DOUBLE;
1379 break;
1380 }
1381 reg[REG_R0].type = REG_S64;
1382 next_pc += sizeof(struct binary_op);
1383 break;
1384 }
1385
1386 case FILTER_OP_NE:
1387 {
1388 struct binary_op *insn = (struct binary_op *) pc;
1389
1390 switch(reg[REG_R0].type) {
1391 default:
1392 ERR("unknown register type\n");
1393 ret = -EINVAL;
1394 goto end;
1395
1396 case REG_STRING:
1397 insn->op = FILTER_OP_NE_STRING;
1398 break;
1399 case REG_S64:
1400 if (reg[REG_R1].type == REG_S64)
1401 insn->op = FILTER_OP_NE_S64;
1402 else
1403 insn->op = FILTER_OP_NE_DOUBLE;
1404 break;
1405 case REG_DOUBLE:
1406 insn->op = FILTER_OP_NE_DOUBLE;
1407 break;
1408 }
1409 reg[REG_R0].type = REG_S64;
1410 next_pc += sizeof(struct binary_op);
1411 break;
1412 }
1413
1414 case FILTER_OP_GT:
1415 {
1416 struct binary_op *insn = (struct binary_op *) pc;
1417
1418 switch(reg[REG_R0].type) {
1419 default:
1420 ERR("unknown register type\n");
1421 ret = -EINVAL;
1422 goto end;
1423
1424 case REG_STRING:
1425 insn->op = FILTER_OP_GT_STRING;
1426 break;
1427 case REG_S64:
1428 if (reg[REG_R1].type == REG_S64)
1429 insn->op = FILTER_OP_GT_S64;
1430 else
1431 insn->op = FILTER_OP_GT_DOUBLE;
1432 break;
1433 case REG_DOUBLE:
1434 insn->op = FILTER_OP_GT_DOUBLE;
1435 break;
1436 }
1437 reg[REG_R0].type = REG_S64;
1438 next_pc += sizeof(struct binary_op);
1439 break;
1440 }
1441
1442 case FILTER_OP_LT:
1443 {
1444 struct binary_op *insn = (struct binary_op *) pc;
1445
1446 switch(reg[REG_R0].type) {
1447 default:
1448 ERR("unknown register type\n");
1449 ret = -EINVAL;
1450 goto end;
1451
1452 case REG_STRING:
1453 insn->op = FILTER_OP_LT_STRING;
1454 break;
1455 case REG_S64:
1456 if (reg[REG_R1].type == REG_S64)
1457 insn->op = FILTER_OP_LT_S64;
1458 else
1459 insn->op = FILTER_OP_LT_DOUBLE;
1460 break;
1461 case REG_DOUBLE:
1462 insn->op = FILTER_OP_LT_DOUBLE;
1463 break;
1464 }
1465 reg[REG_R0].type = REG_S64;
1466 next_pc += sizeof(struct binary_op);
1467 break;
1468 }
1469
1470 case FILTER_OP_GE:
1471 {
1472 struct binary_op *insn = (struct binary_op *) pc;
1473
1474 switch(reg[REG_R0].type) {
1475 default:
1476 ERR("unknown register type\n");
1477 ret = -EINVAL;
1478 goto end;
1479
1480 case REG_STRING:
1481 insn->op = FILTER_OP_GE_STRING;
1482 break;
1483 case REG_S64:
1484 if (reg[REG_R1].type == REG_S64)
1485 insn->op = FILTER_OP_GE_S64;
1486 else
1487 insn->op = FILTER_OP_GE_DOUBLE;
1488 break;
1489 case REG_DOUBLE:
1490 insn->op = FILTER_OP_GE_DOUBLE;
1491 break;
1492 }
1493 reg[REG_R0].type = REG_S64;
1494 next_pc += sizeof(struct binary_op);
1495 break;
1496 }
1497 case FILTER_OP_LE:
1498 {
1499 struct binary_op *insn = (struct binary_op *) pc;
1500
1501 switch(reg[REG_R0].type) {
1502 default:
1503 ERR("unknown register type\n");
1504 ret = -EINVAL;
1505 goto end;
1506
1507 case REG_STRING:
1508 insn->op = FILTER_OP_LE_STRING;
1509 break;
1510 case REG_S64:
1511 if (reg[REG_R1].type == REG_S64)
1512 insn->op = FILTER_OP_LE_S64;
1513 else
1514 insn->op = FILTER_OP_LE_DOUBLE;
1515 break;
1516 case REG_DOUBLE:
1517 insn->op = FILTER_OP_LE_DOUBLE;
1518 break;
1519 }
1520 reg[REG_R0].type = REG_S64;
1521 next_pc += sizeof(struct binary_op);
1522 break;
1523 }
1524
1525 case FILTER_OP_EQ_STRING:
1526 case FILTER_OP_NE_STRING:
1527 case FILTER_OP_GT_STRING:
1528 case FILTER_OP_LT_STRING:
1529 case FILTER_OP_GE_STRING:
1530 case FILTER_OP_LE_STRING:
1531 case FILTER_OP_EQ_S64:
1532 case FILTER_OP_NE_S64:
1533 case FILTER_OP_GT_S64:
1534 case FILTER_OP_LT_S64:
1535 case FILTER_OP_GE_S64:
1536 case FILTER_OP_LE_S64:
1537 case FILTER_OP_EQ_DOUBLE:
1538 case FILTER_OP_NE_DOUBLE:
1539 case FILTER_OP_GT_DOUBLE:
1540 case FILTER_OP_LT_DOUBLE:
1541 case FILTER_OP_GE_DOUBLE:
1542 case FILTER_OP_LE_DOUBLE:
1543 {
1544 reg[REG_R0].type = REG_S64;
1545 next_pc += sizeof(struct binary_op);
1546 break;
1547 }
1548
1549 /* unary */
1550 case FILTER_OP_UNARY_PLUS:
1551 {
1552 struct unary_op *insn = (struct unary_op *) pc;
1553
1554 switch(reg[insn->reg].type) {
1555 default:
1556 ERR("unknown register type\n");
1557 ret = -EINVAL;
1558 goto end;
1559
1560 case REG_S64:
1561 insn->op = FILTER_OP_UNARY_PLUS_S64;
1562 break;
1563 case REG_DOUBLE:
1564 insn->op = FILTER_OP_UNARY_PLUS_DOUBLE;
1565 break;
1566 }
1567 next_pc += sizeof(struct unary_op);
1568 break;
1569 }
1570
1571 case FILTER_OP_UNARY_MINUS:
1572 {
1573 struct unary_op *insn = (struct unary_op *) pc;
1574
1575 switch(reg[insn->reg].type) {
1576 default:
1577 ERR("unknown register type\n");
1578 ret = -EINVAL;
1579 goto end;
1580
1581 case REG_S64:
1582 insn->op = FILTER_OP_UNARY_MINUS_S64;
1583 break;
1584 case REG_DOUBLE:
1585 insn->op = FILTER_OP_UNARY_MINUS_DOUBLE;
1586 break;
1587 }
1588 next_pc += sizeof(struct unary_op);
1589 break;
1590 }
1591
1592 case FILTER_OP_UNARY_NOT:
1593 {
1594 struct unary_op *insn = (struct unary_op *) pc;
1595
1596 switch(reg[insn->reg].type) {
1597 default:
1598 ERR("unknown register type\n");
1599 ret = -EINVAL;
1600 goto end;
1601
1602 case REG_S64:
1603 insn->op = FILTER_OP_UNARY_NOT_S64;
1604 break;
1605 case REG_DOUBLE:
1606 insn->op = FILTER_OP_UNARY_NOT_DOUBLE;
1607 break;
1608 }
1609 next_pc += sizeof(struct unary_op);
1610 break;
1611 }
1612
1613 case FILTER_OP_UNARY_PLUS_S64:
1614 case FILTER_OP_UNARY_MINUS_S64:
1615 case FILTER_OP_UNARY_NOT_S64:
1616 case FILTER_OP_UNARY_PLUS_DOUBLE:
1617 case FILTER_OP_UNARY_MINUS_DOUBLE:
1618 case FILTER_OP_UNARY_NOT_DOUBLE:
1619 {
1620 next_pc += sizeof(struct unary_op);
1621 break;
1622 }
1623
1624 /* logical */
1625 case FILTER_OP_AND:
1626 {
1627 struct logical_op *insn = (struct logical_op *) pc;
1628
1629 switch(reg[REG_R0].type) {
1630 default:
1631 case REG_STRING:
1632 ERR("unknown register type\n");
1633 ret = -EINVAL;
1634 goto end;
1635
1636 case REG_S64:
1637 if (reg[REG_R1].type == REG_S64) {
1638 insn->op = FILTER_OP_AND_S64;
1639 reg[REG_R0].type = REG_S64;
1640 } else {
1641 insn->op = FILTER_OP_AND_DOUBLE;
1642 reg[REG_R0].type = REG_DOUBLE;
1643 }
1644 break;
1645 case REG_DOUBLE:
1646 insn->op = FILTER_OP_AND_DOUBLE;
1647 reg[REG_R0].type = REG_DOUBLE;
1648 break;
1649 }
1650 next_pc += sizeof(struct logical_op);
1651 break;
1652 }
1653 case FILTER_OP_OR:
1654 {
1655 struct logical_op *insn = (struct logical_op *) pc;
1656
1657 switch(reg[REG_R0].type) {
1658 default:
1659 case REG_STRING:
1660 ERR("unknown register type\n");
1661 ret = -EINVAL;
1662 goto end;
1663
1664 case REG_S64:
1665 if (reg[REG_R1].type == REG_S64) {
1666 insn->op = FILTER_OP_OR_S64;
1667 reg[REG_R0].type = REG_S64;
1668 } else {
1669 insn->op = FILTER_OP_OR_DOUBLE;
1670 reg[REG_R0].type = REG_DOUBLE;
1671 }
1672 break;
1673 case REG_DOUBLE:
1674 insn->op = FILTER_OP_OR_DOUBLE;
1675 reg[REG_R0].type = REG_DOUBLE;
1676 break;
1677 }
1678 next_pc += sizeof(struct logical_op);
1679 break;
1680 }
1681
1682 case FILTER_OP_AND_S64:
1683 case FILTER_OP_OR_S64:
1684 case FILTER_OP_AND_DOUBLE:
1685 case FILTER_OP_OR_DOUBLE:
1686 {
1687 next_pc += sizeof(struct logical_op);
1688 break;
1689 }
1690
1691 /* load */
1692 case FILTER_OP_LOAD_FIELD_REF:
1693 {
1694 ERR("Unknown field ref type\n");
1695 ret = -EINVAL;
1696 goto end;
1697 }
1698 case FILTER_OP_LOAD_FIELD_REF_STRING:
1699 case FILTER_OP_LOAD_FIELD_REF_SEQUENCE:
1700 {
1701 struct load_op *insn = (struct load_op *) pc;
1702
1703 reg[insn->reg].type = REG_STRING;
1704 reg[insn->reg].literal = 0;
1705 next_pc += sizeof(struct load_op) + sizeof(struct field_ref);
1706 break;
1707 }
1708 case FILTER_OP_LOAD_FIELD_REF_S64:
1709 {
1710 struct load_op *insn = (struct load_op *) pc;
1711
1712 reg[insn->reg].type = REG_S64;
1713 reg[insn->reg].literal = 0;
1714 next_pc += sizeof(struct load_op) + sizeof(struct field_ref);
1715 break;
1716 }
1717 case FILTER_OP_LOAD_FIELD_REF_DOUBLE:
1718 {
1719 struct load_op *insn = (struct load_op *) pc;
1720
1721 reg[insn->reg].type = REG_DOUBLE;
1722 reg[insn->reg].literal = 0;
1723 next_pc += sizeof(struct load_op) + sizeof(struct field_ref);
1724 break;
1725 }
1726
1727 case FILTER_OP_LOAD_STRING:
1728 {
1729 struct load_op *insn = (struct load_op *) pc;
1730
1731 reg[insn->reg].type = REG_STRING;
1732 reg[insn->reg].literal = 1;
1733 next_pc += sizeof(struct load_op) + strlen(insn->data) + 1;
1734 break;
1735 }
1736
1737 case FILTER_OP_LOAD_S64:
1738 {
1739 struct load_op *insn = (struct load_op *) pc;
1740
1741 reg[insn->reg].type = REG_S64;
1742 reg[insn->reg].literal = 1;
1743 next_pc += sizeof(struct load_op)
1744 + sizeof(struct literal_numeric);
1745 break;
1746 }
1747
1748 case FILTER_OP_LOAD_DOUBLE:
1749 {
1750 struct load_op *insn = (struct load_op *) pc;
1751
1752 reg[insn->reg].type = REG_DOUBLE;
1753 reg[insn->reg].literal = 1;
1754 next_pc += sizeof(struct load_op)
1755 + sizeof(struct literal_double);
1756 break;
1757 }
1758 }
1759 }
1760 end:
1761 return ret;
1762 }
1763
1764
1765
1766 static
1767 int apply_field_reloc(struct ltt_event *event,
1768 struct bytecode_runtime *runtime,
1769 uint32_t runtime_len,
1770 uint32_t reloc_offset,
1771 const char *field_name)
1772 {
1773 const struct lttng_event_desc *desc;
1774 const struct lttng_event_field *fields, *field = NULL;
1775 unsigned int nr_fields, i;
1776 struct field_ref *field_ref;
1777 struct load_op *op;
1778 uint32_t field_offset = 0;
1779
1780 dbg_printf("Apply reloc: %u %s\n", reloc_offset, field_name);
1781
1782 /* Ensure that the reloc is within the code */
1783 if (runtime_len - reloc_offset < sizeof(uint16_t))
1784 return -EINVAL;
1785
1786 /* Lookup event by name */
1787 desc = event->desc;
1788 if (!desc)
1789 return -EINVAL;
1790 fields = desc->fields;
1791 if (!fields)
1792 return -EINVAL;
1793 nr_fields = desc->nr_fields;
1794 for (i = 0; i < nr_fields; i++) {
1795 if (!strcmp(fields[i].name, field_name)) {
1796 field = &fields[i];
1797 break;
1798 }
1799 /* compute field offset */
1800 switch (fields[i].type.atype) {
1801 case atype_integer:
1802 case atype_enum:
1803 field_offset += sizeof(int64_t);
1804 break;
1805 case atype_array:
1806 case atype_sequence:
1807 field_offset += sizeof(unsigned long);
1808 field_offset += sizeof(void *);
1809 break;
1810 case atype_string:
1811 field_offset += sizeof(void *);
1812 break;
1813 case atype_float:
1814 field_offset += sizeof(double);
1815 break;
1816 default:
1817 return -EINVAL;
1818 }
1819 }
1820 if (!field)
1821 return -EINVAL;
1822
1823 /* Check if field offset is too large for 16-bit offset */
1824 if (field_offset > FILTER_BYTECODE_MAX_LEN)
1825 return -EINVAL;
1826
1827 /* set type */
1828 op = (struct load_op *) &runtime->data[reloc_offset];
1829 field_ref = (struct field_ref *) op->data;
1830 switch (field->type.atype) {
1831 case atype_integer:
1832 case atype_enum:
1833 op->op = FILTER_OP_LOAD_FIELD_REF_S64;
1834 break;
1835 case atype_array:
1836 case atype_sequence:
1837 op->op = FILTER_OP_LOAD_FIELD_REF_SEQUENCE;
1838 break;
1839 case atype_string:
1840 op->op = FILTER_OP_LOAD_FIELD_REF_STRING;
1841 break;
1842 case atype_float:
1843 op->op = FILTER_OP_LOAD_FIELD_REF_DOUBLE;
1844 break;
1845 default:
1846 return -EINVAL;
1847 }
1848 /* set offset */
1849 field_ref->offset = (uint16_t) field_offset;
1850 return 0;
1851 }
1852
1853 /*
1854 * Take a bytecode with reloc table and link it to an event to create a
1855 * bytecode runtime.
1856 */
1857 static
1858 int _lttng_filter_event_link_bytecode(struct ltt_event *event,
1859 struct lttng_ust_filter_bytecode *filter_bytecode)
1860 {
1861 int ret, offset, next_offset;
1862 struct bytecode_runtime *runtime = NULL;
1863 size_t runtime_alloc_len;
1864
1865 if (!filter_bytecode)
1866 return 0;
1867 /* Even is not connected to any description */
1868 if (!event->desc)
1869 return 0;
1870 /* Bytecode already linked */
1871 if (event->filter || event->filter_data)
1872 return 0;
1873
1874 dbg_printf("Linking\n");
1875
1876 /* We don't need the reloc table in the runtime */
1877 runtime_alloc_len = sizeof(*runtime) + filter_bytecode->reloc_offset;
1878 runtime = zmalloc(runtime_alloc_len);
1879 if (!runtime) {
1880 ret = -ENOMEM;
1881 goto link_error;
1882 }
1883 runtime->len = filter_bytecode->reloc_offset;
1884 /* copy original bytecode */
1885 memcpy(runtime->data, filter_bytecode->data, runtime->len);
1886 /*
1887 * apply relocs. Those are a uint16_t (offset in bytecode)
1888 * followed by a string (field name).
1889 */
1890 for (offset = filter_bytecode->reloc_offset;
1891 offset < filter_bytecode->len;
1892 offset = next_offset) {
1893 uint16_t reloc_offset =
1894 *(uint16_t *) &filter_bytecode->data[offset];
1895 const char *field_name =
1896 (const char *) &filter_bytecode->data[offset + sizeof(uint16_t)];
1897
1898 ret = apply_field_reloc(event, runtime, runtime->len, reloc_offset, field_name);
1899 if (ret) {
1900 goto link_error;
1901 }
1902 next_offset = offset + sizeof(uint16_t) + strlen(field_name) + 1;
1903 }
1904 /* Validate bytecode */
1905 ret = lttng_filter_validate_bytecode(runtime);
1906 if (ret) {
1907 goto link_error;
1908 }
1909 /* Specialize bytecode */
1910 ret = lttng_filter_specialize_bytecode(runtime);
1911 if (ret) {
1912 goto link_error;
1913 }
1914 event->filter_data = runtime;
1915 event->filter = lttng_filter_interpret_bytecode;
1916 return 0;
1917
1918 link_error:
1919 event->filter = lttng_filter_false;
1920 free(runtime);
1921 return ret;
1922 }
1923
1924 void lttng_filter_event_link_bytecode(struct ltt_event *event,
1925 struct lttng_ust_filter_bytecode *filter_bytecode)
1926 {
1927 int ret;
1928
1929 ret = _lttng_filter_event_link_bytecode(event, filter_bytecode);
1930 if (ret) {
1931 fprintf(stderr, "[lttng filter] error linking event bytecode\n");
1932 }
1933 }
1934
1935 /*
1936 * Link bytecode to all events for a wildcard. Skips events that already
1937 * have a bytecode linked.
1938 * We do not set each event's filter_bytecode field, because they do not
1939 * own the filter_bytecode: the wildcard owns it.
1940 */
1941 void lttng_filter_wildcard_link_bytecode(struct session_wildcard *wildcard)
1942 {
1943 struct ltt_event *event;
1944 int ret;
1945
1946 if (!wildcard->filter_bytecode)
1947 return;
1948
1949 cds_list_for_each_entry(event, &wildcard->events, wildcard_list) {
1950 if (event->filter)
1951 continue;
1952 ret = _lttng_filter_event_link_bytecode(event,
1953 wildcard->filter_bytecode);
1954 if (ret) {
1955 fprintf(stderr, "[lttng filter] error linking wildcard bytecode\n");
1956 }
1957
1958 }
1959 return;
1960 }
1961
1962 /*
1963 * Need to attach filter to an event before starting tracing for the
1964 * session. We own the filter_bytecode if we return success.
1965 */
1966 int lttng_filter_event_attach_bytecode(struct ltt_event *event,
1967 struct lttng_ust_filter_bytecode *filter_bytecode)
1968 {
1969 if (event->chan->session->been_active)
1970 return -EPERM;
1971 if (event->filter_bytecode)
1972 return -EEXIST;
1973 event->filter_bytecode = filter_bytecode;
1974 return 0;
1975 }
1976
1977 /*
1978 * Need to attach filter to a wildcard before starting tracing for the
1979 * session. We own the filter_bytecode if we return success.
1980 */
1981 int lttng_filter_wildcard_attach_bytecode(struct session_wildcard *wildcard,
1982 struct lttng_ust_filter_bytecode *filter_bytecode)
1983 {
1984 if (wildcard->chan->session->been_active)
1985 return -EPERM;
1986 if (wildcard->filter_bytecode)
1987 return -EEXIST;
1988 wildcard->filter_bytecode = filter_bytecode;
1989 return 0;
1990 }
This page took 0.068927 seconds and 5 git commands to generate.