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