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