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