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