Filter: validate that field ref strings are non-NULL
[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 if (unlikely(!reg[insn->reg].str)) {
700 dbg_printf("Filter warning: loading a NULL string.\n");
701 ret = -EINVAL;
702 goto end;
703 }
704 reg[insn->reg].type = REG_STRING;
705 reg[insn->reg].seq_len = UINT_MAX;
706 reg[insn->reg].literal = 0;
707 dbg_printf("ref load string %s\n", reg[insn->reg].str);
708 next_pc += sizeof(struct load_op) + sizeof(struct field_ref);
709 PO;
710 }
711
712 OP(FILTER_OP_LOAD_FIELD_REF_SEQUENCE):
713 {
714 struct load_op *insn = (struct load_op *) pc;
715 struct field_ref *ref = (struct field_ref *) insn->data;
716
717 dbg_printf("load field ref offset %u type sequence\n",
718 ref->offset);
719 reg[insn->reg].seq_len =
720 *(unsigned long *) &filter_stack_data[ref->offset];
721 reg[insn->reg].str =
722 *(const char **) (&filter_stack_data[ref->offset
723 + sizeof(unsigned long)]);
724 if (unlikely(!reg[insn->reg].str)) {
725 dbg_printf("Filter warning: loading a NULL sequence.\n");
726 ret = -EINVAL;
727 goto end;
728 }
729 reg[insn->reg].type = REG_STRING;
730 reg[insn->reg].literal = 0;
731 next_pc += sizeof(struct load_op) + sizeof(struct field_ref);
732 PO;
733 }
734
735 OP(FILTER_OP_LOAD_FIELD_REF_S64):
736 {
737 struct load_op *insn = (struct load_op *) pc;
738 struct field_ref *ref = (struct field_ref *) insn->data;
739
740 dbg_printf("load field ref offset %u type s64\n",
741 ref->offset);
742 memcpy(&reg[insn->reg].v, &filter_stack_data[ref->offset],
743 sizeof(struct literal_numeric));
744 reg[insn->reg].type = REG_S64;
745 dbg_printf("ref load s64 %" PRIi64 "\n", reg[insn->reg].v);
746 next_pc += sizeof(struct load_op) + sizeof(struct field_ref);
747 PO;
748 }
749
750 OP(FILTER_OP_LOAD_FIELD_REF_DOUBLE):
751 {
752 struct load_op *insn = (struct load_op *) pc;
753 struct field_ref *ref = (struct field_ref *) insn->data;
754
755 dbg_printf("load field ref offset %u type double\n",
756 ref->offset);
757 memcpy(&reg[insn->reg].d, &filter_stack_data[ref->offset],
758 sizeof(struct literal_double));
759 reg[insn->reg].type = REG_DOUBLE;
760 dbg_printf("ref load double %g\n", reg[insn->reg].d);
761 next_pc += sizeof(struct load_op) + sizeof(struct field_ref);
762 PO;
763 }
764
765 OP(FILTER_OP_LOAD_STRING):
766 {
767 struct load_op *insn = (struct load_op *) pc;
768
769 dbg_printf("load string %s\n", insn->data);
770 reg[insn->reg].str = insn->data;
771 reg[insn->reg].type = REG_STRING;
772 reg[insn->reg].seq_len = UINT_MAX;
773 reg[insn->reg].literal = 1;
774 next_pc += sizeof(struct load_op) + strlen(insn->data) + 1;
775 PO;
776 }
777
778 OP(FILTER_OP_LOAD_S64):
779 {
780 struct load_op *insn = (struct load_op *) pc;
781
782 memcpy(&reg[insn->reg].v, insn->data,
783 sizeof(struct literal_numeric));
784 dbg_printf("load s64 %" PRIi64 "\n", reg[insn->reg].v);
785 reg[insn->reg].type = REG_S64;
786 next_pc += sizeof(struct load_op)
787 + sizeof(struct literal_numeric);
788 PO;
789 }
790
791 OP(FILTER_OP_LOAD_DOUBLE):
792 {
793 struct load_op *insn = (struct load_op *) pc;
794
795 memcpy(&reg[insn->reg].d, insn->data,
796 sizeof(struct literal_double));
797 dbg_printf("load s64 %g\n", reg[insn->reg].d);
798 reg[insn->reg].type = REG_DOUBLE;
799 next_pc += sizeof(struct load_op)
800 + sizeof(struct literal_double);
801 PO;
802 }
803
804 /* cast */
805 OP(FILTER_OP_CAST_TO_S64):
806 ERR("unsupported non-specialized bytecode op %u\n",
807 (unsigned int) *(filter_opcode_t *) pc);
808 ret = -EINVAL;
809 goto end;
810
811 OP(FILTER_OP_CAST_DOUBLE_TO_S64):
812 {
813 struct cast_op *insn = (struct cast_op *) pc;
814
815 reg[insn->reg].v = (int64_t) reg[insn->reg].d;
816 reg[insn->reg].type = REG_S64;
817 next_pc += sizeof(struct cast_op);
818 PO;
819 }
820
821 OP(FILTER_OP_CAST_NOP):
822 {
823 next_pc += sizeof(struct cast_op);
824 PO;
825 }
826
827 END_OP
828 end:
829 /* return 0 (discard) on error */
830 if (ret)
831 return 0;
832 return retval;
833 }
834
835 #undef START_OP
836 #undef OP
837 #undef PO
838 #undef END_OP
839
840 static
841 int bin_op_compare_check(struct vreg reg[NR_REG], const char *str)
842 {
843 switch (reg[REG_R0].type) {
844 default:
845 goto error_unknown;
846
847 case REG_STRING:
848 switch (reg[REG_R1].type) {
849 default:
850 goto error_unknown;
851
852 case REG_STRING:
853 break;
854 case REG_S64:
855 case REG_DOUBLE:
856 goto error_mismatch;
857 }
858 break;
859 case REG_S64:
860 case REG_DOUBLE:
861 switch (reg[REG_R1].type) {
862 default:
863 goto error_unknown;
864
865 case REG_STRING:
866 goto error_mismatch;
867
868 case REG_S64:
869 case REG_DOUBLE:
870 break;
871 }
872 break;
873 }
874 return 0;
875
876 error_unknown:
877
878 return -EINVAL;
879 error_mismatch:
880 ERR("type mismatch for '%s' binary operator\n", str);
881 return -EINVAL;
882 }
883
884 static
885 int lttng_filter_validate_bytecode(struct bytecode_runtime *bytecode)
886 {
887 void *pc, *next_pc, *start_pc;
888 int ret = -EINVAL;
889 struct vreg reg[NR_REG];
890 int i;
891
892 for (i = 0; i < NR_REG; i++) {
893 reg[i].type = REG_TYPE_UNKNOWN;
894 reg[i].literal = 0;
895 }
896
897 start_pc = &bytecode->data[0];
898 for (pc = next_pc = start_pc; pc - start_pc < bytecode->len;
899 pc = next_pc) {
900 if (unlikely(pc >= start_pc + bytecode->len)) {
901 ERR("filter bytecode overflow\n");
902 ret = -EINVAL;
903 goto end;
904 }
905 dbg_printf("Validating op %s (%u)\n",
906 print_op((unsigned int) *(filter_opcode_t *) pc),
907 (unsigned int) *(filter_opcode_t *) pc);
908 switch (*(filter_opcode_t *) pc) {
909 case FILTER_OP_UNKNOWN:
910 default:
911 ERR("unknown bytecode op %u\n",
912 (unsigned int) *(filter_opcode_t *) pc);
913 ret = -EINVAL;
914 goto end;
915
916 case FILTER_OP_RETURN:
917 ret = 0;
918 goto end;
919
920 /* binary */
921 case FILTER_OP_MUL:
922 case FILTER_OP_DIV:
923 case FILTER_OP_MOD:
924 case FILTER_OP_PLUS:
925 case FILTER_OP_MINUS:
926 case FILTER_OP_RSHIFT:
927 case FILTER_OP_LSHIFT:
928 case FILTER_OP_BIN_AND:
929 case FILTER_OP_BIN_OR:
930 case FILTER_OP_BIN_XOR:
931 ERR("unsupported bytecode op %u\n",
932 (unsigned int) *(filter_opcode_t *) pc);
933 ret = -EINVAL;
934 goto end;
935
936 case FILTER_OP_EQ:
937 {
938 ret = bin_op_compare_check(reg, "==");
939 if (ret)
940 goto end;
941 reg[REG_R0].type = REG_S64;
942 next_pc += sizeof(struct binary_op);
943 break;
944 }
945 case FILTER_OP_NE:
946 {
947 ret = bin_op_compare_check(reg, "!=");
948 if (ret)
949 goto end;
950 reg[REG_R0].type = REG_S64;
951 next_pc += sizeof(struct binary_op);
952 break;
953 }
954 case FILTER_OP_GT:
955 {
956 ret = bin_op_compare_check(reg, ">");
957 if (ret)
958 goto end;
959 reg[REG_R0].type = REG_S64;
960 next_pc += sizeof(struct binary_op);
961 break;
962 }
963 case FILTER_OP_LT:
964 {
965 ret = bin_op_compare_check(reg, "<");
966 if (ret)
967 goto end;
968 reg[REG_R0].type = REG_S64;
969 next_pc += sizeof(struct binary_op);
970 break;
971 }
972 case FILTER_OP_GE:
973 {
974 ret = bin_op_compare_check(reg, ">=");
975 if (ret)
976 goto end;
977 reg[REG_R0].type = REG_S64;
978 next_pc += sizeof(struct binary_op);
979 break;
980 }
981 case FILTER_OP_LE:
982 {
983 ret = bin_op_compare_check(reg, "<=");
984 if (ret)
985 goto end;
986 reg[REG_R0].type = REG_S64;
987 next_pc += sizeof(struct binary_op);
988 break;
989 }
990
991 case FILTER_OP_EQ_STRING:
992 case FILTER_OP_NE_STRING:
993 case FILTER_OP_GT_STRING:
994 case FILTER_OP_LT_STRING:
995 case FILTER_OP_GE_STRING:
996 case FILTER_OP_LE_STRING:
997 {
998 if (reg[REG_R0].type != REG_STRING
999 || reg[REG_R1].type != REG_STRING) {
1000 ERR("Unexpected register type for string comparator\n");
1001 ret = -EINVAL;
1002 goto end;
1003 }
1004 reg[REG_R0].type = REG_S64;
1005 next_pc += sizeof(struct binary_op);
1006 break;
1007 }
1008
1009 case FILTER_OP_EQ_S64:
1010 case FILTER_OP_NE_S64:
1011 case FILTER_OP_GT_S64:
1012 case FILTER_OP_LT_S64:
1013 case FILTER_OP_GE_S64:
1014 case FILTER_OP_LE_S64:
1015 {
1016 if (reg[REG_R0].type != REG_S64
1017 || reg[REG_R1].type != REG_S64) {
1018 ERR("Unexpected register type for s64 comparator\n");
1019 ret = -EINVAL;
1020 goto end;
1021 }
1022 reg[REG_R0].type = REG_S64;
1023 next_pc += sizeof(struct binary_op);
1024 break;
1025 }
1026
1027 case FILTER_OP_EQ_DOUBLE:
1028 case FILTER_OP_NE_DOUBLE:
1029 case FILTER_OP_GT_DOUBLE:
1030 case FILTER_OP_LT_DOUBLE:
1031 case FILTER_OP_GE_DOUBLE:
1032 case FILTER_OP_LE_DOUBLE:
1033 {
1034 if ((reg[REG_R0].type != REG_DOUBLE && reg[REG_R0].type != REG_S64)
1035 || (reg[REG_R1].type != REG_DOUBLE && reg[REG_R1].type != REG_S64)) {
1036 ERR("Unexpected register type for double comparator\n");
1037 ret = -EINVAL;
1038 goto end;
1039 }
1040 if (reg[REG_R0].type != REG_DOUBLE && reg[REG_R1].type != REG_DOUBLE) {
1041 ERR("Double operator should have at least one double register\n");
1042 ret = -EINVAL;
1043 goto end;
1044 }
1045 reg[REG_R0].type = REG_DOUBLE;
1046 next_pc += sizeof(struct binary_op);
1047 break;
1048 }
1049
1050 /* unary */
1051 case FILTER_OP_UNARY_PLUS:
1052 case FILTER_OP_UNARY_MINUS:
1053 case FILTER_OP_UNARY_NOT:
1054 {
1055 struct unary_op *insn = (struct unary_op *) pc;
1056
1057 if (unlikely(insn->reg >= REG_ERROR)) {
1058 ERR("invalid register %u\n",
1059 (unsigned int) insn->reg);
1060 ret = -EINVAL;
1061 goto end;
1062 }
1063 switch (reg[insn->reg].type) {
1064 default:
1065 ERR("unknown register type\n");
1066 ret = -EINVAL;
1067 goto end;
1068
1069 case REG_STRING:
1070 ERR("Unary op can only be applied to numeric or floating point registers\n");
1071 ret = -EINVAL;
1072 goto end;
1073 case REG_S64:
1074 break;
1075 case REG_DOUBLE:
1076 break;
1077 }
1078 next_pc += sizeof(struct unary_op);
1079 break;
1080 }
1081
1082 case FILTER_OP_UNARY_PLUS_S64:
1083 case FILTER_OP_UNARY_MINUS_S64:
1084 case FILTER_OP_UNARY_NOT_S64:
1085 {
1086 struct unary_op *insn = (struct unary_op *) pc;
1087
1088 if (unlikely(insn->reg >= REG_ERROR)) {
1089 ERR("invalid register %u\n",
1090 (unsigned int) insn->reg);
1091 ret = -EINVAL;
1092 goto end;
1093 }
1094 if (reg[insn->reg].type != REG_S64) {
1095 ERR("Invalid register type\n");
1096 ret = -EINVAL;
1097 goto end;
1098 }
1099 next_pc += sizeof(struct unary_op);
1100 break;
1101 }
1102
1103 case FILTER_OP_UNARY_PLUS_DOUBLE:
1104 case FILTER_OP_UNARY_MINUS_DOUBLE:
1105 case FILTER_OP_UNARY_NOT_DOUBLE:
1106 {
1107 struct unary_op *insn = (struct unary_op *) pc;
1108
1109 if (unlikely(insn->reg >= REG_ERROR)) {
1110 ERR("invalid register %u\n",
1111 (unsigned int) insn->reg);
1112 ret = -EINVAL;
1113 goto end;
1114 }
1115 if (reg[insn->reg].type != REG_DOUBLE) {
1116 ERR("Invalid register type\n");
1117 ret = -EINVAL;
1118 goto end;
1119 }
1120 next_pc += sizeof(struct unary_op);
1121 break;
1122 }
1123
1124 /* logical */
1125 case FILTER_OP_AND:
1126 case FILTER_OP_OR:
1127 {
1128 struct logical_op *insn = (struct logical_op *) pc;
1129
1130 if (reg[REG_R0].type != REG_S64) {
1131 ERR("Logical comparator expects S64 register\n");
1132 ret = -EINVAL;
1133 goto end;
1134 }
1135
1136 dbg_printf("Validate jumping to bytecode offset %u\n",
1137 (unsigned int) insn->skip_offset);
1138 if (unlikely(start_pc + insn->skip_offset <= pc)) {
1139 ERR("Loops are not allowed in bytecode\n");
1140 ret = -EINVAL;
1141 goto end;
1142 }
1143 next_pc += sizeof(struct logical_op);
1144 break;
1145 }
1146
1147 /* load */
1148 case FILTER_OP_LOAD_FIELD_REF:
1149 {
1150 ERR("Unknown field ref type\n");
1151 ret = -EINVAL;
1152 goto end;
1153 }
1154 case FILTER_OP_LOAD_FIELD_REF_STRING:
1155 case FILTER_OP_LOAD_FIELD_REF_SEQUENCE:
1156 {
1157 struct load_op *insn = (struct load_op *) pc;
1158 struct field_ref *ref = (struct field_ref *) insn->data;
1159
1160 if (unlikely(insn->reg >= REG_ERROR)) {
1161 ERR("invalid register %u\n",
1162 (unsigned int) insn->reg);
1163 ret = -EINVAL;
1164 goto end;
1165 }
1166 dbg_printf("Validate load field ref offset %u type string\n",
1167 ref->offset);
1168 reg[insn->reg].type = REG_STRING;
1169 reg[insn->reg].literal = 0;
1170 next_pc += sizeof(struct load_op) + sizeof(struct field_ref);
1171 break;
1172 }
1173 case FILTER_OP_LOAD_FIELD_REF_S64:
1174 {
1175 struct load_op *insn = (struct load_op *) pc;
1176 struct field_ref *ref = (struct field_ref *) insn->data;
1177
1178 if (unlikely(insn->reg >= REG_ERROR)) {
1179 ERR("invalid register %u\n",
1180 (unsigned int) insn->reg);
1181 ret = -EINVAL;
1182 goto end;
1183 }
1184 dbg_printf("Validate load field ref offset %u type s64\n",
1185 ref->offset);
1186 reg[insn->reg].type = REG_S64;
1187 reg[insn->reg].literal = 0;
1188 next_pc += sizeof(struct load_op) + sizeof(struct field_ref);
1189 break;
1190 }
1191 case FILTER_OP_LOAD_FIELD_REF_DOUBLE:
1192 {
1193 struct load_op *insn = (struct load_op *) pc;
1194 struct field_ref *ref = (struct field_ref *) insn->data;
1195
1196 if (unlikely(insn->reg >= REG_ERROR)) {
1197 ERR("invalid register %u\n",
1198 (unsigned int) insn->reg);
1199 ret = -EINVAL;
1200 goto end;
1201 }
1202 dbg_printf("Validate load field ref offset %u type double\n",
1203 ref->offset);
1204 reg[insn->reg].type = REG_DOUBLE;
1205 reg[insn->reg].literal = 0;
1206 next_pc += sizeof(struct load_op) + sizeof(struct field_ref);
1207 break;
1208 }
1209
1210 case FILTER_OP_LOAD_STRING:
1211 {
1212 struct load_op *insn = (struct load_op *) pc;
1213
1214 if (unlikely(insn->reg >= REG_ERROR)) {
1215 ERR("invalid register %u\n",
1216 (unsigned int) insn->reg);
1217 ret = -EINVAL;
1218 goto end;
1219 }
1220 reg[insn->reg].type = REG_STRING;
1221 reg[insn->reg].literal = 1;
1222 next_pc += sizeof(struct load_op) + strlen(insn->data) + 1;
1223 break;
1224 }
1225
1226 case FILTER_OP_LOAD_S64:
1227 {
1228 struct load_op *insn = (struct load_op *) pc;
1229
1230 if (unlikely(insn->reg >= REG_ERROR)) {
1231 ERR("invalid register %u\n",
1232 (unsigned int) insn->reg);
1233 ret = -EINVAL;
1234 goto end;
1235 }
1236 reg[insn->reg].type = REG_S64;
1237 reg[insn->reg].literal = 1;
1238 next_pc += sizeof(struct load_op)
1239 + sizeof(struct literal_numeric);
1240 break;
1241 }
1242
1243 case FILTER_OP_LOAD_DOUBLE:
1244 {
1245 struct load_op *insn = (struct load_op *) pc;
1246
1247 if (unlikely(insn->reg >= REG_ERROR)) {
1248 ERR("invalid register %u\n",
1249 (unsigned int) insn->reg);
1250 ret = -EINVAL;
1251 goto end;
1252 }
1253 reg[insn->reg].type = REG_DOUBLE;
1254 reg[insn->reg].literal = 1;
1255 next_pc += sizeof(struct load_op)
1256 + sizeof(struct literal_double);
1257 break;
1258 }
1259
1260 case FILTER_OP_CAST_TO_S64:
1261 case FILTER_OP_CAST_DOUBLE_TO_S64:
1262 {
1263 struct cast_op *insn = (struct cast_op *) pc;
1264
1265 if (unlikely(insn->reg >= REG_ERROR)) {
1266 ERR("invalid register %u\n",
1267 (unsigned int) insn->reg);
1268 ret = -EINVAL;
1269 goto end;
1270 }
1271 switch (reg[insn->reg].type) {
1272 default:
1273 ERR("unknown register type\n");
1274 ret = -EINVAL;
1275 goto end;
1276
1277 case REG_STRING:
1278 ERR("Cast op can only be applied to numeric or floating point registers\n");
1279 ret = -EINVAL;
1280 goto end;
1281 case REG_S64:
1282 break;
1283 case REG_DOUBLE:
1284 break;
1285 }
1286 if (insn->op == FILTER_OP_CAST_DOUBLE_TO_S64) {
1287 if (reg[insn->reg].type != REG_DOUBLE) {
1288 ERR("Cast expects double\n");
1289 ret = -EINVAL;
1290 goto end;
1291 }
1292 }
1293 reg[insn->reg].type = REG_S64;
1294 next_pc += sizeof(struct cast_op);
1295 break;
1296 }
1297 case FILTER_OP_CAST_NOP:
1298 {
1299 next_pc += sizeof(struct cast_op);
1300 break;
1301 }
1302
1303 }
1304 }
1305 end:
1306 return ret;
1307 }
1308
1309 static
1310 int lttng_filter_specialize_bytecode(struct bytecode_runtime *bytecode)
1311 {
1312 void *pc, *next_pc, *start_pc;
1313 int ret = -EINVAL;
1314 struct vreg reg[NR_REG];
1315 int i;
1316
1317 for (i = 0; i < NR_REG; i++) {
1318 reg[i].type = REG_TYPE_UNKNOWN;
1319 reg[i].literal = 0;
1320 }
1321
1322 start_pc = &bytecode->data[0];
1323 for (pc = next_pc = start_pc; pc - start_pc < bytecode->len;
1324 pc = next_pc) {
1325 switch (*(filter_opcode_t *) pc) {
1326 case FILTER_OP_UNKNOWN:
1327 default:
1328 ERR("unknown bytecode op %u\n",
1329 (unsigned int) *(filter_opcode_t *) pc);
1330 ret = -EINVAL;
1331 goto end;
1332
1333 case FILTER_OP_RETURN:
1334 ret = 0;
1335 goto end;
1336
1337 /* binary */
1338 case FILTER_OP_MUL:
1339 case FILTER_OP_DIV:
1340 case FILTER_OP_MOD:
1341 case FILTER_OP_PLUS:
1342 case FILTER_OP_MINUS:
1343 case FILTER_OP_RSHIFT:
1344 case FILTER_OP_LSHIFT:
1345 case FILTER_OP_BIN_AND:
1346 case FILTER_OP_BIN_OR:
1347 case FILTER_OP_BIN_XOR:
1348 ERR("unsupported bytecode op %u\n",
1349 (unsigned int) *(filter_opcode_t *) pc);
1350 ret = -EINVAL;
1351 goto end;
1352
1353 case FILTER_OP_EQ:
1354 {
1355 struct binary_op *insn = (struct binary_op *) pc;
1356
1357 switch(reg[REG_R0].type) {
1358 default:
1359 ERR("unknown register type\n");
1360 ret = -EINVAL;
1361 goto end;
1362
1363 case REG_STRING:
1364 insn->op = FILTER_OP_EQ_STRING;
1365 break;
1366 case REG_S64:
1367 if (reg[REG_R1].type == REG_S64)
1368 insn->op = FILTER_OP_EQ_S64;
1369 else
1370 insn->op = FILTER_OP_EQ_DOUBLE;
1371 break;
1372 case REG_DOUBLE:
1373 insn->op = FILTER_OP_EQ_DOUBLE;
1374 break;
1375 }
1376 reg[REG_R0].type = REG_S64;
1377 next_pc += sizeof(struct binary_op);
1378 break;
1379 }
1380
1381 case FILTER_OP_NE:
1382 {
1383 struct binary_op *insn = (struct binary_op *) pc;
1384
1385 switch(reg[REG_R0].type) {
1386 default:
1387 ERR("unknown register type\n");
1388 ret = -EINVAL;
1389 goto end;
1390
1391 case REG_STRING:
1392 insn->op = FILTER_OP_NE_STRING;
1393 break;
1394 case REG_S64:
1395 if (reg[REG_R1].type == REG_S64)
1396 insn->op = FILTER_OP_NE_S64;
1397 else
1398 insn->op = FILTER_OP_NE_DOUBLE;
1399 break;
1400 case REG_DOUBLE:
1401 insn->op = FILTER_OP_NE_DOUBLE;
1402 break;
1403 }
1404 reg[REG_R0].type = REG_S64;
1405 next_pc += sizeof(struct binary_op);
1406 break;
1407 }
1408
1409 case FILTER_OP_GT:
1410 {
1411 struct binary_op *insn = (struct binary_op *) pc;
1412
1413 switch(reg[REG_R0].type) {
1414 default:
1415 ERR("unknown register type\n");
1416 ret = -EINVAL;
1417 goto end;
1418
1419 case REG_STRING:
1420 insn->op = FILTER_OP_GT_STRING;
1421 break;
1422 case REG_S64:
1423 if (reg[REG_R1].type == REG_S64)
1424 insn->op = FILTER_OP_GT_S64;
1425 else
1426 insn->op = FILTER_OP_GT_DOUBLE;
1427 break;
1428 case REG_DOUBLE:
1429 insn->op = FILTER_OP_GT_DOUBLE;
1430 break;
1431 }
1432 reg[REG_R0].type = REG_S64;
1433 next_pc += sizeof(struct binary_op);
1434 break;
1435 }
1436
1437 case FILTER_OP_LT:
1438 {
1439 struct binary_op *insn = (struct binary_op *) pc;
1440
1441 switch(reg[REG_R0].type) {
1442 default:
1443 ERR("unknown register type\n");
1444 ret = -EINVAL;
1445 goto end;
1446
1447 case REG_STRING:
1448 insn->op = FILTER_OP_LT_STRING;
1449 break;
1450 case REG_S64:
1451 if (reg[REG_R1].type == REG_S64)
1452 insn->op = FILTER_OP_LT_S64;
1453 else
1454 insn->op = FILTER_OP_LT_DOUBLE;
1455 break;
1456 case REG_DOUBLE:
1457 insn->op = FILTER_OP_LT_DOUBLE;
1458 break;
1459 }
1460 reg[REG_R0].type = REG_S64;
1461 next_pc += sizeof(struct binary_op);
1462 break;
1463 }
1464
1465 case FILTER_OP_GE:
1466 {
1467 struct binary_op *insn = (struct binary_op *) pc;
1468
1469 switch(reg[REG_R0].type) {
1470 default:
1471 ERR("unknown register type\n");
1472 ret = -EINVAL;
1473 goto end;
1474
1475 case REG_STRING:
1476 insn->op = FILTER_OP_GE_STRING;
1477 break;
1478 case REG_S64:
1479 if (reg[REG_R1].type == REG_S64)
1480 insn->op = FILTER_OP_GE_S64;
1481 else
1482 insn->op = FILTER_OP_GE_DOUBLE;
1483 break;
1484 case REG_DOUBLE:
1485 insn->op = FILTER_OP_GE_DOUBLE;
1486 break;
1487 }
1488 reg[REG_R0].type = REG_S64;
1489 next_pc += sizeof(struct binary_op);
1490 break;
1491 }
1492 case FILTER_OP_LE:
1493 {
1494 struct binary_op *insn = (struct binary_op *) pc;
1495
1496 switch(reg[REG_R0].type) {
1497 default:
1498 ERR("unknown register type\n");
1499 ret = -EINVAL;
1500 goto end;
1501
1502 case REG_STRING:
1503 insn->op = FILTER_OP_LE_STRING;
1504 break;
1505 case REG_S64:
1506 if (reg[REG_R1].type == REG_S64)
1507 insn->op = FILTER_OP_LE_S64;
1508 else
1509 insn->op = FILTER_OP_LE_DOUBLE;
1510 break;
1511 case REG_DOUBLE:
1512 insn->op = FILTER_OP_LE_DOUBLE;
1513 break;
1514 }
1515 reg[REG_R0].type = REG_S64;
1516 next_pc += sizeof(struct binary_op);
1517 break;
1518 }
1519
1520 case FILTER_OP_EQ_STRING:
1521 case FILTER_OP_NE_STRING:
1522 case FILTER_OP_GT_STRING:
1523 case FILTER_OP_LT_STRING:
1524 case FILTER_OP_GE_STRING:
1525 case FILTER_OP_LE_STRING:
1526 case FILTER_OP_EQ_S64:
1527 case FILTER_OP_NE_S64:
1528 case FILTER_OP_GT_S64:
1529 case FILTER_OP_LT_S64:
1530 case FILTER_OP_GE_S64:
1531 case FILTER_OP_LE_S64:
1532 case FILTER_OP_EQ_DOUBLE:
1533 case FILTER_OP_NE_DOUBLE:
1534 case FILTER_OP_GT_DOUBLE:
1535 case FILTER_OP_LT_DOUBLE:
1536 case FILTER_OP_GE_DOUBLE:
1537 case FILTER_OP_LE_DOUBLE:
1538 {
1539 reg[REG_R0].type = REG_S64;
1540 next_pc += sizeof(struct binary_op);
1541 break;
1542 }
1543
1544 /* unary */
1545 case FILTER_OP_UNARY_PLUS:
1546 {
1547 struct unary_op *insn = (struct unary_op *) pc;
1548
1549 switch(reg[insn->reg].type) {
1550 default:
1551 ERR("unknown register type\n");
1552 ret = -EINVAL;
1553 goto end;
1554
1555 case REG_S64:
1556 insn->op = FILTER_OP_UNARY_PLUS_S64;
1557 break;
1558 case REG_DOUBLE:
1559 insn->op = FILTER_OP_UNARY_PLUS_DOUBLE;
1560 break;
1561 }
1562 next_pc += sizeof(struct unary_op);
1563 break;
1564 }
1565
1566 case FILTER_OP_UNARY_MINUS:
1567 {
1568 struct unary_op *insn = (struct unary_op *) pc;
1569
1570 switch(reg[insn->reg].type) {
1571 default:
1572 ERR("unknown register type\n");
1573 ret = -EINVAL;
1574 goto end;
1575
1576 case REG_S64:
1577 insn->op = FILTER_OP_UNARY_MINUS_S64;
1578 break;
1579 case REG_DOUBLE:
1580 insn->op = FILTER_OP_UNARY_MINUS_DOUBLE;
1581 break;
1582 }
1583 next_pc += sizeof(struct unary_op);
1584 break;
1585 }
1586
1587 case FILTER_OP_UNARY_NOT:
1588 {
1589 struct unary_op *insn = (struct unary_op *) pc;
1590
1591 switch(reg[insn->reg].type) {
1592 default:
1593 ERR("unknown register type\n");
1594 ret = -EINVAL;
1595 goto end;
1596
1597 case REG_S64:
1598 insn->op = FILTER_OP_UNARY_NOT_S64;
1599 break;
1600 case REG_DOUBLE:
1601 insn->op = FILTER_OP_UNARY_NOT_DOUBLE;
1602 break;
1603 }
1604 next_pc += sizeof(struct unary_op);
1605 break;
1606 }
1607
1608 case FILTER_OP_UNARY_PLUS_S64:
1609 case FILTER_OP_UNARY_MINUS_S64:
1610 case FILTER_OP_UNARY_NOT_S64:
1611 case FILTER_OP_UNARY_PLUS_DOUBLE:
1612 case FILTER_OP_UNARY_MINUS_DOUBLE:
1613 case FILTER_OP_UNARY_NOT_DOUBLE:
1614 {
1615 next_pc += sizeof(struct unary_op);
1616 break;
1617 }
1618
1619 /* logical */
1620 case FILTER_OP_AND:
1621 case FILTER_OP_OR:
1622 {
1623 next_pc += sizeof(struct logical_op);
1624 break;
1625 }
1626
1627 /* load */
1628 case FILTER_OP_LOAD_FIELD_REF:
1629 {
1630 ERR("Unknown field ref type\n");
1631 ret = -EINVAL;
1632 goto end;
1633 }
1634 case FILTER_OP_LOAD_FIELD_REF_STRING:
1635 case FILTER_OP_LOAD_FIELD_REF_SEQUENCE:
1636 {
1637 struct load_op *insn = (struct load_op *) pc;
1638
1639 reg[insn->reg].type = REG_STRING;
1640 reg[insn->reg].literal = 0;
1641 next_pc += sizeof(struct load_op) + sizeof(struct field_ref);
1642 break;
1643 }
1644 case FILTER_OP_LOAD_FIELD_REF_S64:
1645 {
1646 struct load_op *insn = (struct load_op *) pc;
1647
1648 reg[insn->reg].type = REG_S64;
1649 reg[insn->reg].literal = 0;
1650 next_pc += sizeof(struct load_op) + sizeof(struct field_ref);
1651 break;
1652 }
1653 case FILTER_OP_LOAD_FIELD_REF_DOUBLE:
1654 {
1655 struct load_op *insn = (struct load_op *) pc;
1656
1657 reg[insn->reg].type = REG_DOUBLE;
1658 reg[insn->reg].literal = 0;
1659 next_pc += sizeof(struct load_op) + sizeof(struct field_ref);
1660 break;
1661 }
1662
1663 case FILTER_OP_LOAD_STRING:
1664 {
1665 struct load_op *insn = (struct load_op *) pc;
1666
1667 reg[insn->reg].type = REG_STRING;
1668 reg[insn->reg].literal = 1;
1669 next_pc += sizeof(struct load_op) + strlen(insn->data) + 1;
1670 break;
1671 }
1672
1673 case FILTER_OP_LOAD_S64:
1674 {
1675 struct load_op *insn = (struct load_op *) pc;
1676
1677 reg[insn->reg].type = REG_S64;
1678 reg[insn->reg].literal = 1;
1679 next_pc += sizeof(struct load_op)
1680 + sizeof(struct literal_numeric);
1681 break;
1682 }
1683
1684 case FILTER_OP_LOAD_DOUBLE:
1685 {
1686 struct load_op *insn = (struct load_op *) pc;
1687
1688 reg[insn->reg].type = REG_DOUBLE;
1689 reg[insn->reg].literal = 1;
1690 next_pc += sizeof(struct load_op)
1691 + sizeof(struct literal_double);
1692 break;
1693 }
1694
1695 /* cast */
1696 case FILTER_OP_CAST_TO_S64:
1697 {
1698 struct cast_op *insn = (struct cast_op *) pc;
1699
1700 switch (reg[insn->reg].type) {
1701 default:
1702 ERR("unknown register type\n");
1703 ret = -EINVAL;
1704 goto end;
1705
1706 case REG_STRING:
1707 ERR("Cast op can only be applied to numeric or floating point registers\n");
1708 ret = -EINVAL;
1709 goto end;
1710 case REG_S64:
1711 insn->op = FILTER_OP_CAST_NOP;
1712 break;
1713 case REG_DOUBLE:
1714 insn->op = FILTER_OP_CAST_DOUBLE_TO_S64;
1715 break;
1716 }
1717 reg[insn->reg].type = REG_S64;
1718 next_pc += sizeof(struct cast_op);
1719 break;
1720 }
1721 case FILTER_OP_CAST_DOUBLE_TO_S64:
1722 {
1723 struct cast_op *insn = (struct cast_op *) pc;
1724
1725 reg[insn->reg].type = REG_S64;
1726 next_pc += sizeof(struct cast_op);
1727 break;
1728 }
1729 case FILTER_OP_CAST_NOP:
1730 {
1731 next_pc += sizeof(struct cast_op);
1732 break;
1733 }
1734
1735
1736 }
1737 }
1738 end:
1739 return ret;
1740 }
1741
1742 static
1743 int apply_field_reloc(struct ltt_event *event,
1744 struct bytecode_runtime *runtime,
1745 uint32_t runtime_len,
1746 uint32_t reloc_offset,
1747 const char *field_name)
1748 {
1749 const struct lttng_event_desc *desc;
1750 const struct lttng_event_field *fields, *field = NULL;
1751 unsigned int nr_fields, i;
1752 struct field_ref *field_ref;
1753 struct load_op *op;
1754 uint32_t field_offset = 0;
1755
1756 dbg_printf("Apply reloc: %u %s\n", reloc_offset, field_name);
1757
1758 /* Ensure that the reloc is within the code */
1759 if (runtime_len - reloc_offset < sizeof(uint16_t))
1760 return -EINVAL;
1761
1762 /* Lookup event by name */
1763 desc = event->desc;
1764 if (!desc)
1765 return -EINVAL;
1766 fields = desc->fields;
1767 if (!fields)
1768 return -EINVAL;
1769 nr_fields = desc->nr_fields;
1770 for (i = 0; i < nr_fields; i++) {
1771 if (!strcmp(fields[i].name, field_name)) {
1772 field = &fields[i];
1773 break;
1774 }
1775 /* compute field offset */
1776 switch (fields[i].type.atype) {
1777 case atype_integer:
1778 case atype_enum:
1779 field_offset += sizeof(int64_t);
1780 break;
1781 case atype_array:
1782 case atype_sequence:
1783 field_offset += sizeof(unsigned long);
1784 field_offset += sizeof(void *);
1785 break;
1786 case atype_string:
1787 field_offset += sizeof(void *);
1788 break;
1789 case atype_float:
1790 field_offset += sizeof(double);
1791 break;
1792 default:
1793 return -EINVAL;
1794 }
1795 }
1796 if (!field)
1797 return -EINVAL;
1798
1799 /* Check if field offset is too large for 16-bit offset */
1800 if (field_offset > FILTER_BYTECODE_MAX_LEN)
1801 return -EINVAL;
1802
1803 /* set type */
1804 op = (struct load_op *) &runtime->data[reloc_offset];
1805 field_ref = (struct field_ref *) op->data;
1806 switch (field->type.atype) {
1807 case atype_integer:
1808 case atype_enum:
1809 op->op = FILTER_OP_LOAD_FIELD_REF_S64;
1810 break;
1811 case atype_array:
1812 case atype_sequence:
1813 op->op = FILTER_OP_LOAD_FIELD_REF_SEQUENCE;
1814 break;
1815 case atype_string:
1816 op->op = FILTER_OP_LOAD_FIELD_REF_STRING;
1817 break;
1818 case atype_float:
1819 op->op = FILTER_OP_LOAD_FIELD_REF_DOUBLE;
1820 break;
1821 default:
1822 return -EINVAL;
1823 }
1824 /* set offset */
1825 field_ref->offset = (uint16_t) field_offset;
1826 return 0;
1827 }
1828
1829 /*
1830 * Take a bytecode with reloc table and link it to an event to create a
1831 * bytecode runtime.
1832 */
1833 static
1834 int _lttng_filter_event_link_bytecode(struct ltt_event *event,
1835 struct lttng_ust_filter_bytecode *filter_bytecode)
1836 {
1837 int ret, offset, next_offset;
1838 struct bytecode_runtime *runtime = NULL;
1839 size_t runtime_alloc_len;
1840
1841 if (!filter_bytecode)
1842 return 0;
1843 /* Even is not connected to any description */
1844 if (!event->desc)
1845 return 0;
1846 /* Bytecode already linked */
1847 if (event->filter || event->filter_data)
1848 return 0;
1849
1850 dbg_printf("Linking\n");
1851
1852 /* We don't need the reloc table in the runtime */
1853 runtime_alloc_len = sizeof(*runtime) + filter_bytecode->reloc_offset;
1854 runtime = zmalloc(runtime_alloc_len);
1855 if (!runtime) {
1856 ret = -ENOMEM;
1857 goto link_error;
1858 }
1859 runtime->len = filter_bytecode->reloc_offset;
1860 /* copy original bytecode */
1861 memcpy(runtime->data, filter_bytecode->data, runtime->len);
1862 /*
1863 * apply relocs. Those are a uint16_t (offset in bytecode)
1864 * followed by a string (field name).
1865 */
1866 for (offset = filter_bytecode->reloc_offset;
1867 offset < filter_bytecode->len;
1868 offset = next_offset) {
1869 uint16_t reloc_offset =
1870 *(uint16_t *) &filter_bytecode->data[offset];
1871 const char *field_name =
1872 (const char *) &filter_bytecode->data[offset + sizeof(uint16_t)];
1873
1874 ret = apply_field_reloc(event, runtime, runtime->len, reloc_offset, field_name);
1875 if (ret) {
1876 goto link_error;
1877 }
1878 next_offset = offset + sizeof(uint16_t) + strlen(field_name) + 1;
1879 }
1880 /* Validate bytecode */
1881 ret = lttng_filter_validate_bytecode(runtime);
1882 if (ret) {
1883 goto link_error;
1884 }
1885 /* Specialize bytecode */
1886 ret = lttng_filter_specialize_bytecode(runtime);
1887 if (ret) {
1888 goto link_error;
1889 }
1890 event->filter_data = runtime;
1891 event->filter = lttng_filter_interpret_bytecode;
1892 return 0;
1893
1894 link_error:
1895 event->filter = lttng_filter_false;
1896 free(runtime);
1897 return ret;
1898 }
1899
1900 void lttng_filter_event_link_bytecode(struct ltt_event *event,
1901 struct lttng_ust_filter_bytecode *filter_bytecode)
1902 {
1903 int ret;
1904
1905 ret = _lttng_filter_event_link_bytecode(event, filter_bytecode);
1906 if (ret) {
1907 fprintf(stderr, "[lttng filter] error linking event bytecode\n");
1908 }
1909 }
1910
1911 /*
1912 * Link bytecode to all events for a wildcard. Skips events that already
1913 * have a bytecode linked.
1914 * We do not set each event's filter_bytecode field, because they do not
1915 * own the filter_bytecode: the wildcard owns it.
1916 */
1917 void lttng_filter_wildcard_link_bytecode(struct session_wildcard *wildcard)
1918 {
1919 struct ltt_event *event;
1920 int ret;
1921
1922 if (!wildcard->filter_bytecode)
1923 return;
1924
1925 cds_list_for_each_entry(event, &wildcard->events, wildcard_list) {
1926 if (event->filter)
1927 continue;
1928 ret = _lttng_filter_event_link_bytecode(event,
1929 wildcard->filter_bytecode);
1930 if (ret) {
1931 fprintf(stderr, "[lttng filter] error linking wildcard bytecode\n");
1932 }
1933
1934 }
1935 return;
1936 }
1937
1938 /*
1939 * Need to attach filter to an event before starting tracing for the
1940 * session. We own the filter_bytecode if we return success.
1941 */
1942 int lttng_filter_event_attach_bytecode(struct ltt_event *event,
1943 struct lttng_ust_filter_bytecode *filter_bytecode)
1944 {
1945 if (event->chan->session->been_active)
1946 return -EPERM;
1947 if (event->filter_bytecode)
1948 return -EEXIST;
1949 event->filter_bytecode = filter_bytecode;
1950 return 0;
1951 }
1952
1953 /*
1954 * Need to attach filter to a wildcard before starting tracing for the
1955 * session. We own the filter_bytecode if we return success.
1956 */
1957 int lttng_filter_wildcard_attach_bytecode(struct session_wildcard *wildcard,
1958 struct lttng_ust_filter_bytecode *filter_bytecode)
1959 {
1960 if (wildcard->chan->session->been_active)
1961 return -EPERM;
1962 if (wildcard->filter_bytecode)
1963 return -EEXIST;
1964 wildcard->filter_bytecode = filter_bytecode;
1965 return 0;
1966 }
This page took 0.076636 seconds and 5 git commands to generate.