bytecode: set register type to `REG_PTR` even if not used
[lttng-ust.git] / liblttng-ust / lttng-filter-interpreter.c
CommitLineData
97b58163
MD
1/*
2 * lttng-filter-interpreter.c
3 *
4 * LTTng UST filter interpreter.
5 *
7e50015d 6 * Copyright (C) 2010-2016 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
97b58163 7 *
7e50015d
MD
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:
97b58163 14 *
7e50015d
MD
15 * The above copyright notice and this permission notice shall be included in
16 * all copies or substantial portions of the Software.
97b58163 17 *
7e50015d
MD
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.
97b58163
MD
25 */
26
3fbec7dc 27#define _LGPL_SOURCE
b4051ad8 28#include <stddef.h>
a63d0dc8 29#include <stdint.h>
b4051ad8 30#include <urcu-pointer.h>
f3503ba9
FD
31#include <byteswap.h>
32
3208818b 33#include <lttng/ust-endian.h>
f3503ba9
FD
34#include <lttng/ust-events.h>
35
97b58163 36#include "lttng-filter.h"
3151a51d 37#include "string-utils.h"
97b58163 38
f3503ba9 39
97b58163
MD
40/*
41 * -1: wildcard found.
42 * -2: unknown escape char.
43 * 0: normal char.
44 */
45
46static
47int 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
3151a51d 66/*
a63d0dc8 67 * Returns SIZE_MAX if the string is null-terminated, or the number of
3151a51d
PP
68 * characters if not.
69 */
70static
71size_t get_str_or_seq_len(const struct estack_entry *entry)
72{
a63d0dc8 73 return entry->u.s.seq_len;
3151a51d
PP
74}
75
76static
77int 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
97b58163 102static
9b33aac4 103int stack_strcmp(struct estack *stack, int top, const char *cmp_type)
97b58163 104{
9b33aac4 105 const char *p = estack_bx(stack, top)->u.s.str, *q = estack_ax(stack, top)->u.s.str;
97b58163
MD
106 int ret;
107 int diff;
108
109 for (;;) {
110 int escaped_r0 = 0;
111
332335cd
MD
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') {
5cf8141d 114 return 0;
a0928c1e 115 } else {
3151a51d
PP
116 if (estack_ax(stack, top)->u.s.literal_type ==
117 ESTACK_STRING_LITERAL_TYPE_PLAIN) {
5cf8141d
MD
118 ret = parse_char(&q);
119 if (ret == -1)
120 return 0;
121 }
122 return -1;
a0928c1e 123 }
97b58163 124 }
332335cd 125 if (unlikely(q - estack_ax(stack, top)->u.s.str >= estack_ax(stack, top)->u.s.seq_len || *q == '\0')) {
3151a51d
PP
126 if (estack_bx(stack, top)->u.s.literal_type ==
127 ESTACK_STRING_LITERAL_TYPE_PLAIN) {
3e6a0694
MD
128 ret = parse_char(&p);
129 if (ret == -1)
130 return 0;
a0928c1e 131 }
3e6a0694 132 return 1;
97b58163 133 }
3151a51d
PP
134 if (estack_bx(stack, top)->u.s.literal_type ==
135 ESTACK_STRING_LITERAL_TYPE_PLAIN) {
97b58163
MD
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 }
3151a51d
PP
144 if (estack_ax(stack, top)->u.s.literal_type ==
145 ESTACK_STRING_LITERAL_TYPE_PLAIN) {
97b58163
MD
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
f3503ba9 169uint64_t lttng_filter_interpret_bytecode_false(void *filter_data,
97b58163
MD
170 const char *filter_stack_data)
171{
4526ba69 172 return LTTNG_FILTER_DISCARD;
97b58163
MD
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
53569322
MD
190#define OP(name) jump_target_##name: __attribute__((unused)); \
191 case name
97b58163
MD
192
193#define PO break
194
195#define END_OP } \
196 }
197
53569322
MD
198#define JUMP_TO(name) \
199 goto jump_target_##name
200
97b58163
MD
201#else
202
203/*
204 * Dispatch-table based interpreter.
205 */
206
207#define START_OP \
47e5f13e 208 start_pc = &bytecode->code[0]; \
97b58163
MD
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) \
215LABEL_##name
216
217#define PO \
218 pc = next_pc; \
219 goto *dispatch[*(filter_opcode_t *) pc];
220
221#define END_OP
222
53569322
MD
223#define JUMP_TO(name) \
224 goto LABEL_##name
225
97b58163
MD
226#endif
227
d97f9b78
MD
228#define IS_INTEGER_REGISTER(reg_type) \
229 (reg_type == REG_U64 || reg_type == REG_S64)
230
47e5f13e
MD
231static 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;
f3503ba9 243 ptr->field = field;
47e5f13e
MD
244
245 switch (field->type.atype) {
246 case atype_integer:
247 ctx_field->get_value(ctx_field, &v);
218deb69 248 if (field->type.u.integer.signedness) {
47e5f13e
MD
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;
218deb69
MD
258 case atype_enum: /* Fall-through */
259 case atype_enum_nestable:
47e5f13e 260 {
218deb69 261 const struct lttng_integer_type *itype;
47e5f13e 262
218deb69
MD
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 }
47e5f13e
MD
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:
218deb69
MD
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) {
47e5f13e
MD
295 ERR("Array nesting only supports integer types.");
296 return -EINVAL;
297 }
218deb69 298 if (field->type.u.array_nestable.elem_type->u.integer.encoding == lttng_encode_none) {
47e5f13e
MD
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:
218deb69
MD
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) {
47e5f13e
MD
321 ERR("Sequence nesting only supports integer types.");
322 return -EINVAL;
323 }
218deb69 324 if (field->type.u.sequence_nestable.elem_type->u.integer.encoding == lttng_encode_none) {
47e5f13e
MD
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;
0245c698 339 ctx_field->get_value(ctx_field, &v);
47e5f13e
MD
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
b77aaa1b 380static int dynamic_get_index(struct lttng_ctx *ctx,
47e5f13e
MD
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
47e5f13e
MD
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;
f3503ba9
FD
402 assert(stack_top->u.ptr.field->type.atype == atype_array ||
403 stack_top->u.ptr.field->type.atype == atype_array_nestable);
47e5f13e
MD
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;
f3503ba9
FD
422 assert(stack_top->u.ptr.field->type.atype == atype_sequence ||
423 stack_top->u.ptr.field->type.atype == atype_sequence_nestable);
47e5f13e
MD
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 {
47e5f13e
MD
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;
f3503ba9 456 stack_top->u.ptr.field = gid->field;
47e5f13e
MD
457 break;
458 }
d312cd35
FD
459
460 stack_top->type = REG_PTR;
461
47e5f13e
MD
462 return 0;
463
464end:
465 return ret;
466}
467
468static 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;
d97f9b78 528 stack_top->type = REG_U64;
47e5f13e
MD
529 break;
530 case OBJECT_TYPE_U16:
531 {
532 uint16_t tmp;
533
055d27d7 534 dbg_printf("op load field u16\n");
47e5f13e
MD
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;
d97f9b78 539 stack_top->type = REG_U64;
47e5f13e
MD
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;
d97f9b78 551 stack_top->type = REG_U64;
47e5f13e
MD
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;
d97f9b78 563 stack_top->type = REG_U64;
47e5f13e
MD
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
625end:
626 return ret;
627}
628
f3503ba9
FD
629static
630int lttng_bytecode_interpret_format_output(struct estack_entry *ax,
631 struct lttng_interpreter_output *output)
632{
633 int ret;
634
635again:
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
8a92ed2a
MD
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 */
f3503ba9
FD
706static
707uint64_t bytecode_interpret(void *interpreter_data,
708 const char *interpreter_stack_data,
709 struct lttng_interpreter_output *output)
97b58163 710{
f3503ba9 711 struct bytecode_runtime *bytecode = interpreter_data;
b77aaa1b 712 struct lttng_ctx *ctx = rcu_dereference(*bytecode->p.pctx);
97b58163
MD
713 void *pc, *next_pc, *start_pc;
714 int ret = -EINVAL;
8b82df15 715 uint64_t retval = 0;
0305960f
MD
716 struct estack _stack;
717 struct estack *stack = &_stack;
9b33aac4 718 register int64_t ax = 0, bx = 0;
53569322 719 register enum entry_type ax_t = REG_UNKNOWN, bx_t = REG_UNKNOWN;
9b33aac4 720 register int top = FILTER_STACK_EMPTY;
97b58163
MD
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,
0039e2d8
MD
733 [ FILTER_OP_BIT_RSHIFT ] = &&LABEL_FILTER_OP_BIT_RSHIFT,
734 [ FILTER_OP_BIT_LSHIFT ] = &&LABEL_FILTER_OP_BIT_LSHIFT,
47e5f13e
MD
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,
97b58163
MD
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
3151a51d
PP
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
97b58163
MD
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
dbea82ec
MD
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
97b58163
MD
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
77aa5901 805 /* load field ref */
97b58163
MD
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
77aa5901 812 /* load from immediate operand */
97b58163 813 [ FILTER_OP_LOAD_STRING ] = &&LABEL_FILTER_OP_LOAD_STRING,
3151a51d 814 [ FILTER_OP_LOAD_STAR_GLOB_STRING ] = &&LABEL_FILTER_OP_LOAD_STAR_GLOB_STRING,
97b58163
MD
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,
77aa5901
MD
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,
47e5f13e
MD
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,
0039e2d8
MD
851
852 [ FILTER_OP_UNARY_BIT_NOT ] = &&LABEL_FILTER_OP_UNARY_BIT_NOT,
93c591bb
MD
853
854 [ FILTER_OP_RETURN_S64 ] = &&LABEL_FILTER_OP_RETURN_S64,
97b58163
MD
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 */
47e5f13e 865 ERR("unknown bytecode op %u",
97b58163
MD
866 (unsigned int) *(filter_opcode_t *) pc);
867 ret = -EINVAL;
868 goto end;
869
870 OP(FILTER_OP_RETURN):
4526ba69 871 /* LTTNG_FILTER_DISCARD or LTTNG_FILTER_RECORD_FLAG */
47e5f13e
MD
872 /* Handle dynamic typing. */
873 switch (estack_ax_t) {
874 case REG_S64:
d97f9b78 875 case REG_U64:
47e5f13e
MD
876 retval = !!estack_ax_v;
877 break;
878 case REG_DOUBLE:
879 case REG_STRING:
f3503ba9
FD
880 case REG_PTR:
881 if (!output) {
882 ret = -EINVAL;
883 goto end;
884 }
885 retval = 0;
886 break;
47e5f13e 887 case REG_STAR_GLOB_STRING:
f3503ba9 888 case REG_UNKNOWN:
47e5f13e
MD
889 default:
890 ret = -EINVAL;
891 goto end;
892 }
97b58163
MD
893 ret = 0;
894 goto end;
895
93c591bb 896 OP(FILTER_OP_RETURN_S64):
4526ba69 897 /* LTTNG_FILTER_DISCARD or LTTNG_FILTER_RECORD_FLAG */
93c591bb
MD
898 retval = !!estack_ax_v;
899 ret = 0;
900 goto end;
901
97b58163
MD
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):
47e5f13e 908 ERR("unsupported bytecode op %u",
97b58163
MD
909 (unsigned int) *(filter_opcode_t *) pc);
910 ret = -EINVAL;
911 goto end;
912
913 OP(FILTER_OP_EQ):
53569322
MD
914 {
915 /* Dynamic typing. */
916 switch (estack_ax_t) {
d97f9b78
MD
917 case REG_S64: /* Fall-through */
918 case REG_U64:
53569322 919 switch (estack_bx_t) {
d97f9b78
MD
920 case REG_S64: /* Fall-through */
921 case REG_U64:
53569322
MD
922 JUMP_TO(FILTER_OP_EQ_S64);
923 case REG_DOUBLE:
924 JUMP_TO(FILTER_OP_EQ_DOUBLE_S64);
3151a51d
PP
925 case REG_STRING: /* Fall-through */
926 case REG_STAR_GLOB_STRING:
53569322
MD
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) {
d97f9b78
MD
938 case REG_S64: /* Fall-through */
939 case REG_U64:
53569322
MD
940 JUMP_TO(FILTER_OP_EQ_S64_DOUBLE);
941 case REG_DOUBLE:
942 JUMP_TO(FILTER_OP_EQ_DOUBLE);
3151a51d
PP
943 case REG_STRING: /* Fall-through */
944 case REG_STAR_GLOB_STRING:
53569322
MD
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 */
d97f9b78 957 case REG_U64: /* Fall-through */
53569322
MD
958 case REG_DOUBLE:
959 ret = -EINVAL;
960 goto end;
961 case REG_STRING:
962 JUMP_TO(FILTER_OP_EQ_STRING);
3151a51d
PP
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 */
d97f9b78 975 case REG_U64: /* Fall-through */
3151a51d
PP
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;
53569322
MD
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 }
97b58163 998 OP(FILTER_OP_NE):
53569322
MD
999 {
1000 /* Dynamic typing. */
1001 switch (estack_ax_t) {
d97f9b78
MD
1002 case REG_S64: /* Fall-through */
1003 case REG_U64:
53569322 1004 switch (estack_bx_t) {
d97f9b78
MD
1005 case REG_S64: /* Fall-through */
1006 case REG_U64:
53569322
MD
1007 JUMP_TO(FILTER_OP_NE_S64);
1008 case REG_DOUBLE:
1009 JUMP_TO(FILTER_OP_NE_DOUBLE_S64);
3151a51d
PP
1010 case REG_STRING: /* Fall-through */
1011 case REG_STAR_GLOB_STRING:
53569322
MD
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) {
d97f9b78
MD
1023 case REG_S64: /* Fall-through */
1024 case REG_U64:
53569322
MD
1025 JUMP_TO(FILTER_OP_NE_S64_DOUBLE);
1026 case REG_DOUBLE:
1027 JUMP_TO(FILTER_OP_NE_DOUBLE);
3151a51d
PP
1028 case REG_STRING: /* Fall-through */
1029 case REG_STAR_GLOB_STRING:
53569322
MD
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 */
d97f9b78 1042 case REG_U64:
53569322
MD
1043 case REG_DOUBLE:
1044 ret = -EINVAL;
1045 goto end;
1046 case REG_STRING:
1047 JUMP_TO(FILTER_OP_NE_STRING);
3151a51d
PP
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 */
d97f9b78 1060 case REG_U64:
3151a51d
PP
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;
53569322
MD
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 }
97b58163 1083 OP(FILTER_OP_GT):
53569322
MD
1084 {
1085 /* Dynamic typing. */
1086 switch (estack_ax_t) {
d97f9b78
MD
1087 case REG_S64: /* Fall-through */
1088 case REG_U64:
53569322 1089 switch (estack_bx_t) {
d97f9b78
MD
1090 case REG_S64: /* Fall-through */
1091 case REG_U64:
53569322
MD
1092 JUMP_TO(FILTER_OP_GT_S64);
1093 case REG_DOUBLE:
1094 JUMP_TO(FILTER_OP_GT_DOUBLE_S64);
3151a51d
PP
1095 case REG_STRING: /* Fall-through */
1096 case REG_STAR_GLOB_STRING:
53569322
MD
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) {
d97f9b78
MD
1108 case REG_S64: /* Fall-through */
1109 case REG_U64:
53569322
MD
1110 JUMP_TO(FILTER_OP_GT_S64_DOUBLE);
1111 case REG_DOUBLE:
1112 JUMP_TO(FILTER_OP_GT_DOUBLE);
3151a51d
PP
1113 case REG_STRING: /* Fall-through */
1114 case REG_STAR_GLOB_STRING:
53569322
MD
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 */
d97f9b78 1127 case REG_U64: /* Fall-through */
3151a51d
PP
1128 case REG_DOUBLE: /* Fall-through */
1129 case REG_STAR_GLOB_STRING:
53569322
MD
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 }
97b58163 1148 OP(FILTER_OP_LT):
53569322
MD
1149 {
1150 /* Dynamic typing. */
1151 switch (estack_ax_t) {
d97f9b78
MD
1152 case REG_S64: /* Fall-through */
1153 case REG_U64:
53569322 1154 switch (estack_bx_t) {
d97f9b78
MD
1155 case REG_S64: /* Fall-through */
1156 case REG_U64:
53569322
MD
1157 JUMP_TO(FILTER_OP_LT_S64);
1158 case REG_DOUBLE:
1159 JUMP_TO(FILTER_OP_LT_DOUBLE_S64);
3151a51d
PP
1160 case REG_STRING: /* Fall-through */
1161 case REG_STAR_GLOB_STRING:
53569322
MD
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) {
d97f9b78
MD
1173 case REG_S64: /* Fall-through */
1174 case REG_U64:
53569322
MD
1175 JUMP_TO(FILTER_OP_LT_S64_DOUBLE);
1176 case REG_DOUBLE:
1177 JUMP_TO(FILTER_OP_LT_DOUBLE);
3151a51d
PP
1178 case REG_STRING: /* Fall-through */
1179 case REG_STAR_GLOB_STRING:
53569322
MD
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 */
d97f9b78 1192 case REG_U64: /* Fall-through */
3151a51d
PP
1193 case REG_DOUBLE: /* Fall-through */
1194 case REG_STAR_GLOB_STRING:
53569322
MD
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 }
97b58163 1213 OP(FILTER_OP_GE):
53569322
MD
1214 {
1215 /* Dynamic typing. */
1216 switch (estack_ax_t) {
d97f9b78
MD
1217 case REG_S64: /* Fall-through */
1218 case REG_U64:
53569322 1219 switch (estack_bx_t) {
d97f9b78
MD
1220 case REG_S64: /* Fall-through */
1221 case REG_U64:
53569322
MD
1222 JUMP_TO(FILTER_OP_GE_S64);
1223 case REG_DOUBLE:
1224 JUMP_TO(FILTER_OP_GE_DOUBLE_S64);
3151a51d
PP
1225 case REG_STRING: /* Fall-through */
1226 case REG_STAR_GLOB_STRING:
53569322
MD
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) {
d97f9b78
MD
1238 case REG_S64: /* Fall-through */
1239 case REG_U64:
53569322
MD
1240 JUMP_TO(FILTER_OP_GE_S64_DOUBLE);
1241 case REG_DOUBLE:
1242 JUMP_TO(FILTER_OP_GE_DOUBLE);
3151a51d
PP
1243 case REG_STRING: /* Fall-through */
1244 case REG_STAR_GLOB_STRING:
53569322
MD
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 */
d97f9b78 1257 case REG_U64: /* Fall-through */
3151a51d
PP
1258 case REG_DOUBLE: /* Fall-through */
1259 case REG_STAR_GLOB_STRING:
53569322
MD
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 }
97b58163 1278 OP(FILTER_OP_LE):
53569322
MD
1279 {
1280 /* Dynamic typing. */
1281 switch (estack_ax_t) {
d97f9b78
MD
1282 case REG_S64: /* Fall-through */
1283 case REG_U64:
53569322 1284 switch (estack_bx_t) {
d97f9b78
MD
1285 case REG_S64: /* Fall-through */
1286 case REG_U64:
53569322
MD
1287 JUMP_TO(FILTER_OP_LE_S64);
1288 case REG_DOUBLE:
1289 JUMP_TO(FILTER_OP_LE_DOUBLE_S64);
3151a51d
PP
1290 case REG_STRING: /* Fall-through */
1291 case REG_STAR_GLOB_STRING:
53569322
MD
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) {
d97f9b78
MD
1303 case REG_S64: /* Fall-through */
1304 case REG_U64:
53569322
MD
1305 JUMP_TO(FILTER_OP_LE_S64_DOUBLE);
1306 case REG_DOUBLE:
1307 JUMP_TO(FILTER_OP_LE_DOUBLE);
3151a51d
PP
1308 case REG_STRING: /* Fall-through */
1309 case REG_STAR_GLOB_STRING:
53569322
MD
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 */
d97f9b78 1322 case REG_U64: /* Fall-through */
3151a51d
PP
1323 case REG_DOUBLE: /* Fall-through */
1324 case REG_STAR_GLOB_STRING:
53569322
MD
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 }
97b58163
MD
1343
1344 OP(FILTER_OP_EQ_STRING):
1345 {
0305960f
MD
1346 int res;
1347
9b33aac4 1348 res = (stack_strcmp(stack, top, "==") == 0);
53569322 1349 estack_pop(stack, top, ax, bx, ax_t, bx_t);
9b33aac4 1350 estack_ax_v = res;
53569322 1351 estack_ax_t = REG_S64;
97b58163
MD
1352 next_pc += sizeof(struct binary_op);
1353 PO;
1354 }
1355 OP(FILTER_OP_NE_STRING):
1356 {
0305960f
MD
1357 int res;
1358
9b33aac4 1359 res = (stack_strcmp(stack, top, "!=") != 0);
53569322 1360 estack_pop(stack, top, ax, bx, ax_t, bx_t);
9b33aac4 1361 estack_ax_v = res;
53569322 1362 estack_ax_t = REG_S64;
97b58163
MD
1363 next_pc += sizeof(struct binary_op);
1364 PO;
1365 }
1366 OP(FILTER_OP_GT_STRING):
1367 {
0305960f
MD
1368 int res;
1369
9b33aac4 1370 res = (stack_strcmp(stack, top, ">") > 0);
53569322 1371 estack_pop(stack, top, ax, bx, ax_t, bx_t);
9b33aac4 1372 estack_ax_v = res;
53569322 1373 estack_ax_t = REG_S64;
97b58163
MD
1374 next_pc += sizeof(struct binary_op);
1375 PO;
1376 }
1377 OP(FILTER_OP_LT_STRING):
1378 {
0305960f
MD
1379 int res;
1380
9b33aac4 1381 res = (stack_strcmp(stack, top, "<") < 0);
53569322 1382 estack_pop(stack, top, ax, bx, ax_t, bx_t);
9b33aac4 1383 estack_ax_v = res;
53569322 1384 estack_ax_t = REG_S64;
97b58163
MD
1385 next_pc += sizeof(struct binary_op);
1386 PO;
1387 }
1388 OP(FILTER_OP_GE_STRING):
1389 {
0305960f
MD
1390 int res;
1391
9b33aac4 1392 res = (stack_strcmp(stack, top, ">=") >= 0);
53569322 1393 estack_pop(stack, top, ax, bx, ax_t, bx_t);
9b33aac4 1394 estack_ax_v = res;
53569322 1395 estack_ax_t = REG_S64;
97b58163
MD
1396 next_pc += sizeof(struct binary_op);
1397 PO;
1398 }
1399 OP(FILTER_OP_LE_STRING):
1400 {
0305960f
MD
1401 int res;
1402
9b33aac4 1403 res = (stack_strcmp(stack, top, "<=") <= 0);
53569322 1404 estack_pop(stack, top, ax, bx, ax_t, bx_t);
9b33aac4 1405 estack_ax_v = res;
53569322 1406 estack_ax_t = REG_S64;
97b58163
MD
1407 next_pc += sizeof(struct binary_op);
1408 PO;
1409 }
1410
3151a51d
PP
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
97b58163
MD
1434 OP(FILTER_OP_EQ_S64):
1435 {
0305960f
MD
1436 int res;
1437
9b33aac4 1438 res = (estack_bx_v == estack_ax_v);
53569322 1439 estack_pop(stack, top, ax, bx, ax_t, bx_t);
9b33aac4 1440 estack_ax_v = res;
53569322 1441 estack_ax_t = REG_S64;
97b58163
MD
1442 next_pc += sizeof(struct binary_op);
1443 PO;
1444 }
1445 OP(FILTER_OP_NE_S64):
1446 {
0305960f
MD
1447 int res;
1448
9b33aac4 1449 res = (estack_bx_v != estack_ax_v);
53569322 1450 estack_pop(stack, top, ax, bx, ax_t, bx_t);
9b33aac4 1451 estack_ax_v = res;
53569322 1452 estack_ax_t = REG_S64;
97b58163
MD
1453 next_pc += sizeof(struct binary_op);
1454 PO;
1455 }
1456 OP(FILTER_OP_GT_S64):
1457 {
0305960f
MD
1458 int res;
1459
9b33aac4 1460 res = (estack_bx_v > estack_ax_v);
53569322 1461 estack_pop(stack, top, ax, bx, ax_t, bx_t);
9b33aac4 1462 estack_ax_v = res;
53569322 1463 estack_ax_t = REG_S64;
97b58163
MD
1464 next_pc += sizeof(struct binary_op);
1465 PO;
1466 }
1467 OP(FILTER_OP_LT_S64):
1468 {
0305960f
MD
1469 int res;
1470
9b33aac4 1471 res = (estack_bx_v < estack_ax_v);
53569322 1472 estack_pop(stack, top, ax, bx, ax_t, bx_t);
9b33aac4 1473 estack_ax_v = res;
53569322 1474 estack_ax_t = REG_S64;
97b58163
MD
1475 next_pc += sizeof(struct binary_op);
1476 PO;
1477 }
1478 OP(FILTER_OP_GE_S64):
1479 {
0305960f
MD
1480 int res;
1481
9b33aac4 1482 res = (estack_bx_v >= estack_ax_v);
53569322 1483 estack_pop(stack, top, ax, bx, ax_t, bx_t);
9b33aac4 1484 estack_ax_v = res;
53569322 1485 estack_ax_t = REG_S64;
97b58163
MD
1486 next_pc += sizeof(struct binary_op);
1487 PO;
1488 }
1489 OP(FILTER_OP_LE_S64):
1490 {
0305960f
MD
1491 int res;
1492
9b33aac4 1493 res = (estack_bx_v <= estack_ax_v);
53569322 1494 estack_pop(stack, top, ax, bx, ax_t, bx_t);
9b33aac4 1495 estack_ax_v = res;
53569322 1496 estack_ax_t = REG_S64;
97b58163
MD
1497 next_pc += sizeof(struct binary_op);
1498 PO;
1499 }
1500
1501 OP(FILTER_OP_EQ_DOUBLE):
1502 {
0305960f
MD
1503 int res;
1504
9b33aac4 1505 res = (estack_bx(stack, top)->u.d == estack_ax(stack, top)->u.d);
53569322 1506 estack_pop(stack, top, ax, bx, ax_t, bx_t);
9b33aac4 1507 estack_ax_v = res;
53569322 1508 estack_ax_t = REG_S64;
97b58163
MD
1509 next_pc += sizeof(struct binary_op);
1510 PO;
1511 }
1512 OP(FILTER_OP_NE_DOUBLE):
1513 {
0305960f
MD
1514 int res;
1515
9b33aac4 1516 res = (estack_bx(stack, top)->u.d != estack_ax(stack, top)->u.d);
53569322 1517 estack_pop(stack, top, ax, bx, ax_t, bx_t);
9b33aac4 1518 estack_ax_v = res;
53569322 1519 estack_ax_t = REG_S64;
97b58163
MD
1520 next_pc += sizeof(struct binary_op);
1521 PO;
1522 }
1523 OP(FILTER_OP_GT_DOUBLE):
1524 {
0305960f
MD
1525 int res;
1526
9b33aac4 1527 res = (estack_bx(stack, top)->u.d > estack_ax(stack, top)->u.d);
53569322 1528 estack_pop(stack, top, ax, bx, ax_t, bx_t);
9b33aac4 1529 estack_ax_v = res;
53569322 1530 estack_ax_t = REG_S64;
97b58163
MD
1531 next_pc += sizeof(struct binary_op);
1532 PO;
1533 }
1534 OP(FILTER_OP_LT_DOUBLE):
1535 {
0305960f
MD
1536 int res;
1537
9b33aac4 1538 res = (estack_bx(stack, top)->u.d < estack_ax(stack, top)->u.d);
53569322 1539 estack_pop(stack, top, ax, bx, ax_t, bx_t);
9b33aac4 1540 estack_ax_v = res;
53569322 1541 estack_ax_t = REG_S64;
97b58163
MD
1542 next_pc += sizeof(struct binary_op);
1543 PO;
1544 }
1545 OP(FILTER_OP_GE_DOUBLE):
1546 {
0305960f
MD
1547 int res;
1548
9b33aac4 1549 res = (estack_bx(stack, top)->u.d >= estack_ax(stack, top)->u.d);
53569322 1550 estack_pop(stack, top, ax, bx, ax_t, bx_t);
9b33aac4 1551 estack_ax_v = res;
53569322 1552 estack_ax_t = REG_S64;
97b58163
MD
1553 next_pc += sizeof(struct binary_op);
1554 PO;
1555 }
1556 OP(FILTER_OP_LE_DOUBLE):
1557 {
0305960f
MD
1558 int res;
1559
9b33aac4 1560 res = (estack_bx(stack, top)->u.d <= estack_ax(stack, top)->u.d);
53569322 1561 estack_pop(stack, top, ax, bx, ax_t, bx_t);
9b33aac4 1562 estack_ax_v = res;
53569322 1563 estack_ax_t = REG_S64;
dbea82ec
MD
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
9b33aac4 1573 res = (estack_bx(stack, top)->u.d == estack_ax_v);
53569322 1574 estack_pop(stack, top, ax, bx, ax_t, bx_t);
9b33aac4 1575 estack_ax_v = res;
53569322 1576 estack_ax_t = REG_S64;
dbea82ec
MD
1577 next_pc += sizeof(struct binary_op);
1578 PO;
1579 }
1580 OP(FILTER_OP_NE_DOUBLE_S64):
1581 {
1582 int res;
1583
9b33aac4 1584 res = (estack_bx(stack, top)->u.d != estack_ax_v);
53569322 1585 estack_pop(stack, top, ax, bx, ax_t, bx_t);
9b33aac4 1586 estack_ax_v = res;
53569322 1587 estack_ax_t = REG_S64;
dbea82ec
MD
1588 next_pc += sizeof(struct binary_op);
1589 PO;
1590 }
1591 OP(FILTER_OP_GT_DOUBLE_S64):
1592 {
1593 int res;
1594
9b33aac4 1595 res = (estack_bx(stack, top)->u.d > estack_ax_v);
53569322 1596 estack_pop(stack, top, ax, bx, ax_t, bx_t);
9b33aac4 1597 estack_ax_v = res;
53569322 1598 estack_ax_t = REG_S64;
dbea82ec
MD
1599 next_pc += sizeof(struct binary_op);
1600 PO;
1601 }
1602 OP(FILTER_OP_LT_DOUBLE_S64):
1603 {
1604 int res;
1605
9b33aac4 1606 res = (estack_bx(stack, top)->u.d < estack_ax_v);
53569322 1607 estack_pop(stack, top, ax, bx, ax_t, bx_t);
9b33aac4 1608 estack_ax_v = res;
53569322 1609 estack_ax_t = REG_S64;
dbea82ec
MD
1610 next_pc += sizeof(struct binary_op);
1611 PO;
1612 }
1613 OP(FILTER_OP_GE_DOUBLE_S64):
1614 {
1615 int res;
1616
9b33aac4 1617 res = (estack_bx(stack, top)->u.d >= estack_ax_v);
53569322 1618 estack_pop(stack, top, ax, bx, ax_t, bx_t);
9b33aac4 1619 estack_ax_v = res;
53569322 1620 estack_ax_t = REG_S64;
dbea82ec
MD
1621 next_pc += sizeof(struct binary_op);
1622 PO;
1623 }
1624 OP(FILTER_OP_LE_DOUBLE_S64):
1625 {
1626 int res;
1627
9b33aac4 1628 res = (estack_bx(stack, top)->u.d <= estack_ax_v);
53569322 1629 estack_pop(stack, top, ax, bx, ax_t, bx_t);
9b33aac4 1630 estack_ax_v = res;
53569322 1631 estack_ax_t = REG_S64;
dbea82ec
MD
1632 next_pc += sizeof(struct binary_op);
1633 PO;
1634 }
1635
1636 OP(FILTER_OP_EQ_S64_DOUBLE):
1637 {
1638 int res;
1639
9b33aac4 1640 res = (estack_bx_v == estack_ax(stack, top)->u.d);
53569322 1641 estack_pop(stack, top, ax, bx, ax_t, bx_t);
9b33aac4 1642 estack_ax_v = res;
53569322 1643 estack_ax_t = REG_S64;
dbea82ec
MD
1644 next_pc += sizeof(struct binary_op);
1645 PO;
1646 }
1647 OP(FILTER_OP_NE_S64_DOUBLE):
1648 {
1649 int res;
1650
9b33aac4 1651 res = (estack_bx_v != estack_ax(stack, top)->u.d);
53569322 1652 estack_pop(stack, top, ax, bx, ax_t, bx_t);
9b33aac4 1653 estack_ax_v = res;
53569322 1654 estack_ax_t = REG_S64;
dbea82ec
MD
1655 next_pc += sizeof(struct binary_op);
1656 PO;
1657 }
1658 OP(FILTER_OP_GT_S64_DOUBLE):
1659 {
1660 int res;
1661
9b33aac4 1662 res = (estack_bx_v > estack_ax(stack, top)->u.d);
53569322 1663 estack_pop(stack, top, ax, bx, ax_t, bx_t);
9b33aac4 1664 estack_ax_v = res;
53569322 1665 estack_ax_t = REG_S64;
dbea82ec
MD
1666 next_pc += sizeof(struct binary_op);
1667 PO;
1668 }
1669 OP(FILTER_OP_LT_S64_DOUBLE):
1670 {
1671 int res;
1672
9b33aac4 1673 res = (estack_bx_v < estack_ax(stack, top)->u.d);
53569322 1674 estack_pop(stack, top, ax, bx, ax_t, bx_t);
9b33aac4 1675 estack_ax_v = res;
53569322 1676 estack_ax_t = REG_S64;
dbea82ec
MD
1677 next_pc += sizeof(struct binary_op);
1678 PO;
1679 }
1680 OP(FILTER_OP_GE_S64_DOUBLE):
1681 {
1682 int res;
1683
9b33aac4 1684 res = (estack_bx_v >= estack_ax(stack, top)->u.d);
53569322 1685 estack_pop(stack, top, ax, bx, ax_t, bx_t);
9b33aac4 1686 estack_ax_v = res;
53569322 1687 estack_ax_t = REG_S64;
dbea82ec
MD
1688 next_pc += sizeof(struct binary_op);
1689 PO;
1690 }
1691 OP(FILTER_OP_LE_S64_DOUBLE):
1692 {
1693 int res;
1694
9b33aac4 1695 res = (estack_bx_v <= estack_ax(stack, top)->u.d);
53569322 1696 estack_pop(stack, top, ax, bx, ax_t, bx_t);
9b33aac4 1697 estack_ax_v = res;
53569322 1698 estack_ax_t = REG_S64;
97b58163
MD
1699 next_pc += sizeof(struct binary_op);
1700 PO;
1701 }
0039e2d8
MD
1702 OP(FILTER_OP_BIT_RSHIFT):
1703 {
1704 int64_t res;
1705
d97f9b78 1706 if (!IS_INTEGER_REGISTER(estack_ax_t) || !IS_INTEGER_REGISTER(estack_bx_t)) {
0039e2d8
MD
1707 ret = -EINVAL;
1708 goto end;
1709 }
d97f9b78 1710
3703f1d2
MD
1711 /* Catch undefined behavior. */
1712 if (caa_unlikely(estack_ax_v < 0 || estack_ax_v >= 64)) {
1713 ret = -EINVAL;
1714 goto end;
1715 }
4e8f9a89 1716 res = ((uint64_t) estack_bx_v >> (uint32_t) estack_ax_v);
0039e2d8
MD
1717 estack_pop(stack, top, ax, bx, ax_t, bx_t);
1718 estack_ax_v = res;
d97f9b78 1719 estack_ax_t = REG_U64;
0039e2d8
MD
1720 next_pc += sizeof(struct binary_op);
1721 PO;
1722 }
1723 OP(FILTER_OP_BIT_LSHIFT):
1724 {
1725 int64_t res;
1726
d97f9b78 1727 if (!IS_INTEGER_REGISTER(estack_ax_t) || !IS_INTEGER_REGISTER(estack_bx_t)) {
0039e2d8
MD
1728 ret = -EINVAL;
1729 goto end;
1730 }
d97f9b78 1731
3703f1d2
MD
1732 /* Catch undefined behavior. */
1733 if (caa_unlikely(estack_ax_v < 0 || estack_ax_v >= 64)) {
1734 ret = -EINVAL;
1735 goto end;
1736 }
4e8f9a89 1737 res = ((uint64_t) estack_bx_v << (uint32_t) estack_ax_v);
0039e2d8
MD
1738 estack_pop(stack, top, ax, bx, ax_t, bx_t);
1739 estack_ax_v = res;
d97f9b78 1740 estack_ax_t = REG_U64;
0039e2d8
MD
1741 next_pc += sizeof(struct binary_op);
1742 PO;
1743 }
47e5f13e
MD
1744 OP(FILTER_OP_BIT_AND):
1745 {
1746 int64_t res;
1747
d97f9b78 1748 if (!IS_INTEGER_REGISTER(estack_ax_t) || !IS_INTEGER_REGISTER(estack_bx_t)) {
47e5f13e
MD
1749 ret = -EINVAL;
1750 goto end;
1751 }
1752
4e8f9a89 1753 res = ((uint64_t) estack_bx_v & (uint64_t) estack_ax_v);
47e5f13e
MD
1754 estack_pop(stack, top, ax, bx, ax_t, bx_t);
1755 estack_ax_v = res;
d97f9b78 1756 estack_ax_t = REG_U64;
47e5f13e
MD
1757 next_pc += sizeof(struct binary_op);
1758 PO;
1759 }
1760 OP(FILTER_OP_BIT_OR):
1761 {
1762 int64_t res;
1763
d97f9b78 1764 if (!IS_INTEGER_REGISTER(estack_ax_t) || !IS_INTEGER_REGISTER(estack_bx_t)) {
47e5f13e
MD
1765 ret = -EINVAL;
1766 goto end;
1767 }
1768
4e8f9a89 1769 res = ((uint64_t) estack_bx_v | (uint64_t) estack_ax_v);
47e5f13e
MD
1770 estack_pop(stack, top, ax, bx, ax_t, bx_t);
1771 estack_ax_v = res;
d97f9b78 1772 estack_ax_t = REG_U64;
47e5f13e
MD
1773 next_pc += sizeof(struct binary_op);
1774 PO;
1775 }
1776 OP(FILTER_OP_BIT_XOR):
1777 {
1778 int64_t res;
1779
d97f9b78 1780 if (!IS_INTEGER_REGISTER(estack_ax_t) || !IS_INTEGER_REGISTER(estack_bx_t)) {
47e5f13e
MD
1781 ret = -EINVAL;
1782 goto end;
1783 }
1784
4e8f9a89 1785 res = ((uint64_t) estack_bx_v ^ (uint64_t) estack_ax_v);
47e5f13e
MD
1786 estack_pop(stack, top, ax, bx, ax_t, bx_t);
1787 estack_ax_v = res;
d97f9b78 1788 estack_ax_t = REG_U64;
47e5f13e
MD
1789 next_pc += sizeof(struct binary_op);
1790 PO;
1791 }
97b58163
MD
1792
1793 /* unary */
1794 OP(FILTER_OP_UNARY_PLUS):
53569322
MD
1795 {
1796 /* Dynamic typing. */
1797 switch (estack_ax_t) {
1798 case REG_S64: /* Fall-through. */
d97f9b78 1799 case REG_U64:
53569322
MD
1800 JUMP_TO(FILTER_OP_UNARY_PLUS_S64);
1801 case REG_DOUBLE:
1802 JUMP_TO(FILTER_OP_UNARY_PLUS_DOUBLE);
3151a51d
PP
1803 case REG_STRING: /* Fall-through */
1804 case REG_STAR_GLOB_STRING:
53569322
MD
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 }
97b58163 1814 OP(FILTER_OP_UNARY_MINUS):
53569322
MD
1815 {
1816 /* Dynamic typing. */
1817 switch (estack_ax_t) {
d97f9b78
MD
1818 case REG_S64: /* Fall-through. */
1819 case REG_U64:
53569322
MD
1820 JUMP_TO(FILTER_OP_UNARY_MINUS_S64);
1821 case REG_DOUBLE:
1822 JUMP_TO(FILTER_OP_UNARY_MINUS_DOUBLE);
3151a51d
PP
1823 case REG_STRING: /* Fall-through */
1824 case REG_STAR_GLOB_STRING:
53569322
MD
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 }
97b58163 1834 OP(FILTER_OP_UNARY_NOT):
53569322
MD
1835 {
1836 /* Dynamic typing. */
1837 switch (estack_ax_t) {
d97f9b78
MD
1838 case REG_S64: /* Fall-through. */
1839 case REG_U64:
53569322
MD
1840 JUMP_TO(FILTER_OP_UNARY_NOT_S64);
1841 case REG_DOUBLE:
1842 JUMP_TO(FILTER_OP_UNARY_NOT_DOUBLE);
3151a51d
PP
1843 case REG_STRING: /* Fall-through */
1844 case REG_STAR_GLOB_STRING:
53569322
MD
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 }
97b58163 1856
0039e2d8
MD
1857 OP(FILTER_OP_UNARY_BIT_NOT):
1858 {
1859 /* Dynamic typing. */
d97f9b78 1860 if (!IS_INTEGER_REGISTER(estack_ax_t)) {
0039e2d8
MD
1861 ret = -EINVAL;
1862 goto end;
1863 }
1864
4e8f9a89 1865 estack_ax_v = ~(uint64_t) estack_ax_v;
d97f9b78 1866 estack_ax_t = REG_U64;
0039e2d8
MD
1867 next_pc += sizeof(struct unary_op);
1868 PO;
1869 }
1870
97b58163
MD
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 {
9b33aac4 1879 estack_ax_v = -estack_ax_v;
97b58163
MD
1880 next_pc += sizeof(struct unary_op);
1881 PO;
1882 }
1883 OP(FILTER_OP_UNARY_MINUS_DOUBLE):
1884 {
9b33aac4 1885 estack_ax(stack, top)->u.d = -estack_ax(stack, top)->u.d;
97b58163
MD
1886 next_pc += sizeof(struct unary_op);
1887 PO;
1888 }
1889 OP(FILTER_OP_UNARY_NOT_S64):
1890 {
9b33aac4 1891 estack_ax_v = !estack_ax_v;
d97f9b78 1892 estack_ax_t = REG_S64;
97b58163
MD
1893 next_pc += sizeof(struct unary_op);
1894 PO;
1895 }
1896 OP(FILTER_OP_UNARY_NOT_DOUBLE):
1897 {
53569322
MD
1898 estack_ax_v = !estack_ax(stack, top)->u.d;
1899 estack_ax_t = REG_S64;
97b58163
MD
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
d97f9b78 1909 if (estack_ax_t != REG_S64 && estack_ax_t != REG_U64) {
53569322
MD
1910 ret = -EINVAL;
1911 goto end;
1912 }
0305960f 1913 /* If AX is 0, skip and evaluate to 0 */
9b33aac4 1914 if (unlikely(estack_ax_v == 0)) {
97b58163
MD
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 {
71c1ceeb 1919 /* Pop 1 when jump not taken */
53569322 1920 estack_pop(stack, top, ax, bx, ax_t, bx_t);
97b58163
MD
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
d97f9b78 1929 if (estack_ax_t != REG_S64 && estack_ax_t != REG_U64) {
53569322
MD
1930 ret = -EINVAL;
1931 goto end;
1932 }
0305960f 1933 /* If AX is nonzero, skip and evaluate to 1 */
9b33aac4
MD
1934 if (unlikely(estack_ax_v != 0)) {
1935 estack_ax_v = 1;
97b58163
MD
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 {
71c1ceeb 1940 /* Pop 1 when jump not taken */
53569322 1941 estack_pop(stack, top, ax, bx, ax_t, bx_t);
97b58163
MD
1942 next_pc += sizeof(struct logical_op);
1943 }
1944 PO;
1945 }
1946
1947
77aa5901 1948 /* load field ref */
97b58163
MD
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);
53569322 1956 estack_push(stack, top, ax, bx, ax_t, bx_t);
9b33aac4 1957 estack_ax(stack, top)->u.s.str =
f3503ba9 1958 *(const char * const *) &interpreter_stack_data[ref->offset];
9b33aac4 1959 if (unlikely(!estack_ax(stack, top)->u.s.str)) {
97b58163
MD
1960 dbg_printf("Filter warning: loading a NULL string.\n");
1961 ret = -EINVAL;
1962 goto end;
1963 }
a63d0dc8 1964 estack_ax(stack, top)->u.s.seq_len = SIZE_MAX;
3151a51d
PP
1965 estack_ax(stack, top)->u.s.literal_type =
1966 ESTACK_STRING_LITERAL_TYPE_NONE;
53569322 1967 estack_ax_t = REG_STRING;
9b33aac4 1968 dbg_printf("ref load string %s\n", estack_ax(stack, top)->u.s.str);
97b58163
MD
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);
53569322 1980 estack_push(stack, top, ax, bx, ax_t, bx_t);
9b33aac4 1981 estack_ax(stack, top)->u.s.seq_len =
f3503ba9 1982 *(unsigned long *) &interpreter_stack_data[ref->offset];
9b33aac4 1983 estack_ax(stack, top)->u.s.str =
f3503ba9 1984 *(const char **) (&interpreter_stack_data[ref->offset
97b58163 1985 + sizeof(unsigned long)]);
53569322 1986 estack_ax_t = REG_STRING;
9b33aac4 1987 if (unlikely(!estack_ax(stack, top)->u.s.str)) {
97b58163
MD
1988 dbg_printf("Filter warning: loading a NULL sequence.\n");
1989 ret = -EINVAL;
1990 goto end;
1991 }
3151a51d
PP
1992 estack_ax(stack, top)->u.s.literal_type =
1993 ESTACK_STRING_LITERAL_TYPE_NONE;
97b58163
MD
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);
53569322 2005 estack_push(stack, top, ax, bx, ax_t, bx_t);
9b33aac4 2006 estack_ax_v =
f3503ba9 2007 ((struct literal_numeric *) &interpreter_stack_data[ref->offset])->v;
53569322 2008 estack_ax_t = REG_S64;
9b33aac4 2009 dbg_printf("ref load s64 %" PRIi64 "\n", estack_ax_v);
97b58163
MD
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);
53569322 2021 estack_push(stack, top, ax, bx, ax_t, bx_t);
f3503ba9 2022 memcpy(&estack_ax(stack, top)->u.d, &interpreter_stack_data[ref->offset],
97b58163 2023 sizeof(struct literal_double));
53569322 2024 estack_ax_t = REG_DOUBLE;
9b33aac4 2025 dbg_printf("ref load double %g\n", estack_ax(stack, top)->u.d);
97b58163
MD
2026 next_pc += sizeof(struct load_op) + sizeof(struct field_ref);
2027 PO;
2028 }
2029
77aa5901 2030 /* load from immediate operand */
97b58163
MD
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);
53569322 2036 estack_push(stack, top, ax, bx, ax_t, bx_t);
9b33aac4 2037 estack_ax(stack, top)->u.s.str = insn->data;
a63d0dc8 2038 estack_ax(stack, top)->u.s.seq_len = SIZE_MAX;
3151a51d
PP
2039 estack_ax(stack, top)->u.s.literal_type =
2040 ESTACK_STRING_LITERAL_TYPE_PLAIN;
53569322 2041 estack_ax_t = REG_STRING;
97b58163
MD
2042 next_pc += sizeof(struct load_op) + strlen(insn->data) + 1;
2043 PO;
2044 }
2045
3151a51d
PP
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;
a63d0dc8 2053 estack_ax(stack, top)->u.s.seq_len = SIZE_MAX;
3151a51d
PP
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
97b58163
MD
2061 OP(FILTER_OP_LOAD_S64):
2062 {
2063 struct load_op *insn = (struct load_op *) pc;
2064
53569322 2065 estack_push(stack, top, ax, bx, ax_t, bx_t);
9b33aac4 2066 estack_ax_v = ((struct literal_numeric *) insn->data)->v;
53569322 2067 estack_ax_t = REG_S64;
9b33aac4 2068 dbg_printf("load s64 %" PRIi64 "\n", estack_ax_v);
97b58163
MD
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
53569322 2078 estack_push(stack, top, ax, bx, ax_t, bx_t);
9b33aac4 2079 memcpy(&estack_ax(stack, top)->u.d, insn->data,
97b58163 2080 sizeof(struct literal_double));
53569322
MD
2081 estack_ax_t = REG_DOUBLE;
2082 dbg_printf("load double %g\n", estack_ax(stack, top)->u.d);
97b58163
MD
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):
53569322
MD
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);
d97f9b78
MD
2097 case REG_U64:
2098 estack_ax_t = REG_S64;
2099 next_pc += sizeof(struct cast_op);
3151a51d
PP
2100 case REG_STRING: /* Fall-through */
2101 case REG_STAR_GLOB_STRING:
53569322
MD
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 }
97b58163
MD
2111
2112 OP(FILTER_OP_CAST_DOUBLE_TO_S64):
2113 {
9b33aac4 2114 estack_ax_v = (int64_t) estack_ax(stack, top)->u.d;
53569322 2115 estack_ax_t = REG_S64;
97b58163
MD
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
77aa5901 2126 /* get context ref */
53569322
MD
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;
53569322
MD
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);
53569322
MD
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 }
a63d0dc8 2160 estack_ax(stack, top)->u.s.seq_len = SIZE_MAX;
3151a51d
PP
2161 estack_ax(stack, top)->u.s.literal_type =
2162 ESTACK_STRING_LITERAL_TYPE_NONE;
53569322
MD
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
77aa5901
MD
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;
53569322 2180 struct lttng_ctx_value v;
77aa5901
MD
2181
2182 dbg_printf("get context ref offset %u type string\n",
2183 ref->offset);
53569322 2184 ctx_field = &ctx->fields[ref->offset];
77aa5901 2185 ctx_field->get_value(ctx_field, &v);
53569322
MD
2186 estack_push(stack, top, ax, bx, ax_t, bx_t);
2187 estack_ax(stack, top)->u.s.str = v.u.str;
77aa5901
MD
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 }
a63d0dc8 2193 estack_ax(stack, top)->u.s.seq_len = SIZE_MAX;
3151a51d
PP
2194 estack_ax(stack, top)->u.s.literal_type =
2195 ESTACK_STRING_LITERAL_TYPE_NONE;
53569322 2196 estack_ax_t = REG_STRING;
77aa5901
MD
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;
53569322 2207 struct lttng_ctx_value v;
77aa5901
MD
2208
2209 dbg_printf("get context ref offset %u type s64\n",
2210 ref->offset);
53569322 2211 ctx_field = &ctx->fields[ref->offset];
77aa5901 2212 ctx_field->get_value(ctx_field, &v);
53569322
MD
2213 estack_push(stack, top, ax, bx, ax_t, bx_t);
2214 estack_ax_v = v.u.s64;
2215 estack_ax_t = REG_S64;
77aa5901
MD
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;
53569322 2226 struct lttng_ctx_value v;
77aa5901
MD
2227
2228 dbg_printf("get context ref offset %u type double\n",
2229 ref->offset);
53569322 2230 ctx_field = &ctx->fields[ref->offset];
77aa5901 2231 ctx_field->get_value(ctx_field, &v);
53569322
MD
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;
77aa5901
MD
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
47e5f13e
MD
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;
f3503ba9 2269 estack_ax(stack, top)->u.ptr.ptr = interpreter_stack_data;
47e5f13e
MD
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");
b77aaa1b 2315 ret = dynamic_get_index(ctx, bytecode, index->index, estack_ax(stack, top));
47e5f13e
MD
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");
b77aaa1b 2330 ret = dynamic_get_index(ctx, bytecode, index->index, estack_ax(stack, top));
47e5f13e
MD
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;
d97f9b78 2392 estack_ax_t = REG_U64;
47e5f13e
MD
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;
d97f9b78 2401 estack_ax_t = REG_U64;
47e5f13e
MD
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;
d97f9b78 2410 estack_ax_t = REG_U64;
47e5f13e
MD
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;
d97f9b78 2419 estack_ax_t = REG_U64;
47e5f13e
MD
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
97b58163
MD
2475 END_OP
2476end:
4526ba69 2477 /* Return _DISCARD on error. */
97b58163 2478 if (ret)
4526ba69 2479 return LTTNG_FILTER_DISCARD;
f3503ba9
FD
2480
2481 if (output) {
2482 return lttng_bytecode_interpret_format_output(estack_ax(stack, top),
2483 output);
2484 }
2485
97b58163
MD
2486 return retval;
2487}
2488
f3503ba9
FD
2489uint64_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
97b58163
MD
2495#undef START_OP
2496#undef OP
2497#undef PO
2498#undef END_OP
This page took 0.143438 seconds and 4 git commands to generate.