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