filter: Add bytecode validation pass
[lttng-ust.git] / liblttng-ust / lttng-filter.c
CommitLineData
2d78951a
MD
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>
cd54f6d9
MD
27#include <stdint.h>
28#include <errno.h>
29#include <string.h>
30#include <inttypes.h>
31#include <limits.h>
b1caea50 32#include <usterr-signal-safe.h>
cd54f6d9
MD
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...) \
54do { \
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 */
62struct bytecode_runtime {
63 uint16_t len;
64 char data[0];
65};
66
9522a886
MD
67enum reg_type {
68 REG_S64,
69 REG_DOUBLE,
70 REG_STRING,
71};
72
73/* Validation registers */
74struct vreg {
75 enum reg_type type;
76 int literal; /* is string literal ? */
77};
78
79/* Execution registers */
cd54f6d9 80struct reg {
9522a886 81 enum reg_type type;
cd54f6d9 82 int64_t v;
da6eed25 83 double d;
cd54f6d9
MD
84
85 const char *str;
86 size_t seq_len;
87 int literal; /* is string literal ? */
88};
89
90static const char *opnames[] = {
91 [ FILTER_OP_UNKNOWN ] = "UNKNOWN",
92
93 [ FILTER_OP_RETURN ] = "RETURN",
94
95 /* binary */
96 [ FILTER_OP_MUL ] = "MUL",
97 [ FILTER_OP_DIV ] = "DIV",
98 [ FILTER_OP_MOD ] = "MOD",
99 [ FILTER_OP_PLUS ] = "PLUS",
100 [ FILTER_OP_MINUS ] = "MINUS",
101 [ FILTER_OP_RSHIFT ] = "RSHIFT",
102 [ FILTER_OP_LSHIFT ] = "LSHIFT",
103 [ FILTER_OP_BIN_AND ] = "BIN_AND",
104 [ FILTER_OP_BIN_OR ] = "BIN_OR",
105 [ FILTER_OP_BIN_XOR ] = "BIN_XOR",
106 [ FILTER_OP_EQ ] = "EQ",
107 [ FILTER_OP_NE ] = "NE",
108 [ FILTER_OP_GT ] = "GT",
109 [ FILTER_OP_LT ] = "LT",
110 [ FILTER_OP_GE ] = "GE",
111 [ FILTER_OP_LE ] = "LE",
112
113 /* unary */
114 [ FILTER_OP_UNARY_PLUS ] = "UNARY_PLUS",
115 [ FILTER_OP_UNARY_MINUS ] = "UNARY_MINUS",
116 [ FILTER_OP_UNARY_NOT ] = "UNARY_NOT",
117
118 /* logical */
119 [ FILTER_OP_AND ] = "AND",
120 [ FILTER_OP_OR ] = "OR",
121
122 /* load */
123 [ FILTER_OP_LOAD_FIELD_REF ] = "LOAD_FIELD_REF",
124 [ FILTER_OP_LOAD_STRING ] = "LOAD_STRING",
125 [ FILTER_OP_LOAD_S64 ] = "LOAD_S64",
da6eed25 126 [ FILTER_OP_LOAD_DOUBLE ] = "LOAD_DOUBLE",
cd54f6d9
MD
127};
128
129static
130const char *print_op(enum filter_op op)
131{
132 if (op >= NR_FILTER_OPS)
133 return "UNKNOWN";
134 else
135 return opnames[op];
136}
137
138/*
139 * -1: wildcard found.
140 * -2: unknown escape char.
141 * 0: normal char.
142 */
143
144static
145int parse_char(const char **p)
146{
147 switch (**p) {
148 case '\\':
149 (*p)++;
150 switch (**p) {
151 case '\\':
152 case '*':
153 return 0;
154 default:
155 return -2;
156 }
157 case '*':
158 return -1;
159 default:
160 return 0;
161 }
162}
163
164static
165int reg_strcmp(struct reg reg[NR_REG], const char *cmp_type)
166{
167 const char *p = reg[REG_R0].str, *q = reg[REG_R1].str;
168 int ret;
169 int diff;
170
171 for (;;) {
172 int escaped_r0 = 0;
173
174 if (unlikely(p - reg[REG_R0].str > reg[REG_R0].seq_len || *p == '\0')) {
175 if (q - reg[REG_R1].str > reg[REG_R1].seq_len || *q == '\0')
176 diff = 0;
177 else
178 diff = -1;
179 break;
180 }
181 if (unlikely(q - reg[REG_R1].str > reg[REG_R1].seq_len || *q == '\0')) {
182 if (p - reg[REG_R0].str > reg[REG_R0].seq_len || *p == '\0')
183 diff = 0;
184 else
185 diff = 1;
186 break;
187 }
188 if (reg[REG_R0].literal) {
189 ret = parse_char(&p);
190 if (ret == -1) {
191 return 0;
192 } else if (ret == -2) {
193 escaped_r0 = 1;
194 }
195 /* else compare both char */
196 }
197 if (reg[REG_R1].literal) {
198 ret = parse_char(&q);
199 if (ret == -1) {
200 return 0;
201 } else if (ret == -2) {
202 if (!escaped_r0)
203 return -1;
204 } else {
205 if (escaped_r0)
206 return 1;
207 }
208 } else {
209 if (escaped_r0)
210 return 1;
211 }
212 diff = *p - *q;
213 if (diff != 0)
214 break;
215 p++;
216 q++;
217 }
218 return diff;
219}
220
221static
222int lttng_filter_false(void *filter_data,
223 const char *filter_stack_data)
224{
225 return 0;
226}
2d78951a
MD
227
228static
229int lttng_filter_interpret_bytecode(void *filter_data,
230 const char *filter_stack_data)
231{
cd54f6d9
MD
232 struct bytecode_runtime *bytecode = filter_data;
233 void *pc, *next_pc, *start_pc;
234 int ret = -EINVAL;
235 int retval = 0;
236 struct reg reg[NR_REG];
237 int i;
238
239 for (i = 0; i < NR_REG; i++) {
240 reg[i].type = REG_S64;
241 reg[i].v = 0;
da6eed25 242 reg[i].d = 0.0;
cd54f6d9
MD
243 reg[i].str = NULL;
244 reg[i].seq_len = 0;
245 reg[i].literal = 0;
246 }
247
248 start_pc = &bytecode->data[0];
249 for (pc = next_pc = start_pc; pc - start_pc < bytecode->len;
250 pc = next_pc) {
251 if (unlikely(pc >= start_pc + bytecode->len)) {
b1caea50 252 ERR("filter bytecode overflow\n");
cd54f6d9
MD
253 ret = -EINVAL;
254 goto end;
255 }
256 dbg_printf("Executing op %s (%u)\n",
257 print_op((unsigned int) *(filter_opcode_t *) pc),
258 (unsigned int) *(filter_opcode_t *) pc);
259 switch (*(filter_opcode_t *) pc) {
260 case FILTER_OP_UNKNOWN:
261 default:
b1caea50 262 ERR("unknown bytecode op %u\n",
cd54f6d9
MD
263 (unsigned int) *(filter_opcode_t *) pc);
264 ret = -EINVAL;
265 goto end;
266
267 case FILTER_OP_RETURN:
268 retval = !!reg[0].v;
269 ret = 0;
270 goto end;
271
272 /* binary */
273 case FILTER_OP_MUL:
274 case FILTER_OP_DIV:
275 case FILTER_OP_MOD:
276 case FILTER_OP_PLUS:
277 case FILTER_OP_MINUS:
278 case FILTER_OP_RSHIFT:
279 case FILTER_OP_LSHIFT:
280 case FILTER_OP_BIN_AND:
281 case FILTER_OP_BIN_OR:
282 case FILTER_OP_BIN_XOR:
b1caea50 283 ERR("unsupported bytecode op %u\n",
cd54f6d9
MD
284 (unsigned int) *(filter_opcode_t *) pc);
285 ret = -EINVAL;
286 goto end;
287
288 case FILTER_OP_EQ:
289 {
da6eed25
MD
290 if (unlikely((reg[REG_R0].type == REG_STRING && reg[REG_R1].type != REG_STRING)
291 || (reg[REG_R0].type != REG_STRING && reg[REG_R1].type == REG_STRING))) {
b1caea50 292 ERR("type mismatch for '==' binary operator\n");
cd54f6d9
MD
293 ret = -EINVAL;
294 goto end;
295 }
296 switch (reg[REG_R0].type) {
297 default:
b1caea50 298 ERR("unknown register type\n");
cd54f6d9
MD
299 ret = -EINVAL;
300 goto end;
301
302 case REG_STRING:
cd54f6d9
MD
303 reg[REG_R0].v = (reg_strcmp(reg, "==") == 0);
304 break;
305 case REG_S64:
da6eed25
MD
306 switch (reg[REG_R1].type) {
307 default:
b1caea50 308 ERR("unknown register type\n");
da6eed25
MD
309 ret = -EINVAL;
310 goto end;
311
312 case REG_S64:
313 reg[REG_R0].v = (reg[REG_R0].v == reg[REG_R1].v);
314 break;
315 case REG_DOUBLE:
316 reg[REG_R0].v = (reg[REG_R0].v == reg[REG_R1].d);
317 break;
318 }
319 break;
320 case REG_DOUBLE:
321 switch (reg[REG_R1].type) {
322 default:
b1caea50 323 ERR("unknown register type\n");
da6eed25
MD
324 ret = -EINVAL;
325 goto end;
326
327 case REG_S64:
328 reg[REG_R0].v = (reg[REG_R0].d == reg[REG_R1].v);
329 break;
330 case REG_DOUBLE:
331 reg[REG_R0].v = (reg[REG_R0].d == reg[REG_R1].d);
332 break;
333 }
cd54f6d9
MD
334 break;
335 }
336 reg[REG_R0].type = REG_S64;
337 next_pc += sizeof(struct binary_op);
338 break;
339 }
340 case FILTER_OP_NE:
341 {
da6eed25
MD
342 if (unlikely((reg[REG_R0].type == REG_STRING && reg[REG_R1].type != REG_STRING)
343 || (reg[REG_R0].type != REG_STRING && reg[REG_R1].type == REG_STRING))) {
b1caea50 344 ERR("type mismatch for '!=' binary operator\n");
cd54f6d9
MD
345 ret = -EINVAL;
346 goto end;
347 }
348 switch (reg[REG_R0].type) {
349 default:
b1caea50 350 ERR("unknown register type\n");
cd54f6d9
MD
351 ret = -EINVAL;
352 goto end;
353
354 case REG_STRING:
cd54f6d9
MD
355 reg[REG_R0].v = (reg_strcmp(reg, "!=") != 0);
356 break;
357 case REG_S64:
da6eed25
MD
358 switch (reg[REG_R1].type) {
359 default:
b1caea50 360 ERR("unknown register type\n");
da6eed25
MD
361 ret = -EINVAL;
362 goto end;
363
364 case REG_S64:
365 reg[REG_R0].v = (reg[REG_R0].v != reg[REG_R1].v);
366 break;
367 case REG_DOUBLE:
368 reg[REG_R0].v = (reg[REG_R0].v != reg[REG_R1].d);
369 break;
370 }
371 break;
372 case REG_DOUBLE:
373 switch (reg[REG_R1].type) {
374 default:
b1caea50 375 ERR("unknown register type\n");
da6eed25
MD
376 ret = -EINVAL;
377 goto end;
378
379 case REG_S64:
380 reg[REG_R0].v = (reg[REG_R0].d != reg[REG_R1].v);
381 break;
382 case REG_DOUBLE:
383 reg[REG_R0].v = (reg[REG_R0].d != reg[REG_R1].d);
384 break;
385 }
cd54f6d9
MD
386 break;
387 }
388 reg[REG_R0].type = REG_S64;
389 next_pc += sizeof(struct binary_op);
390 break;
391 }
392 case FILTER_OP_GT:
393 {
da6eed25
MD
394 if (unlikely((reg[REG_R0].type == REG_STRING && reg[REG_R1].type != REG_STRING)
395 || (reg[REG_R0].type != REG_STRING && reg[REG_R1].type == REG_STRING))) {
b1caea50 396 ERR("type mismatch for '>' binary operator\n");
cd54f6d9
MD
397 ret = -EINVAL;
398 goto end;
399 }
400 switch (reg[REG_R0].type) {
401 default:
b1caea50 402 ERR("unknown register type\n");
cd54f6d9
MD
403 ret = -EINVAL;
404 goto end;
405
406 case REG_STRING:
cd54f6d9
MD
407 reg[REG_R0].v = (reg_strcmp(reg, ">") > 0);
408 break;
409 case REG_S64:
da6eed25
MD
410 switch (reg[REG_R1].type) {
411 default:
b1caea50 412 ERR("unknown register type\n");
da6eed25
MD
413 ret = -EINVAL;
414 goto end;
415
416 case REG_S64:
417 reg[REG_R0].v = (reg[REG_R0].v > reg[REG_R1].v);
418 break;
419 case REG_DOUBLE:
420 reg[REG_R0].v = (reg[REG_R0].v > reg[REG_R1].d);
421 break;
422 }
423 break;
424 case REG_DOUBLE:
425 switch (reg[REG_R1].type) {
426 default:
b1caea50 427 ERR("unknown register type\n");
da6eed25
MD
428 ret = -EINVAL;
429 goto end;
430
431 case REG_S64:
432 reg[REG_R0].v = (reg[REG_R0].d > reg[REG_R1].v);
433 break;
434 case REG_DOUBLE:
435 reg[REG_R0].v = (reg[REG_R0].d > reg[REG_R1].d);
436 break;
437 }
cd54f6d9
MD
438 break;
439 }
440 reg[REG_R0].type = REG_S64;
441 next_pc += sizeof(struct binary_op);
442 break;
443 }
444 case FILTER_OP_LT:
445 {
da6eed25
MD
446 if (unlikely((reg[REG_R0].type == REG_STRING && reg[REG_R1].type != REG_STRING)
447 || (reg[REG_R0].type != REG_STRING && reg[REG_R1].type == REG_STRING))) {
b1caea50 448 ERR("type mismatch for '<' binary operator\n");
cd54f6d9
MD
449 ret = -EINVAL;
450 goto end;
451 }
452 switch (reg[REG_R0].type) {
453 default:
b1caea50 454 ERR("unknown register type\n");
cd54f6d9
MD
455 ret = -EINVAL;
456 goto end;
457
458 case REG_STRING:
cd54f6d9
MD
459 reg[REG_R0].v = (reg_strcmp(reg, "<") < 0);
460 break;
461 case REG_S64:
da6eed25
MD
462 switch (reg[REG_R1].type) {
463 default:
b1caea50 464 ERR("unknown register type\n");
da6eed25
MD
465 ret = -EINVAL;
466 goto end;
467
468 case REG_S64:
469 reg[REG_R0].v = (reg[REG_R0].v < reg[REG_R1].v);
470 break;
471 case REG_DOUBLE:
472 reg[REG_R0].v = (reg[REG_R0].v < reg[REG_R1].d);
473 break;
474 }
475 break;
476 case REG_DOUBLE:
477 switch (reg[REG_R1].type) {
478 default:
b1caea50 479 ERR("unknown register type\n");
da6eed25
MD
480 ret = -EINVAL;
481 goto end;
482
483 case REG_S64:
484 reg[REG_R0].v = (reg[REG_R0].d < reg[REG_R1].v);
485 break;
486 case REG_DOUBLE:
487 reg[REG_R0].v = (reg[REG_R0].d < reg[REG_R1].d);
488 break;
489 }
cd54f6d9
MD
490 break;
491 }
492 reg[REG_R0].type = REG_S64;
493 next_pc += sizeof(struct binary_op);
494 break;
495 }
496 case FILTER_OP_GE:
497 {
da6eed25
MD
498 if (unlikely((reg[REG_R0].type == REG_STRING && reg[REG_R1].type != REG_STRING)
499 || (reg[REG_R0].type != REG_STRING && reg[REG_R1].type == REG_STRING))) {
b1caea50 500 ERR("type mismatch for '>=' binary operator\n");
cd54f6d9
MD
501 ret = -EINVAL;
502 goto end;
503 }
504 switch (reg[REG_R0].type) {
505 default:
b1caea50 506 ERR("unknown register type\n");
cd54f6d9
MD
507 ret = -EINVAL;
508 goto end;
509
510 case REG_STRING:
cd54f6d9
MD
511 reg[REG_R0].v = (reg_strcmp(reg, ">=") >= 0);
512 break;
513 case REG_S64:
da6eed25
MD
514 switch (reg[REG_R1].type) {
515 default:
b1caea50 516 ERR("unknown register type\n");
da6eed25
MD
517 ret = -EINVAL;
518 goto end;
519
520 case REG_S64:
521 reg[REG_R0].v = (reg[REG_R0].v >= reg[REG_R1].v);
522 break;
523 case REG_DOUBLE:
524 reg[REG_R0].v = (reg[REG_R0].v >= reg[REG_R1].d);
525 break;
526 }
527 break;
528 case REG_DOUBLE:
529 switch (reg[REG_R1].type) {
530 default:
b1caea50 531 ERR("unknown register type\n");
da6eed25
MD
532 ret = -EINVAL;
533 goto end;
534
535 case REG_S64:
536 reg[REG_R0].v = (reg[REG_R0].d >= reg[REG_R1].v);
537 break;
538 case REG_DOUBLE:
539 reg[REG_R0].v = (reg[REG_R0].d >= reg[REG_R1].d);
540 break;
541 }
cd54f6d9
MD
542 break;
543 }
544 reg[REG_R0].type = REG_S64;
545 next_pc += sizeof(struct binary_op);
546 break;
547 }
548 case FILTER_OP_LE:
549 {
da6eed25
MD
550 if (unlikely((reg[REG_R0].type == REG_STRING && reg[REG_R1].type != REG_STRING)
551 || (reg[REG_R0].type != REG_STRING && reg[REG_R1].type == REG_STRING))) {
b1caea50 552 ERR("type mismatch for '<=' binary operator\n");
cd54f6d9
MD
553 ret = -EINVAL;
554 goto end;
555 }
556 switch (reg[REG_R0].type) {
557 default:
b1caea50 558 ERR("unknown register type\n");
cd54f6d9
MD
559 ret = -EINVAL;
560 goto end;
561
562 case REG_STRING:
cd54f6d9
MD
563 reg[REG_R0].v = (reg_strcmp(reg, "<=") <= 0);
564 break;
565 case REG_S64:
da6eed25
MD
566 switch (reg[REG_R1].type) {
567 default:
b1caea50 568 ERR("unknown register type\n");
da6eed25
MD
569 ret = -EINVAL;
570 goto end;
571
572 case REG_S64:
573 reg[REG_R0].v = (reg[REG_R0].v <= reg[REG_R1].v);
574 break;
575 case REG_DOUBLE:
576 reg[REG_R0].v = (reg[REG_R0].v <= reg[REG_R1].d);
577 break;
578 }
579 break;
580 case REG_DOUBLE:
581 switch (reg[REG_R1].type) {
582 default:
b1caea50 583 ERR("unknown register type\n");
da6eed25
MD
584 ret = -EINVAL;
585 goto end;
586
587 case REG_S64:
588 reg[REG_R0].v = (reg[REG_R0].d <= reg[REG_R1].v);
589 break;
590 case REG_DOUBLE:
591 reg[REG_R0].v = (reg[REG_R0].d <= reg[REG_R1].d);
592 break;
593 }
cd54f6d9
MD
594 break;
595 }
596 reg[REG_R0].type = REG_S64;
597 next_pc += sizeof(struct binary_op);
598 break;
599 }
600
601 /* unary */
602 case FILTER_OP_UNARY_PLUS:
603 {
604 struct unary_op *insn = (struct unary_op *) pc;
605
606 if (unlikely(insn->reg >= REG_ERROR)) {
b1caea50 607 ERR("invalid register %u\n",
cd54f6d9
MD
608 (unsigned int) insn->reg);
609 ret = -EINVAL;
610 goto end;
611 }
da6eed25
MD
612 switch (reg[insn->reg].type) {
613 default:
b1caea50 614 ERR("unknown register type\n");
da6eed25
MD
615 ret = -EINVAL;
616 goto end;
617
618 case REG_STRING:
b1caea50 619 ERR("Unary plus can only be applied to numeric or floating point registers\n");
cd54f6d9
MD
620 ret = -EINVAL;
621 goto end;
da6eed25
MD
622 case REG_S64:
623 break;
624 case REG_DOUBLE:
625 break;
cd54f6d9
MD
626 }
627 next_pc += sizeof(struct unary_op);
628 break;
629 }
630 case FILTER_OP_UNARY_MINUS:
631 {
632 struct unary_op *insn = (struct unary_op *) pc;
633
634 if (unlikely(insn->reg >= REG_ERROR)) {
b1caea50 635 ERR("invalid register %u\n",
cd54f6d9
MD
636 (unsigned int) insn->reg);
637 ret = -EINVAL;
638 goto end;
639 }
da6eed25
MD
640 switch (reg[insn->reg].type) {
641 default:
b1caea50 642 ERR("unknown register type\n");
cd54f6d9
MD
643 ret = -EINVAL;
644 goto end;
da6eed25
MD
645
646 case REG_STRING:
b1caea50 647 ERR("Unary minus can only be applied to numeric or floating point registers\n");
da6eed25
MD
648 ret = -EINVAL;
649 goto end;
650 case REG_S64:
651 reg[insn->reg].v = -reg[insn->reg].v;
652 break;
653 case REG_DOUBLE:
654 reg[insn->reg].d = -reg[insn->reg].d;
655 break;
cd54f6d9 656 }
cd54f6d9
MD
657 next_pc += sizeof(struct unary_op);
658 break;
659 }
660 case FILTER_OP_UNARY_NOT:
661 {
662 struct unary_op *insn = (struct unary_op *) pc;
663
664 if (unlikely(insn->reg >= REG_ERROR)) {
b1caea50 665 ERR("invalid register %u\n",
cd54f6d9
MD
666 (unsigned int) insn->reg);
667 ret = -EINVAL;
668 goto end;
669 }
da6eed25
MD
670 switch (reg[insn->reg].type) {
671 default:
b1caea50 672 ERR("unknown register type\n");
da6eed25
MD
673 ret = -EINVAL;
674 goto end;
675
676 case REG_STRING:
b1caea50 677 ERR("Unary not can only be applied to numeric or floating point registers\n");
da6eed25
MD
678 ret = -EINVAL;
679 goto end;
680 case REG_S64:
681 reg[insn->reg].v = !reg[insn->reg].v;
682 break;
683 case REG_DOUBLE:
684 reg[insn->reg].d = !reg[insn->reg].d;
685 break;
686 }
cd54f6d9 687 if (unlikely(reg[insn->reg].type != REG_S64)) {
b1caea50 688 ERR("Unary not can only be applied to numeric register\n");
cd54f6d9
MD
689 ret = -EINVAL;
690 goto end;
691 }
692 reg[insn->reg].v = !reg[insn->reg].v;
693 next_pc += sizeof(struct unary_op);
694 break;
695 }
696 /* logical */
697 case FILTER_OP_AND:
698 {
699 struct logical_op *insn = (struct logical_op *) pc;
700
da6eed25 701 if (unlikely(reg[REG_R0].type == REG_STRING)) {
b1caea50 702 ERR("Logical operator 'and' can only be applied to numeric and floating point registers\n");
cd54f6d9
MD
703 ret = -EINVAL;
704 goto end;
705 }
706
707 /* If REG_R0 is 0, skip and evaluate to 0 */
da6eed25
MD
708 if ((reg[REG_R0].type == REG_S64 && reg[REG_R0].v == 0)
709 || (reg[REG_R0].type == REG_DOUBLE && reg[REG_R0].d == 0.0)) {
cd54f6d9
MD
710 dbg_printf("Jumping to bytecode offset %u\n",
711 (unsigned int) insn->skip_offset);
712 next_pc = start_pc + insn->skip_offset;
713 if (unlikely(next_pc <= pc)) {
b1caea50 714 ERR("Loops are not allowed in bytecode\n");
cd54f6d9
MD
715 ret = -EINVAL;
716 goto end;
717 }
718 } else {
719 next_pc += sizeof(struct logical_op);
720 }
721 break;
722 }
723 case FILTER_OP_OR:
724 {
725 struct logical_op *insn = (struct logical_op *) pc;
726
da6eed25 727 if (unlikely(reg[REG_R0].type == REG_STRING)) {
b1caea50 728 ERR("Logical operator 'or' can only be applied to numeric and floating point registers\n");
cd54f6d9
MD
729 ret = -EINVAL;
730 goto end;
731 }
732
733 /* If REG_R0 is nonzero, skip and evaluate to 1 */
da6eed25
MD
734
735 if ((reg[REG_R0].type == REG_S64 && reg[REG_R0].v != 0)
736 || (reg[REG_R0].type == REG_DOUBLE && reg[REG_R0].d != 0.0)) {
cd54f6d9
MD
737 reg[REG_R0].v = 1;
738 dbg_printf("Jumping to bytecode offset %u\n",
739 (unsigned int) insn->skip_offset);
740 next_pc = start_pc + insn->skip_offset;
741 if (unlikely(next_pc <= pc)) {
b1caea50 742 ERR("Loops are not allowed in bytecode\n");
cd54f6d9
MD
743 ret = -EINVAL;
744 goto end;
745 }
746 } else {
747 next_pc += sizeof(struct logical_op);
748 }
749 break;
750 }
751
752 /* load */
753 case FILTER_OP_LOAD_FIELD_REF:
754 {
755 struct load_op *insn = (struct load_op *) pc;
756 struct field_ref *ref = (struct field_ref *) insn->data;
757
758 if (unlikely(insn->reg >= REG_ERROR)) {
b1caea50 759 ERR("invalid register %u\n",
cd54f6d9
MD
760 (unsigned int) insn->reg);
761 ret = -EINVAL;
762 goto end;
763 }
764 dbg_printf("load field ref offset %u type %u\n",
765 ref->offset, ref->type);
766 switch (ref->type) {
767 case FIELD_REF_UNKNOWN:
768 default:
b1caea50 769 ERR("unknown field ref type\n");
cd54f6d9
MD
770 ret = -EINVAL;
771 goto end;
772
773 case FIELD_REF_STRING:
774 reg[insn->reg].str =
775 *(const char * const *) &filter_stack_data[ref->offset];
776 reg[insn->reg].type = REG_STRING;
777 reg[insn->reg].seq_len = UINT_MAX;
778 reg[insn->reg].literal = 0;
779 dbg_printf("ref load string %s\n", reg[insn->reg].str);
780 break;
781 case FIELD_REF_SEQUENCE:
782 reg[insn->reg].seq_len =
783 *(unsigned long *) &filter_stack_data[ref->offset];
784 reg[insn->reg].str =
785 *(const char **) (&filter_stack_data[ref->offset
786 + sizeof(unsigned long)]);
da6eed25 787 reg[insn->reg].type = REG_STRING;
cd54f6d9
MD
788 reg[insn->reg].literal = 0;
789 break;
790 case FIELD_REF_S64:
791 memcpy(&reg[insn->reg].v, &filter_stack_data[ref->offset],
792 sizeof(struct literal_numeric));
793 reg[insn->reg].type = REG_S64;
794 reg[insn->reg].literal = 0;
795 dbg_printf("ref load s64 %" PRIi64 "\n", reg[insn->reg].v);
796 break;
da6eed25
MD
797 case FIELD_REF_DOUBLE:
798 memcpy(&reg[insn->reg].d, &filter_stack_data[ref->offset],
799 sizeof(struct literal_double));
800 reg[insn->reg].type = REG_DOUBLE;
801 reg[insn->reg].literal = 0;
802 dbg_printf("ref load double %g\n", reg[insn->reg].d);
803 break;
cd54f6d9
MD
804 }
805
806 next_pc += sizeof(struct load_op) + sizeof(struct field_ref);
807 break;
808 }
809
810 case FILTER_OP_LOAD_STRING:
811 {
812 struct load_op *insn = (struct load_op *) pc;
813
814 if (unlikely(insn->reg >= REG_ERROR)) {
b1caea50 815 ERR("invalid register %u\n",
cd54f6d9
MD
816 (unsigned int) insn->reg);
817 ret = -EINVAL;
818 goto end;
819 }
820 dbg_printf("load string %s\n", insn->data);
821 reg[insn->reg].str = insn->data;
822 reg[insn->reg].type = REG_STRING;
823 reg[insn->reg].seq_len = UINT_MAX;
824 reg[insn->reg].literal = 1;
825 next_pc += sizeof(struct load_op) + strlen(insn->data) + 1;
826 break;
827 }
828
829 case FILTER_OP_LOAD_S64:
830 {
831 struct load_op *insn = (struct load_op *) pc;
832
833 if (unlikely(insn->reg >= REG_ERROR)) {
b1caea50 834 ERR("invalid register %u\n",
cd54f6d9
MD
835 (unsigned int) insn->reg);
836 ret = -EINVAL;
837 goto end;
838 }
839 memcpy(&reg[insn->reg].v, insn->data,
840 sizeof(struct literal_numeric));
841 dbg_printf("load s64 %" PRIi64 "\n", reg[insn->reg].v);
842 reg[insn->reg].type = REG_S64;
843 next_pc += sizeof(struct load_op)
844 + sizeof(struct literal_numeric);
845 break;
846 }
da6eed25
MD
847
848 case FILTER_OP_LOAD_DOUBLE:
849 {
850 struct load_op *insn = (struct load_op *) pc;
851
852 if (unlikely(insn->reg >= REG_ERROR)) {
b1caea50 853 ERR("invalid register %u\n",
da6eed25
MD
854 (unsigned int) insn->reg);
855 ret = -EINVAL;
856 goto end;
857 }
858 memcpy(&reg[insn->reg].d, insn->data,
859 sizeof(struct literal_double));
860 dbg_printf("load s64 %g\n", reg[insn->reg].d);
861 reg[insn->reg].type = REG_DOUBLE;
862 next_pc += sizeof(struct load_op)
863 + sizeof(struct literal_double);
864 break;
865 }
cd54f6d9
MD
866 }
867 }
868end:
869 /* return 0 (discard) on error */
870 if (ret)
871 return 0;
872 return retval;
873}
874
9522a886
MD
875static
876int bin_op_compare_check(struct vreg reg[NR_REG], const char *str)
877{
878 switch (reg[REG_R0].type) {
879 default:
880 goto error_unknown;
881
882 case REG_STRING:
883 switch (reg[REG_R1].type) {
884 default:
885 goto error_unknown;
886
887 case REG_STRING:
888 break;
889 case REG_S64:
890 case REG_DOUBLE:
891 goto error_mismatch;
892 }
893 break;
894 case REG_S64:
895 case REG_DOUBLE:
896 switch (reg[REG_R1].type) {
897 default:
898 goto error_unknown;
899
900 case REG_STRING:
901 goto error_mismatch;
902
903 case REG_S64:
904 case REG_DOUBLE:
905 break;
906 }
907 break;
908 }
909 return 0;
910
911error_unknown:
912
913 return -EINVAL;
914error_mismatch:
915 ERR("type mismatch for '%s' binary operator\n", str);
916 return -EINVAL;
917}
918
919static
920int lttng_filter_validate_bytecode(struct bytecode_runtime *bytecode)
921{
922 void *pc, *next_pc, *start_pc;
923 int ret = -EINVAL;
924 struct vreg reg[NR_REG];
925 int i;
926
927 for (i = 0; i < NR_REG; i++) {
928 reg[i].type = REG_S64;
929 reg[i].literal = 0;
930 }
931
932 start_pc = &bytecode->data[0];
933 for (pc = next_pc = start_pc; pc - start_pc < bytecode->len;
934 pc = next_pc) {
935 if (unlikely(pc >= start_pc + bytecode->len)) {
936 ERR("filter bytecode overflow\n");
937 ret = -EINVAL;
938 goto end;
939 }
940 dbg_printf("Validating op %s (%u)\n",
941 print_op((unsigned int) *(filter_opcode_t *) pc),
942 (unsigned int) *(filter_opcode_t *) pc);
943 switch (*(filter_opcode_t *) pc) {
944 case FILTER_OP_UNKNOWN:
945 default:
946 ERR("unknown bytecode op %u\n",
947 (unsigned int) *(filter_opcode_t *) pc);
948 ret = -EINVAL;
949 goto end;
950
951 case FILTER_OP_RETURN:
952 ret = 0;
953 goto end;
954
955 /* binary */
956 case FILTER_OP_MUL:
957 case FILTER_OP_DIV:
958 case FILTER_OP_MOD:
959 case FILTER_OP_PLUS:
960 case FILTER_OP_MINUS:
961 case FILTER_OP_RSHIFT:
962 case FILTER_OP_LSHIFT:
963 case FILTER_OP_BIN_AND:
964 case FILTER_OP_BIN_OR:
965 case FILTER_OP_BIN_XOR:
966 ERR("unsupported bytecode op %u\n",
967 (unsigned int) *(filter_opcode_t *) pc);
968 ret = -EINVAL;
969 goto end;
970
971 case FILTER_OP_EQ:
972 {
973 ret = bin_op_compare_check(reg, "==");
974 if (ret)
975 goto end;
976 reg[REG_R0].type = REG_S64;
977 next_pc += sizeof(struct binary_op);
978 break;
979 }
980 case FILTER_OP_NE:
981 {
982 ret = bin_op_compare_check(reg, "!=");
983 if (ret)
984 goto end;
985 reg[REG_R0].type = REG_S64;
986 next_pc += sizeof(struct binary_op);
987 break;
988 }
989 case FILTER_OP_GT:
990 {
991 ret = bin_op_compare_check(reg, ">");
992 if (ret)
993 goto end;
994 reg[REG_R0].type = REG_S64;
995 next_pc += sizeof(struct binary_op);
996 break;
997 }
998 case FILTER_OP_LT:
999 {
1000 ret = bin_op_compare_check(reg, "<");
1001 if (ret)
1002 goto end;
1003 reg[REG_R0].type = REG_S64;
1004 next_pc += sizeof(struct binary_op);
1005 break;
1006 }
1007 case FILTER_OP_GE:
1008 {
1009 ret = bin_op_compare_check(reg, ">=");
1010 if (ret)
1011 goto end;
1012 reg[REG_R0].type = REG_S64;
1013 next_pc += sizeof(struct binary_op);
1014 break;
1015 }
1016 case FILTER_OP_LE:
1017 {
1018 ret = bin_op_compare_check(reg, "<=");
1019 if (ret)
1020 goto end;
1021 reg[REG_R0].type = REG_S64;
1022 next_pc += sizeof(struct binary_op);
1023 break;
1024 }
1025
1026 /* unary */
1027 case FILTER_OP_UNARY_PLUS:
1028 case FILTER_OP_UNARY_MINUS:
1029 case FILTER_OP_UNARY_NOT:
1030 {
1031 struct unary_op *insn = (struct unary_op *) pc;
1032
1033 if (unlikely(insn->reg >= REG_ERROR)) {
1034 ERR("invalid register %u\n",
1035 (unsigned int) insn->reg);
1036 ret = -EINVAL;
1037 goto end;
1038 }
1039 switch (reg[insn->reg].type) {
1040 default:
1041 ERR("unknown register type\n");
1042 ret = -EINVAL;
1043 goto end;
1044
1045 case REG_STRING:
1046 ERR("Unary op can only be applied to numeric or floating point registers\n");
1047 ret = -EINVAL;
1048 goto end;
1049 case REG_S64:
1050 break;
1051 case REG_DOUBLE:
1052 break;
1053 }
1054 next_pc += sizeof(struct unary_op);
1055 break;
1056 }
1057 /* logical */
1058 case FILTER_OP_AND:
1059 case FILTER_OP_OR:
1060 {
1061 struct logical_op *insn = (struct logical_op *) pc;
1062
1063 if (unlikely(reg[REG_R0].type == REG_STRING)) {
1064 ERR("Logical operator 'and' can only be applied to numeric and floating point registers\n");
1065 ret = -EINVAL;
1066 goto end;
1067 }
1068
1069 dbg_printf("Validate jumping to bytecode offset %u\n",
1070 (unsigned int) insn->skip_offset);
1071 if (unlikely(start_pc + insn->skip_offset <= pc)) {
1072 ERR("Loops are not allowed in bytecode\n");
1073 ret = -EINVAL;
1074 goto end;
1075 }
1076 next_pc += sizeof(struct logical_op);
1077 break;
1078 }
1079
1080 /* load */
1081 case FILTER_OP_LOAD_FIELD_REF:
1082 {
1083 struct load_op *insn = (struct load_op *) pc;
1084 struct field_ref *ref = (struct field_ref *) insn->data;
1085
1086 if (unlikely(insn->reg >= REG_ERROR)) {
1087 ERR("invalid register %u\n",
1088 (unsigned int) insn->reg);
1089 ret = -EINVAL;
1090 goto end;
1091 }
1092 dbg_printf("Validate load field ref offset %u type %u\n",
1093 ref->offset, ref->type);
1094 switch (ref->type) {
1095 case FIELD_REF_UNKNOWN:
1096 default:
1097 ERR("unknown field ref type\n");
1098 ret = -EINVAL;
1099 goto end;
1100
1101 case FIELD_REF_STRING:
1102 reg[insn->reg].type = REG_STRING;
1103 reg[insn->reg].literal = 0;
1104 break;
1105 case FIELD_REF_SEQUENCE:
1106 reg[insn->reg].type = REG_STRING;
1107 reg[insn->reg].literal = 0;
1108 break;
1109 case FIELD_REF_S64:
1110 reg[insn->reg].type = REG_S64;
1111 reg[insn->reg].literal = 0;
1112 break;
1113 case FIELD_REF_DOUBLE:
1114 reg[insn->reg].type = REG_DOUBLE;
1115 reg[insn->reg].literal = 0;
1116 break;
1117 }
1118
1119 next_pc += sizeof(struct load_op) + sizeof(struct field_ref);
1120 break;
1121 }
1122
1123 case FILTER_OP_LOAD_STRING:
1124 {
1125 struct load_op *insn = (struct load_op *) pc;
1126
1127 if (unlikely(insn->reg >= REG_ERROR)) {
1128 ERR("invalid register %u\n",
1129 (unsigned int) insn->reg);
1130 ret = -EINVAL;
1131 goto end;
1132 }
1133 reg[insn->reg].type = REG_STRING;
1134 reg[insn->reg].literal = 1;
1135 next_pc += sizeof(struct load_op) + strlen(insn->data) + 1;
1136 break;
1137 }
1138
1139 case FILTER_OP_LOAD_S64:
1140 {
1141 struct load_op *insn = (struct load_op *) pc;
1142
1143 if (unlikely(insn->reg >= REG_ERROR)) {
1144 ERR("invalid register %u\n",
1145 (unsigned int) insn->reg);
1146 ret = -EINVAL;
1147 goto end;
1148 }
1149 reg[insn->reg].type = REG_S64;
1150 next_pc += sizeof(struct load_op)
1151 + sizeof(struct literal_numeric);
1152 break;
1153 }
1154
1155 case FILTER_OP_LOAD_DOUBLE:
1156 {
1157 struct load_op *insn = (struct load_op *) pc;
1158
1159 if (unlikely(insn->reg >= REG_ERROR)) {
1160 ERR("invalid register %u\n",
1161 (unsigned int) insn->reg);
1162 ret = -EINVAL;
1163 goto end;
1164 }
1165 reg[insn->reg].type = REG_DOUBLE;
1166 next_pc += sizeof(struct load_op)
1167 + sizeof(struct literal_double);
1168 break;
1169 }
1170 }
1171 }
1172end:
1173 return ret;
1174}
1175
cd54f6d9
MD
1176static
1177int apply_field_reloc(struct ltt_event *event,
1178 struct bytecode_runtime *runtime,
1179 uint32_t runtime_len,
1180 uint32_t reloc_offset,
1181 const char *field_name)
1182{
1183 const struct lttng_event_desc *desc;
1184 const struct lttng_event_field *fields, *field = NULL;
1185 unsigned int nr_fields, i;
1186 struct field_ref *field_ref;
1187 uint32_t field_offset = 0;
1188
a8c27c7c 1189 dbg_printf("Apply reloc: %u %s\n", reloc_offset, field_name);
cd54f6d9
MD
1190
1191 /* Ensure that the reloc is within the code */
1192 if (runtime_len - reloc_offset < sizeof(uint16_t))
1193 return -EINVAL;
1194
1195 /* Lookup event by name */
1196 desc = event->desc;
1197 if (!desc)
1198 return -EINVAL;
1199 fields = desc->fields;
1200 if (!fields)
1201 return -EINVAL;
1202 nr_fields = desc->nr_fields;
1203 for (i = 0; i < nr_fields; i++) {
1204 if (!strcmp(fields[i].name, field_name)) {
1205 field = &fields[i];
1206 break;
1207 }
1208 /* compute field offset */
1209 switch (fields[i].type.atype) {
1210 case atype_integer:
1211 case atype_enum:
1212 field_offset += sizeof(int64_t);
1213 break;
1214 case atype_array:
1215 case atype_sequence:
1216 field_offset += sizeof(unsigned long);
1217 field_offset += sizeof(void *);
1218 break;
1219 case atype_string:
1220 field_offset += sizeof(void *);
1221 break;
1222 case atype_float:
1223 field_offset += sizeof(double);
da6eed25 1224 break;
cd54f6d9
MD
1225 default:
1226 return -EINVAL;
1227 }
1228 }
1229 if (!field)
1230 return -EINVAL;
1231
1232 /* Check if field offset is too large for 16-bit offset */
1233 if (field_offset > FILTER_BYTECODE_MAX_LEN)
1234 return -EINVAL;
1235
1236 /* set type */
1237 field_ref = (struct field_ref *) &runtime->data[reloc_offset];
1238 switch (field->type.atype) {
1239 case atype_integer:
1240 case atype_enum:
1241 field_ref->type = FIELD_REF_S64;
1242 field_ref->type = FIELD_REF_S64;
1243 break;
1244 case atype_array:
1245 case atype_sequence:
1246 field_ref->type = FIELD_REF_SEQUENCE;
1247 break;
1248 case atype_string:
1249 field_ref->type = FIELD_REF_STRING;
1250 break;
1251 case atype_float:
da6eed25
MD
1252 field_ref->type = FIELD_REF_DOUBLE;
1253 break;
cd54f6d9
MD
1254 default:
1255 return -EINVAL;
1256 }
1257 /* set offset */
1258 field_ref->offset = (uint16_t) field_offset;
2d78951a
MD
1259 return 0;
1260}
1261
cd54f6d9
MD
1262/*
1263 * Take a bytecode with reloc table and link it to an event to create a
1264 * bytecode runtime.
1265 */
2d78951a
MD
1266static
1267int _lttng_filter_event_link_bytecode(struct ltt_event *event,
1268 struct lttng_ust_filter_bytecode *filter_bytecode)
1269{
cd54f6d9
MD
1270 int ret, offset, next_offset;
1271 struct bytecode_runtime *runtime = NULL;
1272 size_t runtime_alloc_len;
1273
2d78951a
MD
1274 if (!filter_bytecode)
1275 return 0;
cd54f6d9
MD
1276 /* Even is not connected to any description */
1277 if (!event->desc)
1278 return 0;
1279 /* Bytecode already linked */
1280 if (event->filter || event->filter_data)
1281 return 0;
2d78951a 1282
a8c27c7c 1283 dbg_printf("Linking\n");
cd54f6d9
MD
1284
1285 /* We don't need the reloc table in the runtime */
1286 runtime_alloc_len = sizeof(*runtime) + filter_bytecode->reloc_offset;
1287 runtime = zmalloc(runtime_alloc_len);
1288 if (!runtime) {
1289 ret = -ENOMEM;
1290 goto link_error;
1291 }
1292 runtime->len = filter_bytecode->reloc_offset;
1293 /* copy original bytecode */
1294 memcpy(runtime->data, filter_bytecode->data, runtime->len);
1295 /*
1296 * apply relocs. Those are a uint16_t (offset in bytecode)
1297 * followed by a string (field name).
1298 */
cd54f6d9
MD
1299 for (offset = filter_bytecode->reloc_offset;
1300 offset < filter_bytecode->len;
1301 offset = next_offset) {
1302 uint16_t reloc_offset =
1303 *(uint16_t *) &filter_bytecode->data[offset];
1304 const char *field_name =
1305 (const char *) &filter_bytecode->data[offset + sizeof(uint16_t)];
1306
1307 ret = apply_field_reloc(event, runtime, runtime->len, reloc_offset, field_name);
1308 if (ret) {
1309 goto link_error;
1310 }
1311 next_offset = offset + sizeof(uint16_t) + strlen(field_name) + 1;
1312 }
9522a886
MD
1313 /* Validate bytecode */
1314 ret = lttng_filter_validate_bytecode(runtime);
1315 if (ret) {
1316 goto link_error;
1317 }
cd54f6d9 1318 event->filter_data = runtime;
2d78951a 1319 event->filter = lttng_filter_interpret_bytecode;
2d78951a 1320 return 0;
cd54f6d9
MD
1321
1322link_error:
1323 event->filter = lttng_filter_false;
1324 free(runtime);
1325 return ret;
2d78951a
MD
1326}
1327
1328void lttng_filter_event_link_bytecode(struct ltt_event *event,
1329 struct lttng_ust_filter_bytecode *filter_bytecode)
1330{
1331 int ret;
1332
cd54f6d9 1333 ret = _lttng_filter_event_link_bytecode(event, filter_bytecode);
2d78951a
MD
1334 if (ret) {
1335 fprintf(stderr, "[lttng filter] error linking event bytecode\n");
1336 }
1337}
1338
1339/*
1340 * Link bytecode to all events for a wildcard. Skips events that already
1341 * have a bytecode linked.
1342 * We do not set each event's filter_bytecode field, because they do not
1343 * own the filter_bytecode: the wildcard owns it.
1344 */
1345void lttng_filter_wildcard_link_bytecode(struct session_wildcard *wildcard)
1346{
1347 struct ltt_event *event;
1348 int ret;
1349
1350 if (!wildcard->filter_bytecode)
1351 return;
1352
1353 cds_list_for_each_entry(event, &wildcard->events, wildcard_list) {
1354 if (event->filter)
1355 continue;
1356 ret = _lttng_filter_event_link_bytecode(event,
1357 wildcard->filter_bytecode);
1358 if (ret) {
1359 fprintf(stderr, "[lttng filter] error linking wildcard bytecode\n");
1360 }
1361
1362 }
1363 return;
1364}
1365
1366/*
1367 * Need to attach filter to an event before starting tracing for the
cd54f6d9 1368 * session. We own the filter_bytecode if we return success.
2d78951a
MD
1369 */
1370int lttng_filter_event_attach_bytecode(struct ltt_event *event,
1371 struct lttng_ust_filter_bytecode *filter_bytecode)
1372{
2d78951a
MD
1373 if (event->chan->session->been_active)
1374 return -EPERM;
1375 if (event->filter_bytecode)
1376 return -EEXIST;
cd54f6d9 1377 event->filter_bytecode = filter_bytecode;
2d78951a
MD
1378 return 0;
1379}
1380
1381/*
1382 * Need to attach filter to a wildcard before starting tracing for the
cd54f6d9 1383 * session. We own the filter_bytecode if we return success.
2d78951a
MD
1384 */
1385int lttng_filter_wildcard_attach_bytecode(struct session_wildcard *wildcard,
1386 struct lttng_ust_filter_bytecode *filter_bytecode)
1387{
2d78951a
MD
1388 if (wildcard->chan->session->been_active)
1389 return -EPERM;
1390 if (wildcard->filter_bytecode)
1391 return -EEXIST;
cd54f6d9 1392 wildcard->filter_bytecode = filter_bytecode;
2d78951a
MD
1393 return 0;
1394}
This page took 0.076981 seconds and 4 git commands to generate.