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