bytecode: set register type to `REG_PTR` even if not used
[deliverable/lttng-ust.git] / liblttng-ust / lttng-filter-interpreter.c
1 /*
2 * lttng-filter-interpreter.c
3 *
4 * LTTng UST filter interpreter.
5 *
6 * Copyright (C) 2010-2016 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
7 *
8 * Permission is hereby granted, free of charge, to any person obtaining a copy
9 * of this software and associated documentation files (the "Software"), to deal
10 * in the Software without restriction, including without limitation the rights
11 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12 * copies of the Software, and to permit persons to whom the Software is
13 * furnished to do so, subject to the following conditions:
14 *
15 * The above copyright notice and this permission notice shall be included in
16 * all copies or substantial portions of the Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24 * SOFTWARE.
25 */
26
27 #define _LGPL_SOURCE
28 #include <stddef.h>
29 #include <stdint.h>
30 #include <urcu-pointer.h>
31 #include <byteswap.h>
32
33 #include <lttng/ust-endian.h>
34 #include <lttng/ust-events.h>
35
36 #include "lttng-filter.h"
37 #include "string-utils.h"
38
39
40 /*
41 * -1: wildcard found.
42 * -2: unknown escape char.
43 * 0: normal char.
44 */
45
46 static
47 int parse_char(const char **p)
48 {
49 switch (**p) {
50 case '\\':
51 (*p)++;
52 switch (**p) {
53 case '\\':
54 case '*':
55 return 0;
56 default:
57 return -2;
58 }
59 case '*':
60 return -1;
61 default:
62 return 0;
63 }
64 }
65
66 /*
67 * Returns SIZE_MAX if the string is null-terminated, or the number of
68 * characters if not.
69 */
70 static
71 size_t get_str_or_seq_len(const struct estack_entry *entry)
72 {
73 return entry->u.s.seq_len;
74 }
75
76 static
77 int stack_star_glob_match(struct estack *stack, int top, const char *cmp_type)
78 {
79 const char *pattern;
80 const char *candidate;
81 size_t pattern_len;
82 size_t candidate_len;
83
84 /* Find out which side is the pattern vs. the candidate. */
85 if (estack_ax(stack, top)->u.s.literal_type == ESTACK_STRING_LITERAL_TYPE_STAR_GLOB) {
86 pattern = estack_ax(stack, top)->u.s.str;
87 pattern_len = get_str_or_seq_len(estack_ax(stack, top));
88 candidate = estack_bx(stack, top)->u.s.str;
89 candidate_len = get_str_or_seq_len(estack_bx(stack, top));
90 } else {
91 pattern = estack_bx(stack, top)->u.s.str;
92 pattern_len = get_str_or_seq_len(estack_bx(stack, top));
93 candidate = estack_ax(stack, top)->u.s.str;
94 candidate_len = get_str_or_seq_len(estack_ax(stack, top));
95 }
96
97 /* Perform the match. Returns 0 when the result is true. */
98 return !strutils_star_glob_match(pattern, pattern_len, candidate,
99 candidate_len);
100 }
101
102 static
103 int stack_strcmp(struct estack *stack, int top, const char *cmp_type)
104 {
105 const char *p = estack_bx(stack, top)->u.s.str, *q = estack_ax(stack, top)->u.s.str;
106 int ret;
107 int diff;
108
109 for (;;) {
110 int escaped_r0 = 0;
111
112 if (unlikely(p - estack_bx(stack, top)->u.s.str >= estack_bx(stack, top)->u.s.seq_len || *p == '\0')) {
113 if (q - estack_ax(stack, top)->u.s.str >= estack_ax(stack, top)->u.s.seq_len || *q == '\0') {
114 return 0;
115 } else {
116 if (estack_ax(stack, top)->u.s.literal_type ==
117 ESTACK_STRING_LITERAL_TYPE_PLAIN) {
118 ret = parse_char(&q);
119 if (ret == -1)
120 return 0;
121 }
122 return -1;
123 }
124 }
125 if (unlikely(q - estack_ax(stack, top)->u.s.str >= estack_ax(stack, top)->u.s.seq_len || *q == '\0')) {
126 if (estack_bx(stack, top)->u.s.literal_type ==
127 ESTACK_STRING_LITERAL_TYPE_PLAIN) {
128 ret = parse_char(&p);
129 if (ret == -1)
130 return 0;
131 }
132 return 1;
133 }
134 if (estack_bx(stack, top)->u.s.literal_type ==
135 ESTACK_STRING_LITERAL_TYPE_PLAIN) {
136 ret = parse_char(&p);
137 if (ret == -1) {
138 return 0;
139 } else if (ret == -2) {
140 escaped_r0 = 1;
141 }
142 /* else compare both char */
143 }
144 if (estack_ax(stack, top)->u.s.literal_type ==
145 ESTACK_STRING_LITERAL_TYPE_PLAIN) {
146 ret = parse_char(&q);
147 if (ret == -1) {
148 return 0;
149 } else if (ret == -2) {
150 if (!escaped_r0)
151 return -1;
152 } else {
153 if (escaped_r0)
154 return 1;
155 }
156 } else {
157 if (escaped_r0)
158 return 1;
159 }
160 diff = *p - *q;
161 if (diff != 0)
162 break;
163 p++;
164 q++;
165 }
166 return diff;
167 }
168
169 uint64_t lttng_filter_interpret_bytecode_false(void *filter_data,
170 const char *filter_stack_data)
171 {
172 return LTTNG_FILTER_DISCARD;
173 }
174
175 #ifdef INTERPRETER_USE_SWITCH
176
177 /*
178 * Fallback for compilers that do not support taking address of labels.
179 */
180
181 #define START_OP \
182 start_pc = &bytecode->data[0]; \
183 for (pc = next_pc = start_pc; pc - start_pc < bytecode->len; \
184 pc = next_pc) { \
185 dbg_printf("Executing op %s (%u)\n", \
186 print_op((unsigned int) *(filter_opcode_t *) pc), \
187 (unsigned int) *(filter_opcode_t *) pc); \
188 switch (*(filter_opcode_t *) pc) {
189
190 #define OP(name) jump_target_##name: __attribute__((unused)); \
191 case name
192
193 #define PO break
194
195 #define END_OP } \
196 }
197
198 #define JUMP_TO(name) \
199 goto jump_target_##name
200
201 #else
202
203 /*
204 * Dispatch-table based interpreter.
205 */
206
207 #define START_OP \
208 start_pc = &bytecode->code[0]; \
209 pc = next_pc = start_pc; \
210 if (unlikely(pc - start_pc >= bytecode->len)) \
211 goto end; \
212 goto *dispatch[*(filter_opcode_t *) pc];
213
214 #define OP(name) \
215 LABEL_##name
216
217 #define PO \
218 pc = next_pc; \
219 goto *dispatch[*(filter_opcode_t *) pc];
220
221 #define END_OP
222
223 #define JUMP_TO(name) \
224 goto LABEL_##name
225
226 #endif
227
228 #define IS_INTEGER_REGISTER(reg_type) \
229 (reg_type == REG_U64 || reg_type == REG_S64)
230
231 static int context_get_index(struct lttng_ctx *ctx,
232 struct load_ptr *ptr,
233 uint32_t idx)
234 {
235
236 struct lttng_ctx_field *ctx_field;
237 struct lttng_event_field *field;
238 struct lttng_ctx_value v;
239
240 ctx_field = &ctx->fields[idx];
241 field = &ctx_field->event_field;
242 ptr->type = LOAD_OBJECT;
243 ptr->field = field;
244
245 switch (field->type.atype) {
246 case atype_integer:
247 ctx_field->get_value(ctx_field, &v);
248 if (field->type.u.integer.signedness) {
249 ptr->object_type = OBJECT_TYPE_S64;
250 ptr->u.s64 = v.u.s64;
251 ptr->ptr = &ptr->u.s64;
252 } else {
253 ptr->object_type = OBJECT_TYPE_U64;
254 ptr->u.u64 = v.u.s64; /* Cast. */
255 ptr->ptr = &ptr->u.u64;
256 }
257 break;
258 case atype_enum: /* Fall-through */
259 case atype_enum_nestable:
260 {
261 const struct lttng_integer_type *itype;
262
263 if (field->type.atype == atype_enum) {
264 itype = &field->type.u.legacy.basic.enumeration.container_type;
265 } else {
266 itype = &field->type.u.enum_nestable.container_type->u.integer;
267 }
268 ctx_field->get_value(ctx_field, &v);
269 if (itype->signedness) {
270 ptr->object_type = OBJECT_TYPE_S64;
271 ptr->u.s64 = v.u.s64;
272 ptr->ptr = &ptr->u.s64;
273 } else {
274 ptr->object_type = OBJECT_TYPE_U64;
275 ptr->u.u64 = v.u.s64; /* Cast. */
276 ptr->ptr = &ptr->u.u64;
277 }
278 break;
279 }
280 case atype_array:
281 if (field->type.u.legacy.array.elem_type.atype != atype_integer) {
282 ERR("Array nesting only supports integer types.");
283 return -EINVAL;
284 }
285 if (field->type.u.legacy.array.elem_type.u.basic.integer.encoding == lttng_encode_none) {
286 ERR("Only string arrays are supported for contexts.");
287 return -EINVAL;
288 }
289 ptr->object_type = OBJECT_TYPE_STRING;
290 ctx_field->get_value(ctx_field, &v);
291 ptr->ptr = v.u.str;
292 break;
293 case atype_array_nestable:
294 if (field->type.u.array_nestable.elem_type->atype != atype_integer) {
295 ERR("Array nesting only supports integer types.");
296 return -EINVAL;
297 }
298 if (field->type.u.array_nestable.elem_type->u.integer.encoding == lttng_encode_none) {
299 ERR("Only string arrays are supported for contexts.");
300 return -EINVAL;
301 }
302 ptr->object_type = OBJECT_TYPE_STRING;
303 ctx_field->get_value(ctx_field, &v);
304 ptr->ptr = v.u.str;
305 break;
306 case atype_sequence:
307 if (field->type.u.legacy.sequence.elem_type.atype != atype_integer) {
308 ERR("Sequence nesting only supports integer types.");
309 return -EINVAL;
310 }
311 if (field->type.u.legacy.sequence.elem_type.u.basic.integer.encoding == lttng_encode_none) {
312 ERR("Only string sequences are supported for contexts.");
313 return -EINVAL;
314 }
315 ptr->object_type = OBJECT_TYPE_STRING;
316 ctx_field->get_value(ctx_field, &v);
317 ptr->ptr = v.u.str;
318 break;
319 case atype_sequence_nestable:
320 if (field->type.u.sequence_nestable.elem_type->atype != atype_integer) {
321 ERR("Sequence nesting only supports integer types.");
322 return -EINVAL;
323 }
324 if (field->type.u.sequence_nestable.elem_type->u.integer.encoding == lttng_encode_none) {
325 ERR("Only string sequences are supported for contexts.");
326 return -EINVAL;
327 }
328 ptr->object_type = OBJECT_TYPE_STRING;
329 ctx_field->get_value(ctx_field, &v);
330 ptr->ptr = v.u.str;
331 break;
332 case atype_string:
333 ptr->object_type = OBJECT_TYPE_STRING;
334 ctx_field->get_value(ctx_field, &v);
335 ptr->ptr = v.u.str;
336 break;
337 case atype_float:
338 ptr->object_type = OBJECT_TYPE_DOUBLE;
339 ctx_field->get_value(ctx_field, &v);
340 ptr->u.d = v.u.d;
341 ptr->ptr = &ptr->u.d;
342 break;
343 case atype_dynamic:
344 ctx_field->get_value(ctx_field, &v);
345 switch (v.sel) {
346 case LTTNG_UST_DYNAMIC_TYPE_NONE:
347 return -EINVAL;
348 case LTTNG_UST_DYNAMIC_TYPE_S64:
349 ptr->object_type = OBJECT_TYPE_S64;
350 ptr->u.s64 = v.u.s64;
351 ptr->ptr = &ptr->u.s64;
352 dbg_printf("context get index dynamic s64 %" PRIi64 "\n", ptr->u.s64);
353 break;
354 case LTTNG_UST_DYNAMIC_TYPE_DOUBLE:
355 ptr->object_type = OBJECT_TYPE_DOUBLE;
356 ptr->u.d = v.u.d;
357 ptr->ptr = &ptr->u.d;
358 dbg_printf("context get index dynamic double %g\n", ptr->u.d);
359 break;
360 case LTTNG_UST_DYNAMIC_TYPE_STRING:
361 ptr->object_type = OBJECT_TYPE_STRING;
362 ptr->ptr = v.u.str;
363 dbg_printf("context get index dynamic string %s\n", (const char *) ptr->ptr);
364 break;
365 default:
366 dbg_printf("Filter warning: unknown dynamic type (%d).\n", (int) v.sel);
367 return -EINVAL;
368 }
369 break;
370 case atype_struct:
371 ERR("Structure type cannot be loaded.");
372 return -EINVAL;
373 default:
374 ERR("Unknown type: %d", (int) field->type.atype);
375 return -EINVAL;
376 }
377 return 0;
378 }
379
380 static int dynamic_get_index(struct lttng_ctx *ctx,
381 struct bytecode_runtime *runtime,
382 uint64_t index, struct estack_entry *stack_top)
383 {
384 int ret;
385 const struct filter_get_index_data *gid;
386
387 gid = (const struct filter_get_index_data *) &runtime->data[index];
388 switch (stack_top->u.ptr.type) {
389 case LOAD_OBJECT:
390 switch (stack_top->u.ptr.object_type) {
391 case OBJECT_TYPE_ARRAY:
392 {
393 const char *ptr;
394
395 assert(gid->offset < gid->array_len);
396 /* Skip count (unsigned long) */
397 ptr = *(const char **) (stack_top->u.ptr.ptr + sizeof(unsigned long));
398 ptr = ptr + gid->offset;
399 stack_top->u.ptr.ptr = ptr;
400 stack_top->u.ptr.object_type = gid->elem.type;
401 stack_top->u.ptr.rev_bo = gid->elem.rev_bo;
402 assert(stack_top->u.ptr.field->type.atype == atype_array ||
403 stack_top->u.ptr.field->type.atype == atype_array_nestable);
404 stack_top->u.ptr.field = NULL;
405 break;
406 }
407 case OBJECT_TYPE_SEQUENCE:
408 {
409 const char *ptr;
410 size_t ptr_seq_len;
411
412 ptr = *(const char **) (stack_top->u.ptr.ptr + sizeof(unsigned long));
413 ptr_seq_len = *(unsigned long *) stack_top->u.ptr.ptr;
414 if (gid->offset >= gid->elem.len * ptr_seq_len) {
415 ret = -EINVAL;
416 goto end;
417 }
418 ptr = ptr + gid->offset;
419 stack_top->u.ptr.ptr = ptr;
420 stack_top->u.ptr.object_type = gid->elem.type;
421 stack_top->u.ptr.rev_bo = gid->elem.rev_bo;
422 assert(stack_top->u.ptr.field->type.atype == atype_sequence ||
423 stack_top->u.ptr.field->type.atype == atype_sequence_nestable);
424 stack_top->u.ptr.field = NULL;
425 break;
426 }
427 case OBJECT_TYPE_STRUCT:
428 ERR("Nested structures are not supported yet.");
429 ret = -EINVAL;
430 goto end;
431 case OBJECT_TYPE_VARIANT:
432 default:
433 ERR("Unexpected get index type %d",
434 (int) stack_top->u.ptr.object_type);
435 ret = -EINVAL;
436 goto end;
437 }
438 break;
439 case LOAD_ROOT_CONTEXT:
440 case LOAD_ROOT_APP_CONTEXT: /* Fall-through */
441 {
442 ret = context_get_index(ctx,
443 &stack_top->u.ptr,
444 gid->ctx_index);
445 if (ret) {
446 goto end;
447 }
448 break;
449 }
450 case LOAD_ROOT_PAYLOAD:
451 stack_top->u.ptr.ptr += gid->offset;
452 if (gid->elem.type == OBJECT_TYPE_STRING)
453 stack_top->u.ptr.ptr = *(const char * const *) stack_top->u.ptr.ptr;
454 stack_top->u.ptr.object_type = gid->elem.type;
455 stack_top->u.ptr.type = LOAD_OBJECT;
456 stack_top->u.ptr.field = gid->field;
457 break;
458 }
459
460 stack_top->type = REG_PTR;
461
462 return 0;
463
464 end:
465 return ret;
466 }
467
468 static int dynamic_load_field(struct estack_entry *stack_top)
469 {
470 int ret;
471
472 switch (stack_top->u.ptr.type) {
473 case LOAD_OBJECT:
474 break;
475 case LOAD_ROOT_CONTEXT:
476 case LOAD_ROOT_APP_CONTEXT:
477 case LOAD_ROOT_PAYLOAD:
478 default:
479 dbg_printf("Filter warning: cannot load root, missing field name.\n");
480 ret = -EINVAL;
481 goto end;
482 }
483 switch (stack_top->u.ptr.object_type) {
484 case OBJECT_TYPE_S8:
485 dbg_printf("op load field s8\n");
486 stack_top->u.v = *(int8_t *) stack_top->u.ptr.ptr;
487 stack_top->type = REG_S64;
488 break;
489 case OBJECT_TYPE_S16:
490 {
491 int16_t tmp;
492
493 dbg_printf("op load field s16\n");
494 tmp = *(int16_t *) stack_top->u.ptr.ptr;
495 if (stack_top->u.ptr.rev_bo)
496 tmp = bswap_16(tmp);
497 stack_top->u.v = tmp;
498 stack_top->type = REG_S64;
499 break;
500 }
501 case OBJECT_TYPE_S32:
502 {
503 int32_t tmp;
504
505 dbg_printf("op load field s32\n");
506 tmp = *(int32_t *) stack_top->u.ptr.ptr;
507 if (stack_top->u.ptr.rev_bo)
508 tmp = bswap_32(tmp);
509 stack_top->u.v = tmp;
510 stack_top->type = REG_S64;
511 break;
512 }
513 case OBJECT_TYPE_S64:
514 {
515 int64_t tmp;
516
517 dbg_printf("op load field s64\n");
518 tmp = *(int64_t *) stack_top->u.ptr.ptr;
519 if (stack_top->u.ptr.rev_bo)
520 tmp = bswap_64(tmp);
521 stack_top->u.v = tmp;
522 stack_top->type = REG_S64;
523 break;
524 }
525 case OBJECT_TYPE_U8:
526 dbg_printf("op load field u8\n");
527 stack_top->u.v = *(uint8_t *) stack_top->u.ptr.ptr;
528 stack_top->type = REG_U64;
529 break;
530 case OBJECT_TYPE_U16:
531 {
532 uint16_t tmp;
533
534 dbg_printf("op load field u16\n");
535 tmp = *(uint16_t *) stack_top->u.ptr.ptr;
536 if (stack_top->u.ptr.rev_bo)
537 tmp = bswap_16(tmp);
538 stack_top->u.v = tmp;
539 stack_top->type = REG_U64;
540 break;
541 }
542 case OBJECT_TYPE_U32:
543 {
544 uint32_t tmp;
545
546 dbg_printf("op load field u32\n");
547 tmp = *(uint32_t *) stack_top->u.ptr.ptr;
548 if (stack_top->u.ptr.rev_bo)
549 tmp = bswap_32(tmp);
550 stack_top->u.v = tmp;
551 stack_top->type = REG_U64;
552 break;
553 }
554 case OBJECT_TYPE_U64:
555 {
556 uint64_t tmp;
557
558 dbg_printf("op load field u64\n");
559 tmp = *(uint64_t *) stack_top->u.ptr.ptr;
560 if (stack_top->u.ptr.rev_bo)
561 tmp = bswap_64(tmp);
562 stack_top->u.v = tmp;
563 stack_top->type = REG_U64;
564 break;
565 }
566 case OBJECT_TYPE_DOUBLE:
567 memcpy(&stack_top->u.d,
568 stack_top->u.ptr.ptr,
569 sizeof(struct literal_double));
570 stack_top->type = REG_DOUBLE;
571 break;
572 case OBJECT_TYPE_STRING:
573 {
574 const char *str;
575
576 dbg_printf("op load field string\n");
577 str = (const char *) stack_top->u.ptr.ptr;
578 stack_top->u.s.str = str;
579 if (unlikely(!stack_top->u.s.str)) {
580 dbg_printf("Filter warning: loading a NULL string.\n");
581 ret = -EINVAL;
582 goto end;
583 }
584 stack_top->u.s.seq_len = SIZE_MAX;
585 stack_top->u.s.literal_type =
586 ESTACK_STRING_LITERAL_TYPE_NONE;
587 stack_top->type = REG_STRING;
588 break;
589 }
590 case OBJECT_TYPE_STRING_SEQUENCE:
591 {
592 const char *ptr;
593
594 dbg_printf("op load field string sequence\n");
595 ptr = stack_top->u.ptr.ptr;
596 stack_top->u.s.seq_len = *(unsigned long *) ptr;
597 stack_top->u.s.str = *(const char **) (ptr + sizeof(unsigned long));
598 stack_top->type = REG_STRING;
599 if (unlikely(!stack_top->u.s.str)) {
600 dbg_printf("Filter warning: loading a NULL sequence.\n");
601 ret = -EINVAL;
602 goto end;
603 }
604 stack_top->u.s.literal_type =
605 ESTACK_STRING_LITERAL_TYPE_NONE;
606 break;
607 }
608 case OBJECT_TYPE_DYNAMIC:
609 /*
610 * Dynamic types in context are looked up
611 * by context get index.
612 */
613 ret = -EINVAL;
614 goto end;
615 case OBJECT_TYPE_SEQUENCE:
616 case OBJECT_TYPE_ARRAY:
617 case OBJECT_TYPE_STRUCT:
618 case OBJECT_TYPE_VARIANT:
619 ERR("Sequences, arrays, struct and variant cannot be loaded (nested types).");
620 ret = -EINVAL;
621 goto end;
622 }
623 return 0;
624
625 end:
626 return ret;
627 }
628
629 static
630 int lttng_bytecode_interpret_format_output(struct estack_entry *ax,
631 struct lttng_interpreter_output *output)
632 {
633 int ret;
634
635 again:
636 switch (ax->type) {
637 case REG_S64:
638 output->type = LTTNG_INTERPRETER_TYPE_S64;
639 output->u.s = ax->u.v;
640 break;
641 case REG_U64:
642 output->type = LTTNG_INTERPRETER_TYPE_U64;
643 output->u.u = (uint64_t) ax->u.v;
644 break;
645 case REG_DOUBLE:
646 output->type = LTTNG_INTERPRETER_TYPE_DOUBLE;
647 output->u.d = ax->u.d;
648 break;
649 case REG_STRING:
650 output->type = LTTNG_INTERPRETER_TYPE_STRING;
651 output->u.str.str = ax->u.s.str;
652 output->u.str.len = ax->u.s.seq_len;
653 break;
654 case REG_PTR:
655 switch (ax->u.ptr.object_type) {
656 case OBJECT_TYPE_S8:
657 case OBJECT_TYPE_S16:
658 case OBJECT_TYPE_S32:
659 case OBJECT_TYPE_S64:
660 case OBJECT_TYPE_U8:
661 case OBJECT_TYPE_U16:
662 case OBJECT_TYPE_U32:
663 case OBJECT_TYPE_U64:
664 case OBJECT_TYPE_DOUBLE:
665 case OBJECT_TYPE_STRING:
666 case OBJECT_TYPE_STRING_SEQUENCE:
667 ret = dynamic_load_field(ax);
668 if (ret)
669 return ret;
670 /* Retry after loading ptr into stack top. */
671 goto again;
672 case OBJECT_TYPE_SEQUENCE:
673 output->type = LTTNG_INTERPRETER_TYPE_SEQUENCE;
674 output->u.sequence.ptr = *(const char **) (ax->u.ptr.ptr + sizeof(unsigned long));
675 output->u.sequence.nr_elem = *(unsigned long *) ax->u.ptr.ptr;
676 output->u.sequence.nested_type = ax->u.ptr.field->type.u.sequence_nestable.elem_type;
677 break;
678 case OBJECT_TYPE_ARRAY:
679 /* Skip count (unsigned long) */
680 output->type = LTTNG_INTERPRETER_TYPE_SEQUENCE;
681 output->u.sequence.ptr = *(const char **) (ax->u.ptr.ptr + sizeof(unsigned long));
682 output->u.sequence.nr_elem = ax->u.ptr.field->type.u.array_nestable.length;
683 output->u.sequence.nested_type = ax->u.ptr.field->type.u.array_nestable.elem_type;
684 break;
685 case OBJECT_TYPE_STRUCT:
686 case OBJECT_TYPE_VARIANT:
687 default:
688 return -EINVAL;
689 }
690
691 break;
692 case REG_STAR_GLOB_STRING:
693 case REG_UNKNOWN:
694 default:
695 return -EINVAL;
696 }
697
698 return LTTNG_FILTER_RECORD_FLAG;
699 }
700
701 /*
702 * Return 0 (discard), or raise the 0x1 flag (log event).
703 * Currently, other flags are kept for future extensions and have no
704 * effect.
705 */
706 static
707 uint64_t bytecode_interpret(void *interpreter_data,
708 const char *interpreter_stack_data,
709 struct lttng_interpreter_output *output)
710 {
711 struct bytecode_runtime *bytecode = interpreter_data;
712 struct lttng_ctx *ctx = rcu_dereference(*bytecode->p.pctx);
713 void *pc, *next_pc, *start_pc;
714 int ret = -EINVAL;
715 uint64_t retval = 0;
716 struct estack _stack;
717 struct estack *stack = &_stack;
718 register int64_t ax = 0, bx = 0;
719 register enum entry_type ax_t = REG_UNKNOWN, bx_t = REG_UNKNOWN;
720 register int top = FILTER_STACK_EMPTY;
721 #ifndef INTERPRETER_USE_SWITCH
722 static void *dispatch[NR_FILTER_OPS] = {
723 [ FILTER_OP_UNKNOWN ] = &&LABEL_FILTER_OP_UNKNOWN,
724
725 [ FILTER_OP_RETURN ] = &&LABEL_FILTER_OP_RETURN,
726
727 /* binary */
728 [ FILTER_OP_MUL ] = &&LABEL_FILTER_OP_MUL,
729 [ FILTER_OP_DIV ] = &&LABEL_FILTER_OP_DIV,
730 [ FILTER_OP_MOD ] = &&LABEL_FILTER_OP_MOD,
731 [ FILTER_OP_PLUS ] = &&LABEL_FILTER_OP_PLUS,
732 [ FILTER_OP_MINUS ] = &&LABEL_FILTER_OP_MINUS,
733 [ FILTER_OP_BIT_RSHIFT ] = &&LABEL_FILTER_OP_BIT_RSHIFT,
734 [ FILTER_OP_BIT_LSHIFT ] = &&LABEL_FILTER_OP_BIT_LSHIFT,
735 [ FILTER_OP_BIT_AND ] = &&LABEL_FILTER_OP_BIT_AND,
736 [ FILTER_OP_BIT_OR ] = &&LABEL_FILTER_OP_BIT_OR,
737 [ FILTER_OP_BIT_XOR ] = &&LABEL_FILTER_OP_BIT_XOR,
738
739 /* binary comparators */
740 [ FILTER_OP_EQ ] = &&LABEL_FILTER_OP_EQ,
741 [ FILTER_OP_NE ] = &&LABEL_FILTER_OP_NE,
742 [ FILTER_OP_GT ] = &&LABEL_FILTER_OP_GT,
743 [ FILTER_OP_LT ] = &&LABEL_FILTER_OP_LT,
744 [ FILTER_OP_GE ] = &&LABEL_FILTER_OP_GE,
745 [ FILTER_OP_LE ] = &&LABEL_FILTER_OP_LE,
746
747 /* string binary comparator */
748 [ FILTER_OP_EQ_STRING ] = &&LABEL_FILTER_OP_EQ_STRING,
749 [ FILTER_OP_NE_STRING ] = &&LABEL_FILTER_OP_NE_STRING,
750 [ FILTER_OP_GT_STRING ] = &&LABEL_FILTER_OP_GT_STRING,
751 [ FILTER_OP_LT_STRING ] = &&LABEL_FILTER_OP_LT_STRING,
752 [ FILTER_OP_GE_STRING ] = &&LABEL_FILTER_OP_GE_STRING,
753 [ FILTER_OP_LE_STRING ] = &&LABEL_FILTER_OP_LE_STRING,
754
755 /* globbing pattern binary comparator */
756 [ FILTER_OP_EQ_STAR_GLOB_STRING ] = &&LABEL_FILTER_OP_EQ_STAR_GLOB_STRING,
757 [ FILTER_OP_NE_STAR_GLOB_STRING ] = &&LABEL_FILTER_OP_NE_STAR_GLOB_STRING,
758
759 /* s64 binary comparator */
760 [ FILTER_OP_EQ_S64 ] = &&LABEL_FILTER_OP_EQ_S64,
761 [ FILTER_OP_NE_S64 ] = &&LABEL_FILTER_OP_NE_S64,
762 [ FILTER_OP_GT_S64 ] = &&LABEL_FILTER_OP_GT_S64,
763 [ FILTER_OP_LT_S64 ] = &&LABEL_FILTER_OP_LT_S64,
764 [ FILTER_OP_GE_S64 ] = &&LABEL_FILTER_OP_GE_S64,
765 [ FILTER_OP_LE_S64 ] = &&LABEL_FILTER_OP_LE_S64,
766
767 /* double binary comparator */
768 [ FILTER_OP_EQ_DOUBLE ] = &&LABEL_FILTER_OP_EQ_DOUBLE,
769 [ FILTER_OP_NE_DOUBLE ] = &&LABEL_FILTER_OP_NE_DOUBLE,
770 [ FILTER_OP_GT_DOUBLE ] = &&LABEL_FILTER_OP_GT_DOUBLE,
771 [ FILTER_OP_LT_DOUBLE ] = &&LABEL_FILTER_OP_LT_DOUBLE,
772 [ FILTER_OP_GE_DOUBLE ] = &&LABEL_FILTER_OP_GE_DOUBLE,
773 [ FILTER_OP_LE_DOUBLE ] = &&LABEL_FILTER_OP_LE_DOUBLE,
774
775 /* Mixed S64-double binary comparators */
776 [ FILTER_OP_EQ_DOUBLE_S64 ] = &&LABEL_FILTER_OP_EQ_DOUBLE_S64,
777 [ FILTER_OP_NE_DOUBLE_S64 ] = &&LABEL_FILTER_OP_NE_DOUBLE_S64,
778 [ FILTER_OP_GT_DOUBLE_S64 ] = &&LABEL_FILTER_OP_GT_DOUBLE_S64,
779 [ FILTER_OP_LT_DOUBLE_S64 ] = &&LABEL_FILTER_OP_LT_DOUBLE_S64,
780 [ FILTER_OP_GE_DOUBLE_S64 ] = &&LABEL_FILTER_OP_GE_DOUBLE_S64,
781 [ FILTER_OP_LE_DOUBLE_S64 ] = &&LABEL_FILTER_OP_LE_DOUBLE_S64,
782
783 [ FILTER_OP_EQ_S64_DOUBLE ] = &&LABEL_FILTER_OP_EQ_S64_DOUBLE,
784 [ FILTER_OP_NE_S64_DOUBLE ] = &&LABEL_FILTER_OP_NE_S64_DOUBLE,
785 [ FILTER_OP_GT_S64_DOUBLE ] = &&LABEL_FILTER_OP_GT_S64_DOUBLE,
786 [ FILTER_OP_LT_S64_DOUBLE ] = &&LABEL_FILTER_OP_LT_S64_DOUBLE,
787 [ FILTER_OP_GE_S64_DOUBLE ] = &&LABEL_FILTER_OP_GE_S64_DOUBLE,
788 [ FILTER_OP_LE_S64_DOUBLE ] = &&LABEL_FILTER_OP_LE_S64_DOUBLE,
789
790 /* unary */
791 [ FILTER_OP_UNARY_PLUS ] = &&LABEL_FILTER_OP_UNARY_PLUS,
792 [ FILTER_OP_UNARY_MINUS ] = &&LABEL_FILTER_OP_UNARY_MINUS,
793 [ FILTER_OP_UNARY_NOT ] = &&LABEL_FILTER_OP_UNARY_NOT,
794 [ FILTER_OP_UNARY_PLUS_S64 ] = &&LABEL_FILTER_OP_UNARY_PLUS_S64,
795 [ FILTER_OP_UNARY_MINUS_S64 ] = &&LABEL_FILTER_OP_UNARY_MINUS_S64,
796 [ FILTER_OP_UNARY_NOT_S64 ] = &&LABEL_FILTER_OP_UNARY_NOT_S64,
797 [ FILTER_OP_UNARY_PLUS_DOUBLE ] = &&LABEL_FILTER_OP_UNARY_PLUS_DOUBLE,
798 [ FILTER_OP_UNARY_MINUS_DOUBLE ] = &&LABEL_FILTER_OP_UNARY_MINUS_DOUBLE,
799 [ FILTER_OP_UNARY_NOT_DOUBLE ] = &&LABEL_FILTER_OP_UNARY_NOT_DOUBLE,
800
801 /* logical */
802 [ FILTER_OP_AND ] = &&LABEL_FILTER_OP_AND,
803 [ FILTER_OP_OR ] = &&LABEL_FILTER_OP_OR,
804
805 /* load field ref */
806 [ FILTER_OP_LOAD_FIELD_REF ] = &&LABEL_FILTER_OP_LOAD_FIELD_REF,
807 [ FILTER_OP_LOAD_FIELD_REF_STRING ] = &&LABEL_FILTER_OP_LOAD_FIELD_REF_STRING,
808 [ FILTER_OP_LOAD_FIELD_REF_SEQUENCE ] = &&LABEL_FILTER_OP_LOAD_FIELD_REF_SEQUENCE,
809 [ FILTER_OP_LOAD_FIELD_REF_S64 ] = &&LABEL_FILTER_OP_LOAD_FIELD_REF_S64,
810 [ FILTER_OP_LOAD_FIELD_REF_DOUBLE ] = &&LABEL_FILTER_OP_LOAD_FIELD_REF_DOUBLE,
811
812 /* load from immediate operand */
813 [ FILTER_OP_LOAD_STRING ] = &&LABEL_FILTER_OP_LOAD_STRING,
814 [ FILTER_OP_LOAD_STAR_GLOB_STRING ] = &&LABEL_FILTER_OP_LOAD_STAR_GLOB_STRING,
815 [ FILTER_OP_LOAD_S64 ] = &&LABEL_FILTER_OP_LOAD_S64,
816 [ FILTER_OP_LOAD_DOUBLE ] = &&LABEL_FILTER_OP_LOAD_DOUBLE,
817
818 /* cast */
819 [ FILTER_OP_CAST_TO_S64 ] = &&LABEL_FILTER_OP_CAST_TO_S64,
820 [ FILTER_OP_CAST_DOUBLE_TO_S64 ] = &&LABEL_FILTER_OP_CAST_DOUBLE_TO_S64,
821 [ FILTER_OP_CAST_NOP ] = &&LABEL_FILTER_OP_CAST_NOP,
822
823 /* get context ref */
824 [ FILTER_OP_GET_CONTEXT_REF ] = &&LABEL_FILTER_OP_GET_CONTEXT_REF,
825 [ FILTER_OP_GET_CONTEXT_REF_STRING ] = &&LABEL_FILTER_OP_GET_CONTEXT_REF_STRING,
826 [ FILTER_OP_GET_CONTEXT_REF_S64 ] = &&LABEL_FILTER_OP_GET_CONTEXT_REF_S64,
827 [ FILTER_OP_GET_CONTEXT_REF_DOUBLE ] = &&LABEL_FILTER_OP_GET_CONTEXT_REF_DOUBLE,
828
829 /* Instructions for recursive traversal through composed types. */
830 [ FILTER_OP_GET_CONTEXT_ROOT ] = &&LABEL_FILTER_OP_GET_CONTEXT_ROOT,
831 [ FILTER_OP_GET_APP_CONTEXT_ROOT ] = &&LABEL_FILTER_OP_GET_APP_CONTEXT_ROOT,
832 [ FILTER_OP_GET_PAYLOAD_ROOT ] = &&LABEL_FILTER_OP_GET_PAYLOAD_ROOT,
833
834 [ FILTER_OP_GET_SYMBOL ] = &&LABEL_FILTER_OP_GET_SYMBOL,
835 [ FILTER_OP_GET_SYMBOL_FIELD ] = &&LABEL_FILTER_OP_GET_SYMBOL_FIELD,
836 [ FILTER_OP_GET_INDEX_U16 ] = &&LABEL_FILTER_OP_GET_INDEX_U16,
837 [ FILTER_OP_GET_INDEX_U64 ] = &&LABEL_FILTER_OP_GET_INDEX_U64,
838
839 [ FILTER_OP_LOAD_FIELD ] = &&LABEL_FILTER_OP_LOAD_FIELD,
840 [ FILTER_OP_LOAD_FIELD_S8 ] = &&LABEL_FILTER_OP_LOAD_FIELD_S8,
841 [ FILTER_OP_LOAD_FIELD_S16 ] = &&LABEL_FILTER_OP_LOAD_FIELD_S16,
842 [ FILTER_OP_LOAD_FIELD_S32 ] = &&LABEL_FILTER_OP_LOAD_FIELD_S32,
843 [ FILTER_OP_LOAD_FIELD_S64 ] = &&LABEL_FILTER_OP_LOAD_FIELD_S64,
844 [ FILTER_OP_LOAD_FIELD_U8 ] = &&LABEL_FILTER_OP_LOAD_FIELD_U8,
845 [ FILTER_OP_LOAD_FIELD_U16 ] = &&LABEL_FILTER_OP_LOAD_FIELD_U16,
846 [ FILTER_OP_LOAD_FIELD_U32 ] = &&LABEL_FILTER_OP_LOAD_FIELD_U32,
847 [ FILTER_OP_LOAD_FIELD_U64 ] = &&LABEL_FILTER_OP_LOAD_FIELD_U64,
848 [ FILTER_OP_LOAD_FIELD_STRING ] = &&LABEL_FILTER_OP_LOAD_FIELD_STRING,
849 [ FILTER_OP_LOAD_FIELD_SEQUENCE ] = &&LABEL_FILTER_OP_LOAD_FIELD_SEQUENCE,
850 [ FILTER_OP_LOAD_FIELD_DOUBLE ] = &&LABEL_FILTER_OP_LOAD_FIELD_DOUBLE,
851
852 [ FILTER_OP_UNARY_BIT_NOT ] = &&LABEL_FILTER_OP_UNARY_BIT_NOT,
853
854 [ FILTER_OP_RETURN_S64 ] = &&LABEL_FILTER_OP_RETURN_S64,
855 };
856 #endif /* #ifndef INTERPRETER_USE_SWITCH */
857
858 START_OP
859
860 OP(FILTER_OP_UNKNOWN):
861 OP(FILTER_OP_LOAD_FIELD_REF):
862 #ifdef INTERPRETER_USE_SWITCH
863 default:
864 #endif /* INTERPRETER_USE_SWITCH */
865 ERR("unknown bytecode op %u",
866 (unsigned int) *(filter_opcode_t *) pc);
867 ret = -EINVAL;
868 goto end;
869
870 OP(FILTER_OP_RETURN):
871 /* LTTNG_FILTER_DISCARD or LTTNG_FILTER_RECORD_FLAG */
872 /* Handle dynamic typing. */
873 switch (estack_ax_t) {
874 case REG_S64:
875 case REG_U64:
876 retval = !!estack_ax_v;
877 break;
878 case REG_DOUBLE:
879 case REG_STRING:
880 case REG_PTR:
881 if (!output) {
882 ret = -EINVAL;
883 goto end;
884 }
885 retval = 0;
886 break;
887 case REG_STAR_GLOB_STRING:
888 case REG_UNKNOWN:
889 default:
890 ret = -EINVAL;
891 goto end;
892 }
893 ret = 0;
894 goto end;
895
896 OP(FILTER_OP_RETURN_S64):
897 /* LTTNG_FILTER_DISCARD or LTTNG_FILTER_RECORD_FLAG */
898 retval = !!estack_ax_v;
899 ret = 0;
900 goto end;
901
902 /* binary */
903 OP(FILTER_OP_MUL):
904 OP(FILTER_OP_DIV):
905 OP(FILTER_OP_MOD):
906 OP(FILTER_OP_PLUS):
907 OP(FILTER_OP_MINUS):
908 ERR("unsupported bytecode op %u",
909 (unsigned int) *(filter_opcode_t *) pc);
910 ret = -EINVAL;
911 goto end;
912
913 OP(FILTER_OP_EQ):
914 {
915 /* Dynamic typing. */
916 switch (estack_ax_t) {
917 case REG_S64: /* Fall-through */
918 case REG_U64:
919 switch (estack_bx_t) {
920 case REG_S64: /* Fall-through */
921 case REG_U64:
922 JUMP_TO(FILTER_OP_EQ_S64);
923 case REG_DOUBLE:
924 JUMP_TO(FILTER_OP_EQ_DOUBLE_S64);
925 case REG_STRING: /* Fall-through */
926 case REG_STAR_GLOB_STRING:
927 ret = -EINVAL;
928 goto end;
929 default:
930 ERR("Unknown filter register type (%d)",
931 (int) estack_bx_t);
932 ret = -EINVAL;
933 goto end;
934 }
935 break;
936 case REG_DOUBLE:
937 switch (estack_bx_t) {
938 case REG_S64: /* Fall-through */
939 case REG_U64:
940 JUMP_TO(FILTER_OP_EQ_S64_DOUBLE);
941 case REG_DOUBLE:
942 JUMP_TO(FILTER_OP_EQ_DOUBLE);
943 case REG_STRING: /* Fall-through */
944 case REG_STAR_GLOB_STRING:
945 ret = -EINVAL;
946 goto end;
947 default:
948 ERR("Unknown filter register type (%d)",
949 (int) estack_bx_t);
950 ret = -EINVAL;
951 goto end;
952 }
953 break;
954 case REG_STRING:
955 switch (estack_bx_t) {
956 case REG_S64: /* Fall-through */
957 case REG_U64: /* Fall-through */
958 case REG_DOUBLE:
959 ret = -EINVAL;
960 goto end;
961 case REG_STRING:
962 JUMP_TO(FILTER_OP_EQ_STRING);
963 case REG_STAR_GLOB_STRING:
964 JUMP_TO(FILTER_OP_EQ_STAR_GLOB_STRING);
965 default:
966 ERR("Unknown filter register type (%d)",
967 (int) estack_bx_t);
968 ret = -EINVAL;
969 goto end;
970 }
971 break;
972 case REG_STAR_GLOB_STRING:
973 switch (estack_bx_t) {
974 case REG_S64: /* Fall-through */
975 case REG_U64: /* Fall-through */
976 case REG_DOUBLE:
977 ret = -EINVAL;
978 goto end;
979 case REG_STRING:
980 JUMP_TO(FILTER_OP_EQ_STAR_GLOB_STRING);
981 case REG_STAR_GLOB_STRING:
982 ret = -EINVAL;
983 goto end;
984 default:
985 ERR("Unknown filter register type (%d)",
986 (int) estack_bx_t);
987 ret = -EINVAL;
988 goto end;
989 }
990 break;
991 default:
992 ERR("Unknown filter register type (%d)",
993 (int) estack_ax_t);
994 ret = -EINVAL;
995 goto end;
996 }
997 }
998 OP(FILTER_OP_NE):
999 {
1000 /* Dynamic typing. */
1001 switch (estack_ax_t) {
1002 case REG_S64: /* Fall-through */
1003 case REG_U64:
1004 switch (estack_bx_t) {
1005 case REG_S64: /* Fall-through */
1006 case REG_U64:
1007 JUMP_TO(FILTER_OP_NE_S64);
1008 case REG_DOUBLE:
1009 JUMP_TO(FILTER_OP_NE_DOUBLE_S64);
1010 case REG_STRING: /* Fall-through */
1011 case REG_STAR_GLOB_STRING:
1012 ret = -EINVAL;
1013 goto end;
1014 default:
1015 ERR("Unknown filter register type (%d)",
1016 (int) estack_bx_t);
1017 ret = -EINVAL;
1018 goto end;
1019 }
1020 break;
1021 case REG_DOUBLE:
1022 switch (estack_bx_t) {
1023 case REG_S64: /* Fall-through */
1024 case REG_U64:
1025 JUMP_TO(FILTER_OP_NE_S64_DOUBLE);
1026 case REG_DOUBLE:
1027 JUMP_TO(FILTER_OP_NE_DOUBLE);
1028 case REG_STRING: /* Fall-through */
1029 case REG_STAR_GLOB_STRING:
1030 ret = -EINVAL;
1031 goto end;
1032 default:
1033 ERR("Unknown filter register type (%d)",
1034 (int) estack_bx_t);
1035 ret = -EINVAL;
1036 goto end;
1037 }
1038 break;
1039 case REG_STRING:
1040 switch (estack_bx_t) {
1041 case REG_S64: /* Fall-through */
1042 case REG_U64:
1043 case REG_DOUBLE:
1044 ret = -EINVAL;
1045 goto end;
1046 case REG_STRING:
1047 JUMP_TO(FILTER_OP_NE_STRING);
1048 case REG_STAR_GLOB_STRING:
1049 JUMP_TO(FILTER_OP_NE_STAR_GLOB_STRING);
1050 default:
1051 ERR("Unknown filter register type (%d)",
1052 (int) estack_bx_t);
1053 ret = -EINVAL;
1054 goto end;
1055 }
1056 break;
1057 case REG_STAR_GLOB_STRING:
1058 switch (estack_bx_t) {
1059 case REG_S64: /* Fall-through */
1060 case REG_U64:
1061 case REG_DOUBLE:
1062 ret = -EINVAL;
1063 goto end;
1064 case REG_STRING:
1065 JUMP_TO(FILTER_OP_NE_STAR_GLOB_STRING);
1066 case REG_STAR_GLOB_STRING:
1067 ret = -EINVAL;
1068 goto end;
1069 default:
1070 ERR("Unknown filter register type (%d)",
1071 (int) estack_bx_t);
1072 ret = -EINVAL;
1073 goto end;
1074 }
1075 break;
1076 default:
1077 ERR("Unknown filter register type (%d)",
1078 (int) estack_ax_t);
1079 ret = -EINVAL;
1080 goto end;
1081 }
1082 }
1083 OP(FILTER_OP_GT):
1084 {
1085 /* Dynamic typing. */
1086 switch (estack_ax_t) {
1087 case REG_S64: /* Fall-through */
1088 case REG_U64:
1089 switch (estack_bx_t) {
1090 case REG_S64: /* Fall-through */
1091 case REG_U64:
1092 JUMP_TO(FILTER_OP_GT_S64);
1093 case REG_DOUBLE:
1094 JUMP_TO(FILTER_OP_GT_DOUBLE_S64);
1095 case REG_STRING: /* Fall-through */
1096 case REG_STAR_GLOB_STRING:
1097 ret = -EINVAL;
1098 goto end;
1099 default:
1100 ERR("Unknown filter register type (%d)",
1101 (int) estack_bx_t);
1102 ret = -EINVAL;
1103 goto end;
1104 }
1105 break;
1106 case REG_DOUBLE:
1107 switch (estack_bx_t) {
1108 case REG_S64: /* Fall-through */
1109 case REG_U64:
1110 JUMP_TO(FILTER_OP_GT_S64_DOUBLE);
1111 case REG_DOUBLE:
1112 JUMP_TO(FILTER_OP_GT_DOUBLE);
1113 case REG_STRING: /* Fall-through */
1114 case REG_STAR_GLOB_STRING:
1115 ret = -EINVAL;
1116 goto end;
1117 default:
1118 ERR("Unknown filter register type (%d)",
1119 (int) estack_bx_t);
1120 ret = -EINVAL;
1121 goto end;
1122 }
1123 break;
1124 case REG_STRING:
1125 switch (estack_bx_t) {
1126 case REG_S64: /* Fall-through */
1127 case REG_U64: /* Fall-through */
1128 case REG_DOUBLE: /* Fall-through */
1129 case REG_STAR_GLOB_STRING:
1130 ret = -EINVAL;
1131 goto end;
1132 case REG_STRING:
1133 JUMP_TO(FILTER_OP_GT_STRING);
1134 default:
1135 ERR("Unknown filter register type (%d)",
1136 (int) estack_bx_t);
1137 ret = -EINVAL;
1138 goto end;
1139 }
1140 break;
1141 default:
1142 ERR("Unknown filter register type (%d)",
1143 (int) estack_ax_t);
1144 ret = -EINVAL;
1145 goto end;
1146 }
1147 }
1148 OP(FILTER_OP_LT):
1149 {
1150 /* Dynamic typing. */
1151 switch (estack_ax_t) {
1152 case REG_S64: /* Fall-through */
1153 case REG_U64:
1154 switch (estack_bx_t) {
1155 case REG_S64: /* Fall-through */
1156 case REG_U64:
1157 JUMP_TO(FILTER_OP_LT_S64);
1158 case REG_DOUBLE:
1159 JUMP_TO(FILTER_OP_LT_DOUBLE_S64);
1160 case REG_STRING: /* Fall-through */
1161 case REG_STAR_GLOB_STRING:
1162 ret = -EINVAL;
1163 goto end;
1164 default:
1165 ERR("Unknown filter register type (%d)",
1166 (int) estack_bx_t);
1167 ret = -EINVAL;
1168 goto end;
1169 }
1170 break;
1171 case REG_DOUBLE:
1172 switch (estack_bx_t) {
1173 case REG_S64: /* Fall-through */
1174 case REG_U64:
1175 JUMP_TO(FILTER_OP_LT_S64_DOUBLE);
1176 case REG_DOUBLE:
1177 JUMP_TO(FILTER_OP_LT_DOUBLE);
1178 case REG_STRING: /* Fall-through */
1179 case REG_STAR_GLOB_STRING:
1180 ret = -EINVAL;
1181 goto end;
1182 default:
1183 ERR("Unknown filter register type (%d)",
1184 (int) estack_bx_t);
1185 ret = -EINVAL;
1186 goto end;
1187 }
1188 break;
1189 case REG_STRING:
1190 switch (estack_bx_t) {
1191 case REG_S64: /* Fall-through */
1192 case REG_U64: /* Fall-through */
1193 case REG_DOUBLE: /* Fall-through */
1194 case REG_STAR_GLOB_STRING:
1195 ret = -EINVAL;
1196 goto end;
1197 case REG_STRING:
1198 JUMP_TO(FILTER_OP_LT_STRING);
1199 default:
1200 ERR("Unknown filter register type (%d)",
1201 (int) estack_bx_t);
1202 ret = -EINVAL;
1203 goto end;
1204 }
1205 break;
1206 default:
1207 ERR("Unknown filter register type (%d)",
1208 (int) estack_ax_t);
1209 ret = -EINVAL;
1210 goto end;
1211 }
1212 }
1213 OP(FILTER_OP_GE):
1214 {
1215 /* Dynamic typing. */
1216 switch (estack_ax_t) {
1217 case REG_S64: /* Fall-through */
1218 case REG_U64:
1219 switch (estack_bx_t) {
1220 case REG_S64: /* Fall-through */
1221 case REG_U64:
1222 JUMP_TO(FILTER_OP_GE_S64);
1223 case REG_DOUBLE:
1224 JUMP_TO(FILTER_OP_GE_DOUBLE_S64);
1225 case REG_STRING: /* Fall-through */
1226 case REG_STAR_GLOB_STRING:
1227 ret = -EINVAL;
1228 goto end;
1229 default:
1230 ERR("Unknown filter register type (%d)",
1231 (int) estack_bx_t);
1232 ret = -EINVAL;
1233 goto end;
1234 }
1235 break;
1236 case REG_DOUBLE:
1237 switch (estack_bx_t) {
1238 case REG_S64: /* Fall-through */
1239 case REG_U64:
1240 JUMP_TO(FILTER_OP_GE_S64_DOUBLE);
1241 case REG_DOUBLE:
1242 JUMP_TO(FILTER_OP_GE_DOUBLE);
1243 case REG_STRING: /* Fall-through */
1244 case REG_STAR_GLOB_STRING:
1245 ret = -EINVAL;
1246 goto end;
1247 default:
1248 ERR("Unknown filter register type (%d)",
1249 (int) estack_bx_t);
1250 ret = -EINVAL;
1251 goto end;
1252 }
1253 break;
1254 case REG_STRING:
1255 switch (estack_bx_t) {
1256 case REG_S64: /* Fall-through */
1257 case REG_U64: /* Fall-through */
1258 case REG_DOUBLE: /* Fall-through */
1259 case REG_STAR_GLOB_STRING:
1260 ret = -EINVAL;
1261 goto end;
1262 case REG_STRING:
1263 JUMP_TO(FILTER_OP_GE_STRING);
1264 default:
1265 ERR("Unknown filter register type (%d)",
1266 (int) estack_bx_t);
1267 ret = -EINVAL;
1268 goto end;
1269 }
1270 break;
1271 default:
1272 ERR("Unknown filter register type (%d)",
1273 (int) estack_ax_t);
1274 ret = -EINVAL;
1275 goto end;
1276 }
1277 }
1278 OP(FILTER_OP_LE):
1279 {
1280 /* Dynamic typing. */
1281 switch (estack_ax_t) {
1282 case REG_S64: /* Fall-through */
1283 case REG_U64:
1284 switch (estack_bx_t) {
1285 case REG_S64: /* Fall-through */
1286 case REG_U64:
1287 JUMP_TO(FILTER_OP_LE_S64);
1288 case REG_DOUBLE:
1289 JUMP_TO(FILTER_OP_LE_DOUBLE_S64);
1290 case REG_STRING: /* Fall-through */
1291 case REG_STAR_GLOB_STRING:
1292 ret = -EINVAL;
1293 goto end;
1294 default:
1295 ERR("Unknown filter register type (%d)",
1296 (int) estack_bx_t);
1297 ret = -EINVAL;
1298 goto end;
1299 }
1300 break;
1301 case REG_DOUBLE:
1302 switch (estack_bx_t) {
1303 case REG_S64: /* Fall-through */
1304 case REG_U64:
1305 JUMP_TO(FILTER_OP_LE_S64_DOUBLE);
1306 case REG_DOUBLE:
1307 JUMP_TO(FILTER_OP_LE_DOUBLE);
1308 case REG_STRING: /* Fall-through */
1309 case REG_STAR_GLOB_STRING:
1310 ret = -EINVAL;
1311 goto end;
1312 default:
1313 ERR("Unknown filter register type (%d)",
1314 (int) estack_bx_t);
1315 ret = -EINVAL;
1316 goto end;
1317 }
1318 break;
1319 case REG_STRING:
1320 switch (estack_bx_t) {
1321 case REG_S64: /* Fall-through */
1322 case REG_U64: /* Fall-through */
1323 case REG_DOUBLE: /* Fall-through */
1324 case REG_STAR_GLOB_STRING:
1325 ret = -EINVAL;
1326 goto end;
1327 case REG_STRING:
1328 JUMP_TO(FILTER_OP_LE_STRING);
1329 default:
1330 ERR("Unknown filter register type (%d)",
1331 (int) estack_bx_t);
1332 ret = -EINVAL;
1333 goto end;
1334 }
1335 break;
1336 default:
1337 ERR("Unknown filter register type (%d)",
1338 (int) estack_ax_t);
1339 ret = -EINVAL;
1340 goto end;
1341 }
1342 }
1343
1344 OP(FILTER_OP_EQ_STRING):
1345 {
1346 int res;
1347
1348 res = (stack_strcmp(stack, top, "==") == 0);
1349 estack_pop(stack, top, ax, bx, ax_t, bx_t);
1350 estack_ax_v = res;
1351 estack_ax_t = REG_S64;
1352 next_pc += sizeof(struct binary_op);
1353 PO;
1354 }
1355 OP(FILTER_OP_NE_STRING):
1356 {
1357 int res;
1358
1359 res = (stack_strcmp(stack, top, "!=") != 0);
1360 estack_pop(stack, top, ax, bx, ax_t, bx_t);
1361 estack_ax_v = res;
1362 estack_ax_t = REG_S64;
1363 next_pc += sizeof(struct binary_op);
1364 PO;
1365 }
1366 OP(FILTER_OP_GT_STRING):
1367 {
1368 int res;
1369
1370 res = (stack_strcmp(stack, top, ">") > 0);
1371 estack_pop(stack, top, ax, bx, ax_t, bx_t);
1372 estack_ax_v = res;
1373 estack_ax_t = REG_S64;
1374 next_pc += sizeof(struct binary_op);
1375 PO;
1376 }
1377 OP(FILTER_OP_LT_STRING):
1378 {
1379 int res;
1380
1381 res = (stack_strcmp(stack, top, "<") < 0);
1382 estack_pop(stack, top, ax, bx, ax_t, bx_t);
1383 estack_ax_v = res;
1384 estack_ax_t = REG_S64;
1385 next_pc += sizeof(struct binary_op);
1386 PO;
1387 }
1388 OP(FILTER_OP_GE_STRING):
1389 {
1390 int res;
1391
1392 res = (stack_strcmp(stack, top, ">=") >= 0);
1393 estack_pop(stack, top, ax, bx, ax_t, bx_t);
1394 estack_ax_v = res;
1395 estack_ax_t = REG_S64;
1396 next_pc += sizeof(struct binary_op);
1397 PO;
1398 }
1399 OP(FILTER_OP_LE_STRING):
1400 {
1401 int res;
1402
1403 res = (stack_strcmp(stack, top, "<=") <= 0);
1404 estack_pop(stack, top, ax, bx, ax_t, bx_t);
1405 estack_ax_v = res;
1406 estack_ax_t = REG_S64;
1407 next_pc += sizeof(struct binary_op);
1408 PO;
1409 }
1410
1411 OP(FILTER_OP_EQ_STAR_GLOB_STRING):
1412 {
1413 int res;
1414
1415 res = (stack_star_glob_match(stack, top, "==") == 0);
1416 estack_pop(stack, top, ax, bx, ax_t, bx_t);
1417 estack_ax_v = res;
1418 estack_ax_t = REG_S64;
1419 next_pc += sizeof(struct binary_op);
1420 PO;
1421 }
1422 OP(FILTER_OP_NE_STAR_GLOB_STRING):
1423 {
1424 int res;
1425
1426 res = (stack_star_glob_match(stack, top, "!=") != 0);
1427 estack_pop(stack, top, ax, bx, ax_t, bx_t);
1428 estack_ax_v = res;
1429 estack_ax_t = REG_S64;
1430 next_pc += sizeof(struct binary_op);
1431 PO;
1432 }
1433
1434 OP(FILTER_OP_EQ_S64):
1435 {
1436 int res;
1437
1438 res = (estack_bx_v == estack_ax_v);
1439 estack_pop(stack, top, ax, bx, ax_t, bx_t);
1440 estack_ax_v = res;
1441 estack_ax_t = REG_S64;
1442 next_pc += sizeof(struct binary_op);
1443 PO;
1444 }
1445 OP(FILTER_OP_NE_S64):
1446 {
1447 int res;
1448
1449 res = (estack_bx_v != estack_ax_v);
1450 estack_pop(stack, top, ax, bx, ax_t, bx_t);
1451 estack_ax_v = res;
1452 estack_ax_t = REG_S64;
1453 next_pc += sizeof(struct binary_op);
1454 PO;
1455 }
1456 OP(FILTER_OP_GT_S64):
1457 {
1458 int res;
1459
1460 res = (estack_bx_v > estack_ax_v);
1461 estack_pop(stack, top, ax, bx, ax_t, bx_t);
1462 estack_ax_v = res;
1463 estack_ax_t = REG_S64;
1464 next_pc += sizeof(struct binary_op);
1465 PO;
1466 }
1467 OP(FILTER_OP_LT_S64):
1468 {
1469 int res;
1470
1471 res = (estack_bx_v < estack_ax_v);
1472 estack_pop(stack, top, ax, bx, ax_t, bx_t);
1473 estack_ax_v = res;
1474 estack_ax_t = REG_S64;
1475 next_pc += sizeof(struct binary_op);
1476 PO;
1477 }
1478 OP(FILTER_OP_GE_S64):
1479 {
1480 int res;
1481
1482 res = (estack_bx_v >= estack_ax_v);
1483 estack_pop(stack, top, ax, bx, ax_t, bx_t);
1484 estack_ax_v = res;
1485 estack_ax_t = REG_S64;
1486 next_pc += sizeof(struct binary_op);
1487 PO;
1488 }
1489 OP(FILTER_OP_LE_S64):
1490 {
1491 int res;
1492
1493 res = (estack_bx_v <= estack_ax_v);
1494 estack_pop(stack, top, ax, bx, ax_t, bx_t);
1495 estack_ax_v = res;
1496 estack_ax_t = REG_S64;
1497 next_pc += sizeof(struct binary_op);
1498 PO;
1499 }
1500
1501 OP(FILTER_OP_EQ_DOUBLE):
1502 {
1503 int res;
1504
1505 res = (estack_bx(stack, top)->u.d == estack_ax(stack, top)->u.d);
1506 estack_pop(stack, top, ax, bx, ax_t, bx_t);
1507 estack_ax_v = res;
1508 estack_ax_t = REG_S64;
1509 next_pc += sizeof(struct binary_op);
1510 PO;
1511 }
1512 OP(FILTER_OP_NE_DOUBLE):
1513 {
1514 int res;
1515
1516 res = (estack_bx(stack, top)->u.d != estack_ax(stack, top)->u.d);
1517 estack_pop(stack, top, ax, bx, ax_t, bx_t);
1518 estack_ax_v = res;
1519 estack_ax_t = REG_S64;
1520 next_pc += sizeof(struct binary_op);
1521 PO;
1522 }
1523 OP(FILTER_OP_GT_DOUBLE):
1524 {
1525 int res;
1526
1527 res = (estack_bx(stack, top)->u.d > estack_ax(stack, top)->u.d);
1528 estack_pop(stack, top, ax, bx, ax_t, bx_t);
1529 estack_ax_v = res;
1530 estack_ax_t = REG_S64;
1531 next_pc += sizeof(struct binary_op);
1532 PO;
1533 }
1534 OP(FILTER_OP_LT_DOUBLE):
1535 {
1536 int res;
1537
1538 res = (estack_bx(stack, top)->u.d < estack_ax(stack, top)->u.d);
1539 estack_pop(stack, top, ax, bx, ax_t, bx_t);
1540 estack_ax_v = res;
1541 estack_ax_t = REG_S64;
1542 next_pc += sizeof(struct binary_op);
1543 PO;
1544 }
1545 OP(FILTER_OP_GE_DOUBLE):
1546 {
1547 int res;
1548
1549 res = (estack_bx(stack, top)->u.d >= estack_ax(stack, top)->u.d);
1550 estack_pop(stack, top, ax, bx, ax_t, bx_t);
1551 estack_ax_v = res;
1552 estack_ax_t = REG_S64;
1553 next_pc += sizeof(struct binary_op);
1554 PO;
1555 }
1556 OP(FILTER_OP_LE_DOUBLE):
1557 {
1558 int res;
1559
1560 res = (estack_bx(stack, top)->u.d <= estack_ax(stack, top)->u.d);
1561 estack_pop(stack, top, ax, bx, ax_t, bx_t);
1562 estack_ax_v = res;
1563 estack_ax_t = REG_S64;
1564 next_pc += sizeof(struct binary_op);
1565 PO;
1566 }
1567
1568 /* Mixed S64-double binary comparators */
1569 OP(FILTER_OP_EQ_DOUBLE_S64):
1570 {
1571 int res;
1572
1573 res = (estack_bx(stack, top)->u.d == estack_ax_v);
1574 estack_pop(stack, top, ax, bx, ax_t, bx_t);
1575 estack_ax_v = res;
1576 estack_ax_t = REG_S64;
1577 next_pc += sizeof(struct binary_op);
1578 PO;
1579 }
1580 OP(FILTER_OP_NE_DOUBLE_S64):
1581 {
1582 int res;
1583
1584 res = (estack_bx(stack, top)->u.d != estack_ax_v);
1585 estack_pop(stack, top, ax, bx, ax_t, bx_t);
1586 estack_ax_v = res;
1587 estack_ax_t = REG_S64;
1588 next_pc += sizeof(struct binary_op);
1589 PO;
1590 }
1591 OP(FILTER_OP_GT_DOUBLE_S64):
1592 {
1593 int res;
1594
1595 res = (estack_bx(stack, top)->u.d > estack_ax_v);
1596 estack_pop(stack, top, ax, bx, ax_t, bx_t);
1597 estack_ax_v = res;
1598 estack_ax_t = REG_S64;
1599 next_pc += sizeof(struct binary_op);
1600 PO;
1601 }
1602 OP(FILTER_OP_LT_DOUBLE_S64):
1603 {
1604 int res;
1605
1606 res = (estack_bx(stack, top)->u.d < estack_ax_v);
1607 estack_pop(stack, top, ax, bx, ax_t, bx_t);
1608 estack_ax_v = res;
1609 estack_ax_t = REG_S64;
1610 next_pc += sizeof(struct binary_op);
1611 PO;
1612 }
1613 OP(FILTER_OP_GE_DOUBLE_S64):
1614 {
1615 int res;
1616
1617 res = (estack_bx(stack, top)->u.d >= estack_ax_v);
1618 estack_pop(stack, top, ax, bx, ax_t, bx_t);
1619 estack_ax_v = res;
1620 estack_ax_t = REG_S64;
1621 next_pc += sizeof(struct binary_op);
1622 PO;
1623 }
1624 OP(FILTER_OP_LE_DOUBLE_S64):
1625 {
1626 int res;
1627
1628 res = (estack_bx(stack, top)->u.d <= estack_ax_v);
1629 estack_pop(stack, top, ax, bx, ax_t, bx_t);
1630 estack_ax_v = res;
1631 estack_ax_t = REG_S64;
1632 next_pc += sizeof(struct binary_op);
1633 PO;
1634 }
1635
1636 OP(FILTER_OP_EQ_S64_DOUBLE):
1637 {
1638 int res;
1639
1640 res = (estack_bx_v == estack_ax(stack, top)->u.d);
1641 estack_pop(stack, top, ax, bx, ax_t, bx_t);
1642 estack_ax_v = res;
1643 estack_ax_t = REG_S64;
1644 next_pc += sizeof(struct binary_op);
1645 PO;
1646 }
1647 OP(FILTER_OP_NE_S64_DOUBLE):
1648 {
1649 int res;
1650
1651 res = (estack_bx_v != estack_ax(stack, top)->u.d);
1652 estack_pop(stack, top, ax, bx, ax_t, bx_t);
1653 estack_ax_v = res;
1654 estack_ax_t = REG_S64;
1655 next_pc += sizeof(struct binary_op);
1656 PO;
1657 }
1658 OP(FILTER_OP_GT_S64_DOUBLE):
1659 {
1660 int res;
1661
1662 res = (estack_bx_v > estack_ax(stack, top)->u.d);
1663 estack_pop(stack, top, ax, bx, ax_t, bx_t);
1664 estack_ax_v = res;
1665 estack_ax_t = REG_S64;
1666 next_pc += sizeof(struct binary_op);
1667 PO;
1668 }
1669 OP(FILTER_OP_LT_S64_DOUBLE):
1670 {
1671 int res;
1672
1673 res = (estack_bx_v < estack_ax(stack, top)->u.d);
1674 estack_pop(stack, top, ax, bx, ax_t, bx_t);
1675 estack_ax_v = res;
1676 estack_ax_t = REG_S64;
1677 next_pc += sizeof(struct binary_op);
1678 PO;
1679 }
1680 OP(FILTER_OP_GE_S64_DOUBLE):
1681 {
1682 int res;
1683
1684 res = (estack_bx_v >= estack_ax(stack, top)->u.d);
1685 estack_pop(stack, top, ax, bx, ax_t, bx_t);
1686 estack_ax_v = res;
1687 estack_ax_t = REG_S64;
1688 next_pc += sizeof(struct binary_op);
1689 PO;
1690 }
1691 OP(FILTER_OP_LE_S64_DOUBLE):
1692 {
1693 int res;
1694
1695 res = (estack_bx_v <= estack_ax(stack, top)->u.d);
1696 estack_pop(stack, top, ax, bx, ax_t, bx_t);
1697 estack_ax_v = res;
1698 estack_ax_t = REG_S64;
1699 next_pc += sizeof(struct binary_op);
1700 PO;
1701 }
1702 OP(FILTER_OP_BIT_RSHIFT):
1703 {
1704 int64_t res;
1705
1706 if (!IS_INTEGER_REGISTER(estack_ax_t) || !IS_INTEGER_REGISTER(estack_bx_t)) {
1707 ret = -EINVAL;
1708 goto end;
1709 }
1710
1711 /* Catch undefined behavior. */
1712 if (caa_unlikely(estack_ax_v < 0 || estack_ax_v >= 64)) {
1713 ret = -EINVAL;
1714 goto end;
1715 }
1716 res = ((uint64_t) estack_bx_v >> (uint32_t) estack_ax_v);
1717 estack_pop(stack, top, ax, bx, ax_t, bx_t);
1718 estack_ax_v = res;
1719 estack_ax_t = REG_U64;
1720 next_pc += sizeof(struct binary_op);
1721 PO;
1722 }
1723 OP(FILTER_OP_BIT_LSHIFT):
1724 {
1725 int64_t res;
1726
1727 if (!IS_INTEGER_REGISTER(estack_ax_t) || !IS_INTEGER_REGISTER(estack_bx_t)) {
1728 ret = -EINVAL;
1729 goto end;
1730 }
1731
1732 /* Catch undefined behavior. */
1733 if (caa_unlikely(estack_ax_v < 0 || estack_ax_v >= 64)) {
1734 ret = -EINVAL;
1735 goto end;
1736 }
1737 res = ((uint64_t) estack_bx_v << (uint32_t) estack_ax_v);
1738 estack_pop(stack, top, ax, bx, ax_t, bx_t);
1739 estack_ax_v = res;
1740 estack_ax_t = REG_U64;
1741 next_pc += sizeof(struct binary_op);
1742 PO;
1743 }
1744 OP(FILTER_OP_BIT_AND):
1745 {
1746 int64_t res;
1747
1748 if (!IS_INTEGER_REGISTER(estack_ax_t) || !IS_INTEGER_REGISTER(estack_bx_t)) {
1749 ret = -EINVAL;
1750 goto end;
1751 }
1752
1753 res = ((uint64_t) estack_bx_v & (uint64_t) estack_ax_v);
1754 estack_pop(stack, top, ax, bx, ax_t, bx_t);
1755 estack_ax_v = res;
1756 estack_ax_t = REG_U64;
1757 next_pc += sizeof(struct binary_op);
1758 PO;
1759 }
1760 OP(FILTER_OP_BIT_OR):
1761 {
1762 int64_t res;
1763
1764 if (!IS_INTEGER_REGISTER(estack_ax_t) || !IS_INTEGER_REGISTER(estack_bx_t)) {
1765 ret = -EINVAL;
1766 goto end;
1767 }
1768
1769 res = ((uint64_t) estack_bx_v | (uint64_t) estack_ax_v);
1770 estack_pop(stack, top, ax, bx, ax_t, bx_t);
1771 estack_ax_v = res;
1772 estack_ax_t = REG_U64;
1773 next_pc += sizeof(struct binary_op);
1774 PO;
1775 }
1776 OP(FILTER_OP_BIT_XOR):
1777 {
1778 int64_t res;
1779
1780 if (!IS_INTEGER_REGISTER(estack_ax_t) || !IS_INTEGER_REGISTER(estack_bx_t)) {
1781 ret = -EINVAL;
1782 goto end;
1783 }
1784
1785 res = ((uint64_t) estack_bx_v ^ (uint64_t) estack_ax_v);
1786 estack_pop(stack, top, ax, bx, ax_t, bx_t);
1787 estack_ax_v = res;
1788 estack_ax_t = REG_U64;
1789 next_pc += sizeof(struct binary_op);
1790 PO;
1791 }
1792
1793 /* unary */
1794 OP(FILTER_OP_UNARY_PLUS):
1795 {
1796 /* Dynamic typing. */
1797 switch (estack_ax_t) {
1798 case REG_S64: /* Fall-through. */
1799 case REG_U64:
1800 JUMP_TO(FILTER_OP_UNARY_PLUS_S64);
1801 case REG_DOUBLE:
1802 JUMP_TO(FILTER_OP_UNARY_PLUS_DOUBLE);
1803 case REG_STRING: /* Fall-through */
1804 case REG_STAR_GLOB_STRING:
1805 ret = -EINVAL;
1806 goto end;
1807 default:
1808 ERR("Unknown filter register type (%d)",
1809 (int) estack_ax_t);
1810 ret = -EINVAL;
1811 goto end;
1812 }
1813 }
1814 OP(FILTER_OP_UNARY_MINUS):
1815 {
1816 /* Dynamic typing. */
1817 switch (estack_ax_t) {
1818 case REG_S64: /* Fall-through. */
1819 case REG_U64:
1820 JUMP_TO(FILTER_OP_UNARY_MINUS_S64);
1821 case REG_DOUBLE:
1822 JUMP_TO(FILTER_OP_UNARY_MINUS_DOUBLE);
1823 case REG_STRING: /* Fall-through */
1824 case REG_STAR_GLOB_STRING:
1825 ret = -EINVAL;
1826 goto end;
1827 default:
1828 ERR("Unknown filter register type (%d)",
1829 (int) estack_ax_t);
1830 ret = -EINVAL;
1831 goto end;
1832 }
1833 }
1834 OP(FILTER_OP_UNARY_NOT):
1835 {
1836 /* Dynamic typing. */
1837 switch (estack_ax_t) {
1838 case REG_S64: /* Fall-through. */
1839 case REG_U64:
1840 JUMP_TO(FILTER_OP_UNARY_NOT_S64);
1841 case REG_DOUBLE:
1842 JUMP_TO(FILTER_OP_UNARY_NOT_DOUBLE);
1843 case REG_STRING: /* Fall-through */
1844 case REG_STAR_GLOB_STRING:
1845 ret = -EINVAL;
1846 goto end;
1847 default:
1848 ERR("Unknown filter register type (%d)",
1849 (int) estack_ax_t);
1850 ret = -EINVAL;
1851 goto end;
1852 }
1853 next_pc += sizeof(struct unary_op);
1854 PO;
1855 }
1856
1857 OP(FILTER_OP_UNARY_BIT_NOT):
1858 {
1859 /* Dynamic typing. */
1860 if (!IS_INTEGER_REGISTER(estack_ax_t)) {
1861 ret = -EINVAL;
1862 goto end;
1863 }
1864
1865 estack_ax_v = ~(uint64_t) estack_ax_v;
1866 estack_ax_t = REG_U64;
1867 next_pc += sizeof(struct unary_op);
1868 PO;
1869 }
1870
1871 OP(FILTER_OP_UNARY_PLUS_S64):
1872 OP(FILTER_OP_UNARY_PLUS_DOUBLE):
1873 {
1874 next_pc += sizeof(struct unary_op);
1875 PO;
1876 }
1877 OP(FILTER_OP_UNARY_MINUS_S64):
1878 {
1879 estack_ax_v = -estack_ax_v;
1880 next_pc += sizeof(struct unary_op);
1881 PO;
1882 }
1883 OP(FILTER_OP_UNARY_MINUS_DOUBLE):
1884 {
1885 estack_ax(stack, top)->u.d = -estack_ax(stack, top)->u.d;
1886 next_pc += sizeof(struct unary_op);
1887 PO;
1888 }
1889 OP(FILTER_OP_UNARY_NOT_S64):
1890 {
1891 estack_ax_v = !estack_ax_v;
1892 estack_ax_t = REG_S64;
1893 next_pc += sizeof(struct unary_op);
1894 PO;
1895 }
1896 OP(FILTER_OP_UNARY_NOT_DOUBLE):
1897 {
1898 estack_ax_v = !estack_ax(stack, top)->u.d;
1899 estack_ax_t = REG_S64;
1900 next_pc += sizeof(struct unary_op);
1901 PO;
1902 }
1903
1904 /* logical */
1905 OP(FILTER_OP_AND):
1906 {
1907 struct logical_op *insn = (struct logical_op *) pc;
1908
1909 if (estack_ax_t != REG_S64 && estack_ax_t != REG_U64) {
1910 ret = -EINVAL;
1911 goto end;
1912 }
1913 /* If AX is 0, skip and evaluate to 0 */
1914 if (unlikely(estack_ax_v == 0)) {
1915 dbg_printf("Jumping to bytecode offset %u\n",
1916 (unsigned int) insn->skip_offset);
1917 next_pc = start_pc + insn->skip_offset;
1918 } else {
1919 /* Pop 1 when jump not taken */
1920 estack_pop(stack, top, ax, bx, ax_t, bx_t);
1921 next_pc += sizeof(struct logical_op);
1922 }
1923 PO;
1924 }
1925 OP(FILTER_OP_OR):
1926 {
1927 struct logical_op *insn = (struct logical_op *) pc;
1928
1929 if (estack_ax_t != REG_S64 && estack_ax_t != REG_U64) {
1930 ret = -EINVAL;
1931 goto end;
1932 }
1933 /* If AX is nonzero, skip and evaluate to 1 */
1934 if (unlikely(estack_ax_v != 0)) {
1935 estack_ax_v = 1;
1936 dbg_printf("Jumping to bytecode offset %u\n",
1937 (unsigned int) insn->skip_offset);
1938 next_pc = start_pc + insn->skip_offset;
1939 } else {
1940 /* Pop 1 when jump not taken */
1941 estack_pop(stack, top, ax, bx, ax_t, bx_t);
1942 next_pc += sizeof(struct logical_op);
1943 }
1944 PO;
1945 }
1946
1947
1948 /* load field ref */
1949 OP(FILTER_OP_LOAD_FIELD_REF_STRING):
1950 {
1951 struct load_op *insn = (struct load_op *) pc;
1952 struct field_ref *ref = (struct field_ref *) insn->data;
1953
1954 dbg_printf("load field ref offset %u type string\n",
1955 ref->offset);
1956 estack_push(stack, top, ax, bx, ax_t, bx_t);
1957 estack_ax(stack, top)->u.s.str =
1958 *(const char * const *) &interpreter_stack_data[ref->offset];
1959 if (unlikely(!estack_ax(stack, top)->u.s.str)) {
1960 dbg_printf("Filter warning: loading a NULL string.\n");
1961 ret = -EINVAL;
1962 goto end;
1963 }
1964 estack_ax(stack, top)->u.s.seq_len = SIZE_MAX;
1965 estack_ax(stack, top)->u.s.literal_type =
1966 ESTACK_STRING_LITERAL_TYPE_NONE;
1967 estack_ax_t = REG_STRING;
1968 dbg_printf("ref load string %s\n", estack_ax(stack, top)->u.s.str);
1969 next_pc += sizeof(struct load_op) + sizeof(struct field_ref);
1970 PO;
1971 }
1972
1973 OP(FILTER_OP_LOAD_FIELD_REF_SEQUENCE):
1974 {
1975 struct load_op *insn = (struct load_op *) pc;
1976 struct field_ref *ref = (struct field_ref *) insn->data;
1977
1978 dbg_printf("load field ref offset %u type sequence\n",
1979 ref->offset);
1980 estack_push(stack, top, ax, bx, ax_t, bx_t);
1981 estack_ax(stack, top)->u.s.seq_len =
1982 *(unsigned long *) &interpreter_stack_data[ref->offset];
1983 estack_ax(stack, top)->u.s.str =
1984 *(const char **) (&interpreter_stack_data[ref->offset
1985 + sizeof(unsigned long)]);
1986 estack_ax_t = REG_STRING;
1987 if (unlikely(!estack_ax(stack, top)->u.s.str)) {
1988 dbg_printf("Filter warning: loading a NULL sequence.\n");
1989 ret = -EINVAL;
1990 goto end;
1991 }
1992 estack_ax(stack, top)->u.s.literal_type =
1993 ESTACK_STRING_LITERAL_TYPE_NONE;
1994 next_pc += sizeof(struct load_op) + sizeof(struct field_ref);
1995 PO;
1996 }
1997
1998 OP(FILTER_OP_LOAD_FIELD_REF_S64):
1999 {
2000 struct load_op *insn = (struct load_op *) pc;
2001 struct field_ref *ref = (struct field_ref *) insn->data;
2002
2003 dbg_printf("load field ref offset %u type s64\n",
2004 ref->offset);
2005 estack_push(stack, top, ax, bx, ax_t, bx_t);
2006 estack_ax_v =
2007 ((struct literal_numeric *) &interpreter_stack_data[ref->offset])->v;
2008 estack_ax_t = REG_S64;
2009 dbg_printf("ref load s64 %" PRIi64 "\n", estack_ax_v);
2010 next_pc += sizeof(struct load_op) + sizeof(struct field_ref);
2011 PO;
2012 }
2013
2014 OP(FILTER_OP_LOAD_FIELD_REF_DOUBLE):
2015 {
2016 struct load_op *insn = (struct load_op *) pc;
2017 struct field_ref *ref = (struct field_ref *) insn->data;
2018
2019 dbg_printf("load field ref offset %u type double\n",
2020 ref->offset);
2021 estack_push(stack, top, ax, bx, ax_t, bx_t);
2022 memcpy(&estack_ax(stack, top)->u.d, &interpreter_stack_data[ref->offset],
2023 sizeof(struct literal_double));
2024 estack_ax_t = REG_DOUBLE;
2025 dbg_printf("ref load double %g\n", estack_ax(stack, top)->u.d);
2026 next_pc += sizeof(struct load_op) + sizeof(struct field_ref);
2027 PO;
2028 }
2029
2030 /* load from immediate operand */
2031 OP(FILTER_OP_LOAD_STRING):
2032 {
2033 struct load_op *insn = (struct load_op *) pc;
2034
2035 dbg_printf("load string %s\n", insn->data);
2036 estack_push(stack, top, ax, bx, ax_t, bx_t);
2037 estack_ax(stack, top)->u.s.str = insn->data;
2038 estack_ax(stack, top)->u.s.seq_len = SIZE_MAX;
2039 estack_ax(stack, top)->u.s.literal_type =
2040 ESTACK_STRING_LITERAL_TYPE_PLAIN;
2041 estack_ax_t = REG_STRING;
2042 next_pc += sizeof(struct load_op) + strlen(insn->data) + 1;
2043 PO;
2044 }
2045
2046 OP(FILTER_OP_LOAD_STAR_GLOB_STRING):
2047 {
2048 struct load_op *insn = (struct load_op *) pc;
2049
2050 dbg_printf("load globbing pattern %s\n", insn->data);
2051 estack_push(stack, top, ax, bx, ax_t, bx_t);
2052 estack_ax(stack, top)->u.s.str = insn->data;
2053 estack_ax(stack, top)->u.s.seq_len = SIZE_MAX;
2054 estack_ax(stack, top)->u.s.literal_type =
2055 ESTACK_STRING_LITERAL_TYPE_STAR_GLOB;
2056 estack_ax_t = REG_STAR_GLOB_STRING;
2057 next_pc += sizeof(struct load_op) + strlen(insn->data) + 1;
2058 PO;
2059 }
2060
2061 OP(FILTER_OP_LOAD_S64):
2062 {
2063 struct load_op *insn = (struct load_op *) pc;
2064
2065 estack_push(stack, top, ax, bx, ax_t, bx_t);
2066 estack_ax_v = ((struct literal_numeric *) insn->data)->v;
2067 estack_ax_t = REG_S64;
2068 dbg_printf("load s64 %" PRIi64 "\n", estack_ax_v);
2069 next_pc += sizeof(struct load_op)
2070 + sizeof(struct literal_numeric);
2071 PO;
2072 }
2073
2074 OP(FILTER_OP_LOAD_DOUBLE):
2075 {
2076 struct load_op *insn = (struct load_op *) pc;
2077
2078 estack_push(stack, top, ax, bx, ax_t, bx_t);
2079 memcpy(&estack_ax(stack, top)->u.d, insn->data,
2080 sizeof(struct literal_double));
2081 estack_ax_t = REG_DOUBLE;
2082 dbg_printf("load double %g\n", estack_ax(stack, top)->u.d);
2083 next_pc += sizeof(struct load_op)
2084 + sizeof(struct literal_double);
2085 PO;
2086 }
2087
2088 /* cast */
2089 OP(FILTER_OP_CAST_TO_S64):
2090 {
2091 /* Dynamic typing. */
2092 switch (estack_ax_t) {
2093 case REG_S64:
2094 JUMP_TO(FILTER_OP_CAST_NOP);
2095 case REG_DOUBLE:
2096 JUMP_TO(FILTER_OP_CAST_DOUBLE_TO_S64);
2097 case REG_U64:
2098 estack_ax_t = REG_S64;
2099 next_pc += sizeof(struct cast_op);
2100 case REG_STRING: /* Fall-through */
2101 case REG_STAR_GLOB_STRING:
2102 ret = -EINVAL;
2103 goto end;
2104 default:
2105 ERR("Unknown filter register type (%d)",
2106 (int) estack_ax_t);
2107 ret = -EINVAL;
2108 goto end;
2109 }
2110 }
2111
2112 OP(FILTER_OP_CAST_DOUBLE_TO_S64):
2113 {
2114 estack_ax_v = (int64_t) estack_ax(stack, top)->u.d;
2115 estack_ax_t = REG_S64;
2116 next_pc += sizeof(struct cast_op);
2117 PO;
2118 }
2119
2120 OP(FILTER_OP_CAST_NOP):
2121 {
2122 next_pc += sizeof(struct cast_op);
2123 PO;
2124 }
2125
2126 /* get context ref */
2127 OP(FILTER_OP_GET_CONTEXT_REF):
2128 {
2129 struct load_op *insn = (struct load_op *) pc;
2130 struct field_ref *ref = (struct field_ref *) insn->data;
2131 struct lttng_ctx_field *ctx_field;
2132 struct lttng_ctx_value v;
2133
2134 dbg_printf("get context ref offset %u type dynamic\n",
2135 ref->offset);
2136 ctx_field = &ctx->fields[ref->offset];
2137 ctx_field->get_value(ctx_field, &v);
2138 estack_push(stack, top, ax, bx, ax_t, bx_t);
2139 switch (v.sel) {
2140 case LTTNG_UST_DYNAMIC_TYPE_NONE:
2141 ret = -EINVAL;
2142 goto end;
2143 case LTTNG_UST_DYNAMIC_TYPE_S64:
2144 estack_ax_v = v.u.s64;
2145 estack_ax_t = REG_S64;
2146 dbg_printf("ref get context dynamic s64 %" PRIi64 "\n", estack_ax_v);
2147 break;
2148 case LTTNG_UST_DYNAMIC_TYPE_DOUBLE:
2149 estack_ax(stack, top)->u.d = v.u.d;
2150 estack_ax_t = REG_DOUBLE;
2151 dbg_printf("ref get context dynamic double %g\n", estack_ax(stack, top)->u.d);
2152 break;
2153 case LTTNG_UST_DYNAMIC_TYPE_STRING:
2154 estack_ax(stack, top)->u.s.str = v.u.str;
2155 if (unlikely(!estack_ax(stack, top)->u.s.str)) {
2156 dbg_printf("Filter warning: loading a NULL string.\n");
2157 ret = -EINVAL;
2158 goto end;
2159 }
2160 estack_ax(stack, top)->u.s.seq_len = SIZE_MAX;
2161 estack_ax(stack, top)->u.s.literal_type =
2162 ESTACK_STRING_LITERAL_TYPE_NONE;
2163 dbg_printf("ref get context dynamic string %s\n", estack_ax(stack, top)->u.s.str);
2164 estack_ax_t = REG_STRING;
2165 break;
2166 default:
2167 dbg_printf("Filter warning: unknown dynamic type (%d).\n", (int) v.sel);
2168 ret = -EINVAL;
2169 goto end;
2170 }
2171 next_pc += sizeof(struct load_op) + sizeof(struct field_ref);
2172 PO;
2173 }
2174
2175 OP(FILTER_OP_GET_CONTEXT_REF_STRING):
2176 {
2177 struct load_op *insn = (struct load_op *) pc;
2178 struct field_ref *ref = (struct field_ref *) insn->data;
2179 struct lttng_ctx_field *ctx_field;
2180 struct lttng_ctx_value v;
2181
2182 dbg_printf("get context ref offset %u type string\n",
2183 ref->offset);
2184 ctx_field = &ctx->fields[ref->offset];
2185 ctx_field->get_value(ctx_field, &v);
2186 estack_push(stack, top, ax, bx, ax_t, bx_t);
2187 estack_ax(stack, top)->u.s.str = v.u.str;
2188 if (unlikely(!estack_ax(stack, top)->u.s.str)) {
2189 dbg_printf("Filter warning: loading a NULL string.\n");
2190 ret = -EINVAL;
2191 goto end;
2192 }
2193 estack_ax(stack, top)->u.s.seq_len = SIZE_MAX;
2194 estack_ax(stack, top)->u.s.literal_type =
2195 ESTACK_STRING_LITERAL_TYPE_NONE;
2196 estack_ax_t = REG_STRING;
2197 dbg_printf("ref get context string %s\n", estack_ax(stack, top)->u.s.str);
2198 next_pc += sizeof(struct load_op) + sizeof(struct field_ref);
2199 PO;
2200 }
2201
2202 OP(FILTER_OP_GET_CONTEXT_REF_S64):
2203 {
2204 struct load_op *insn = (struct load_op *) pc;
2205 struct field_ref *ref = (struct field_ref *) insn->data;
2206 struct lttng_ctx_field *ctx_field;
2207 struct lttng_ctx_value v;
2208
2209 dbg_printf("get context ref offset %u type s64\n",
2210 ref->offset);
2211 ctx_field = &ctx->fields[ref->offset];
2212 ctx_field->get_value(ctx_field, &v);
2213 estack_push(stack, top, ax, bx, ax_t, bx_t);
2214 estack_ax_v = v.u.s64;
2215 estack_ax_t = REG_S64;
2216 dbg_printf("ref get context s64 %" PRIi64 "\n", estack_ax_v);
2217 next_pc += sizeof(struct load_op) + sizeof(struct field_ref);
2218 PO;
2219 }
2220
2221 OP(FILTER_OP_GET_CONTEXT_REF_DOUBLE):
2222 {
2223 struct load_op *insn = (struct load_op *) pc;
2224 struct field_ref *ref = (struct field_ref *) insn->data;
2225 struct lttng_ctx_field *ctx_field;
2226 struct lttng_ctx_value v;
2227
2228 dbg_printf("get context ref offset %u type double\n",
2229 ref->offset);
2230 ctx_field = &ctx->fields[ref->offset];
2231 ctx_field->get_value(ctx_field, &v);
2232 estack_push(stack, top, ax, bx, ax_t, bx_t);
2233 memcpy(&estack_ax(stack, top)->u.d, &v.u.d, sizeof(struct literal_double));
2234 estack_ax_t = REG_DOUBLE;
2235 dbg_printf("ref get context double %g\n", estack_ax(stack, top)->u.d);
2236 next_pc += sizeof(struct load_op) + sizeof(struct field_ref);
2237 PO;
2238 }
2239
2240 OP(FILTER_OP_GET_CONTEXT_ROOT):
2241 {
2242 dbg_printf("op get context root\n");
2243 estack_push(stack, top, ax, bx, ax_t, bx_t);
2244 estack_ax(stack, top)->u.ptr.type = LOAD_ROOT_CONTEXT;
2245 /* "field" only needed for variants. */
2246 estack_ax(stack, top)->u.ptr.field = NULL;
2247 estack_ax_t = REG_PTR;
2248 next_pc += sizeof(struct load_op);
2249 PO;
2250 }
2251
2252 OP(FILTER_OP_GET_APP_CONTEXT_ROOT):
2253 {
2254 dbg_printf("op get app context root\n");
2255 estack_push(stack, top, ax, bx, ax_t, bx_t);
2256 estack_ax(stack, top)->u.ptr.type = LOAD_ROOT_APP_CONTEXT;
2257 /* "field" only needed for variants. */
2258 estack_ax(stack, top)->u.ptr.field = NULL;
2259 estack_ax_t = REG_PTR;
2260 next_pc += sizeof(struct load_op);
2261 PO;
2262 }
2263
2264 OP(FILTER_OP_GET_PAYLOAD_ROOT):
2265 {
2266 dbg_printf("op get app payload root\n");
2267 estack_push(stack, top, ax, bx, ax_t, bx_t);
2268 estack_ax(stack, top)->u.ptr.type = LOAD_ROOT_PAYLOAD;
2269 estack_ax(stack, top)->u.ptr.ptr = interpreter_stack_data;
2270 /* "field" only needed for variants. */
2271 estack_ax(stack, top)->u.ptr.field = NULL;
2272 estack_ax_t = REG_PTR;
2273 next_pc += sizeof(struct load_op);
2274 PO;
2275 }
2276
2277 OP(FILTER_OP_GET_SYMBOL):
2278 {
2279 dbg_printf("op get symbol\n");
2280 switch (estack_ax(stack, top)->u.ptr.type) {
2281 case LOAD_OBJECT:
2282 ERR("Nested fields not implemented yet.");
2283 ret = -EINVAL;
2284 goto end;
2285 case LOAD_ROOT_CONTEXT:
2286 case LOAD_ROOT_APP_CONTEXT:
2287 case LOAD_ROOT_PAYLOAD:
2288 /*
2289 * symbol lookup is performed by
2290 * specialization.
2291 */
2292 ret = -EINVAL;
2293 goto end;
2294 }
2295 next_pc += sizeof(struct load_op) + sizeof(struct get_symbol);
2296 PO;
2297 }
2298
2299 OP(FILTER_OP_GET_SYMBOL_FIELD):
2300 {
2301 /*
2302 * Used for first variant encountered in a
2303 * traversal. Variants are not implemented yet.
2304 */
2305 ret = -EINVAL;
2306 goto end;
2307 }
2308
2309 OP(FILTER_OP_GET_INDEX_U16):
2310 {
2311 struct load_op *insn = (struct load_op *) pc;
2312 struct get_index_u16 *index = (struct get_index_u16 *) insn->data;
2313
2314 dbg_printf("op get index u16\n");
2315 ret = dynamic_get_index(ctx, bytecode, index->index, estack_ax(stack, top));
2316 if (ret)
2317 goto end;
2318 estack_ax_v = estack_ax(stack, top)->u.v;
2319 estack_ax_t = estack_ax(stack, top)->type;
2320 next_pc += sizeof(struct load_op) + sizeof(struct get_index_u16);
2321 PO;
2322 }
2323
2324 OP(FILTER_OP_GET_INDEX_U64):
2325 {
2326 struct load_op *insn = (struct load_op *) pc;
2327 struct get_index_u64 *index = (struct get_index_u64 *) insn->data;
2328
2329 dbg_printf("op get index u64\n");
2330 ret = dynamic_get_index(ctx, bytecode, index->index, estack_ax(stack, top));
2331 if (ret)
2332 goto end;
2333 estack_ax_v = estack_ax(stack, top)->u.v;
2334 estack_ax_t = estack_ax(stack, top)->type;
2335 next_pc += sizeof(struct load_op) + sizeof(struct get_index_u64);
2336 PO;
2337 }
2338
2339 OP(FILTER_OP_LOAD_FIELD):
2340 {
2341 dbg_printf("op load field\n");
2342 ret = dynamic_load_field(estack_ax(stack, top));
2343 if (ret)
2344 goto end;
2345 estack_ax_v = estack_ax(stack, top)->u.v;
2346 estack_ax_t = estack_ax(stack, top)->type;
2347 next_pc += sizeof(struct load_op);
2348 PO;
2349 }
2350
2351 OP(FILTER_OP_LOAD_FIELD_S8):
2352 {
2353 dbg_printf("op load field s8\n");
2354
2355 estack_ax_v = *(int8_t *) estack_ax(stack, top)->u.ptr.ptr;
2356 estack_ax_t = REG_S64;
2357 next_pc += sizeof(struct load_op);
2358 PO;
2359 }
2360 OP(FILTER_OP_LOAD_FIELD_S16):
2361 {
2362 dbg_printf("op load field s16\n");
2363
2364 estack_ax_v = *(int16_t *) estack_ax(stack, top)->u.ptr.ptr;
2365 estack_ax_t = REG_S64;
2366 next_pc += sizeof(struct load_op);
2367 PO;
2368 }
2369 OP(FILTER_OP_LOAD_FIELD_S32):
2370 {
2371 dbg_printf("op load field s32\n");
2372
2373 estack_ax_v = *(int32_t *) estack_ax(stack, top)->u.ptr.ptr;
2374 estack_ax_t = REG_S64;
2375 next_pc += sizeof(struct load_op);
2376 PO;
2377 }
2378 OP(FILTER_OP_LOAD_FIELD_S64):
2379 {
2380 dbg_printf("op load field s64\n");
2381
2382 estack_ax_v = *(int64_t *) estack_ax(stack, top)->u.ptr.ptr;
2383 estack_ax_t = REG_S64;
2384 next_pc += sizeof(struct load_op);
2385 PO;
2386 }
2387 OP(FILTER_OP_LOAD_FIELD_U8):
2388 {
2389 dbg_printf("op load field u8\n");
2390
2391 estack_ax_v = *(uint8_t *) estack_ax(stack, top)->u.ptr.ptr;
2392 estack_ax_t = REG_U64;
2393 next_pc += sizeof(struct load_op);
2394 PO;
2395 }
2396 OP(FILTER_OP_LOAD_FIELD_U16):
2397 {
2398 dbg_printf("op load field u16\n");
2399
2400 estack_ax_v = *(uint16_t *) estack_ax(stack, top)->u.ptr.ptr;
2401 estack_ax_t = REG_U64;
2402 next_pc += sizeof(struct load_op);
2403 PO;
2404 }
2405 OP(FILTER_OP_LOAD_FIELD_U32):
2406 {
2407 dbg_printf("op load field u32\n");
2408
2409 estack_ax_v = *(uint32_t *) estack_ax(stack, top)->u.ptr.ptr;
2410 estack_ax_t = REG_U64;
2411 next_pc += sizeof(struct load_op);
2412 PO;
2413 }
2414 OP(FILTER_OP_LOAD_FIELD_U64):
2415 {
2416 dbg_printf("op load field u64\n");
2417
2418 estack_ax_v = *(uint64_t *) estack_ax(stack, top)->u.ptr.ptr;
2419 estack_ax_t = REG_U64;
2420 next_pc += sizeof(struct load_op);
2421 PO;
2422 }
2423 OP(FILTER_OP_LOAD_FIELD_DOUBLE):
2424 {
2425 dbg_printf("op load field double\n");
2426
2427 memcpy(&estack_ax(stack, top)->u.d,
2428 estack_ax(stack, top)->u.ptr.ptr,
2429 sizeof(struct literal_double));
2430 estack_ax(stack, top)->type = REG_DOUBLE;
2431 next_pc += sizeof(struct load_op);
2432 PO;
2433 }
2434
2435 OP(FILTER_OP_LOAD_FIELD_STRING):
2436 {
2437 const char *str;
2438
2439 dbg_printf("op load field string\n");
2440 str = (const char *) estack_ax(stack, top)->u.ptr.ptr;
2441 estack_ax(stack, top)->u.s.str = str;
2442 if (unlikely(!estack_ax(stack, top)->u.s.str)) {
2443 dbg_printf("Filter warning: loading a NULL string.\n");
2444 ret = -EINVAL;
2445 goto end;
2446 }
2447 estack_ax(stack, top)->u.s.seq_len = SIZE_MAX;
2448 estack_ax(stack, top)->u.s.literal_type =
2449 ESTACK_STRING_LITERAL_TYPE_NONE;
2450 estack_ax(stack, top)->type = REG_STRING;
2451 next_pc += sizeof(struct load_op);
2452 PO;
2453 }
2454
2455 OP(FILTER_OP_LOAD_FIELD_SEQUENCE):
2456 {
2457 const char *ptr;
2458
2459 dbg_printf("op load field string sequence\n");
2460 ptr = estack_ax(stack, top)->u.ptr.ptr;
2461 estack_ax(stack, top)->u.s.seq_len = *(unsigned long *) ptr;
2462 estack_ax(stack, top)->u.s.str = *(const char **) (ptr + sizeof(unsigned long));
2463 estack_ax(stack, top)->type = REG_STRING;
2464 if (unlikely(!estack_ax(stack, top)->u.s.str)) {
2465 dbg_printf("Filter warning: loading a NULL sequence.\n");
2466 ret = -EINVAL;
2467 goto end;
2468 }
2469 estack_ax(stack, top)->u.s.literal_type =
2470 ESTACK_STRING_LITERAL_TYPE_NONE;
2471 next_pc += sizeof(struct load_op);
2472 PO;
2473 }
2474
2475 END_OP
2476 end:
2477 /* Return _DISCARD on error. */
2478 if (ret)
2479 return LTTNG_FILTER_DISCARD;
2480
2481 if (output) {
2482 return lttng_bytecode_interpret_format_output(estack_ax(stack, top),
2483 output);
2484 }
2485
2486 return retval;
2487 }
2488
2489 uint64_t lttng_filter_interpret_bytecode(void *filter_data,
2490 const char *filter_stack_data)
2491 {
2492 return bytecode_interpret(filter_data, filter_stack_data, NULL);
2493 }
2494
2495 #undef START_OP
2496 #undef OP
2497 #undef PO
2498 #undef END_OP
This page took 0.135988 seconds and 5 git commands to generate.