Filter: cleanup macros
[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 /*
885 * Validate bytecode range overflow within the validation pass.
886 * Called for each instruction encountered.
887 */
888 static
889 int bytecode_validate_overflow(struct bytecode_runtime *bytecode,
890 void *start_pc, void *pc)
891 {
892 int ret = 0;
893
894 switch (*(filter_opcode_t *) pc) {
895 case FILTER_OP_UNKNOWN:
896 default:
897 {
898 ERR("unknown bytecode op %u\n",
899 (unsigned int) *(filter_opcode_t *) pc);
900 ret = -EINVAL;
901 break;
902 }
903
904 case FILTER_OP_RETURN:
905 {
906 if (unlikely(pc + sizeof(struct return_op)
907 > start_pc + bytecode->len)) {
908 ret = -EINVAL;
909 }
910 break;
911 }
912
913 /* binary */
914 case FILTER_OP_MUL:
915 case FILTER_OP_DIV:
916 case FILTER_OP_MOD:
917 case FILTER_OP_PLUS:
918 case FILTER_OP_MINUS:
919 case FILTER_OP_RSHIFT:
920 case FILTER_OP_LSHIFT:
921 case FILTER_OP_BIN_AND:
922 case FILTER_OP_BIN_OR:
923 case FILTER_OP_BIN_XOR:
924 {
925 ERR("unsupported bytecode op %u\n",
926 (unsigned int) *(filter_opcode_t *) pc);
927 ret = -EINVAL;
928 break;
929 }
930
931 case FILTER_OP_EQ:
932 case FILTER_OP_NE:
933 case FILTER_OP_GT:
934 case FILTER_OP_LT:
935 case FILTER_OP_GE:
936 case FILTER_OP_LE:
937 case FILTER_OP_EQ_STRING:
938 case FILTER_OP_NE_STRING:
939 case FILTER_OP_GT_STRING:
940 case FILTER_OP_LT_STRING:
941 case FILTER_OP_GE_STRING:
942 case FILTER_OP_LE_STRING:
943 case FILTER_OP_EQ_S64:
944 case FILTER_OP_NE_S64:
945 case FILTER_OP_GT_S64:
946 case FILTER_OP_LT_S64:
947 case FILTER_OP_GE_S64:
948 case FILTER_OP_LE_S64:
949 case FILTER_OP_EQ_DOUBLE:
950 case FILTER_OP_NE_DOUBLE:
951 case FILTER_OP_GT_DOUBLE:
952 case FILTER_OP_LT_DOUBLE:
953 case FILTER_OP_GE_DOUBLE:
954 case FILTER_OP_LE_DOUBLE:
955 {
956 if (unlikely(pc + sizeof(struct binary_op)
957 > start_pc + bytecode->len)) {
958 ret = -EINVAL;
959 }
960 break;
961 }
962
963 /* unary */
964 case FILTER_OP_UNARY_PLUS:
965 case FILTER_OP_UNARY_MINUS:
966 case FILTER_OP_UNARY_NOT:
967 case FILTER_OP_UNARY_PLUS_S64:
968 case FILTER_OP_UNARY_MINUS_S64:
969 case FILTER_OP_UNARY_NOT_S64:
970 case FILTER_OP_UNARY_PLUS_DOUBLE:
971 case FILTER_OP_UNARY_MINUS_DOUBLE:
972 case FILTER_OP_UNARY_NOT_DOUBLE:
973 {
974 if (unlikely(pc + sizeof(struct unary_op)
975 > start_pc + bytecode->len)) {
976 ret = -EINVAL;
977 }
978 break;
979 }
980
981 /* logical */
982 case FILTER_OP_AND:
983 case FILTER_OP_OR:
984 {
985 if (unlikely(pc + sizeof(struct logical_op)
986 > start_pc + bytecode->len)) {
987 ret = -EINVAL;
988 }
989 break;
990 }
991
992 /* load */
993 case FILTER_OP_LOAD_FIELD_REF:
994 {
995 ERR("Unknown field ref type\n");
996 ret = -EINVAL;
997 break;
998 }
999 case FILTER_OP_LOAD_FIELD_REF_STRING:
1000 case FILTER_OP_LOAD_FIELD_REF_SEQUENCE:
1001 case FILTER_OP_LOAD_FIELD_REF_S64:
1002 case FILTER_OP_LOAD_FIELD_REF_DOUBLE:
1003 {
1004 if (unlikely(pc + sizeof(struct load_op) + sizeof(struct field_ref)
1005 > start_pc + bytecode->len)) {
1006 ret = -EINVAL;
1007 }
1008 break;
1009 }
1010
1011 case FILTER_OP_LOAD_STRING:
1012 {
1013 struct load_op *insn = (struct load_op *) pc;
1014 uint32_t str_len, maxlen;
1015
1016 if (unlikely(pc + sizeof(struct load_op)
1017 > start_pc + bytecode->len)) {
1018 ret = -EINVAL;
1019 break;
1020 }
1021
1022 maxlen = start_pc + bytecode->len - pc - sizeof(struct load_op);
1023 str_len = strnlen(insn->data, maxlen);
1024 if (unlikely(str_len >= maxlen)) {
1025 /* Final '\0' not found within range */
1026 ret = -EINVAL;
1027 }
1028 break;
1029 }
1030
1031 case FILTER_OP_LOAD_S64:
1032 {
1033 if (unlikely(pc + sizeof(struct load_op) + sizeof(struct literal_numeric)
1034 > start_pc + bytecode->len)) {
1035 ret = -EINVAL;
1036 }
1037 break;
1038 }
1039
1040 case FILTER_OP_LOAD_DOUBLE:
1041 {
1042 if (unlikely(pc + sizeof(struct load_op) + sizeof(struct literal_double)
1043 > start_pc + bytecode->len)) {
1044 ret = -EINVAL;
1045 }
1046 break;
1047 }
1048
1049 case FILTER_OP_CAST_TO_S64:
1050 case FILTER_OP_CAST_DOUBLE_TO_S64:
1051 case FILTER_OP_CAST_NOP:
1052 {
1053 if (unlikely(pc + sizeof(struct cast_op)
1054 > start_pc + bytecode->len)) {
1055 ret = -EINVAL;
1056 }
1057 break;
1058 }
1059 }
1060
1061 return ret;
1062 }
1063
1064 static
1065 int lttng_filter_validate_bytecode(struct bytecode_runtime *bytecode)
1066 {
1067 void *pc, *next_pc, *start_pc;
1068 int ret = -EINVAL;
1069 struct vreg reg[NR_REG];
1070 int i;
1071
1072 for (i = 0; i < NR_REG; i++) {
1073 reg[i].type = REG_TYPE_UNKNOWN;
1074 reg[i].literal = 0;
1075 }
1076
1077 start_pc = &bytecode->data[0];
1078 for (pc = next_pc = start_pc; pc - start_pc < bytecode->len;
1079 pc = next_pc) {
1080 if (bytecode_validate_overflow(bytecode, start_pc, pc) != 0) {
1081 ERR("filter bytecode overflow\n");
1082 ret = -EINVAL;
1083 goto end;
1084 }
1085 dbg_printf("Validating op %s (%u)\n",
1086 print_op((unsigned int) *(filter_opcode_t *) pc),
1087 (unsigned int) *(filter_opcode_t *) pc);
1088 switch (*(filter_opcode_t *) pc) {
1089 case FILTER_OP_UNKNOWN:
1090 default:
1091 ERR("unknown bytecode op %u\n",
1092 (unsigned int) *(filter_opcode_t *) pc);
1093 ret = -EINVAL;
1094 goto end;
1095
1096 case FILTER_OP_RETURN:
1097 ret = 0;
1098 goto end;
1099
1100 /* binary */
1101 case FILTER_OP_MUL:
1102 case FILTER_OP_DIV:
1103 case FILTER_OP_MOD:
1104 case FILTER_OP_PLUS:
1105 case FILTER_OP_MINUS:
1106 case FILTER_OP_RSHIFT:
1107 case FILTER_OP_LSHIFT:
1108 case FILTER_OP_BIN_AND:
1109 case FILTER_OP_BIN_OR:
1110 case FILTER_OP_BIN_XOR:
1111 ERR("unsupported bytecode op %u\n",
1112 (unsigned int) *(filter_opcode_t *) pc);
1113 ret = -EINVAL;
1114 goto end;
1115
1116 case FILTER_OP_EQ:
1117 {
1118 ret = bin_op_compare_check(reg, "==");
1119 if (ret)
1120 goto end;
1121 reg[REG_R0].type = REG_S64;
1122 next_pc += sizeof(struct binary_op);
1123 break;
1124 }
1125 case FILTER_OP_NE:
1126 {
1127 ret = bin_op_compare_check(reg, "!=");
1128 if (ret)
1129 goto end;
1130 reg[REG_R0].type = REG_S64;
1131 next_pc += sizeof(struct binary_op);
1132 break;
1133 }
1134 case FILTER_OP_GT:
1135 {
1136 ret = bin_op_compare_check(reg, ">");
1137 if (ret)
1138 goto end;
1139 reg[REG_R0].type = REG_S64;
1140 next_pc += sizeof(struct binary_op);
1141 break;
1142 }
1143 case FILTER_OP_LT:
1144 {
1145 ret = bin_op_compare_check(reg, "<");
1146 if (ret)
1147 goto end;
1148 reg[REG_R0].type = REG_S64;
1149 next_pc += sizeof(struct binary_op);
1150 break;
1151 }
1152 case FILTER_OP_GE:
1153 {
1154 ret = bin_op_compare_check(reg, ">=");
1155 if (ret)
1156 goto end;
1157 reg[REG_R0].type = REG_S64;
1158 next_pc += sizeof(struct binary_op);
1159 break;
1160 }
1161 case FILTER_OP_LE:
1162 {
1163 ret = bin_op_compare_check(reg, "<=");
1164 if (ret)
1165 goto end;
1166 reg[REG_R0].type = REG_S64;
1167 next_pc += sizeof(struct binary_op);
1168 break;
1169 }
1170
1171 case FILTER_OP_EQ_STRING:
1172 case FILTER_OP_NE_STRING:
1173 case FILTER_OP_GT_STRING:
1174 case FILTER_OP_LT_STRING:
1175 case FILTER_OP_GE_STRING:
1176 case FILTER_OP_LE_STRING:
1177 {
1178 if (reg[REG_R0].type != REG_STRING
1179 || reg[REG_R1].type != REG_STRING) {
1180 ERR("Unexpected register type for string comparator\n");
1181 ret = -EINVAL;
1182 goto end;
1183 }
1184 reg[REG_R0].type = REG_S64;
1185 next_pc += sizeof(struct binary_op);
1186 break;
1187 }
1188
1189 case FILTER_OP_EQ_S64:
1190 case FILTER_OP_NE_S64:
1191 case FILTER_OP_GT_S64:
1192 case FILTER_OP_LT_S64:
1193 case FILTER_OP_GE_S64:
1194 case FILTER_OP_LE_S64:
1195 {
1196 if (reg[REG_R0].type != REG_S64
1197 || reg[REG_R1].type != REG_S64) {
1198 ERR("Unexpected register type for s64 comparator\n");
1199 ret = -EINVAL;
1200 goto end;
1201 }
1202 reg[REG_R0].type = REG_S64;
1203 next_pc += sizeof(struct binary_op);
1204 break;
1205 }
1206
1207 case FILTER_OP_EQ_DOUBLE:
1208 case FILTER_OP_NE_DOUBLE:
1209 case FILTER_OP_GT_DOUBLE:
1210 case FILTER_OP_LT_DOUBLE:
1211 case FILTER_OP_GE_DOUBLE:
1212 case FILTER_OP_LE_DOUBLE:
1213 {
1214 if ((reg[REG_R0].type != REG_DOUBLE && reg[REG_R0].type != REG_S64)
1215 || (reg[REG_R1].type != REG_DOUBLE && reg[REG_R1].type != REG_S64)) {
1216 ERR("Unexpected register type for double comparator\n");
1217 ret = -EINVAL;
1218 goto end;
1219 }
1220 if (reg[REG_R0].type != REG_DOUBLE && reg[REG_R1].type != REG_DOUBLE) {
1221 ERR("Double operator should have at least one double register\n");
1222 ret = -EINVAL;
1223 goto end;
1224 }
1225 reg[REG_R0].type = REG_DOUBLE;
1226 next_pc += sizeof(struct binary_op);
1227 break;
1228 }
1229
1230 /* unary */
1231 case FILTER_OP_UNARY_PLUS:
1232 case FILTER_OP_UNARY_MINUS:
1233 case FILTER_OP_UNARY_NOT:
1234 {
1235 struct unary_op *insn = (struct unary_op *) pc;
1236
1237 if (unlikely(insn->reg >= REG_ERROR)) {
1238 ERR("invalid register %u\n",
1239 (unsigned int) insn->reg);
1240 ret = -EINVAL;
1241 goto end;
1242 }
1243 switch (reg[insn->reg].type) {
1244 default:
1245 ERR("unknown register type\n");
1246 ret = -EINVAL;
1247 goto end;
1248
1249 case REG_STRING:
1250 ERR("Unary op can only be applied to numeric or floating point registers\n");
1251 ret = -EINVAL;
1252 goto end;
1253 case REG_S64:
1254 break;
1255 case REG_DOUBLE:
1256 break;
1257 }
1258 next_pc += sizeof(struct unary_op);
1259 break;
1260 }
1261
1262 case FILTER_OP_UNARY_PLUS_S64:
1263 case FILTER_OP_UNARY_MINUS_S64:
1264 case FILTER_OP_UNARY_NOT_S64:
1265 {
1266 struct unary_op *insn = (struct unary_op *) pc;
1267
1268 if (unlikely(insn->reg >= REG_ERROR)) {
1269 ERR("invalid register %u\n",
1270 (unsigned int) insn->reg);
1271 ret = -EINVAL;
1272 goto end;
1273 }
1274 if (reg[insn->reg].type != REG_S64) {
1275 ERR("Invalid register type\n");
1276 ret = -EINVAL;
1277 goto end;
1278 }
1279 next_pc += sizeof(struct unary_op);
1280 break;
1281 }
1282
1283 case FILTER_OP_UNARY_PLUS_DOUBLE:
1284 case FILTER_OP_UNARY_MINUS_DOUBLE:
1285 case FILTER_OP_UNARY_NOT_DOUBLE:
1286 {
1287 struct unary_op *insn = (struct unary_op *) pc;
1288
1289 if (unlikely(insn->reg >= REG_ERROR)) {
1290 ERR("invalid register %u\n",
1291 (unsigned int) insn->reg);
1292 ret = -EINVAL;
1293 goto end;
1294 }
1295 if (reg[insn->reg].type != REG_DOUBLE) {
1296 ERR("Invalid register type\n");
1297 ret = -EINVAL;
1298 goto end;
1299 }
1300 next_pc += sizeof(struct unary_op);
1301 break;
1302 }
1303
1304 /* logical */
1305 case FILTER_OP_AND:
1306 case FILTER_OP_OR:
1307 {
1308 struct logical_op *insn = (struct logical_op *) pc;
1309
1310 if (reg[REG_R0].type != REG_S64) {
1311 ERR("Logical comparator expects S64 register\n");
1312 ret = -EINVAL;
1313 goto end;
1314 }
1315
1316 dbg_printf("Validate jumping to bytecode offset %u\n",
1317 (unsigned int) insn->skip_offset);
1318 if (unlikely(start_pc + insn->skip_offset <= pc)) {
1319 ERR("Loops are not allowed in bytecode\n");
1320 ret = -EINVAL;
1321 goto end;
1322 }
1323 next_pc += sizeof(struct logical_op);
1324 break;
1325 }
1326
1327 /* load */
1328 case FILTER_OP_LOAD_FIELD_REF:
1329 {
1330 ERR("Unknown field ref type\n");
1331 ret = -EINVAL;
1332 goto end;
1333 }
1334 case FILTER_OP_LOAD_FIELD_REF_STRING:
1335 case FILTER_OP_LOAD_FIELD_REF_SEQUENCE:
1336 {
1337 struct load_op *insn = (struct load_op *) pc;
1338 struct field_ref *ref = (struct field_ref *) insn->data;
1339
1340 if (unlikely(insn->reg >= REG_ERROR)) {
1341 ERR("invalid register %u\n",
1342 (unsigned int) insn->reg);
1343 ret = -EINVAL;
1344 goto end;
1345 }
1346 dbg_printf("Validate load field ref offset %u type string\n",
1347 ref->offset);
1348 reg[insn->reg].type = REG_STRING;
1349 reg[insn->reg].literal = 0;
1350 next_pc += sizeof(struct load_op) + sizeof(struct field_ref);
1351 break;
1352 }
1353 case FILTER_OP_LOAD_FIELD_REF_S64:
1354 {
1355 struct load_op *insn = (struct load_op *) pc;
1356 struct field_ref *ref = (struct field_ref *) insn->data;
1357
1358 if (unlikely(insn->reg >= REG_ERROR)) {
1359 ERR("invalid register %u\n",
1360 (unsigned int) insn->reg);
1361 ret = -EINVAL;
1362 goto end;
1363 }
1364 dbg_printf("Validate load field ref offset %u type s64\n",
1365 ref->offset);
1366 reg[insn->reg].type = REG_S64;
1367 reg[insn->reg].literal = 0;
1368 next_pc += sizeof(struct load_op) + sizeof(struct field_ref);
1369 break;
1370 }
1371 case FILTER_OP_LOAD_FIELD_REF_DOUBLE:
1372 {
1373 struct load_op *insn = (struct load_op *) pc;
1374 struct field_ref *ref = (struct field_ref *) insn->data;
1375
1376 if (unlikely(insn->reg >= REG_ERROR)) {
1377 ERR("invalid register %u\n",
1378 (unsigned int) insn->reg);
1379 ret = -EINVAL;
1380 goto end;
1381 }
1382 dbg_printf("Validate load field ref offset %u type double\n",
1383 ref->offset);
1384 reg[insn->reg].type = REG_DOUBLE;
1385 reg[insn->reg].literal = 0;
1386 next_pc += sizeof(struct load_op) + sizeof(struct field_ref);
1387 break;
1388 }
1389
1390 case FILTER_OP_LOAD_STRING:
1391 {
1392 struct load_op *insn = (struct load_op *) pc;
1393
1394 if (unlikely(insn->reg >= REG_ERROR)) {
1395 ERR("invalid register %u\n",
1396 (unsigned int) insn->reg);
1397 ret = -EINVAL;
1398 goto end;
1399 }
1400 reg[insn->reg].type = REG_STRING;
1401 reg[insn->reg].literal = 1;
1402 next_pc += sizeof(struct load_op) + strlen(insn->data) + 1;
1403 break;
1404 }
1405
1406 case FILTER_OP_LOAD_S64:
1407 {
1408 struct load_op *insn = (struct load_op *) pc;
1409
1410 if (unlikely(insn->reg >= REG_ERROR)) {
1411 ERR("invalid register %u\n",
1412 (unsigned int) insn->reg);
1413 ret = -EINVAL;
1414 goto end;
1415 }
1416 reg[insn->reg].type = REG_S64;
1417 reg[insn->reg].literal = 1;
1418 next_pc += sizeof(struct load_op)
1419 + sizeof(struct literal_numeric);
1420 break;
1421 }
1422
1423 case FILTER_OP_LOAD_DOUBLE:
1424 {
1425 struct load_op *insn = (struct load_op *) pc;
1426
1427 if (unlikely(insn->reg >= REG_ERROR)) {
1428 ERR("invalid register %u\n",
1429 (unsigned int) insn->reg);
1430 ret = -EINVAL;
1431 goto end;
1432 }
1433 reg[insn->reg].type = REG_DOUBLE;
1434 reg[insn->reg].literal = 1;
1435 next_pc += sizeof(struct load_op)
1436 + sizeof(struct literal_double);
1437 break;
1438 }
1439
1440 case FILTER_OP_CAST_TO_S64:
1441 case FILTER_OP_CAST_DOUBLE_TO_S64:
1442 {
1443 struct cast_op *insn = (struct cast_op *) pc;
1444
1445 if (unlikely(insn->reg >= REG_ERROR)) {
1446 ERR("invalid register %u\n",
1447 (unsigned int) insn->reg);
1448 ret = -EINVAL;
1449 goto end;
1450 }
1451 switch (reg[insn->reg].type) {
1452 default:
1453 ERR("unknown register type\n");
1454 ret = -EINVAL;
1455 goto end;
1456
1457 case REG_STRING:
1458 ERR("Cast op can only be applied to numeric or floating point registers\n");
1459 ret = -EINVAL;
1460 goto end;
1461 case REG_S64:
1462 break;
1463 case REG_DOUBLE:
1464 break;
1465 }
1466 if (insn->op == FILTER_OP_CAST_DOUBLE_TO_S64) {
1467 if (reg[insn->reg].type != REG_DOUBLE) {
1468 ERR("Cast expects double\n");
1469 ret = -EINVAL;
1470 goto end;
1471 }
1472 }
1473 reg[insn->reg].type = REG_S64;
1474 next_pc += sizeof(struct cast_op);
1475 break;
1476 }
1477 case FILTER_OP_CAST_NOP:
1478 {
1479 next_pc += sizeof(struct cast_op);
1480 break;
1481 }
1482
1483 }
1484 }
1485 end:
1486 return ret;
1487 }
1488
1489 static
1490 int lttng_filter_specialize_bytecode(struct bytecode_runtime *bytecode)
1491 {
1492 void *pc, *next_pc, *start_pc;
1493 int ret = -EINVAL;
1494 struct vreg reg[NR_REG];
1495 int i;
1496
1497 for (i = 0; i < NR_REG; i++) {
1498 reg[i].type = REG_TYPE_UNKNOWN;
1499 reg[i].literal = 0;
1500 }
1501
1502 start_pc = &bytecode->data[0];
1503 for (pc = next_pc = start_pc; pc - start_pc < bytecode->len;
1504 pc = next_pc) {
1505 switch (*(filter_opcode_t *) pc) {
1506 case FILTER_OP_UNKNOWN:
1507 default:
1508 ERR("unknown bytecode op %u\n",
1509 (unsigned int) *(filter_opcode_t *) pc);
1510 ret = -EINVAL;
1511 goto end;
1512
1513 case FILTER_OP_RETURN:
1514 ret = 0;
1515 goto end;
1516
1517 /* binary */
1518 case FILTER_OP_MUL:
1519 case FILTER_OP_DIV:
1520 case FILTER_OP_MOD:
1521 case FILTER_OP_PLUS:
1522 case FILTER_OP_MINUS:
1523 case FILTER_OP_RSHIFT:
1524 case FILTER_OP_LSHIFT:
1525 case FILTER_OP_BIN_AND:
1526 case FILTER_OP_BIN_OR:
1527 case FILTER_OP_BIN_XOR:
1528 ERR("unsupported bytecode op %u\n",
1529 (unsigned int) *(filter_opcode_t *) pc);
1530 ret = -EINVAL;
1531 goto end;
1532
1533 case FILTER_OP_EQ:
1534 {
1535 struct binary_op *insn = (struct binary_op *) pc;
1536
1537 switch(reg[REG_R0].type) {
1538 default:
1539 ERR("unknown register type\n");
1540 ret = -EINVAL;
1541 goto end;
1542
1543 case REG_STRING:
1544 insn->op = FILTER_OP_EQ_STRING;
1545 break;
1546 case REG_S64:
1547 if (reg[REG_R1].type == REG_S64)
1548 insn->op = FILTER_OP_EQ_S64;
1549 else
1550 insn->op = FILTER_OP_EQ_DOUBLE;
1551 break;
1552 case REG_DOUBLE:
1553 insn->op = FILTER_OP_EQ_DOUBLE;
1554 break;
1555 }
1556 reg[REG_R0].type = REG_S64;
1557 next_pc += sizeof(struct binary_op);
1558 break;
1559 }
1560
1561 case FILTER_OP_NE:
1562 {
1563 struct binary_op *insn = (struct binary_op *) pc;
1564
1565 switch(reg[REG_R0].type) {
1566 default:
1567 ERR("unknown register type\n");
1568 ret = -EINVAL;
1569 goto end;
1570
1571 case REG_STRING:
1572 insn->op = FILTER_OP_NE_STRING;
1573 break;
1574 case REG_S64:
1575 if (reg[REG_R1].type == REG_S64)
1576 insn->op = FILTER_OP_NE_S64;
1577 else
1578 insn->op = FILTER_OP_NE_DOUBLE;
1579 break;
1580 case REG_DOUBLE:
1581 insn->op = FILTER_OP_NE_DOUBLE;
1582 break;
1583 }
1584 reg[REG_R0].type = REG_S64;
1585 next_pc += sizeof(struct binary_op);
1586 break;
1587 }
1588
1589 case FILTER_OP_GT:
1590 {
1591 struct binary_op *insn = (struct binary_op *) pc;
1592
1593 switch(reg[REG_R0].type) {
1594 default:
1595 ERR("unknown register type\n");
1596 ret = -EINVAL;
1597 goto end;
1598
1599 case REG_STRING:
1600 insn->op = FILTER_OP_GT_STRING;
1601 break;
1602 case REG_S64:
1603 if (reg[REG_R1].type == REG_S64)
1604 insn->op = FILTER_OP_GT_S64;
1605 else
1606 insn->op = FILTER_OP_GT_DOUBLE;
1607 break;
1608 case REG_DOUBLE:
1609 insn->op = FILTER_OP_GT_DOUBLE;
1610 break;
1611 }
1612 reg[REG_R0].type = REG_S64;
1613 next_pc += sizeof(struct binary_op);
1614 break;
1615 }
1616
1617 case FILTER_OP_LT:
1618 {
1619 struct binary_op *insn = (struct binary_op *) pc;
1620
1621 switch(reg[REG_R0].type) {
1622 default:
1623 ERR("unknown register type\n");
1624 ret = -EINVAL;
1625 goto end;
1626
1627 case REG_STRING:
1628 insn->op = FILTER_OP_LT_STRING;
1629 break;
1630 case REG_S64:
1631 if (reg[REG_R1].type == REG_S64)
1632 insn->op = FILTER_OP_LT_S64;
1633 else
1634 insn->op = FILTER_OP_LT_DOUBLE;
1635 break;
1636 case REG_DOUBLE:
1637 insn->op = FILTER_OP_LT_DOUBLE;
1638 break;
1639 }
1640 reg[REG_R0].type = REG_S64;
1641 next_pc += sizeof(struct binary_op);
1642 break;
1643 }
1644
1645 case FILTER_OP_GE:
1646 {
1647 struct binary_op *insn = (struct binary_op *) pc;
1648
1649 switch(reg[REG_R0].type) {
1650 default:
1651 ERR("unknown register type\n");
1652 ret = -EINVAL;
1653 goto end;
1654
1655 case REG_STRING:
1656 insn->op = FILTER_OP_GE_STRING;
1657 break;
1658 case REG_S64:
1659 if (reg[REG_R1].type == REG_S64)
1660 insn->op = FILTER_OP_GE_S64;
1661 else
1662 insn->op = FILTER_OP_GE_DOUBLE;
1663 break;
1664 case REG_DOUBLE:
1665 insn->op = FILTER_OP_GE_DOUBLE;
1666 break;
1667 }
1668 reg[REG_R0].type = REG_S64;
1669 next_pc += sizeof(struct binary_op);
1670 break;
1671 }
1672 case FILTER_OP_LE:
1673 {
1674 struct binary_op *insn = (struct binary_op *) pc;
1675
1676 switch(reg[REG_R0].type) {
1677 default:
1678 ERR("unknown register type\n");
1679 ret = -EINVAL;
1680 goto end;
1681
1682 case REG_STRING:
1683 insn->op = FILTER_OP_LE_STRING;
1684 break;
1685 case REG_S64:
1686 if (reg[REG_R1].type == REG_S64)
1687 insn->op = FILTER_OP_LE_S64;
1688 else
1689 insn->op = FILTER_OP_LE_DOUBLE;
1690 break;
1691 case REG_DOUBLE:
1692 insn->op = FILTER_OP_LE_DOUBLE;
1693 break;
1694 }
1695 reg[REG_R0].type = REG_S64;
1696 next_pc += sizeof(struct binary_op);
1697 break;
1698 }
1699
1700 case FILTER_OP_EQ_STRING:
1701 case FILTER_OP_NE_STRING:
1702 case FILTER_OP_GT_STRING:
1703 case FILTER_OP_LT_STRING:
1704 case FILTER_OP_GE_STRING:
1705 case FILTER_OP_LE_STRING:
1706 case FILTER_OP_EQ_S64:
1707 case FILTER_OP_NE_S64:
1708 case FILTER_OP_GT_S64:
1709 case FILTER_OP_LT_S64:
1710 case FILTER_OP_GE_S64:
1711 case FILTER_OP_LE_S64:
1712 case FILTER_OP_EQ_DOUBLE:
1713 case FILTER_OP_NE_DOUBLE:
1714 case FILTER_OP_GT_DOUBLE:
1715 case FILTER_OP_LT_DOUBLE:
1716 case FILTER_OP_GE_DOUBLE:
1717 case FILTER_OP_LE_DOUBLE:
1718 {
1719 reg[REG_R0].type = REG_S64;
1720 next_pc += sizeof(struct binary_op);
1721 break;
1722 }
1723
1724 /* unary */
1725 case FILTER_OP_UNARY_PLUS:
1726 {
1727 struct unary_op *insn = (struct unary_op *) pc;
1728
1729 switch(reg[insn->reg].type) {
1730 default:
1731 ERR("unknown register type\n");
1732 ret = -EINVAL;
1733 goto end;
1734
1735 case REG_S64:
1736 insn->op = FILTER_OP_UNARY_PLUS_S64;
1737 break;
1738 case REG_DOUBLE:
1739 insn->op = FILTER_OP_UNARY_PLUS_DOUBLE;
1740 break;
1741 }
1742 next_pc += sizeof(struct unary_op);
1743 break;
1744 }
1745
1746 case FILTER_OP_UNARY_MINUS:
1747 {
1748 struct unary_op *insn = (struct unary_op *) pc;
1749
1750 switch(reg[insn->reg].type) {
1751 default:
1752 ERR("unknown register type\n");
1753 ret = -EINVAL;
1754 goto end;
1755
1756 case REG_S64:
1757 insn->op = FILTER_OP_UNARY_MINUS_S64;
1758 break;
1759 case REG_DOUBLE:
1760 insn->op = FILTER_OP_UNARY_MINUS_DOUBLE;
1761 break;
1762 }
1763 next_pc += sizeof(struct unary_op);
1764 break;
1765 }
1766
1767 case FILTER_OP_UNARY_NOT:
1768 {
1769 struct unary_op *insn = (struct unary_op *) pc;
1770
1771 switch(reg[insn->reg].type) {
1772 default:
1773 ERR("unknown register type\n");
1774 ret = -EINVAL;
1775 goto end;
1776
1777 case REG_S64:
1778 insn->op = FILTER_OP_UNARY_NOT_S64;
1779 break;
1780 case REG_DOUBLE:
1781 insn->op = FILTER_OP_UNARY_NOT_DOUBLE;
1782 break;
1783 }
1784 next_pc += sizeof(struct unary_op);
1785 break;
1786 }
1787
1788 case FILTER_OP_UNARY_PLUS_S64:
1789 case FILTER_OP_UNARY_MINUS_S64:
1790 case FILTER_OP_UNARY_NOT_S64:
1791 case FILTER_OP_UNARY_PLUS_DOUBLE:
1792 case FILTER_OP_UNARY_MINUS_DOUBLE:
1793 case FILTER_OP_UNARY_NOT_DOUBLE:
1794 {
1795 next_pc += sizeof(struct unary_op);
1796 break;
1797 }
1798
1799 /* logical */
1800 case FILTER_OP_AND:
1801 case FILTER_OP_OR:
1802 {
1803 next_pc += sizeof(struct logical_op);
1804 break;
1805 }
1806
1807 /* load */
1808 case FILTER_OP_LOAD_FIELD_REF:
1809 {
1810 ERR("Unknown field ref type\n");
1811 ret = -EINVAL;
1812 goto end;
1813 }
1814 case FILTER_OP_LOAD_FIELD_REF_STRING:
1815 case FILTER_OP_LOAD_FIELD_REF_SEQUENCE:
1816 {
1817 struct load_op *insn = (struct load_op *) pc;
1818
1819 reg[insn->reg].type = REG_STRING;
1820 reg[insn->reg].literal = 0;
1821 next_pc += sizeof(struct load_op) + sizeof(struct field_ref);
1822 break;
1823 }
1824 case FILTER_OP_LOAD_FIELD_REF_S64:
1825 {
1826 struct load_op *insn = (struct load_op *) pc;
1827
1828 reg[insn->reg].type = REG_S64;
1829 reg[insn->reg].literal = 0;
1830 next_pc += sizeof(struct load_op) + sizeof(struct field_ref);
1831 break;
1832 }
1833 case FILTER_OP_LOAD_FIELD_REF_DOUBLE:
1834 {
1835 struct load_op *insn = (struct load_op *) pc;
1836
1837 reg[insn->reg].type = REG_DOUBLE;
1838 reg[insn->reg].literal = 0;
1839 next_pc += sizeof(struct load_op) + sizeof(struct field_ref);
1840 break;
1841 }
1842
1843 case FILTER_OP_LOAD_STRING:
1844 {
1845 struct load_op *insn = (struct load_op *) pc;
1846
1847 reg[insn->reg].type = REG_STRING;
1848 reg[insn->reg].literal = 1;
1849 next_pc += sizeof(struct load_op) + strlen(insn->data) + 1;
1850 break;
1851 }
1852
1853 case FILTER_OP_LOAD_S64:
1854 {
1855 struct load_op *insn = (struct load_op *) pc;
1856
1857 reg[insn->reg].type = REG_S64;
1858 reg[insn->reg].literal = 1;
1859 next_pc += sizeof(struct load_op)
1860 + sizeof(struct literal_numeric);
1861 break;
1862 }
1863
1864 case FILTER_OP_LOAD_DOUBLE:
1865 {
1866 struct load_op *insn = (struct load_op *) pc;
1867
1868 reg[insn->reg].type = REG_DOUBLE;
1869 reg[insn->reg].literal = 1;
1870 next_pc += sizeof(struct load_op)
1871 + sizeof(struct literal_double);
1872 break;
1873 }
1874
1875 /* cast */
1876 case FILTER_OP_CAST_TO_S64:
1877 {
1878 struct cast_op *insn = (struct cast_op *) pc;
1879
1880 switch (reg[insn->reg].type) {
1881 default:
1882 ERR("unknown register type\n");
1883 ret = -EINVAL;
1884 goto end;
1885
1886 case REG_STRING:
1887 ERR("Cast op can only be applied to numeric or floating point registers\n");
1888 ret = -EINVAL;
1889 goto end;
1890 case REG_S64:
1891 insn->op = FILTER_OP_CAST_NOP;
1892 break;
1893 case REG_DOUBLE:
1894 insn->op = FILTER_OP_CAST_DOUBLE_TO_S64;
1895 break;
1896 }
1897 reg[insn->reg].type = REG_S64;
1898 next_pc += sizeof(struct cast_op);
1899 break;
1900 }
1901 case FILTER_OP_CAST_DOUBLE_TO_S64:
1902 {
1903 struct cast_op *insn = (struct cast_op *) pc;
1904
1905 reg[insn->reg].type = REG_S64;
1906 next_pc += sizeof(struct cast_op);
1907 break;
1908 }
1909 case FILTER_OP_CAST_NOP:
1910 {
1911 next_pc += sizeof(struct cast_op);
1912 break;
1913 }
1914
1915
1916 }
1917 }
1918 end:
1919 return ret;
1920 }
1921
1922 static
1923 int apply_field_reloc(struct ltt_event *event,
1924 struct bytecode_runtime *runtime,
1925 uint32_t runtime_len,
1926 uint32_t reloc_offset,
1927 const char *field_name)
1928 {
1929 const struct lttng_event_desc *desc;
1930 const struct lttng_event_field *fields, *field = NULL;
1931 unsigned int nr_fields, i;
1932 struct field_ref *field_ref;
1933 struct load_op *op;
1934 uint32_t field_offset = 0;
1935
1936 dbg_printf("Apply reloc: %u %s\n", reloc_offset, field_name);
1937
1938 /* Ensure that the reloc is within the code */
1939 if (runtime_len - reloc_offset < sizeof(uint16_t))
1940 return -EINVAL;
1941
1942 /* Lookup event by name */
1943 desc = event->desc;
1944 if (!desc)
1945 return -EINVAL;
1946 fields = desc->fields;
1947 if (!fields)
1948 return -EINVAL;
1949 nr_fields = desc->nr_fields;
1950 for (i = 0; i < nr_fields; i++) {
1951 if (!strcmp(fields[i].name, field_name)) {
1952 field = &fields[i];
1953 break;
1954 }
1955 /* compute field offset */
1956 switch (fields[i].type.atype) {
1957 case atype_integer:
1958 case atype_enum:
1959 field_offset += sizeof(int64_t);
1960 break;
1961 case atype_array:
1962 case atype_sequence:
1963 field_offset += sizeof(unsigned long);
1964 field_offset += sizeof(void *);
1965 break;
1966 case atype_string:
1967 field_offset += sizeof(void *);
1968 break;
1969 case atype_float:
1970 field_offset += sizeof(double);
1971 break;
1972 default:
1973 return -EINVAL;
1974 }
1975 }
1976 if (!field)
1977 return -EINVAL;
1978
1979 /* Check if field offset is too large for 16-bit offset */
1980 if (field_offset > FILTER_BYTECODE_MAX_LEN)
1981 return -EINVAL;
1982
1983 /* set type */
1984 op = (struct load_op *) &runtime->data[reloc_offset];
1985 field_ref = (struct field_ref *) op->data;
1986 switch (field->type.atype) {
1987 case atype_integer:
1988 case atype_enum:
1989 op->op = FILTER_OP_LOAD_FIELD_REF_S64;
1990 break;
1991 case atype_array:
1992 case atype_sequence:
1993 op->op = FILTER_OP_LOAD_FIELD_REF_SEQUENCE;
1994 break;
1995 case atype_string:
1996 op->op = FILTER_OP_LOAD_FIELD_REF_STRING;
1997 break;
1998 case atype_float:
1999 op->op = FILTER_OP_LOAD_FIELD_REF_DOUBLE;
2000 break;
2001 default:
2002 return -EINVAL;
2003 }
2004 /* set offset */
2005 field_ref->offset = (uint16_t) field_offset;
2006 return 0;
2007 }
2008
2009 /*
2010 * Take a bytecode with reloc table and link it to an event to create a
2011 * bytecode runtime.
2012 */
2013 static
2014 int _lttng_filter_event_link_bytecode(struct ltt_event *event,
2015 struct lttng_ust_filter_bytecode *filter_bytecode)
2016 {
2017 int ret, offset, next_offset;
2018 struct bytecode_runtime *runtime = NULL;
2019 size_t runtime_alloc_len;
2020
2021 if (!filter_bytecode)
2022 return 0;
2023 /* Even is not connected to any description */
2024 if (!event->desc)
2025 return 0;
2026 /* Bytecode already linked */
2027 if (event->filter || event->filter_data)
2028 return 0;
2029
2030 dbg_printf("Linking\n");
2031
2032 /* We don't need the reloc table in the runtime */
2033 runtime_alloc_len = sizeof(*runtime) + filter_bytecode->reloc_offset;
2034 runtime = zmalloc(runtime_alloc_len);
2035 if (!runtime) {
2036 ret = -ENOMEM;
2037 goto link_error;
2038 }
2039 runtime->len = filter_bytecode->reloc_offset;
2040 /* copy original bytecode */
2041 memcpy(runtime->data, filter_bytecode->data, runtime->len);
2042 /*
2043 * apply relocs. Those are a uint16_t (offset in bytecode)
2044 * followed by a string (field name).
2045 */
2046 for (offset = filter_bytecode->reloc_offset;
2047 offset < filter_bytecode->len;
2048 offset = next_offset) {
2049 uint16_t reloc_offset =
2050 *(uint16_t *) &filter_bytecode->data[offset];
2051 const char *field_name =
2052 (const char *) &filter_bytecode->data[offset + sizeof(uint16_t)];
2053
2054 ret = apply_field_reloc(event, runtime, runtime->len, reloc_offset, field_name);
2055 if (ret) {
2056 goto link_error;
2057 }
2058 next_offset = offset + sizeof(uint16_t) + strlen(field_name) + 1;
2059 }
2060 /* Validate bytecode */
2061 ret = lttng_filter_validate_bytecode(runtime);
2062 if (ret) {
2063 goto link_error;
2064 }
2065 /* Specialize bytecode */
2066 ret = lttng_filter_specialize_bytecode(runtime);
2067 if (ret) {
2068 goto link_error;
2069 }
2070 event->filter_data = runtime;
2071 event->filter = lttng_filter_interpret_bytecode;
2072 return 0;
2073
2074 link_error:
2075 event->filter = lttng_filter_false;
2076 free(runtime);
2077 return ret;
2078 }
2079
2080 void lttng_filter_event_link_bytecode(struct ltt_event *event,
2081 struct lttng_ust_filter_bytecode *filter_bytecode)
2082 {
2083 int ret;
2084
2085 ret = _lttng_filter_event_link_bytecode(event, filter_bytecode);
2086 if (ret) {
2087 fprintf(stderr, "[lttng filter] error linking event bytecode\n");
2088 }
2089 }
2090
2091 /*
2092 * Link bytecode to all events for a wildcard. Skips events that already
2093 * have a bytecode linked.
2094 * We do not set each event's filter_bytecode field, because they do not
2095 * own the filter_bytecode: the wildcard owns it.
2096 */
2097 void lttng_filter_wildcard_link_bytecode(struct session_wildcard *wildcard)
2098 {
2099 struct ltt_event *event;
2100 int ret;
2101
2102 if (!wildcard->filter_bytecode)
2103 return;
2104
2105 cds_list_for_each_entry(event, &wildcard->events, wildcard_list) {
2106 if (event->filter)
2107 continue;
2108 ret = _lttng_filter_event_link_bytecode(event,
2109 wildcard->filter_bytecode);
2110 if (ret) {
2111 fprintf(stderr, "[lttng filter] error linking wildcard bytecode\n");
2112 }
2113
2114 }
2115 return;
2116 }
2117
2118 /*
2119 * Need to attach filter to an event before starting tracing for the
2120 * session. We own the filter_bytecode if we return success.
2121 */
2122 int lttng_filter_event_attach_bytecode(struct ltt_event *event,
2123 struct lttng_ust_filter_bytecode *filter_bytecode)
2124 {
2125 if (event->chan->session->been_active)
2126 return -EPERM;
2127 if (event->filter_bytecode)
2128 return -EEXIST;
2129 event->filter_bytecode = filter_bytecode;
2130 return 0;
2131 }
2132
2133 /*
2134 * Need to attach filter to a wildcard before starting tracing for the
2135 * session. We own the filter_bytecode if we return success.
2136 */
2137 int lttng_filter_wildcard_attach_bytecode(struct session_wildcard *wildcard,
2138 struct lttng_ust_filter_bytecode *filter_bytecode)
2139 {
2140 if (wildcard->chan->session->been_active)
2141 return -EPERM;
2142 if (wildcard->filter_bytecode)
2143 return -EEXIST;
2144 wildcard->filter_bytecode = filter_bytecode;
2145 return 0;
2146 }
This page took 0.102909 seconds and 5 git commands to generate.