filter: use SIZE_MAX rather than UINT_MAX and tuncating -1ULL
[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>
97b58163 30#include "lttng-filter.h"
3151a51d 31#include "string-utils.h"
97b58163
MD
32
33/*
34 * -1: wildcard found.
35 * -2: unknown escape char.
36 * 0: normal char.
37 */
38
39static
40int parse_char(const char **p)
41{
42 switch (**p) {
43 case '\\':
44 (*p)++;
45 switch (**p) {
46 case '\\':
47 case '*':
48 return 0;
49 default:
50 return -2;
51 }
52 case '*':
53 return -1;
54 default:
55 return 0;
56 }
57}
58
3151a51d 59/*
a63d0dc8 60 * Returns SIZE_MAX if the string is null-terminated, or the number of
3151a51d
PP
61 * characters if not.
62 */
63static
64size_t get_str_or_seq_len(const struct estack_entry *entry)
65{
a63d0dc8 66 return entry->u.s.seq_len;
3151a51d
PP
67}
68
69static
70int stack_star_glob_match(struct estack *stack, int top, const char *cmp_type)
71{
72 const char *pattern;
73 const char *candidate;
74 size_t pattern_len;
75 size_t candidate_len;
76
77 /* Find out which side is the pattern vs. the candidate. */
78 if (estack_ax(stack, top)->u.s.literal_type == ESTACK_STRING_LITERAL_TYPE_STAR_GLOB) {
79 pattern = estack_ax(stack, top)->u.s.str;
80 pattern_len = get_str_or_seq_len(estack_ax(stack, top));
81 candidate = estack_bx(stack, top)->u.s.str;
82 candidate_len = get_str_or_seq_len(estack_bx(stack, top));
83 } else {
84 pattern = estack_bx(stack, top)->u.s.str;
85 pattern_len = get_str_or_seq_len(estack_bx(stack, top));
86 candidate = estack_ax(stack, top)->u.s.str;
87 candidate_len = get_str_or_seq_len(estack_ax(stack, top));
88 }
89
90 /* Perform the match. Returns 0 when the result is true. */
91 return !strutils_star_glob_match(pattern, pattern_len, candidate,
92 candidate_len);
93}
94
97b58163 95static
9b33aac4 96int stack_strcmp(struct estack *stack, int top, const char *cmp_type)
97b58163 97{
9b33aac4 98 const char *p = estack_bx(stack, top)->u.s.str, *q = estack_ax(stack, top)->u.s.str;
97b58163
MD
99 int ret;
100 int diff;
101
102 for (;;) {
103 int escaped_r0 = 0;
104
332335cd
MD
105 if (unlikely(p - estack_bx(stack, top)->u.s.str >= estack_bx(stack, top)->u.s.seq_len || *p == '\0')) {
106 if (q - estack_ax(stack, top)->u.s.str >= estack_ax(stack, top)->u.s.seq_len || *q == '\0') {
5cf8141d 107 return 0;
a0928c1e 108 } else {
3151a51d
PP
109 if (estack_ax(stack, top)->u.s.literal_type ==
110 ESTACK_STRING_LITERAL_TYPE_PLAIN) {
5cf8141d
MD
111 ret = parse_char(&q);
112 if (ret == -1)
113 return 0;
114 }
115 return -1;
a0928c1e 116 }
97b58163 117 }
332335cd 118 if (unlikely(q - estack_ax(stack, top)->u.s.str >= estack_ax(stack, top)->u.s.seq_len || *q == '\0')) {
3151a51d
PP
119 if (estack_bx(stack, top)->u.s.literal_type ==
120 ESTACK_STRING_LITERAL_TYPE_PLAIN) {
3e6a0694
MD
121 ret = parse_char(&p);
122 if (ret == -1)
123 return 0;
a0928c1e 124 }
3e6a0694 125 return 1;
97b58163 126 }
3151a51d
PP
127 if (estack_bx(stack, top)->u.s.literal_type ==
128 ESTACK_STRING_LITERAL_TYPE_PLAIN) {
97b58163
MD
129 ret = parse_char(&p);
130 if (ret == -1) {
131 return 0;
132 } else if (ret == -2) {
133 escaped_r0 = 1;
134 }
135 /* else compare both char */
136 }
3151a51d
PP
137 if (estack_ax(stack, top)->u.s.literal_type ==
138 ESTACK_STRING_LITERAL_TYPE_PLAIN) {
97b58163
MD
139 ret = parse_char(&q);
140 if (ret == -1) {
141 return 0;
142 } else if (ret == -2) {
143 if (!escaped_r0)
144 return -1;
145 } else {
146 if (escaped_r0)
147 return 1;
148 }
149 } else {
150 if (escaped_r0)
151 return 1;
152 }
153 diff = *p - *q;
154 if (diff != 0)
155 break;
156 p++;
157 q++;
158 }
159 return diff;
160}
161
8a92ed2a 162uint64_t lttng_filter_false(void *filter_data,
97b58163
MD
163 const char *filter_stack_data)
164{
165 return 0;
166}
167
168#ifdef INTERPRETER_USE_SWITCH
169
170/*
171 * Fallback for compilers that do not support taking address of labels.
172 */
173
174#define START_OP \
175 start_pc = &bytecode->data[0]; \
176 for (pc = next_pc = start_pc; pc - start_pc < bytecode->len; \
177 pc = next_pc) { \
178 dbg_printf("Executing op %s (%u)\n", \
179 print_op((unsigned int) *(filter_opcode_t *) pc), \
180 (unsigned int) *(filter_opcode_t *) pc); \
181 switch (*(filter_opcode_t *) pc) {
182
53569322
MD
183#define OP(name) jump_target_##name: __attribute__((unused)); \
184 case name
97b58163
MD
185
186#define PO break
187
188#define END_OP } \
189 }
190
53569322
MD
191#define JUMP_TO(name) \
192 goto jump_target_##name
193
97b58163
MD
194#else
195
196/*
197 * Dispatch-table based interpreter.
198 */
199
200#define START_OP \
201 start_pc = &bytecode->data[0]; \
202 pc = next_pc = start_pc; \
203 if (unlikely(pc - start_pc >= bytecode->len)) \
204 goto end; \
205 goto *dispatch[*(filter_opcode_t *) pc];
206
207#define OP(name) \
208LABEL_##name
209
210#define PO \
211 pc = next_pc; \
212 goto *dispatch[*(filter_opcode_t *) pc];
213
214#define END_OP
215
53569322
MD
216#define JUMP_TO(name) \
217 goto LABEL_##name
218
97b58163
MD
219#endif
220
8a92ed2a
MD
221/*
222 * Return 0 (discard), or raise the 0x1 flag (log event).
223 * Currently, other flags are kept for future extensions and have no
224 * effect.
225 */
226uint64_t lttng_filter_interpret_bytecode(void *filter_data,
97b58163
MD
227 const char *filter_stack_data)
228{
229 struct bytecode_runtime *bytecode = filter_data;
53569322 230 struct lttng_session *session = bytecode->p.session;
97b58163
MD
231 void *pc, *next_pc, *start_pc;
232 int ret = -EINVAL;
8b82df15 233 uint64_t retval = 0;
0305960f
MD
234 struct estack _stack;
235 struct estack *stack = &_stack;
9b33aac4 236 register int64_t ax = 0, bx = 0;
53569322 237 register enum entry_type ax_t = REG_UNKNOWN, bx_t = REG_UNKNOWN;
9b33aac4 238 register int top = FILTER_STACK_EMPTY;
97b58163
MD
239#ifndef INTERPRETER_USE_SWITCH
240 static void *dispatch[NR_FILTER_OPS] = {
241 [ FILTER_OP_UNKNOWN ] = &&LABEL_FILTER_OP_UNKNOWN,
242
243 [ FILTER_OP_RETURN ] = &&LABEL_FILTER_OP_RETURN,
244
245 /* binary */
246 [ FILTER_OP_MUL ] = &&LABEL_FILTER_OP_MUL,
247 [ FILTER_OP_DIV ] = &&LABEL_FILTER_OP_DIV,
248 [ FILTER_OP_MOD ] = &&LABEL_FILTER_OP_MOD,
249 [ FILTER_OP_PLUS ] = &&LABEL_FILTER_OP_PLUS,
250 [ FILTER_OP_MINUS ] = &&LABEL_FILTER_OP_MINUS,
251 [ FILTER_OP_RSHIFT ] = &&LABEL_FILTER_OP_RSHIFT,
252 [ FILTER_OP_LSHIFT ] = &&LABEL_FILTER_OP_LSHIFT,
253 [ FILTER_OP_BIN_AND ] = &&LABEL_FILTER_OP_BIN_AND,
254 [ FILTER_OP_BIN_OR ] = &&LABEL_FILTER_OP_BIN_OR,
255 [ FILTER_OP_BIN_XOR ] = &&LABEL_FILTER_OP_BIN_XOR,
256
257 /* binary comparators */
258 [ FILTER_OP_EQ ] = &&LABEL_FILTER_OP_EQ,
259 [ FILTER_OP_NE ] = &&LABEL_FILTER_OP_NE,
260 [ FILTER_OP_GT ] = &&LABEL_FILTER_OP_GT,
261 [ FILTER_OP_LT ] = &&LABEL_FILTER_OP_LT,
262 [ FILTER_OP_GE ] = &&LABEL_FILTER_OP_GE,
263 [ FILTER_OP_LE ] = &&LABEL_FILTER_OP_LE,
264
265 /* string binary comparator */
266 [ FILTER_OP_EQ_STRING ] = &&LABEL_FILTER_OP_EQ_STRING,
267 [ FILTER_OP_NE_STRING ] = &&LABEL_FILTER_OP_NE_STRING,
268 [ FILTER_OP_GT_STRING ] = &&LABEL_FILTER_OP_GT_STRING,
269 [ FILTER_OP_LT_STRING ] = &&LABEL_FILTER_OP_LT_STRING,
270 [ FILTER_OP_GE_STRING ] = &&LABEL_FILTER_OP_GE_STRING,
271 [ FILTER_OP_LE_STRING ] = &&LABEL_FILTER_OP_LE_STRING,
272
3151a51d
PP
273 /* globbing pattern binary comparator */
274 [ FILTER_OP_EQ_STAR_GLOB_STRING ] = &&LABEL_FILTER_OP_EQ_STAR_GLOB_STRING,
275 [ FILTER_OP_NE_STAR_GLOB_STRING ] = &&LABEL_FILTER_OP_NE_STAR_GLOB_STRING,
276
97b58163
MD
277 /* s64 binary comparator */
278 [ FILTER_OP_EQ_S64 ] = &&LABEL_FILTER_OP_EQ_S64,
279 [ FILTER_OP_NE_S64 ] = &&LABEL_FILTER_OP_NE_S64,
280 [ FILTER_OP_GT_S64 ] = &&LABEL_FILTER_OP_GT_S64,
281 [ FILTER_OP_LT_S64 ] = &&LABEL_FILTER_OP_LT_S64,
282 [ FILTER_OP_GE_S64 ] = &&LABEL_FILTER_OP_GE_S64,
283 [ FILTER_OP_LE_S64 ] = &&LABEL_FILTER_OP_LE_S64,
284
285 /* double binary comparator */
286 [ FILTER_OP_EQ_DOUBLE ] = &&LABEL_FILTER_OP_EQ_DOUBLE,
287 [ FILTER_OP_NE_DOUBLE ] = &&LABEL_FILTER_OP_NE_DOUBLE,
288 [ FILTER_OP_GT_DOUBLE ] = &&LABEL_FILTER_OP_GT_DOUBLE,
289 [ FILTER_OP_LT_DOUBLE ] = &&LABEL_FILTER_OP_LT_DOUBLE,
290 [ FILTER_OP_GE_DOUBLE ] = &&LABEL_FILTER_OP_GE_DOUBLE,
291 [ FILTER_OP_LE_DOUBLE ] = &&LABEL_FILTER_OP_LE_DOUBLE,
292
dbea82ec
MD
293 /* Mixed S64-double binary comparators */
294 [ FILTER_OP_EQ_DOUBLE_S64 ] = &&LABEL_FILTER_OP_EQ_DOUBLE_S64,
295 [ FILTER_OP_NE_DOUBLE_S64 ] = &&LABEL_FILTER_OP_NE_DOUBLE_S64,
296 [ FILTER_OP_GT_DOUBLE_S64 ] = &&LABEL_FILTER_OP_GT_DOUBLE_S64,
297 [ FILTER_OP_LT_DOUBLE_S64 ] = &&LABEL_FILTER_OP_LT_DOUBLE_S64,
298 [ FILTER_OP_GE_DOUBLE_S64 ] = &&LABEL_FILTER_OP_GE_DOUBLE_S64,
299 [ FILTER_OP_LE_DOUBLE_S64 ] = &&LABEL_FILTER_OP_LE_DOUBLE_S64,
300
301 [ FILTER_OP_EQ_S64_DOUBLE ] = &&LABEL_FILTER_OP_EQ_S64_DOUBLE,
302 [ FILTER_OP_NE_S64_DOUBLE ] = &&LABEL_FILTER_OP_NE_S64_DOUBLE,
303 [ FILTER_OP_GT_S64_DOUBLE ] = &&LABEL_FILTER_OP_GT_S64_DOUBLE,
304 [ FILTER_OP_LT_S64_DOUBLE ] = &&LABEL_FILTER_OP_LT_S64_DOUBLE,
305 [ FILTER_OP_GE_S64_DOUBLE ] = &&LABEL_FILTER_OP_GE_S64_DOUBLE,
306 [ FILTER_OP_LE_S64_DOUBLE ] = &&LABEL_FILTER_OP_LE_S64_DOUBLE,
307
97b58163
MD
308 /* unary */
309 [ FILTER_OP_UNARY_PLUS ] = &&LABEL_FILTER_OP_UNARY_PLUS,
310 [ FILTER_OP_UNARY_MINUS ] = &&LABEL_FILTER_OP_UNARY_MINUS,
311 [ FILTER_OP_UNARY_NOT ] = &&LABEL_FILTER_OP_UNARY_NOT,
312 [ FILTER_OP_UNARY_PLUS_S64 ] = &&LABEL_FILTER_OP_UNARY_PLUS_S64,
313 [ FILTER_OP_UNARY_MINUS_S64 ] = &&LABEL_FILTER_OP_UNARY_MINUS_S64,
314 [ FILTER_OP_UNARY_NOT_S64 ] = &&LABEL_FILTER_OP_UNARY_NOT_S64,
315 [ FILTER_OP_UNARY_PLUS_DOUBLE ] = &&LABEL_FILTER_OP_UNARY_PLUS_DOUBLE,
316 [ FILTER_OP_UNARY_MINUS_DOUBLE ] = &&LABEL_FILTER_OP_UNARY_MINUS_DOUBLE,
317 [ FILTER_OP_UNARY_NOT_DOUBLE ] = &&LABEL_FILTER_OP_UNARY_NOT_DOUBLE,
318
319 /* logical */
320 [ FILTER_OP_AND ] = &&LABEL_FILTER_OP_AND,
321 [ FILTER_OP_OR ] = &&LABEL_FILTER_OP_OR,
322
77aa5901 323 /* load field ref */
97b58163
MD
324 [ FILTER_OP_LOAD_FIELD_REF ] = &&LABEL_FILTER_OP_LOAD_FIELD_REF,
325 [ FILTER_OP_LOAD_FIELD_REF_STRING ] = &&LABEL_FILTER_OP_LOAD_FIELD_REF_STRING,
326 [ FILTER_OP_LOAD_FIELD_REF_SEQUENCE ] = &&LABEL_FILTER_OP_LOAD_FIELD_REF_SEQUENCE,
327 [ FILTER_OP_LOAD_FIELD_REF_S64 ] = &&LABEL_FILTER_OP_LOAD_FIELD_REF_S64,
328 [ FILTER_OP_LOAD_FIELD_REF_DOUBLE ] = &&LABEL_FILTER_OP_LOAD_FIELD_REF_DOUBLE,
329
77aa5901 330 /* load from immediate operand */
97b58163 331 [ FILTER_OP_LOAD_STRING ] = &&LABEL_FILTER_OP_LOAD_STRING,
3151a51d 332 [ FILTER_OP_LOAD_STAR_GLOB_STRING ] = &&LABEL_FILTER_OP_LOAD_STAR_GLOB_STRING,
97b58163
MD
333 [ FILTER_OP_LOAD_S64 ] = &&LABEL_FILTER_OP_LOAD_S64,
334 [ FILTER_OP_LOAD_DOUBLE ] = &&LABEL_FILTER_OP_LOAD_DOUBLE,
335
336 /* cast */
337 [ FILTER_OP_CAST_TO_S64 ] = &&LABEL_FILTER_OP_CAST_TO_S64,
338 [ FILTER_OP_CAST_DOUBLE_TO_S64 ] = &&LABEL_FILTER_OP_CAST_DOUBLE_TO_S64,
339 [ FILTER_OP_CAST_NOP ] = &&LABEL_FILTER_OP_CAST_NOP,
77aa5901
MD
340
341 /* get context ref */
342 [ FILTER_OP_GET_CONTEXT_REF ] = &&LABEL_FILTER_OP_GET_CONTEXT_REF,
343 [ FILTER_OP_GET_CONTEXT_REF_STRING ] = &&LABEL_FILTER_OP_GET_CONTEXT_REF_STRING,
344 [ FILTER_OP_GET_CONTEXT_REF_S64 ] = &&LABEL_FILTER_OP_GET_CONTEXT_REF_S64,
345 [ FILTER_OP_GET_CONTEXT_REF_DOUBLE ] = &&LABEL_FILTER_OP_GET_CONTEXT_REF_DOUBLE,
97b58163
MD
346 };
347#endif /* #ifndef INTERPRETER_USE_SWITCH */
348
349 START_OP
350
351 OP(FILTER_OP_UNKNOWN):
352 OP(FILTER_OP_LOAD_FIELD_REF):
353#ifdef INTERPRETER_USE_SWITCH
354 default:
355#endif /* INTERPRETER_USE_SWITCH */
356 ERR("unknown bytecode op %u\n",
357 (unsigned int) *(filter_opcode_t *) pc);
358 ret = -EINVAL;
359 goto end;
360
361 OP(FILTER_OP_RETURN):
8a92ed2a 362 /* LTTNG_FILTER_DISCARD or LTTNG_FILTER_RECORD_FLAG */
9b33aac4 363 retval = !!estack_ax_v;
97b58163
MD
364 ret = 0;
365 goto end;
366
367 /* binary */
368 OP(FILTER_OP_MUL):
369 OP(FILTER_OP_DIV):
370 OP(FILTER_OP_MOD):
371 OP(FILTER_OP_PLUS):
372 OP(FILTER_OP_MINUS):
373 OP(FILTER_OP_RSHIFT):
374 OP(FILTER_OP_LSHIFT):
375 OP(FILTER_OP_BIN_AND):
376 OP(FILTER_OP_BIN_OR):
377 OP(FILTER_OP_BIN_XOR):
378 ERR("unsupported bytecode op %u\n",
379 (unsigned int) *(filter_opcode_t *) pc);
380 ret = -EINVAL;
381 goto end;
382
383 OP(FILTER_OP_EQ):
53569322
MD
384 {
385 /* Dynamic typing. */
386 switch (estack_ax_t) {
387 case REG_S64:
388 switch (estack_bx_t) {
389 case REG_S64:
390 JUMP_TO(FILTER_OP_EQ_S64);
391 case REG_DOUBLE:
392 JUMP_TO(FILTER_OP_EQ_DOUBLE_S64);
3151a51d
PP
393 case REG_STRING: /* Fall-through */
394 case REG_STAR_GLOB_STRING:
53569322
MD
395 ret = -EINVAL;
396 goto end;
397 default:
398 ERR("Unknown filter register type (%d)",
399 (int) estack_bx_t);
400 ret = -EINVAL;
401 goto end;
402 }
403 break;
404 case REG_DOUBLE:
405 switch (estack_bx_t) {
406 case REG_S64:
407 JUMP_TO(FILTER_OP_EQ_S64_DOUBLE);
408 case REG_DOUBLE:
409 JUMP_TO(FILTER_OP_EQ_DOUBLE);
3151a51d
PP
410 case REG_STRING: /* Fall-through */
411 case REG_STAR_GLOB_STRING:
53569322
MD
412 ret = -EINVAL;
413 goto end;
414 default:
415 ERR("Unknown filter register type (%d)",
416 (int) estack_bx_t);
417 ret = -EINVAL;
418 goto end;
419 }
420 break;
421 case REG_STRING:
422 switch (estack_bx_t) {
423 case REG_S64: /* Fall-through */
424 case REG_DOUBLE:
425 ret = -EINVAL;
426 goto end;
427 case REG_STRING:
428 JUMP_TO(FILTER_OP_EQ_STRING);
3151a51d
PP
429 case REG_STAR_GLOB_STRING:
430 JUMP_TO(FILTER_OP_EQ_STAR_GLOB_STRING);
431 default:
432 ERR("Unknown filter register type (%d)",
433 (int) estack_bx_t);
434 ret = -EINVAL;
435 goto end;
436 }
437 break;
438 case REG_STAR_GLOB_STRING:
439 switch (estack_bx_t) {
440 case REG_S64: /* Fall-through */
441 case REG_DOUBLE:
442 ret = -EINVAL;
443 goto end;
444 case REG_STRING:
445 JUMP_TO(FILTER_OP_EQ_STAR_GLOB_STRING);
446 case REG_STAR_GLOB_STRING:
447 ret = -EINVAL;
448 goto end;
53569322
MD
449 default:
450 ERR("Unknown filter register type (%d)",
451 (int) estack_bx_t);
452 ret = -EINVAL;
453 goto end;
454 }
455 break;
456 default:
457 ERR("Unknown filter register type (%d)",
458 (int) estack_ax_t);
459 ret = -EINVAL;
460 goto end;
461 }
462 }
97b58163 463 OP(FILTER_OP_NE):
53569322
MD
464 {
465 /* Dynamic typing. */
466 switch (estack_ax_t) {
467 case REG_S64:
468 switch (estack_bx_t) {
469 case REG_S64:
470 JUMP_TO(FILTER_OP_NE_S64);
471 case REG_DOUBLE:
472 JUMP_TO(FILTER_OP_NE_DOUBLE_S64);
3151a51d
PP
473 case REG_STRING: /* Fall-through */
474 case REG_STAR_GLOB_STRING:
53569322
MD
475 ret = -EINVAL;
476 goto end;
477 default:
478 ERR("Unknown filter register type (%d)",
479 (int) estack_bx_t);
480 ret = -EINVAL;
481 goto end;
482 }
483 break;
484 case REG_DOUBLE:
485 switch (estack_bx_t) {
486 case REG_S64:
487 JUMP_TO(FILTER_OP_NE_S64_DOUBLE);
488 case REG_DOUBLE:
489 JUMP_TO(FILTER_OP_NE_DOUBLE);
3151a51d
PP
490 case REG_STRING: /* Fall-through */
491 case REG_STAR_GLOB_STRING:
53569322
MD
492 ret = -EINVAL;
493 goto end;
494 default:
495 ERR("Unknown filter register type (%d)",
496 (int) estack_bx_t);
497 ret = -EINVAL;
498 goto end;
499 }
500 break;
501 case REG_STRING:
502 switch (estack_bx_t) {
503 case REG_S64: /* Fall-through */
504 case REG_DOUBLE:
505 ret = -EINVAL;
506 goto end;
507 case REG_STRING:
508 JUMP_TO(FILTER_OP_NE_STRING);
3151a51d
PP
509 case REG_STAR_GLOB_STRING:
510 JUMP_TO(FILTER_OP_NE_STAR_GLOB_STRING);
511 default:
512 ERR("Unknown filter register type (%d)",
513 (int) estack_bx_t);
514 ret = -EINVAL;
515 goto end;
516 }
517 break;
518 case REG_STAR_GLOB_STRING:
519 switch (estack_bx_t) {
520 case REG_S64: /* Fall-through */
521 case REG_DOUBLE:
522 ret = -EINVAL;
523 goto end;
524 case REG_STRING:
525 JUMP_TO(FILTER_OP_NE_STAR_GLOB_STRING);
526 case REG_STAR_GLOB_STRING:
527 ret = -EINVAL;
528 goto end;
53569322
MD
529 default:
530 ERR("Unknown filter register type (%d)",
531 (int) estack_bx_t);
532 ret = -EINVAL;
533 goto end;
534 }
535 break;
536 default:
537 ERR("Unknown filter register type (%d)",
538 (int) estack_ax_t);
539 ret = -EINVAL;
540 goto end;
541 }
542 }
97b58163 543 OP(FILTER_OP_GT):
53569322
MD
544 {
545 /* Dynamic typing. */
546 switch (estack_ax_t) {
547 case REG_S64:
548 switch (estack_bx_t) {
549 case REG_S64:
550 JUMP_TO(FILTER_OP_GT_S64);
551 case REG_DOUBLE:
552 JUMP_TO(FILTER_OP_GT_DOUBLE_S64);
3151a51d
PP
553 case REG_STRING: /* Fall-through */
554 case REG_STAR_GLOB_STRING:
53569322
MD
555 ret = -EINVAL;
556 goto end;
557 default:
558 ERR("Unknown filter register type (%d)",
559 (int) estack_bx_t);
560 ret = -EINVAL;
561 goto end;
562 }
563 break;
564 case REG_DOUBLE:
565 switch (estack_bx_t) {
566 case REG_S64:
567 JUMP_TO(FILTER_OP_GT_S64_DOUBLE);
568 case REG_DOUBLE:
569 JUMP_TO(FILTER_OP_GT_DOUBLE);
3151a51d
PP
570 case REG_STRING: /* Fall-through */
571 case REG_STAR_GLOB_STRING:
53569322
MD
572 ret = -EINVAL;
573 goto end;
574 default:
575 ERR("Unknown filter register type (%d)",
576 (int) estack_bx_t);
577 ret = -EINVAL;
578 goto end;
579 }
580 break;
581 case REG_STRING:
582 switch (estack_bx_t) {
583 case REG_S64: /* Fall-through */
3151a51d
PP
584 case REG_DOUBLE: /* Fall-through */
585 case REG_STAR_GLOB_STRING:
53569322
MD
586 ret = -EINVAL;
587 goto end;
588 case REG_STRING:
589 JUMP_TO(FILTER_OP_GT_STRING);
590 default:
591 ERR("Unknown filter register type (%d)",
592 (int) estack_bx_t);
593 ret = -EINVAL;
594 goto end;
595 }
596 break;
597 default:
598 ERR("Unknown filter register type (%d)",
599 (int) estack_ax_t);
600 ret = -EINVAL;
601 goto end;
602 }
603 }
97b58163 604 OP(FILTER_OP_LT):
53569322
MD
605 {
606 /* Dynamic typing. */
607 switch (estack_ax_t) {
608 case REG_S64:
609 switch (estack_bx_t) {
610 case REG_S64:
611 JUMP_TO(FILTER_OP_LT_S64);
612 case REG_DOUBLE:
613 JUMP_TO(FILTER_OP_LT_DOUBLE_S64);
3151a51d
PP
614 case REG_STRING: /* Fall-through */
615 case REG_STAR_GLOB_STRING:
53569322
MD
616 ret = -EINVAL;
617 goto end;
618 default:
619 ERR("Unknown filter register type (%d)",
620 (int) estack_bx_t);
621 ret = -EINVAL;
622 goto end;
623 }
624 break;
625 case REG_DOUBLE:
626 switch (estack_bx_t) {
627 case REG_S64:
628 JUMP_TO(FILTER_OP_LT_S64_DOUBLE);
629 case REG_DOUBLE:
630 JUMP_TO(FILTER_OP_LT_DOUBLE);
3151a51d
PP
631 case REG_STRING: /* Fall-through */
632 case REG_STAR_GLOB_STRING:
53569322
MD
633 ret = -EINVAL;
634 goto end;
635 default:
636 ERR("Unknown filter register type (%d)",
637 (int) estack_bx_t);
638 ret = -EINVAL;
639 goto end;
640 }
641 break;
642 case REG_STRING:
643 switch (estack_bx_t) {
644 case REG_S64: /* Fall-through */
3151a51d
PP
645 case REG_DOUBLE: /* Fall-through */
646 case REG_STAR_GLOB_STRING:
53569322
MD
647 ret = -EINVAL;
648 goto end;
649 case REG_STRING:
650 JUMP_TO(FILTER_OP_LT_STRING);
651 default:
652 ERR("Unknown filter register type (%d)",
653 (int) estack_bx_t);
654 ret = -EINVAL;
655 goto end;
656 }
657 break;
658 default:
659 ERR("Unknown filter register type (%d)",
660 (int) estack_ax_t);
661 ret = -EINVAL;
662 goto end;
663 }
664 }
97b58163 665 OP(FILTER_OP_GE):
53569322
MD
666 {
667 /* Dynamic typing. */
668 switch (estack_ax_t) {
669 case REG_S64:
670 switch (estack_bx_t) {
671 case REG_S64:
672 JUMP_TO(FILTER_OP_GE_S64);
673 case REG_DOUBLE:
674 JUMP_TO(FILTER_OP_GE_DOUBLE_S64);
3151a51d
PP
675 case REG_STRING: /* Fall-through */
676 case REG_STAR_GLOB_STRING:
53569322
MD
677 ret = -EINVAL;
678 goto end;
679 default:
680 ERR("Unknown filter register type (%d)",
681 (int) estack_bx_t);
682 ret = -EINVAL;
683 goto end;
684 }
685 break;
686 case REG_DOUBLE:
687 switch (estack_bx_t) {
688 case REG_S64:
689 JUMP_TO(FILTER_OP_GE_S64_DOUBLE);
690 case REG_DOUBLE:
691 JUMP_TO(FILTER_OP_GE_DOUBLE);
3151a51d
PP
692 case REG_STRING: /* Fall-through */
693 case REG_STAR_GLOB_STRING:
53569322
MD
694 ret = -EINVAL;
695 goto end;
696 default:
697 ERR("Unknown filter register type (%d)",
698 (int) estack_bx_t);
699 ret = -EINVAL;
700 goto end;
701 }
702 break;
703 case REG_STRING:
704 switch (estack_bx_t) {
705 case REG_S64: /* Fall-through */
3151a51d
PP
706 case REG_DOUBLE: /* Fall-through */
707 case REG_STAR_GLOB_STRING:
53569322
MD
708 ret = -EINVAL;
709 goto end;
710 case REG_STRING:
711 JUMP_TO(FILTER_OP_GE_STRING);
712 default:
713 ERR("Unknown filter register type (%d)",
714 (int) estack_bx_t);
715 ret = -EINVAL;
716 goto end;
717 }
718 break;
719 default:
720 ERR("Unknown filter register type (%d)",
721 (int) estack_ax_t);
722 ret = -EINVAL;
723 goto end;
724 }
725 }
97b58163 726 OP(FILTER_OP_LE):
53569322
MD
727 {
728 /* Dynamic typing. */
729 switch (estack_ax_t) {
730 case REG_S64:
731 switch (estack_bx_t) {
732 case REG_S64:
733 JUMP_TO(FILTER_OP_LE_S64);
734 case REG_DOUBLE:
735 JUMP_TO(FILTER_OP_LE_DOUBLE_S64);
3151a51d
PP
736 case REG_STRING: /* Fall-through */
737 case REG_STAR_GLOB_STRING:
53569322
MD
738 ret = -EINVAL;
739 goto end;
740 default:
741 ERR("Unknown filter register type (%d)",
742 (int) estack_bx_t);
743 ret = -EINVAL;
744 goto end;
745 }
746 break;
747 case REG_DOUBLE:
748 switch (estack_bx_t) {
749 case REG_S64:
750 JUMP_TO(FILTER_OP_LE_S64_DOUBLE);
751 case REG_DOUBLE:
752 JUMP_TO(FILTER_OP_LE_DOUBLE);
3151a51d
PP
753 case REG_STRING: /* Fall-through */
754 case REG_STAR_GLOB_STRING:
53569322
MD
755 ret = -EINVAL;
756 goto end;
757 default:
758 ERR("Unknown filter register type (%d)",
759 (int) estack_bx_t);
760 ret = -EINVAL;
761 goto end;
762 }
763 break;
764 case REG_STRING:
765 switch (estack_bx_t) {
766 case REG_S64: /* Fall-through */
3151a51d
PP
767 case REG_DOUBLE: /* Fall-through */
768 case REG_STAR_GLOB_STRING:
53569322
MD
769 ret = -EINVAL;
770 goto end;
771 case REG_STRING:
772 JUMP_TO(FILTER_OP_LE_STRING);
773 default:
774 ERR("Unknown filter register type (%d)",
775 (int) estack_bx_t);
776 ret = -EINVAL;
777 goto end;
778 }
779 break;
780 default:
781 ERR("Unknown filter register type (%d)",
782 (int) estack_ax_t);
783 ret = -EINVAL;
784 goto end;
785 }
786 }
97b58163
MD
787
788 OP(FILTER_OP_EQ_STRING):
789 {
0305960f
MD
790 int res;
791
9b33aac4 792 res = (stack_strcmp(stack, top, "==") == 0);
53569322 793 estack_pop(stack, top, ax, bx, ax_t, bx_t);
9b33aac4 794 estack_ax_v = res;
53569322 795 estack_ax_t = REG_S64;
97b58163
MD
796 next_pc += sizeof(struct binary_op);
797 PO;
798 }
799 OP(FILTER_OP_NE_STRING):
800 {
0305960f
MD
801 int res;
802
9b33aac4 803 res = (stack_strcmp(stack, top, "!=") != 0);
53569322 804 estack_pop(stack, top, ax, bx, ax_t, bx_t);
9b33aac4 805 estack_ax_v = res;
53569322 806 estack_ax_t = REG_S64;
97b58163
MD
807 next_pc += sizeof(struct binary_op);
808 PO;
809 }
810 OP(FILTER_OP_GT_STRING):
811 {
0305960f
MD
812 int res;
813
9b33aac4 814 res = (stack_strcmp(stack, top, ">") > 0);
53569322 815 estack_pop(stack, top, ax, bx, ax_t, bx_t);
9b33aac4 816 estack_ax_v = res;
53569322 817 estack_ax_t = REG_S64;
97b58163
MD
818 next_pc += sizeof(struct binary_op);
819 PO;
820 }
821 OP(FILTER_OP_LT_STRING):
822 {
0305960f
MD
823 int res;
824
9b33aac4 825 res = (stack_strcmp(stack, top, "<") < 0);
53569322 826 estack_pop(stack, top, ax, bx, ax_t, bx_t);
9b33aac4 827 estack_ax_v = res;
53569322 828 estack_ax_t = REG_S64;
97b58163
MD
829 next_pc += sizeof(struct binary_op);
830 PO;
831 }
832 OP(FILTER_OP_GE_STRING):
833 {
0305960f
MD
834 int res;
835
9b33aac4 836 res = (stack_strcmp(stack, top, ">=") >= 0);
53569322 837 estack_pop(stack, top, ax, bx, ax_t, bx_t);
9b33aac4 838 estack_ax_v = res;
53569322 839 estack_ax_t = REG_S64;
97b58163
MD
840 next_pc += sizeof(struct binary_op);
841 PO;
842 }
843 OP(FILTER_OP_LE_STRING):
844 {
0305960f
MD
845 int res;
846
9b33aac4 847 res = (stack_strcmp(stack, top, "<=") <= 0);
53569322 848 estack_pop(stack, top, ax, bx, ax_t, bx_t);
9b33aac4 849 estack_ax_v = res;
53569322 850 estack_ax_t = REG_S64;
97b58163
MD
851 next_pc += sizeof(struct binary_op);
852 PO;
853 }
854
3151a51d
PP
855 OP(FILTER_OP_EQ_STAR_GLOB_STRING):
856 {
857 int res;
858
859 res = (stack_star_glob_match(stack, top, "==") == 0);
860 estack_pop(stack, top, ax, bx, ax_t, bx_t);
861 estack_ax_v = res;
862 estack_ax_t = REG_S64;
863 next_pc += sizeof(struct binary_op);
864 PO;
865 }
866 OP(FILTER_OP_NE_STAR_GLOB_STRING):
867 {
868 int res;
869
870 res = (stack_star_glob_match(stack, top, "!=") != 0);
871 estack_pop(stack, top, ax, bx, ax_t, bx_t);
872 estack_ax_v = res;
873 estack_ax_t = REG_S64;
874 next_pc += sizeof(struct binary_op);
875 PO;
876 }
877
97b58163
MD
878 OP(FILTER_OP_EQ_S64):
879 {
0305960f
MD
880 int res;
881
9b33aac4 882 res = (estack_bx_v == estack_ax_v);
53569322 883 estack_pop(stack, top, ax, bx, ax_t, bx_t);
9b33aac4 884 estack_ax_v = res;
53569322 885 estack_ax_t = REG_S64;
97b58163
MD
886 next_pc += sizeof(struct binary_op);
887 PO;
888 }
889 OP(FILTER_OP_NE_S64):
890 {
0305960f
MD
891 int res;
892
9b33aac4 893 res = (estack_bx_v != estack_ax_v);
53569322 894 estack_pop(stack, top, ax, bx, ax_t, bx_t);
9b33aac4 895 estack_ax_v = res;
53569322 896 estack_ax_t = REG_S64;
97b58163
MD
897 next_pc += sizeof(struct binary_op);
898 PO;
899 }
900 OP(FILTER_OP_GT_S64):
901 {
0305960f
MD
902 int res;
903
9b33aac4 904 res = (estack_bx_v > estack_ax_v);
53569322 905 estack_pop(stack, top, ax, bx, ax_t, bx_t);
9b33aac4 906 estack_ax_v = res;
53569322 907 estack_ax_t = REG_S64;
97b58163
MD
908 next_pc += sizeof(struct binary_op);
909 PO;
910 }
911 OP(FILTER_OP_LT_S64):
912 {
0305960f
MD
913 int res;
914
9b33aac4 915 res = (estack_bx_v < estack_ax_v);
53569322 916 estack_pop(stack, top, ax, bx, ax_t, bx_t);
9b33aac4 917 estack_ax_v = res;
53569322 918 estack_ax_t = REG_S64;
97b58163
MD
919 next_pc += sizeof(struct binary_op);
920 PO;
921 }
922 OP(FILTER_OP_GE_S64):
923 {
0305960f
MD
924 int res;
925
9b33aac4 926 res = (estack_bx_v >= estack_ax_v);
53569322 927 estack_pop(stack, top, ax, bx, ax_t, bx_t);
9b33aac4 928 estack_ax_v = res;
53569322 929 estack_ax_t = REG_S64;
97b58163
MD
930 next_pc += sizeof(struct binary_op);
931 PO;
932 }
933 OP(FILTER_OP_LE_S64):
934 {
0305960f
MD
935 int res;
936
9b33aac4 937 res = (estack_bx_v <= estack_ax_v);
53569322 938 estack_pop(stack, top, ax, bx, ax_t, bx_t);
9b33aac4 939 estack_ax_v = res;
53569322 940 estack_ax_t = REG_S64;
97b58163
MD
941 next_pc += sizeof(struct binary_op);
942 PO;
943 }
944
945 OP(FILTER_OP_EQ_DOUBLE):
946 {
0305960f
MD
947 int res;
948
9b33aac4 949 res = (estack_bx(stack, top)->u.d == estack_ax(stack, top)->u.d);
53569322 950 estack_pop(stack, top, ax, bx, ax_t, bx_t);
9b33aac4 951 estack_ax_v = res;
53569322 952 estack_ax_t = REG_S64;
97b58163
MD
953 next_pc += sizeof(struct binary_op);
954 PO;
955 }
956 OP(FILTER_OP_NE_DOUBLE):
957 {
0305960f
MD
958 int res;
959
9b33aac4 960 res = (estack_bx(stack, top)->u.d != estack_ax(stack, top)->u.d);
53569322 961 estack_pop(stack, top, ax, bx, ax_t, bx_t);
9b33aac4 962 estack_ax_v = res;
53569322 963 estack_ax_t = REG_S64;
97b58163
MD
964 next_pc += sizeof(struct binary_op);
965 PO;
966 }
967 OP(FILTER_OP_GT_DOUBLE):
968 {
0305960f
MD
969 int res;
970
9b33aac4 971 res = (estack_bx(stack, top)->u.d > estack_ax(stack, top)->u.d);
53569322 972 estack_pop(stack, top, ax, bx, ax_t, bx_t);
9b33aac4 973 estack_ax_v = res;
53569322 974 estack_ax_t = REG_S64;
97b58163
MD
975 next_pc += sizeof(struct binary_op);
976 PO;
977 }
978 OP(FILTER_OP_LT_DOUBLE):
979 {
0305960f
MD
980 int res;
981
9b33aac4 982 res = (estack_bx(stack, top)->u.d < estack_ax(stack, top)->u.d);
53569322 983 estack_pop(stack, top, ax, bx, ax_t, bx_t);
9b33aac4 984 estack_ax_v = res;
53569322 985 estack_ax_t = REG_S64;
97b58163
MD
986 next_pc += sizeof(struct binary_op);
987 PO;
988 }
989 OP(FILTER_OP_GE_DOUBLE):
990 {
0305960f
MD
991 int res;
992
9b33aac4 993 res = (estack_bx(stack, top)->u.d >= estack_ax(stack, top)->u.d);
53569322 994 estack_pop(stack, top, ax, bx, ax_t, bx_t);
9b33aac4 995 estack_ax_v = res;
53569322 996 estack_ax_t = REG_S64;
97b58163
MD
997 next_pc += sizeof(struct binary_op);
998 PO;
999 }
1000 OP(FILTER_OP_LE_DOUBLE):
1001 {
0305960f
MD
1002 int res;
1003
9b33aac4 1004 res = (estack_bx(stack, top)->u.d <= estack_ax(stack, top)->u.d);
53569322 1005 estack_pop(stack, top, ax, bx, ax_t, bx_t);
9b33aac4 1006 estack_ax_v = res;
53569322 1007 estack_ax_t = REG_S64;
dbea82ec
MD
1008 next_pc += sizeof(struct binary_op);
1009 PO;
1010 }
1011
1012 /* Mixed S64-double binary comparators */
1013 OP(FILTER_OP_EQ_DOUBLE_S64):
1014 {
1015 int res;
1016
9b33aac4 1017 res = (estack_bx(stack, top)->u.d == estack_ax_v);
53569322 1018 estack_pop(stack, top, ax, bx, ax_t, bx_t);
9b33aac4 1019 estack_ax_v = res;
53569322 1020 estack_ax_t = REG_S64;
dbea82ec
MD
1021 next_pc += sizeof(struct binary_op);
1022 PO;
1023 }
1024 OP(FILTER_OP_NE_DOUBLE_S64):
1025 {
1026 int res;
1027
9b33aac4 1028 res = (estack_bx(stack, top)->u.d != estack_ax_v);
53569322 1029 estack_pop(stack, top, ax, bx, ax_t, bx_t);
9b33aac4 1030 estack_ax_v = res;
53569322 1031 estack_ax_t = REG_S64;
dbea82ec
MD
1032 next_pc += sizeof(struct binary_op);
1033 PO;
1034 }
1035 OP(FILTER_OP_GT_DOUBLE_S64):
1036 {
1037 int res;
1038
9b33aac4 1039 res = (estack_bx(stack, top)->u.d > estack_ax_v);
53569322 1040 estack_pop(stack, top, ax, bx, ax_t, bx_t);
9b33aac4 1041 estack_ax_v = res;
53569322 1042 estack_ax_t = REG_S64;
dbea82ec
MD
1043 next_pc += sizeof(struct binary_op);
1044 PO;
1045 }
1046 OP(FILTER_OP_LT_DOUBLE_S64):
1047 {
1048 int res;
1049
9b33aac4 1050 res = (estack_bx(stack, top)->u.d < estack_ax_v);
53569322 1051 estack_pop(stack, top, ax, bx, ax_t, bx_t);
9b33aac4 1052 estack_ax_v = res;
53569322 1053 estack_ax_t = REG_S64;
dbea82ec
MD
1054 next_pc += sizeof(struct binary_op);
1055 PO;
1056 }
1057 OP(FILTER_OP_GE_DOUBLE_S64):
1058 {
1059 int res;
1060
9b33aac4 1061 res = (estack_bx(stack, top)->u.d >= estack_ax_v);
53569322 1062 estack_pop(stack, top, ax, bx, ax_t, bx_t);
9b33aac4 1063 estack_ax_v = res;
53569322 1064 estack_ax_t = REG_S64;
dbea82ec
MD
1065 next_pc += sizeof(struct binary_op);
1066 PO;
1067 }
1068 OP(FILTER_OP_LE_DOUBLE_S64):
1069 {
1070 int res;
1071
9b33aac4 1072 res = (estack_bx(stack, top)->u.d <= estack_ax_v);
53569322 1073 estack_pop(stack, top, ax, bx, ax_t, bx_t);
9b33aac4 1074 estack_ax_v = res;
53569322 1075 estack_ax_t = REG_S64;
dbea82ec
MD
1076 next_pc += sizeof(struct binary_op);
1077 PO;
1078 }
1079
1080 OP(FILTER_OP_EQ_S64_DOUBLE):
1081 {
1082 int res;
1083
9b33aac4 1084 res = (estack_bx_v == estack_ax(stack, top)->u.d);
53569322 1085 estack_pop(stack, top, ax, bx, ax_t, bx_t);
9b33aac4 1086 estack_ax_v = res;
53569322 1087 estack_ax_t = REG_S64;
dbea82ec
MD
1088 next_pc += sizeof(struct binary_op);
1089 PO;
1090 }
1091 OP(FILTER_OP_NE_S64_DOUBLE):
1092 {
1093 int res;
1094
9b33aac4 1095 res = (estack_bx_v != estack_ax(stack, top)->u.d);
53569322 1096 estack_pop(stack, top, ax, bx, ax_t, bx_t);
9b33aac4 1097 estack_ax_v = res;
53569322 1098 estack_ax_t = REG_S64;
dbea82ec
MD
1099 next_pc += sizeof(struct binary_op);
1100 PO;
1101 }
1102 OP(FILTER_OP_GT_S64_DOUBLE):
1103 {
1104 int res;
1105
9b33aac4 1106 res = (estack_bx_v > estack_ax(stack, top)->u.d);
53569322 1107 estack_pop(stack, top, ax, bx, ax_t, bx_t);
9b33aac4 1108 estack_ax_v = res;
53569322 1109 estack_ax_t = REG_S64;
dbea82ec
MD
1110 next_pc += sizeof(struct binary_op);
1111 PO;
1112 }
1113 OP(FILTER_OP_LT_S64_DOUBLE):
1114 {
1115 int res;
1116
9b33aac4 1117 res = (estack_bx_v < estack_ax(stack, top)->u.d);
53569322 1118 estack_pop(stack, top, ax, bx, ax_t, bx_t);
9b33aac4 1119 estack_ax_v = res;
53569322 1120 estack_ax_t = REG_S64;
dbea82ec
MD
1121 next_pc += sizeof(struct binary_op);
1122 PO;
1123 }
1124 OP(FILTER_OP_GE_S64_DOUBLE):
1125 {
1126 int res;
1127
9b33aac4 1128 res = (estack_bx_v >= estack_ax(stack, top)->u.d);
53569322 1129 estack_pop(stack, top, ax, bx, ax_t, bx_t);
9b33aac4 1130 estack_ax_v = res;
53569322 1131 estack_ax_t = REG_S64;
dbea82ec
MD
1132 next_pc += sizeof(struct binary_op);
1133 PO;
1134 }
1135 OP(FILTER_OP_LE_S64_DOUBLE):
1136 {
1137 int res;
1138
9b33aac4 1139 res = (estack_bx_v <= estack_ax(stack, top)->u.d);
53569322 1140 estack_pop(stack, top, ax, bx, ax_t, bx_t);
9b33aac4 1141 estack_ax_v = res;
53569322 1142 estack_ax_t = REG_S64;
97b58163
MD
1143 next_pc += sizeof(struct binary_op);
1144 PO;
1145 }
1146
1147 /* unary */
1148 OP(FILTER_OP_UNARY_PLUS):
53569322
MD
1149 {
1150 /* Dynamic typing. */
1151 switch (estack_ax_t) {
1152 case REG_S64: /* Fall-through. */
1153 JUMP_TO(FILTER_OP_UNARY_PLUS_S64);
1154 case REG_DOUBLE:
1155 JUMP_TO(FILTER_OP_UNARY_PLUS_DOUBLE);
3151a51d
PP
1156 case REG_STRING: /* Fall-through */
1157 case REG_STAR_GLOB_STRING:
53569322
MD
1158 ret = -EINVAL;
1159 goto end;
1160 default:
1161 ERR("Unknown filter register type (%d)",
1162 (int) estack_ax_t);
1163 ret = -EINVAL;
1164 goto end;
1165 }
1166 }
97b58163 1167 OP(FILTER_OP_UNARY_MINUS):
53569322
MD
1168 {
1169 /* Dynamic typing. */
1170 switch (estack_ax_t) {
1171 case REG_S64:
1172 JUMP_TO(FILTER_OP_UNARY_MINUS_S64);
1173 case REG_DOUBLE:
1174 JUMP_TO(FILTER_OP_UNARY_MINUS_DOUBLE);
3151a51d
PP
1175 case REG_STRING: /* Fall-through */
1176 case REG_STAR_GLOB_STRING:
53569322
MD
1177 ret = -EINVAL;
1178 goto end;
1179 default:
1180 ERR("Unknown filter register type (%d)",
1181 (int) estack_ax_t);
1182 ret = -EINVAL;
1183 goto end;
1184 }
1185 }
97b58163 1186 OP(FILTER_OP_UNARY_NOT):
53569322
MD
1187 {
1188 /* Dynamic typing. */
1189 switch (estack_ax_t) {
1190 case REG_S64:
1191 JUMP_TO(FILTER_OP_UNARY_NOT_S64);
1192 case REG_DOUBLE:
1193 JUMP_TO(FILTER_OP_UNARY_NOT_DOUBLE);
3151a51d
PP
1194 case REG_STRING: /* Fall-through */
1195 case REG_STAR_GLOB_STRING:
53569322
MD
1196 ret = -EINVAL;
1197 goto end;
1198 default:
1199 ERR("Unknown filter register type (%d)",
1200 (int) estack_ax_t);
1201 ret = -EINVAL;
1202 goto end;
1203 }
1204 next_pc += sizeof(struct unary_op);
1205 PO;
1206 }
97b58163
MD
1207
1208 OP(FILTER_OP_UNARY_PLUS_S64):
1209 OP(FILTER_OP_UNARY_PLUS_DOUBLE):
1210 {
1211 next_pc += sizeof(struct unary_op);
1212 PO;
1213 }
1214 OP(FILTER_OP_UNARY_MINUS_S64):
1215 {
9b33aac4 1216 estack_ax_v = -estack_ax_v;
97b58163
MD
1217 next_pc += sizeof(struct unary_op);
1218 PO;
1219 }
1220 OP(FILTER_OP_UNARY_MINUS_DOUBLE):
1221 {
9b33aac4 1222 estack_ax(stack, top)->u.d = -estack_ax(stack, top)->u.d;
97b58163
MD
1223 next_pc += sizeof(struct unary_op);
1224 PO;
1225 }
1226 OP(FILTER_OP_UNARY_NOT_S64):
1227 {
9b33aac4 1228 estack_ax_v = !estack_ax_v;
97b58163
MD
1229 next_pc += sizeof(struct unary_op);
1230 PO;
1231 }
1232 OP(FILTER_OP_UNARY_NOT_DOUBLE):
1233 {
53569322
MD
1234 estack_ax_v = !estack_ax(stack, top)->u.d;
1235 estack_ax_t = REG_S64;
97b58163
MD
1236 next_pc += sizeof(struct unary_op);
1237 PO;
1238 }
1239
1240 /* logical */
1241 OP(FILTER_OP_AND):
1242 {
1243 struct logical_op *insn = (struct logical_op *) pc;
1244
53569322
MD
1245 if (estack_ax_t != REG_S64) {
1246 ret = -EINVAL;
1247 goto end;
1248 }
0305960f 1249 /* If AX is 0, skip and evaluate to 0 */
9b33aac4 1250 if (unlikely(estack_ax_v == 0)) {
97b58163
MD
1251 dbg_printf("Jumping to bytecode offset %u\n",
1252 (unsigned int) insn->skip_offset);
1253 next_pc = start_pc + insn->skip_offset;
1254 } else {
71c1ceeb 1255 /* Pop 1 when jump not taken */
53569322 1256 estack_pop(stack, top, ax, bx, ax_t, bx_t);
97b58163
MD
1257 next_pc += sizeof(struct logical_op);
1258 }
1259 PO;
1260 }
1261 OP(FILTER_OP_OR):
1262 {
1263 struct logical_op *insn = (struct logical_op *) pc;
1264
53569322
MD
1265 if (estack_ax_t != REG_S64) {
1266 ret = -EINVAL;
1267 goto end;
1268 }
0305960f 1269 /* If AX is nonzero, skip and evaluate to 1 */
9b33aac4
MD
1270 if (unlikely(estack_ax_v != 0)) {
1271 estack_ax_v = 1;
97b58163
MD
1272 dbg_printf("Jumping to bytecode offset %u\n",
1273 (unsigned int) insn->skip_offset);
1274 next_pc = start_pc + insn->skip_offset;
1275 } else {
71c1ceeb 1276 /* Pop 1 when jump not taken */
53569322 1277 estack_pop(stack, top, ax, bx, ax_t, bx_t);
97b58163
MD
1278 next_pc += sizeof(struct logical_op);
1279 }
1280 PO;
1281 }
1282
1283
77aa5901 1284 /* load field ref */
97b58163
MD
1285 OP(FILTER_OP_LOAD_FIELD_REF_STRING):
1286 {
1287 struct load_op *insn = (struct load_op *) pc;
1288 struct field_ref *ref = (struct field_ref *) insn->data;
1289
1290 dbg_printf("load field ref offset %u type string\n",
1291 ref->offset);
53569322 1292 estack_push(stack, top, ax, bx, ax_t, bx_t);
9b33aac4 1293 estack_ax(stack, top)->u.s.str =
97b58163 1294 *(const char * const *) &filter_stack_data[ref->offset];
9b33aac4 1295 if (unlikely(!estack_ax(stack, top)->u.s.str)) {
97b58163
MD
1296 dbg_printf("Filter warning: loading a NULL string.\n");
1297 ret = -EINVAL;
1298 goto end;
1299 }
a63d0dc8 1300 estack_ax(stack, top)->u.s.seq_len = SIZE_MAX;
3151a51d
PP
1301 estack_ax(stack, top)->u.s.literal_type =
1302 ESTACK_STRING_LITERAL_TYPE_NONE;
53569322 1303 estack_ax_t = REG_STRING;
9b33aac4 1304 dbg_printf("ref load string %s\n", estack_ax(stack, top)->u.s.str);
97b58163
MD
1305 next_pc += sizeof(struct load_op) + sizeof(struct field_ref);
1306 PO;
1307 }
1308
1309 OP(FILTER_OP_LOAD_FIELD_REF_SEQUENCE):
1310 {
1311 struct load_op *insn = (struct load_op *) pc;
1312 struct field_ref *ref = (struct field_ref *) insn->data;
1313
1314 dbg_printf("load field ref offset %u type sequence\n",
1315 ref->offset);
53569322 1316 estack_push(stack, top, ax, bx, ax_t, bx_t);
9b33aac4 1317 estack_ax(stack, top)->u.s.seq_len =
97b58163 1318 *(unsigned long *) &filter_stack_data[ref->offset];
9b33aac4 1319 estack_ax(stack, top)->u.s.str =
97b58163
MD
1320 *(const char **) (&filter_stack_data[ref->offset
1321 + sizeof(unsigned long)]);
53569322 1322 estack_ax_t = REG_STRING;
9b33aac4 1323 if (unlikely(!estack_ax(stack, top)->u.s.str)) {
97b58163
MD
1324 dbg_printf("Filter warning: loading a NULL sequence.\n");
1325 ret = -EINVAL;
1326 goto end;
1327 }
3151a51d
PP
1328 estack_ax(stack, top)->u.s.literal_type =
1329 ESTACK_STRING_LITERAL_TYPE_NONE;
97b58163
MD
1330 next_pc += sizeof(struct load_op) + sizeof(struct field_ref);
1331 PO;
1332 }
1333
1334 OP(FILTER_OP_LOAD_FIELD_REF_S64):
1335 {
1336 struct load_op *insn = (struct load_op *) pc;
1337 struct field_ref *ref = (struct field_ref *) insn->data;
1338
1339 dbg_printf("load field ref offset %u type s64\n",
1340 ref->offset);
53569322 1341 estack_push(stack, top, ax, bx, ax_t, bx_t);
9b33aac4
MD
1342 estack_ax_v =
1343 ((struct literal_numeric *) &filter_stack_data[ref->offset])->v;
53569322 1344 estack_ax_t = REG_S64;
9b33aac4 1345 dbg_printf("ref load s64 %" PRIi64 "\n", estack_ax_v);
97b58163
MD
1346 next_pc += sizeof(struct load_op) + sizeof(struct field_ref);
1347 PO;
1348 }
1349
1350 OP(FILTER_OP_LOAD_FIELD_REF_DOUBLE):
1351 {
1352 struct load_op *insn = (struct load_op *) pc;
1353 struct field_ref *ref = (struct field_ref *) insn->data;
1354
1355 dbg_printf("load field ref offset %u type double\n",
1356 ref->offset);
53569322 1357 estack_push(stack, top, ax, bx, ax_t, bx_t);
9b33aac4 1358 memcpy(&estack_ax(stack, top)->u.d, &filter_stack_data[ref->offset],
97b58163 1359 sizeof(struct literal_double));
53569322 1360 estack_ax_t = REG_DOUBLE;
9b33aac4 1361 dbg_printf("ref load double %g\n", estack_ax(stack, top)->u.d);
97b58163
MD
1362 next_pc += sizeof(struct load_op) + sizeof(struct field_ref);
1363 PO;
1364 }
1365
77aa5901 1366 /* load from immediate operand */
97b58163
MD
1367 OP(FILTER_OP_LOAD_STRING):
1368 {
1369 struct load_op *insn = (struct load_op *) pc;
1370
1371 dbg_printf("load string %s\n", insn->data);
53569322 1372 estack_push(stack, top, ax, bx, ax_t, bx_t);
9b33aac4 1373 estack_ax(stack, top)->u.s.str = insn->data;
a63d0dc8 1374 estack_ax(stack, top)->u.s.seq_len = SIZE_MAX;
3151a51d
PP
1375 estack_ax(stack, top)->u.s.literal_type =
1376 ESTACK_STRING_LITERAL_TYPE_PLAIN;
53569322 1377 estack_ax_t = REG_STRING;
97b58163
MD
1378 next_pc += sizeof(struct load_op) + strlen(insn->data) + 1;
1379 PO;
1380 }
1381
3151a51d
PP
1382 OP(FILTER_OP_LOAD_STAR_GLOB_STRING):
1383 {
1384 struct load_op *insn = (struct load_op *) pc;
1385
1386 dbg_printf("load globbing pattern %s\n", insn->data);
1387 estack_push(stack, top, ax, bx, ax_t, bx_t);
1388 estack_ax(stack, top)->u.s.str = insn->data;
a63d0dc8 1389 estack_ax(stack, top)->u.s.seq_len = SIZE_MAX;
3151a51d
PP
1390 estack_ax(stack, top)->u.s.literal_type =
1391 ESTACK_STRING_LITERAL_TYPE_STAR_GLOB;
1392 estack_ax_t = REG_STAR_GLOB_STRING;
1393 next_pc += sizeof(struct load_op) + strlen(insn->data) + 1;
1394 PO;
1395 }
1396
97b58163
MD
1397 OP(FILTER_OP_LOAD_S64):
1398 {
1399 struct load_op *insn = (struct load_op *) pc;
1400
53569322 1401 estack_push(stack, top, ax, bx, ax_t, bx_t);
9b33aac4 1402 estack_ax_v = ((struct literal_numeric *) insn->data)->v;
53569322 1403 estack_ax_t = REG_S64;
9b33aac4 1404 dbg_printf("load s64 %" PRIi64 "\n", estack_ax_v);
97b58163
MD
1405 next_pc += sizeof(struct load_op)
1406 + sizeof(struct literal_numeric);
1407 PO;
1408 }
1409
1410 OP(FILTER_OP_LOAD_DOUBLE):
1411 {
1412 struct load_op *insn = (struct load_op *) pc;
1413
53569322 1414 estack_push(stack, top, ax, bx, ax_t, bx_t);
9b33aac4 1415 memcpy(&estack_ax(stack, top)->u.d, insn->data,
97b58163 1416 sizeof(struct literal_double));
53569322
MD
1417 estack_ax_t = REG_DOUBLE;
1418 dbg_printf("load double %g\n", estack_ax(stack, top)->u.d);
97b58163
MD
1419 next_pc += sizeof(struct load_op)
1420 + sizeof(struct literal_double);
1421 PO;
1422 }
1423
1424 /* cast */
1425 OP(FILTER_OP_CAST_TO_S64):
53569322
MD
1426 {
1427 /* Dynamic typing. */
1428 switch (estack_ax_t) {
1429 case REG_S64:
1430 JUMP_TO(FILTER_OP_CAST_NOP);
1431 case REG_DOUBLE:
1432 JUMP_TO(FILTER_OP_CAST_DOUBLE_TO_S64);
3151a51d
PP
1433 case REG_STRING: /* Fall-through */
1434 case REG_STAR_GLOB_STRING:
53569322
MD
1435 ret = -EINVAL;
1436 goto end;
1437 default:
1438 ERR("Unknown filter register type (%d)",
1439 (int) estack_ax_t);
1440 ret = -EINVAL;
1441 goto end;
1442 }
1443 }
97b58163
MD
1444
1445 OP(FILTER_OP_CAST_DOUBLE_TO_S64):
1446 {
9b33aac4 1447 estack_ax_v = (int64_t) estack_ax(stack, top)->u.d;
53569322 1448 estack_ax_t = REG_S64;
97b58163
MD
1449 next_pc += sizeof(struct cast_op);
1450 PO;
1451 }
1452
1453 OP(FILTER_OP_CAST_NOP):
1454 {
1455 next_pc += sizeof(struct cast_op);
1456 PO;
1457 }
1458
77aa5901 1459 /* get context ref */
53569322
MD
1460 OP(FILTER_OP_GET_CONTEXT_REF):
1461 {
1462 struct load_op *insn = (struct load_op *) pc;
1463 struct field_ref *ref = (struct field_ref *) insn->data;
1464 struct lttng_ctx *ctx;
1465 struct lttng_ctx_field *ctx_field;
1466 struct lttng_ctx_value v;
1467
1468 dbg_printf("get context ref offset %u type dynamic\n",
1469 ref->offset);
1470 ctx = rcu_dereference(session->ctx);
1471 ctx_field = &ctx->fields[ref->offset];
1472 ctx_field->get_value(ctx_field, &v);
1473 estack_push(stack, top, ax, bx, ax_t, bx_t);
1474 switch (v.sel) {
1475 case LTTNG_UST_DYNAMIC_TYPE_NONE:
1476 ret = -EINVAL;
1477 goto end;
1478 case LTTNG_UST_DYNAMIC_TYPE_S64:
1479 estack_ax_v = v.u.s64;
1480 estack_ax_t = REG_S64;
1481 dbg_printf("ref get context dynamic s64 %" PRIi64 "\n", estack_ax_v);
1482 break;
1483 case LTTNG_UST_DYNAMIC_TYPE_DOUBLE:
1484 estack_ax(stack, top)->u.d = v.u.d;
1485 estack_ax_t = REG_DOUBLE;
1486 dbg_printf("ref get context dynamic double %g\n", estack_ax(stack, top)->u.d);
1487 break;
1488 case LTTNG_UST_DYNAMIC_TYPE_STRING:
1489 estack_ax(stack, top)->u.s.str = v.u.str;
1490 if (unlikely(!estack_ax(stack, top)->u.s.str)) {
1491 dbg_printf("Filter warning: loading a NULL string.\n");
1492 ret = -EINVAL;
1493 goto end;
1494 }
a63d0dc8 1495 estack_ax(stack, top)->u.s.seq_len = SIZE_MAX;
3151a51d
PP
1496 estack_ax(stack, top)->u.s.literal_type =
1497 ESTACK_STRING_LITERAL_TYPE_NONE;
53569322
MD
1498 dbg_printf("ref get context dynamic string %s\n", estack_ax(stack, top)->u.s.str);
1499 estack_ax_t = REG_STRING;
1500 break;
1501 default:
1502 dbg_printf("Filter warning: unknown dynamic type (%d).\n", (int) v.sel);
1503 ret = -EINVAL;
1504 goto end;
1505 }
1506 next_pc += sizeof(struct load_op) + sizeof(struct field_ref);
1507 PO;
1508 }
1509
77aa5901
MD
1510 OP(FILTER_OP_GET_CONTEXT_REF_STRING):
1511 {
1512 struct load_op *insn = (struct load_op *) pc;
1513 struct field_ref *ref = (struct field_ref *) insn->data;
53569322 1514 struct lttng_ctx *ctx;
77aa5901 1515 struct lttng_ctx_field *ctx_field;
53569322 1516 struct lttng_ctx_value v;
77aa5901
MD
1517
1518 dbg_printf("get context ref offset %u type string\n",
1519 ref->offset);
53569322
MD
1520 ctx = rcu_dereference(session->ctx);
1521 ctx_field = &ctx->fields[ref->offset];
77aa5901 1522 ctx_field->get_value(ctx_field, &v);
53569322
MD
1523 estack_push(stack, top, ax, bx, ax_t, bx_t);
1524 estack_ax(stack, top)->u.s.str = v.u.str;
77aa5901
MD
1525 if (unlikely(!estack_ax(stack, top)->u.s.str)) {
1526 dbg_printf("Filter warning: loading a NULL string.\n");
1527 ret = -EINVAL;
1528 goto end;
1529 }
a63d0dc8 1530 estack_ax(stack, top)->u.s.seq_len = SIZE_MAX;
3151a51d
PP
1531 estack_ax(stack, top)->u.s.literal_type =
1532 ESTACK_STRING_LITERAL_TYPE_NONE;
53569322 1533 estack_ax_t = REG_STRING;
77aa5901
MD
1534 dbg_printf("ref get context string %s\n", estack_ax(stack, top)->u.s.str);
1535 next_pc += sizeof(struct load_op) + sizeof(struct field_ref);
1536 PO;
1537 }
1538
1539 OP(FILTER_OP_GET_CONTEXT_REF_S64):
1540 {
1541 struct load_op *insn = (struct load_op *) pc;
1542 struct field_ref *ref = (struct field_ref *) insn->data;
53569322 1543 struct lttng_ctx *ctx;
77aa5901 1544 struct lttng_ctx_field *ctx_field;
53569322 1545 struct lttng_ctx_value v;
77aa5901
MD
1546
1547 dbg_printf("get context ref offset %u type s64\n",
1548 ref->offset);
53569322
MD
1549 ctx = rcu_dereference(session->ctx);
1550 ctx_field = &ctx->fields[ref->offset];
77aa5901 1551 ctx_field->get_value(ctx_field, &v);
53569322
MD
1552 estack_push(stack, top, ax, bx, ax_t, bx_t);
1553 estack_ax_v = v.u.s64;
1554 estack_ax_t = REG_S64;
77aa5901
MD
1555 dbg_printf("ref get context s64 %" PRIi64 "\n", estack_ax_v);
1556 next_pc += sizeof(struct load_op) + sizeof(struct field_ref);
1557 PO;
1558 }
1559
1560 OP(FILTER_OP_GET_CONTEXT_REF_DOUBLE):
1561 {
1562 struct load_op *insn = (struct load_op *) pc;
1563 struct field_ref *ref = (struct field_ref *) insn->data;
53569322 1564 struct lttng_ctx *ctx;
77aa5901 1565 struct lttng_ctx_field *ctx_field;
53569322 1566 struct lttng_ctx_value v;
77aa5901
MD
1567
1568 dbg_printf("get context ref offset %u type double\n",
1569 ref->offset);
53569322
MD
1570 ctx = rcu_dereference(session->ctx);
1571 ctx_field = &ctx->fields[ref->offset];
77aa5901 1572 ctx_field->get_value(ctx_field, &v);
53569322
MD
1573 estack_push(stack, top, ax, bx, ax_t, bx_t);
1574 memcpy(&estack_ax(stack, top)->u.d, &v.u.d, sizeof(struct literal_double));
1575 estack_ax_t = REG_DOUBLE;
77aa5901
MD
1576 dbg_printf("ref get context double %g\n", estack_ax(stack, top)->u.d);
1577 next_pc += sizeof(struct load_op) + sizeof(struct field_ref);
1578 PO;
1579 }
1580
97b58163
MD
1581 END_OP
1582end:
1583 /* return 0 (discard) on error */
1584 if (ret)
1585 return 0;
1586 return retval;
1587}
1588
1589#undef START_OP
1590#undef OP
1591#undef PO
1592#undef END_OP
This page took 0.096038 seconds and 4 git commands to generate.