tracepoint: Refactor representation of nested types
[lttng-ust.git] / liblttng-ust / lttng-filter-specialize.c
CommitLineData
97b58163
MD
1/*
2 * lttng-filter-specialize.c
3 *
4 * LTTng UST filter code specializer.
5 *
7e50015d 6 * Copyright (C) 2010-2016 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
97b58163 7 *
7e50015d
MD
8 * Permission is hereby granted, free of charge, to any person obtaining a copy
9 * of this software and associated documentation files (the "Software"), to deal
10 * in the Software without restriction, including without limitation the rights
11 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12 * copies of the Software, and to permit persons to whom the Software is
13 * furnished to do so, subject to the following conditions:
97b58163 14 *
7e50015d
MD
15 * The above copyright notice and this permission notice shall be included in
16 * all copies or substantial portions of the Software.
97b58163 17 *
7e50015d
MD
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24 * SOFTWARE.
97b58163
MD
25 */
26
3fbec7dc 27#define _LGPL_SOURCE
b4051ad8 28#include <stddef.h>
fb31eb73 29#include <stdint.h>
b4051ad8 30
97b58163 31#include "lttng-filter.h"
47e5f13e 32#include <lttng/align.h>
97b58163 33
47e5f13e
MD
34static int lttng_fls(int val)
35{
36 int r = 32;
37 unsigned int x = (unsigned int) val;
38
39 if (!x)
40 return 0;
41 if (!(x & 0xFFFF0000U)) {
42 x <<= 16;
43 r -= 16;
44 }
45 if (!(x & 0xFF000000U)) {
46 x <<= 8;
47 r -= 8;
48 }
49 if (!(x & 0xF0000000U)) {
50 x <<= 4;
51 r -= 4;
52 }
53 if (!(x & 0xC0000000U)) {
54 x <<= 2;
55 r -= 2;
56 }
57 if (!(x & 0x80000000U)) {
58 r -= 1;
59 }
60 return r;
61}
62
63static int get_count_order(unsigned int count)
64{
65 int order;
66
67 order = lttng_fls(count) - 1;
68 if (count & (count - 1))
69 order++;
70 return order;
71}
72
73static ssize_t bytecode_reserve_data(struct bytecode_runtime *runtime,
74 size_t align, size_t len)
75{
76 ssize_t ret;
77 size_t padding = offset_align(runtime->data_len, align);
78 size_t new_len = runtime->data_len + padding + len;
79 size_t new_alloc_len = new_len;
80 size_t old_alloc_len = runtime->data_alloc_len;
81
82 if (new_len > FILTER_MAX_DATA_LEN)
83 return -EINVAL;
84
85 if (new_alloc_len > old_alloc_len) {
86 char *newptr;
87
88 new_alloc_len =
89 max_t(size_t, 1U << get_count_order(new_alloc_len), old_alloc_len << 1);
90 newptr = realloc(runtime->data, new_alloc_len);
91 if (!newptr)
92 return -ENOMEM;
93 runtime->data = newptr;
94 /* We zero directly the memory from start of allocation. */
95 memset(&runtime->data[old_alloc_len], 0, new_alloc_len - old_alloc_len);
96 runtime->data_alloc_len = new_alloc_len;
97 }
98 runtime->data_len += padding;
99 ret = runtime->data_len;
100 runtime->data_len += len;
101 return ret;
102}
103
104static ssize_t bytecode_push_data(struct bytecode_runtime *runtime,
105 const void *p, size_t align, size_t len)
106{
107 ssize_t offset;
108
109 offset = bytecode_reserve_data(runtime, align, len);
110 if (offset < 0)
111 return -ENOMEM;
112 memcpy(&runtime->data[offset], p, len);
113 return offset;
114}
115
116static int specialize_load_field(struct vstack_entry *stack_top,
117 struct load_op *insn)
118{
119 int ret;
120
121 switch (stack_top->load.type) {
122 case LOAD_OBJECT:
123 break;
124 case LOAD_ROOT_CONTEXT:
125 case LOAD_ROOT_APP_CONTEXT:
126 case LOAD_ROOT_PAYLOAD:
127 default:
128 dbg_printf("Filter warning: cannot load root, missing field name.\n");
129 ret = -EINVAL;
130 goto end;
131 }
132 switch (stack_top->load.object_type) {
133 case OBJECT_TYPE_S8:
134 dbg_printf("op load field s8\n");
135 stack_top->type = REG_S64;
136 if (!stack_top->load.rev_bo)
137 insn->op = FILTER_OP_LOAD_FIELD_S8;
138 break;
139 case OBJECT_TYPE_S16:
140 dbg_printf("op load field s16\n");
141 stack_top->type = REG_S64;
142 if (!stack_top->load.rev_bo)
143 insn->op = FILTER_OP_LOAD_FIELD_S16;
144 break;
145 case OBJECT_TYPE_S32:
146 dbg_printf("op load field s32\n");
147 stack_top->type = REG_S64;
148 if (!stack_top->load.rev_bo)
149 insn->op = FILTER_OP_LOAD_FIELD_S32;
150 break;
151 case OBJECT_TYPE_S64:
152 dbg_printf("op load field s64\n");
153 stack_top->type = REG_S64;
154 if (!stack_top->load.rev_bo)
155 insn->op = FILTER_OP_LOAD_FIELD_S64;
156 break;
157 case OBJECT_TYPE_U8:
158 dbg_printf("op load field u8\n");
159 stack_top->type = REG_S64;
160 insn->op = FILTER_OP_LOAD_FIELD_U8;
161 break;
162 case OBJECT_TYPE_U16:
163 dbg_printf("op load field u16\n");
164 stack_top->type = REG_S64;
165 if (!stack_top->load.rev_bo)
166 insn->op = FILTER_OP_LOAD_FIELD_U16;
167 break;
168 case OBJECT_TYPE_U32:
169 dbg_printf("op load field u32\n");
170 stack_top->type = REG_S64;
171 if (!stack_top->load.rev_bo)
172 insn->op = FILTER_OP_LOAD_FIELD_U32;
173 break;
174 case OBJECT_TYPE_U64:
175 dbg_printf("op load field u64\n");
176 stack_top->type = REG_S64;
177 if (!stack_top->load.rev_bo)
178 insn->op = FILTER_OP_LOAD_FIELD_U64;
179 break;
180 case OBJECT_TYPE_DOUBLE:
181 stack_top->type = REG_DOUBLE;
182 insn->op = FILTER_OP_LOAD_FIELD_DOUBLE;
183 break;
184 case OBJECT_TYPE_STRING:
185 dbg_printf("op load field string\n");
186 stack_top->type = REG_STRING;
187 insn->op = FILTER_OP_LOAD_FIELD_STRING;
188 break;
189 case OBJECT_TYPE_STRING_SEQUENCE:
190 dbg_printf("op load field string sequence\n");
191 stack_top->type = REG_STRING;
192 insn->op = FILTER_OP_LOAD_FIELD_SEQUENCE;
193 break;
194 case OBJECT_TYPE_DYNAMIC:
195 dbg_printf("op load field dynamic\n");
196 stack_top->type = REG_UNKNOWN;
197 /* Don't specialize load op. */
198 break;
199 case OBJECT_TYPE_SEQUENCE:
200 case OBJECT_TYPE_ARRAY:
201 case OBJECT_TYPE_STRUCT:
202 case OBJECT_TYPE_VARIANT:
203 ERR("Sequences, arrays, struct and variant cannot be loaded (nested types).");
204 ret = -EINVAL;
205 goto end;
206 }
207 return 0;
208
209end:
210 return ret;
211}
212
213static int specialize_get_index_object_type(enum object_type *otype,
214 int signedness, uint32_t elem_len)
215{
216 switch (elem_len) {
217 case 8:
218 if (signedness)
219 *otype = OBJECT_TYPE_S8;
220 else
221 *otype = OBJECT_TYPE_U8;
222 break;
223 case 16:
224 if (signedness)
225 *otype = OBJECT_TYPE_S16;
226 else
227 *otype = OBJECT_TYPE_U16;
228 break;
229 case 32:
230 if (signedness)
231 *otype = OBJECT_TYPE_S32;
232 else
233 *otype = OBJECT_TYPE_U32;
234 break;
235 case 64:
236 if (signedness)
237 *otype = OBJECT_TYPE_S64;
238 else
239 *otype = OBJECT_TYPE_U64;
240 break;
241 default:
242 return -EINVAL;
243 }
244 return 0;
245}
246
247static int specialize_get_index(struct bytecode_runtime *runtime,
248 struct load_op *insn, uint64_t index,
249 struct vstack_entry *stack_top,
250 int idx_len)
251{
252 int ret;
253 struct filter_get_index_data gid;
254 ssize_t data_offset;
255
256 memset(&gid, 0, sizeof(gid));
257 switch (stack_top->load.type) {
258 case LOAD_OBJECT:
259 switch (stack_top->load.object_type) {
260 case OBJECT_TYPE_ARRAY:
261 {
218deb69 262 const struct lttng_integer_type *integer_type;
47e5f13e
MD
263 const struct lttng_event_field *field;
264 uint32_t elem_len, num_elems;
265 int signedness;
266
267 field = stack_top->load.field;
218deb69
MD
268 switch (field->type.atype) {
269 case atype_array:
270 integer_type = &field->type.u.legacy.array.elem_type.u.basic.integer;
271 num_elems = field->type.u.legacy.array.length;
272 break;
273 case atype_array_nestable:
274 if (field->type.u.array_nestable.elem_type->atype != atype_integer) {
275 ret = -EINVAL;
276 goto end;
277 }
278 integer_type = &field->type.u.array_nestable.elem_type->u.integer;
279 num_elems = field->type.u.array_nestable.length;
280 break;
281 default:
282 ret = -EINVAL;
283 goto end;
284 }
285 elem_len = integer_type->size;
286 signedness = integer_type->signedness;
47e5f13e
MD
287 if (index >= num_elems) {
288 ret = -EINVAL;
289 goto end;
290 }
291 ret = specialize_get_index_object_type(&stack_top->load.object_type,
292 signedness, elem_len);
293 if (ret)
294 goto end;
295 gid.offset = index * (elem_len / CHAR_BIT);
296 gid.array_len = num_elems * (elem_len / CHAR_BIT);
297 gid.elem.type = stack_top->load.object_type;
298 gid.elem.len = elem_len;
218deb69 299 if (integer_type->reverse_byte_order)
47e5f13e
MD
300 gid.elem.rev_bo = true;
301 stack_top->load.rev_bo = gid.elem.rev_bo;
302 break;
303 }
304 case OBJECT_TYPE_SEQUENCE:
305 {
218deb69 306 const struct lttng_integer_type *integer_type;
47e5f13e
MD
307 const struct lttng_event_field *field;
308 uint32_t elem_len;
309 int signedness;
310
311 field = stack_top->load.field;
218deb69
MD
312 switch (field->type.atype) {
313 case atype_sequence:
314 integer_type = &field->type.u.legacy.sequence.elem_type.u.basic.integer;
315 break;
316 case atype_sequence_nestable:
317 if (field->type.u.sequence_nestable.elem_type->atype != atype_integer) {
318 ret = -EINVAL;
319 goto end;
320 }
321 integer_type = &field->type.u.sequence_nestable.elem_type->u.integer;
322 break;
323 default:
324 ret = -EINVAL;
325 goto end;
326 }
327 elem_len = integer_type->size;
328 signedness = integer_type->signedness;
47e5f13e
MD
329 ret = specialize_get_index_object_type(&stack_top->load.object_type,
330 signedness, elem_len);
331 if (ret)
332 goto end;
333 gid.offset = index * (elem_len / CHAR_BIT);
334 gid.elem.type = stack_top->load.object_type;
335 gid.elem.len = elem_len;
218deb69 336 if (integer_type->reverse_byte_order)
47e5f13e
MD
337 gid.elem.rev_bo = true;
338 stack_top->load.rev_bo = gid.elem.rev_bo;
339 break;
340 }
341 case OBJECT_TYPE_STRUCT:
342 /* Only generated by the specialize phase. */
343 case OBJECT_TYPE_VARIANT: /* Fall-through */
344 default:
345 ERR("Unexpected get index type %d",
346 (int) stack_top->load.object_type);
347 ret = -EINVAL;
348 goto end;
349 }
350 break;
351 case LOAD_ROOT_CONTEXT:
352 case LOAD_ROOT_APP_CONTEXT:
353 case LOAD_ROOT_PAYLOAD:
354 ERR("Index lookup for root field not implemented yet.");
355 ret = -EINVAL;
356 goto end;
357 }
358 data_offset = bytecode_push_data(runtime, &gid,
359 __alignof__(gid), sizeof(gid));
360 if (data_offset < 0) {
361 ret = -EINVAL;
362 goto end;
363 }
364 switch (idx_len) {
365 case 2:
366 ((struct get_index_u16 *) insn->data)->index = data_offset;
367 break;
368 case 8:
369 ((struct get_index_u64 *) insn->data)->index = data_offset;
370 break;
371 default:
372 ret = -EINVAL;
373 goto end;
374 }
375
376 return 0;
377
378end:
379 return ret;
380}
381
382static int specialize_context_lookup_name(struct lttng_ctx *ctx,
383 struct bytecode_runtime *bytecode,
384 struct load_op *insn)
385{
386 uint16_t offset;
387 const char *name;
388
389 offset = ((struct get_symbol *) insn->data)->offset;
390 name = bytecode->p.bc->bc.data + bytecode->p.bc->bc.reloc_offset + offset;
391 return lttng_get_context_index(ctx, name);
392}
393
394static int specialize_load_object(const struct lttng_event_field *field,
395 struct vstack_load *load, bool is_context)
396{
397 load->type = LOAD_OBJECT;
398 /*
399 * LTTng-UST layout all integer fields as s64 on the stack for the filter.
400 */
401 switch (field->type.atype) {
402 case atype_integer:
218deb69 403 if (field->type.u.integer.signedness)
47e5f13e
MD
404 load->object_type = OBJECT_TYPE_S64;
405 else
406 load->object_type = OBJECT_TYPE_U64;
407 load->rev_bo = false;
408 break;
409 case atype_enum:
218deb69 410 case atype_enum_nestable:
47e5f13e 411 {
218deb69 412 const struct lttng_integer_type *itype;
47e5f13e 413
218deb69
MD
414 if (field->type.atype == atype_enum) {
415 itype = &field->type.u.legacy.basic.enumeration.container_type;
416 } else {
417 itype = &field->type.u.enum_nestable.container_type->u.integer;
418 }
47e5f13e
MD
419 if (itype->signedness)
420 load->object_type = OBJECT_TYPE_S64;
421 else
422 load->object_type = OBJECT_TYPE_U64;
423 load->rev_bo = false;
424 break;
425 }
426 case atype_array:
218deb69
MD
427 if (field->type.u.legacy.array.elem_type.atype != atype_integer) {
428 ERR("Array nesting only supports integer types.");
429 return -EINVAL;
430 }
431 if (is_context) {
432 load->object_type = OBJECT_TYPE_STRING;
433 } else {
434 if (field->type.u.legacy.array.elem_type.u.basic.integer.encoding == lttng_encode_none) {
435 load->object_type = OBJECT_TYPE_ARRAY;
436 load->field = field;
437 } else {
438 load->object_type = OBJECT_TYPE_STRING_SEQUENCE;
439 }
440 }
441 break;
442 case atype_array_nestable:
443 if (field->type.u.array_nestable.elem_type->atype != atype_integer) {
47e5f13e
MD
444 ERR("Array nesting only supports integer types.");
445 return -EINVAL;
446 }
447 if (is_context) {
448 load->object_type = OBJECT_TYPE_STRING;
449 } else {
218deb69 450 if (field->type.u.array_nestable.elem_type->u.integer.encoding == lttng_encode_none) {
47e5f13e
MD
451 load->object_type = OBJECT_TYPE_ARRAY;
452 load->field = field;
453 } else {
454 load->object_type = OBJECT_TYPE_STRING_SEQUENCE;
455 }
456 }
457 break;
458 case atype_sequence:
218deb69
MD
459 if (field->type.u.legacy.sequence.elem_type.atype != atype_integer) {
460 ERR("Sequence nesting only supports integer types.");
461 return -EINVAL;
462 }
463 if (is_context) {
464 load->object_type = OBJECT_TYPE_STRING;
465 } else {
466 if (field->type.u.legacy.sequence.elem_type.u.basic.integer.encoding == lttng_encode_none) {
467 load->object_type = OBJECT_TYPE_SEQUENCE;
468 load->field = field;
469 } else {
470 load->object_type = OBJECT_TYPE_STRING_SEQUENCE;
471 }
472 }
473 break;
474 case atype_sequence_nestable:
475 if (field->type.u.sequence_nestable.elem_type->atype != atype_integer) {
47e5f13e
MD
476 ERR("Sequence nesting only supports integer types.");
477 return -EINVAL;
478 }
479 if (is_context) {
480 load->object_type = OBJECT_TYPE_STRING;
481 } else {
218deb69 482 if (field->type.u.sequence_nestable.elem_type->u.integer.encoding == lttng_encode_none) {
47e5f13e
MD
483 load->object_type = OBJECT_TYPE_SEQUENCE;
484 load->field = field;
485 } else {
486 load->object_type = OBJECT_TYPE_STRING_SEQUENCE;
487 }
488 }
489 break;
218deb69 490
47e5f13e
MD
491 case atype_string:
492 load->object_type = OBJECT_TYPE_STRING;
493 break;
494 case atype_float:
495 load->object_type = OBJECT_TYPE_DOUBLE;
496 break;
497 case atype_dynamic:
498 load->object_type = OBJECT_TYPE_DYNAMIC;
8d3190bd 499 break;
47e5f13e
MD
500 case atype_struct:
501 ERR("Structure type cannot be loaded.");
502 return -EINVAL;
503 default:
504 ERR("Unknown type: %d", (int) field->type.atype);
505 return -EINVAL;
506 }
507 return 0;
508}
509
510static int specialize_context_lookup(struct lttng_session *session,
511 struct bytecode_runtime *runtime,
512 struct load_op *insn,
513 struct vstack_load *load)
514{
515 int idx, ret;
516 struct lttng_ctx_field *ctx_field;
517 struct lttng_event_field *field;
518 struct filter_get_index_data gid;
519 ssize_t data_offset;
520
521 idx = specialize_context_lookup_name(session->ctx, runtime, insn);
522 if (idx < 0) {
523 return -ENOENT;
524 }
525 ctx_field = &session->ctx->fields[idx];
526 field = &ctx_field->event_field;
527 ret = specialize_load_object(field, load, true);
528 if (ret)
529 return ret;
530 /* Specialize each get_symbol into a get_index. */
531 insn->op = FILTER_OP_GET_INDEX_U16;
532 memset(&gid, 0, sizeof(gid));
533 gid.ctx_index = idx;
534 gid.elem.type = load->object_type;
535 data_offset = bytecode_push_data(runtime, &gid,
536 __alignof__(gid), sizeof(gid));
537 if (data_offset < 0) {
538 return -EINVAL;
539 }
540 ((struct get_index_u16 *) insn->data)->index = data_offset;
541 return 0;
542}
543
544static int specialize_app_context_lookup(struct lttng_session *session,
545 struct bytecode_runtime *runtime,
546 struct load_op *insn,
547 struct vstack_load *load)
548{
549 uint16_t offset;
550 const char *orig_name;
551 char *name = NULL;
552 int idx, ret;
553 struct lttng_ctx_field *ctx_field;
554 struct lttng_event_field *field;
555 struct filter_get_index_data gid;
556 ssize_t data_offset;
557
558 offset = ((struct get_symbol *) insn->data)->offset;
559 orig_name = runtime->p.bc->bc.data + runtime->p.bc->bc.reloc_offset + offset;
560 name = zmalloc(strlen(orig_name) + strlen("$app.") + 1);
561 if (!name) {
562 ret = -ENOMEM;
563 goto end;
564 }
565 strcpy(name, "$app.");
566 strcat(name, orig_name);
567 idx = lttng_get_context_index(session->ctx, name);
568 if (idx < 0) {
569 assert(lttng_context_is_app(name));
570 ret = lttng_ust_add_app_context_to_ctx_rcu(name,
571 &session->ctx);
572 if (ret)
573 return ret;
574 idx = lttng_get_context_index(session->ctx,
575 name);
576 if (idx < 0)
577 return -ENOENT;
578 }
579 ctx_field = &session->ctx->fields[idx];
580 field = &ctx_field->event_field;
581 ret = specialize_load_object(field, load, true);
582 if (ret)
583 goto end;
584 /* Specialize each get_symbol into a get_index. */
585 insn->op = FILTER_OP_GET_INDEX_U16;
586 memset(&gid, 0, sizeof(gid));
587 gid.ctx_index = idx;
588 gid.elem.type = load->object_type;
589 data_offset = bytecode_push_data(runtime, &gid,
590 __alignof__(gid), sizeof(gid));
591 if (data_offset < 0) {
592 ret = -EINVAL;
593 goto end;
594 }
595 ((struct get_index_u16 *) insn->data)->index = data_offset;
596 ret = 0;
597end:
598 free(name);
599 return ret;
600}
601
602static int specialize_event_payload_lookup(struct lttng_event *event,
603 struct bytecode_runtime *runtime,
604 struct load_op *insn,
605 struct vstack_load *load)
606{
607 const char *name;
608 uint16_t offset;
609 const struct lttng_event_desc *desc = event->desc;
610 unsigned int i, nr_fields;
611 bool found = false;
612 uint32_t field_offset = 0;
613 const struct lttng_event_field *field;
614 int ret;
615 struct filter_get_index_data gid;
616 ssize_t data_offset;
617
618 nr_fields = desc->nr_fields;
619 offset = ((struct get_symbol *) insn->data)->offset;
620 name = runtime->p.bc->bc.data + runtime->p.bc->bc.reloc_offset + offset;
621 for (i = 0; i < nr_fields; i++) {
622 field = &desc->fields[i];
218deb69
MD
623 if (field->u.ext.nofilter) {
624 continue;
625 }
47e5f13e
MD
626 if (!strcmp(field->name, name)) {
627 found = true;
628 break;
629 }
630 /* compute field offset on stack */
631 switch (field->type.atype) {
632 case atype_integer:
633 case atype_enum:
218deb69 634 case atype_enum_nestable:
47e5f13e
MD
635 field_offset += sizeof(int64_t);
636 break;
637 case atype_array:
218deb69 638 case atype_array_nestable:
47e5f13e 639 case atype_sequence:
218deb69 640 case atype_sequence_nestable:
47e5f13e
MD
641 field_offset += sizeof(unsigned long);
642 field_offset += sizeof(void *);
643 break;
644 case atype_string:
645 field_offset += sizeof(void *);
646 break;
647 case atype_float:
648 field_offset += sizeof(double);
649 break;
650 default:
651 ret = -EINVAL;
652 goto end;
653 }
654 }
655 if (!found) {
656 ret = -EINVAL;
657 goto end;
658 }
659
660 ret = specialize_load_object(field, load, false);
661 if (ret)
662 goto end;
663
664 /* Specialize each get_symbol into a get_index. */
665 insn->op = FILTER_OP_GET_INDEX_U16;
666 memset(&gid, 0, sizeof(gid));
667 gid.offset = field_offset;
668 gid.elem.type = load->object_type;
669 data_offset = bytecode_push_data(runtime, &gid,
670 __alignof__(gid), sizeof(gid));
671 if (data_offset < 0) {
672 ret = -EINVAL;
673 goto end;
674 }
675 ((struct get_index_u16 *) insn->data)->index = data_offset;
676 ret = 0;
677end:
678 return ret;
679}
680
681int lttng_filter_specialize_bytecode(struct lttng_event *event,
682 struct bytecode_runtime *bytecode)
97b58163
MD
683{
684 void *pc, *next_pc, *start_pc;
685 int ret = -EINVAL;
0305960f
MD
686 struct vstack _stack;
687 struct vstack *stack = &_stack;
47e5f13e 688 struct lttng_session *session = bytecode->p.session;
97b58163 689
0305960f 690 vstack_init(stack);
97b58163 691
47e5f13e 692 start_pc = &bytecode->code[0];
97b58163
MD
693 for (pc = next_pc = start_pc; pc - start_pc < bytecode->len;
694 pc = next_pc) {
695 switch (*(filter_opcode_t *) pc) {
696 case FILTER_OP_UNKNOWN:
697 default:
698 ERR("unknown bytecode op %u\n",
699 (unsigned int) *(filter_opcode_t *) pc);
700 ret = -EINVAL;
701 goto end;
702
703 case FILTER_OP_RETURN:
93c591bb
MD
704 if (vstack_ax(stack)->type == REG_S64)
705 *(filter_opcode_t *) pc = FILTER_OP_RETURN_S64;
706 ret = 0;
707 goto end;
708
709 case FILTER_OP_RETURN_S64:
710 if (vstack_ax(stack)->type != REG_S64) {
711 ERR("Unexpected register type\n");
712 ret = -EINVAL;
713 goto end;
714 }
97b58163
MD
715 ret = 0;
716 goto end;
717
718 /* binary */
719 case FILTER_OP_MUL:
720 case FILTER_OP_DIV:
721 case FILTER_OP_MOD:
722 case FILTER_OP_PLUS:
723 case FILTER_OP_MINUS:
97b58163
MD
724 ERR("unsupported bytecode op %u\n",
725 (unsigned int) *(filter_opcode_t *) pc);
726 ret = -EINVAL;
727 goto end;
728
729 case FILTER_OP_EQ:
730 {
731 struct binary_op *insn = (struct binary_op *) pc;
732
0305960f 733 switch(vstack_ax(stack)->type) {
97b58163
MD
734 default:
735 ERR("unknown register type\n");
736 ret = -EINVAL;
737 goto end;
738
739 case REG_STRING:
53569322
MD
740 if (vstack_bx(stack)->type == REG_UNKNOWN)
741 break;
3151a51d
PP
742 if (vstack_bx(stack)->type == REG_STAR_GLOB_STRING)
743 insn->op = FILTER_OP_EQ_STAR_GLOB_STRING;
744 else
745 insn->op = FILTER_OP_EQ_STRING;
746 break;
747 case REG_STAR_GLOB_STRING:
748 if (vstack_bx(stack)->type == REG_UNKNOWN)
749 break;
750 insn->op = FILTER_OP_EQ_STAR_GLOB_STRING;
97b58163
MD
751 break;
752 case REG_S64:
53569322
MD
753 if (vstack_bx(stack)->type == REG_UNKNOWN)
754 break;
0305960f 755 if (vstack_bx(stack)->type == REG_S64)
97b58163
MD
756 insn->op = FILTER_OP_EQ_S64;
757 else
dbea82ec 758 insn->op = FILTER_OP_EQ_DOUBLE_S64;
97b58163
MD
759 break;
760 case REG_DOUBLE:
53569322
MD
761 if (vstack_bx(stack)->type == REG_UNKNOWN)
762 break;
dbea82ec
MD
763 if (vstack_bx(stack)->type == REG_S64)
764 insn->op = FILTER_OP_EQ_S64_DOUBLE;
765 else
766 insn->op = FILTER_OP_EQ_DOUBLE;
97b58163 767 break;
53569322
MD
768 case REG_UNKNOWN:
769 break; /* Dynamic typing. */
97b58163 770 }
0305960f
MD
771 /* Pop 2, push 1 */
772 if (vstack_pop(stack)) {
773 ret = -EINVAL;
774 goto end;
775 }
776 vstack_ax(stack)->type = REG_S64;
97b58163
MD
777 next_pc += sizeof(struct binary_op);
778 break;
779 }
780
781 case FILTER_OP_NE:
782 {
783 struct binary_op *insn = (struct binary_op *) pc;
784
0305960f 785 switch(vstack_ax(stack)->type) {
97b58163
MD
786 default:
787 ERR("unknown register type\n");
788 ret = -EINVAL;
789 goto end;
790
791 case REG_STRING:
53569322
MD
792 if (vstack_bx(stack)->type == REG_UNKNOWN)
793 break;
3151a51d
PP
794 if (vstack_bx(stack)->type == REG_STAR_GLOB_STRING)
795 insn->op = FILTER_OP_NE_STAR_GLOB_STRING;
796 else
797 insn->op = FILTER_OP_NE_STRING;
798 break;
799 case REG_STAR_GLOB_STRING:
800 if (vstack_bx(stack)->type == REG_UNKNOWN)
801 break;
802 insn->op = FILTER_OP_NE_STAR_GLOB_STRING;
97b58163
MD
803 break;
804 case REG_S64:
53569322
MD
805 if (vstack_bx(stack)->type == REG_UNKNOWN)
806 break;
0305960f 807 if (vstack_bx(stack)->type == REG_S64)
97b58163
MD
808 insn->op = FILTER_OP_NE_S64;
809 else
dbea82ec 810 insn->op = FILTER_OP_NE_DOUBLE_S64;
97b58163
MD
811 break;
812 case REG_DOUBLE:
53569322
MD
813 if (vstack_bx(stack)->type == REG_UNKNOWN)
814 break;
dbea82ec
MD
815 if (vstack_bx(stack)->type == REG_S64)
816 insn->op = FILTER_OP_NE_S64_DOUBLE;
817 else
818 insn->op = FILTER_OP_NE_DOUBLE;
97b58163 819 break;
53569322
MD
820 case REG_UNKNOWN:
821 break; /* Dynamic typing. */
97b58163 822 }
0305960f
MD
823 /* Pop 2, push 1 */
824 if (vstack_pop(stack)) {
825 ret = -EINVAL;
826 goto end;
827 }
828 vstack_ax(stack)->type = REG_S64;
97b58163
MD
829 next_pc += sizeof(struct binary_op);
830 break;
831 }
832
833 case FILTER_OP_GT:
834 {
835 struct binary_op *insn = (struct binary_op *) pc;
836
0305960f 837 switch(vstack_ax(stack)->type) {
97b58163
MD
838 default:
839 ERR("unknown register type\n");
840 ret = -EINVAL;
841 goto end;
842
3151a51d
PP
843 case REG_STAR_GLOB_STRING:
844 ERR("invalid register type for > binary operator\n");
845 ret = -EINVAL;
846 goto end;
97b58163 847 case REG_STRING:
53569322
MD
848 if (vstack_bx(stack)->type == REG_UNKNOWN)
849 break;
97b58163
MD
850 insn->op = FILTER_OP_GT_STRING;
851 break;
852 case REG_S64:
53569322
MD
853 if (vstack_bx(stack)->type == REG_UNKNOWN)
854 break;
0305960f 855 if (vstack_bx(stack)->type == REG_S64)
97b58163
MD
856 insn->op = FILTER_OP_GT_S64;
857 else
dbea82ec 858 insn->op = FILTER_OP_GT_DOUBLE_S64;
97b58163
MD
859 break;
860 case REG_DOUBLE:
53569322
MD
861 if (vstack_bx(stack)->type == REG_UNKNOWN)
862 break;
dbea82ec
MD
863 if (vstack_bx(stack)->type == REG_S64)
864 insn->op = FILTER_OP_GT_S64_DOUBLE;
865 else
866 insn->op = FILTER_OP_GT_DOUBLE;
97b58163 867 break;
53569322
MD
868 case REG_UNKNOWN:
869 break; /* Dynamic typing. */
97b58163 870 }
0305960f
MD
871 /* Pop 2, push 1 */
872 if (vstack_pop(stack)) {
873 ret = -EINVAL;
874 goto end;
875 }
876 vstack_ax(stack)->type = REG_S64;
97b58163
MD
877 next_pc += sizeof(struct binary_op);
878 break;
879 }
880
881 case FILTER_OP_LT:
882 {
883 struct binary_op *insn = (struct binary_op *) pc;
884
0305960f 885 switch(vstack_ax(stack)->type) {
97b58163
MD
886 default:
887 ERR("unknown register type\n");
888 ret = -EINVAL;
889 goto end;
890
3151a51d
PP
891 case REG_STAR_GLOB_STRING:
892 ERR("invalid register type for < binary operator\n");
893 ret = -EINVAL;
894 goto end;
97b58163 895 case REG_STRING:
53569322
MD
896 if (vstack_bx(stack)->type == REG_UNKNOWN)
897 break;
97b58163
MD
898 insn->op = FILTER_OP_LT_STRING;
899 break;
900 case REG_S64:
53569322
MD
901 if (vstack_bx(stack)->type == REG_UNKNOWN)
902 break;
0305960f 903 if (vstack_bx(stack)->type == REG_S64)
97b58163
MD
904 insn->op = FILTER_OP_LT_S64;
905 else
dbea82ec 906 insn->op = FILTER_OP_LT_DOUBLE_S64;
97b58163
MD
907 break;
908 case REG_DOUBLE:
53569322
MD
909 if (vstack_bx(stack)->type == REG_UNKNOWN)
910 break;
dbea82ec
MD
911 if (vstack_bx(stack)->type == REG_S64)
912 insn->op = FILTER_OP_LT_S64_DOUBLE;
913 else
914 insn->op = FILTER_OP_LT_DOUBLE;
97b58163 915 break;
53569322
MD
916 case REG_UNKNOWN:
917 break; /* Dynamic typing. */
97b58163 918 }
0305960f
MD
919 /* Pop 2, push 1 */
920 if (vstack_pop(stack)) {
921 ret = -EINVAL;
922 goto end;
923 }
924 vstack_ax(stack)->type = REG_S64;
97b58163
MD
925 next_pc += sizeof(struct binary_op);
926 break;
927 }
928
929 case FILTER_OP_GE:
930 {
931 struct binary_op *insn = (struct binary_op *) pc;
932
0305960f 933 switch(vstack_ax(stack)->type) {
97b58163
MD
934 default:
935 ERR("unknown register type\n");
936 ret = -EINVAL;
937 goto end;
938
3151a51d
PP
939 case REG_STAR_GLOB_STRING:
940 ERR("invalid register type for >= binary operator\n");
941 ret = -EINVAL;
942 goto end;
97b58163 943 case REG_STRING:
53569322
MD
944 if (vstack_bx(stack)->type == REG_UNKNOWN)
945 break;
97b58163
MD
946 insn->op = FILTER_OP_GE_STRING;
947 break;
948 case REG_S64:
53569322
MD
949 if (vstack_bx(stack)->type == REG_UNKNOWN)
950 break;
0305960f 951 if (vstack_bx(stack)->type == REG_S64)
97b58163
MD
952 insn->op = FILTER_OP_GE_S64;
953 else
dbea82ec 954 insn->op = FILTER_OP_GE_DOUBLE_S64;
97b58163
MD
955 break;
956 case REG_DOUBLE:
53569322
MD
957 if (vstack_bx(stack)->type == REG_UNKNOWN)
958 break;
dbea82ec
MD
959 if (vstack_bx(stack)->type == REG_S64)
960 insn->op = FILTER_OP_GE_S64_DOUBLE;
961 else
962 insn->op = FILTER_OP_GE_DOUBLE;
97b58163 963 break;
53569322
MD
964 case REG_UNKNOWN:
965 break; /* Dynamic typing. */
97b58163 966 }
0305960f
MD
967 /* Pop 2, push 1 */
968 if (vstack_pop(stack)) {
969 ret = -EINVAL;
970 goto end;
971 }
972 vstack_ax(stack)->type = REG_S64;
97b58163
MD
973 next_pc += sizeof(struct binary_op);
974 break;
975 }
976 case FILTER_OP_LE:
977 {
978 struct binary_op *insn = (struct binary_op *) pc;
979
0305960f 980 switch(vstack_ax(stack)->type) {
97b58163
MD
981 default:
982 ERR("unknown register type\n");
983 ret = -EINVAL;
984 goto end;
985
3151a51d
PP
986 case REG_STAR_GLOB_STRING:
987 ERR("invalid register type for <= binary operator\n");
988 ret = -EINVAL;
989 goto end;
97b58163 990 case REG_STRING:
53569322
MD
991 if (vstack_bx(stack)->type == REG_UNKNOWN)
992 break;
97b58163
MD
993 insn->op = FILTER_OP_LE_STRING;
994 break;
995 case REG_S64:
53569322
MD
996 if (vstack_bx(stack)->type == REG_UNKNOWN)
997 break;
0305960f 998 if (vstack_bx(stack)->type == REG_S64)
97b58163
MD
999 insn->op = FILTER_OP_LE_S64;
1000 else
dbea82ec 1001 insn->op = FILTER_OP_LE_DOUBLE_S64;
97b58163
MD
1002 break;
1003 case REG_DOUBLE:
53569322
MD
1004 if (vstack_bx(stack)->type == REG_UNKNOWN)
1005 break;
dbea82ec
MD
1006 if (vstack_bx(stack)->type == REG_S64)
1007 insn->op = FILTER_OP_LE_S64_DOUBLE;
1008 else
1009 insn->op = FILTER_OP_LE_DOUBLE;
97b58163 1010 break;
53569322
MD
1011 case REG_UNKNOWN:
1012 break; /* Dynamic typing. */
97b58163 1013 }
0305960f 1014 vstack_ax(stack)->type = REG_S64;
97b58163
MD
1015 next_pc += sizeof(struct binary_op);
1016 break;
1017 }
1018
1019 case FILTER_OP_EQ_STRING:
1020 case FILTER_OP_NE_STRING:
1021 case FILTER_OP_GT_STRING:
1022 case FILTER_OP_LT_STRING:
1023 case FILTER_OP_GE_STRING:
1024 case FILTER_OP_LE_STRING:
3151a51d
PP
1025 case FILTER_OP_EQ_STAR_GLOB_STRING:
1026 case FILTER_OP_NE_STAR_GLOB_STRING:
97b58163
MD
1027 case FILTER_OP_EQ_S64:
1028 case FILTER_OP_NE_S64:
1029 case FILTER_OP_GT_S64:
1030 case FILTER_OP_LT_S64:
1031 case FILTER_OP_GE_S64:
1032 case FILTER_OP_LE_S64:
1033 case FILTER_OP_EQ_DOUBLE:
1034 case FILTER_OP_NE_DOUBLE:
1035 case FILTER_OP_GT_DOUBLE:
1036 case FILTER_OP_LT_DOUBLE:
1037 case FILTER_OP_GE_DOUBLE:
1038 case FILTER_OP_LE_DOUBLE:
dbea82ec
MD
1039 case FILTER_OP_EQ_DOUBLE_S64:
1040 case FILTER_OP_NE_DOUBLE_S64:
1041 case FILTER_OP_GT_DOUBLE_S64:
1042 case FILTER_OP_LT_DOUBLE_S64:
1043 case FILTER_OP_GE_DOUBLE_S64:
1044 case FILTER_OP_LE_DOUBLE_S64:
1045 case FILTER_OP_EQ_S64_DOUBLE:
1046 case FILTER_OP_NE_S64_DOUBLE:
1047 case FILTER_OP_GT_S64_DOUBLE:
1048 case FILTER_OP_LT_S64_DOUBLE:
1049 case FILTER_OP_GE_S64_DOUBLE:
1050 case FILTER_OP_LE_S64_DOUBLE:
0039e2d8
MD
1051 case FILTER_OP_BIT_RSHIFT:
1052 case FILTER_OP_BIT_LSHIFT:
47e5f13e
MD
1053 case FILTER_OP_BIT_AND:
1054 case FILTER_OP_BIT_OR:
1055 case FILTER_OP_BIT_XOR:
97b58163 1056 {
0305960f
MD
1057 /* Pop 2, push 1 */
1058 if (vstack_pop(stack)) {
1059 ret = -EINVAL;
1060 goto end;
1061 }
1062 vstack_ax(stack)->type = REG_S64;
97b58163
MD
1063 next_pc += sizeof(struct binary_op);
1064 break;
1065 }
1066
1067 /* unary */
1068 case FILTER_OP_UNARY_PLUS:
1069 {
1070 struct unary_op *insn = (struct unary_op *) pc;
1071
0305960f 1072 switch(vstack_ax(stack)->type) {
97b58163
MD
1073 default:
1074 ERR("unknown register type\n");
1075 ret = -EINVAL;
1076 goto end;
1077
1078 case REG_S64:
1079 insn->op = FILTER_OP_UNARY_PLUS_S64;
1080 break;
1081 case REG_DOUBLE:
1082 insn->op = FILTER_OP_UNARY_PLUS_DOUBLE;
1083 break;
53569322
MD
1084 case REG_UNKNOWN: /* Dynamic typing. */
1085 break;
97b58163 1086 }
0305960f 1087 /* Pop 1, push 1 */
97b58163
MD
1088 next_pc += sizeof(struct unary_op);
1089 break;
1090 }
1091
1092 case FILTER_OP_UNARY_MINUS:
1093 {
1094 struct unary_op *insn = (struct unary_op *) pc;
1095
0305960f 1096 switch(vstack_ax(stack)->type) {
97b58163
MD
1097 default:
1098 ERR("unknown register type\n");
1099 ret = -EINVAL;
1100 goto end;
1101
1102 case REG_S64:
1103 insn->op = FILTER_OP_UNARY_MINUS_S64;
1104 break;
1105 case REG_DOUBLE:
1106 insn->op = FILTER_OP_UNARY_MINUS_DOUBLE;
1107 break;
53569322
MD
1108 case REG_UNKNOWN: /* Dynamic typing. */
1109 break;
97b58163 1110 }
0305960f 1111 /* Pop 1, push 1 */
97b58163
MD
1112 next_pc += sizeof(struct unary_op);
1113 break;
1114 }
1115
1116 case FILTER_OP_UNARY_NOT:
1117 {
1118 struct unary_op *insn = (struct unary_op *) pc;
1119
0305960f 1120 switch(vstack_ax(stack)->type) {
97b58163
MD
1121 default:
1122 ERR("unknown register type\n");
1123 ret = -EINVAL;
1124 goto end;
1125
1126 case REG_S64:
1127 insn->op = FILTER_OP_UNARY_NOT_S64;
1128 break;
1129 case REG_DOUBLE:
1130 insn->op = FILTER_OP_UNARY_NOT_DOUBLE;
1131 break;
53569322
MD
1132 case REG_UNKNOWN: /* Dynamic typing. */
1133 break;
97b58163 1134 }
0305960f 1135 /* Pop 1, push 1 */
97b58163
MD
1136 next_pc += sizeof(struct unary_op);
1137 break;
1138 }
1139
0039e2d8
MD
1140 case FILTER_OP_UNARY_BIT_NOT:
1141 {
1142 /* Pop 1, push 1 */
1143 next_pc += sizeof(struct unary_op);
1144 break;
1145 }
1146
97b58163
MD
1147 case FILTER_OP_UNARY_PLUS_S64:
1148 case FILTER_OP_UNARY_MINUS_S64:
1149 case FILTER_OP_UNARY_NOT_S64:
1150 case FILTER_OP_UNARY_PLUS_DOUBLE:
1151 case FILTER_OP_UNARY_MINUS_DOUBLE:
1152 case FILTER_OP_UNARY_NOT_DOUBLE:
1153 {
0305960f 1154 /* Pop 1, push 1 */
97b58163
MD
1155 next_pc += sizeof(struct unary_op);
1156 break;
1157 }
1158
1159 /* logical */
1160 case FILTER_OP_AND:
1161 case FILTER_OP_OR:
1162 {
b9f4cd79
MD
1163 /* Continue to next instruction */
1164 /* Pop 1 when jump not taken */
1165 if (vstack_pop(stack)) {
1166 ret = -EINVAL;
1167 goto end;
1168 }
97b58163
MD
1169 next_pc += sizeof(struct logical_op);
1170 break;
1171 }
1172
77aa5901 1173 /* load field ref */
97b58163
MD
1174 case FILTER_OP_LOAD_FIELD_REF:
1175 {
1176 ERR("Unknown field ref type\n");
1177 ret = -EINVAL;
1178 goto end;
1179 }
77aa5901
MD
1180 /* get context ref */
1181 case FILTER_OP_GET_CONTEXT_REF:
1182 {
53569322
MD
1183 if (vstack_push(stack)) {
1184 ret = -EINVAL;
1185 goto end;
1186 }
1187 vstack_ax(stack)->type = REG_UNKNOWN;
1188 next_pc += sizeof(struct load_op) + sizeof(struct field_ref);
1189 break;
77aa5901 1190 }
97b58163
MD
1191 case FILTER_OP_LOAD_FIELD_REF_STRING:
1192 case FILTER_OP_LOAD_FIELD_REF_SEQUENCE:
77aa5901 1193 case FILTER_OP_GET_CONTEXT_REF_STRING:
97b58163 1194 {
0305960f
MD
1195 if (vstack_push(stack)) {
1196 ret = -EINVAL;
1197 goto end;
1198 }
1199 vstack_ax(stack)->type = REG_STRING;
97b58163
MD
1200 next_pc += sizeof(struct load_op) + sizeof(struct field_ref);
1201 break;
1202 }
1203 case FILTER_OP_LOAD_FIELD_REF_S64:
77aa5901 1204 case FILTER_OP_GET_CONTEXT_REF_S64:
97b58163 1205 {
0305960f
MD
1206 if (vstack_push(stack)) {
1207 ret = -EINVAL;
1208 goto end;
1209 }
1210 vstack_ax(stack)->type = REG_S64;
97b58163
MD
1211 next_pc += sizeof(struct load_op) + sizeof(struct field_ref);
1212 break;
1213 }
1214 case FILTER_OP_LOAD_FIELD_REF_DOUBLE:
77aa5901 1215 case FILTER_OP_GET_CONTEXT_REF_DOUBLE:
97b58163 1216 {
0305960f
MD
1217 if (vstack_push(stack)) {
1218 ret = -EINVAL;
1219 goto end;
1220 }
1221 vstack_ax(stack)->type = REG_DOUBLE;
97b58163
MD
1222 next_pc += sizeof(struct load_op) + sizeof(struct field_ref);
1223 break;
1224 }
1225
77aa5901 1226 /* load from immediate operand */
97b58163
MD
1227 case FILTER_OP_LOAD_STRING:
1228 {
1229 struct load_op *insn = (struct load_op *) pc;
1230
0305960f
MD
1231 if (vstack_push(stack)) {
1232 ret = -EINVAL;
1233 goto end;
1234 }
1235 vstack_ax(stack)->type = REG_STRING;
97b58163
MD
1236 next_pc += sizeof(struct load_op) + strlen(insn->data) + 1;
1237 break;
1238 }
1239
3151a51d
PP
1240 case FILTER_OP_LOAD_STAR_GLOB_STRING:
1241 {
1242 struct load_op *insn = (struct load_op *) pc;
1243
1244 if (vstack_push(stack)) {
1245 ret = -EINVAL;
1246 goto end;
1247 }
1248 vstack_ax(stack)->type = REG_STAR_GLOB_STRING;
1249 next_pc += sizeof(struct load_op) + strlen(insn->data) + 1;
1250 break;
1251 }
1252
97b58163
MD
1253 case FILTER_OP_LOAD_S64:
1254 {
0305960f
MD
1255 if (vstack_push(stack)) {
1256 ret = -EINVAL;
1257 goto end;
1258 }
1259 vstack_ax(stack)->type = REG_S64;
97b58163
MD
1260 next_pc += sizeof(struct load_op)
1261 + sizeof(struct literal_numeric);
1262 break;
1263 }
1264
1265 case FILTER_OP_LOAD_DOUBLE:
1266 {
0305960f
MD
1267 if (vstack_push(stack)) {
1268 ret = -EINVAL;
1269 goto end;
1270 }
1271 vstack_ax(stack)->type = REG_DOUBLE;
97b58163
MD
1272 next_pc += sizeof(struct load_op)
1273 + sizeof(struct literal_double);
1274 break;
1275 }
1276
1277 /* cast */
1278 case FILTER_OP_CAST_TO_S64:
1279 {
1280 struct cast_op *insn = (struct cast_op *) pc;
1281
0305960f 1282 switch (vstack_ax(stack)->type) {
97b58163
MD
1283 default:
1284 ERR("unknown register type\n");
1285 ret = -EINVAL;
1286 goto end;
1287
1288 case REG_STRING:
3151a51d 1289 case REG_STAR_GLOB_STRING:
97b58163
MD
1290 ERR("Cast op can only be applied to numeric or floating point registers\n");
1291 ret = -EINVAL;
1292 goto end;
1293 case REG_S64:
1294 insn->op = FILTER_OP_CAST_NOP;
1295 break;
1296 case REG_DOUBLE:
1297 insn->op = FILTER_OP_CAST_DOUBLE_TO_S64;
1298 break;
53569322
MD
1299 case REG_UNKNOWN:
1300 break;
97b58163 1301 }
0305960f
MD
1302 /* Pop 1, push 1 */
1303 vstack_ax(stack)->type = REG_S64;
97b58163
MD
1304 next_pc += sizeof(struct cast_op);
1305 break;
1306 }
1307 case FILTER_OP_CAST_DOUBLE_TO_S64:
1308 {
0305960f
MD
1309 /* Pop 1, push 1 */
1310 vstack_ax(stack)->type = REG_S64;
97b58163
MD
1311 next_pc += sizeof(struct cast_op);
1312 break;
1313 }
1314 case FILTER_OP_CAST_NOP:
1315 {
1316 next_pc += sizeof(struct cast_op);
1317 break;
1318 }
1319
47e5f13e
MD
1320 /*
1321 * Instructions for recursive traversal through composed types.
1322 */
1323 case FILTER_OP_GET_CONTEXT_ROOT:
1324 {
1325 if (vstack_push(stack)) {
1326 ret = -EINVAL;
1327 goto end;
1328 }
1329 vstack_ax(stack)->type = REG_PTR;
1330 vstack_ax(stack)->load.type = LOAD_ROOT_CONTEXT;
1331 next_pc += sizeof(struct load_op);
1332 break;
1333 }
1334 case FILTER_OP_GET_APP_CONTEXT_ROOT:
1335 {
1336 if (vstack_push(stack)) {
1337 ret = -EINVAL;
1338 goto end;
1339 }
1340 vstack_ax(stack)->type = REG_PTR;
1341 vstack_ax(stack)->load.type = LOAD_ROOT_APP_CONTEXT;
1342 next_pc += sizeof(struct load_op);
1343 break;
1344 }
1345 case FILTER_OP_GET_PAYLOAD_ROOT:
1346 {
1347 if (vstack_push(stack)) {
1348 ret = -EINVAL;
1349 goto end;
1350 }
1351 vstack_ax(stack)->type = REG_PTR;
1352 vstack_ax(stack)->load.type = LOAD_ROOT_PAYLOAD;
1353 next_pc += sizeof(struct load_op);
1354 break;
1355 }
1356
1357 case FILTER_OP_LOAD_FIELD:
1358 {
1359 struct load_op *insn = (struct load_op *) pc;
1360
1361 assert(vstack_ax(stack)->type == REG_PTR);
1362 /* Pop 1, push 1 */
1363 ret = specialize_load_field(vstack_ax(stack), insn);
1364 if (ret)
1365 goto end;
1366
1367 next_pc += sizeof(struct load_op);
1368 break;
1369 }
1370
1371 case FILTER_OP_LOAD_FIELD_S8:
1372 case FILTER_OP_LOAD_FIELD_S16:
1373 case FILTER_OP_LOAD_FIELD_S32:
1374 case FILTER_OP_LOAD_FIELD_S64:
1375 case FILTER_OP_LOAD_FIELD_U8:
1376 case FILTER_OP_LOAD_FIELD_U16:
1377 case FILTER_OP_LOAD_FIELD_U32:
1378 case FILTER_OP_LOAD_FIELD_U64:
1379 {
1380 /* Pop 1, push 1 */
1381 vstack_ax(stack)->type = REG_S64;
1382 next_pc += sizeof(struct load_op);
1383 break;
1384 }
1385
1386 case FILTER_OP_LOAD_FIELD_STRING:
1387 case FILTER_OP_LOAD_FIELD_SEQUENCE:
1388 {
1389 /* Pop 1, push 1 */
1390 vstack_ax(stack)->type = REG_STRING;
1391 next_pc += sizeof(struct load_op);
1392 break;
1393 }
1394
1395 case FILTER_OP_LOAD_FIELD_DOUBLE:
1396 {
1397 /* Pop 1, push 1 */
1398 vstack_ax(stack)->type = REG_DOUBLE;
1399 next_pc += sizeof(struct load_op);
1400 break;
1401 }
1402
1403 case FILTER_OP_GET_SYMBOL:
1404 {
1405 struct load_op *insn = (struct load_op *) pc;
1406
1407 dbg_printf("op get symbol\n");
1408 switch (vstack_ax(stack)->load.type) {
1409 case LOAD_OBJECT:
1410 ERR("Nested fields not implemented yet.");
1411 ret = -EINVAL;
1412 goto end;
1413 case LOAD_ROOT_CONTEXT:
1414 /* Lookup context field. */
1415 ret = specialize_context_lookup(session,
1416 bytecode, insn,
1417 &vstack_ax(stack)->load);
1418 if (ret)
1419 goto end;
1420 break;
1421 case LOAD_ROOT_APP_CONTEXT:
1422 /* Lookup app context field. */
1423 ret = specialize_app_context_lookup(session,
1424 bytecode, insn,
1425 &vstack_ax(stack)->load);
1426 if (ret)
1427 goto end;
1428 break;
1429 case LOAD_ROOT_PAYLOAD:
1430 /* Lookup event payload field. */
1431 ret = specialize_event_payload_lookup(event,
1432 bytecode, insn,
1433 &vstack_ax(stack)->load);
1434 if (ret)
1435 goto end;
1436 break;
1437 }
1438 next_pc += sizeof(struct load_op) + sizeof(struct get_symbol);
1439 break;
1440 }
1441
1442 case FILTER_OP_GET_SYMBOL_FIELD:
1443 {
1444 /* Always generated by specialize phase. */
1445 ret = -EINVAL;
1446 goto end;
1447 }
1448
1449 case FILTER_OP_GET_INDEX_U16:
1450 {
1451 struct load_op *insn = (struct load_op *) pc;
1452 struct get_index_u16 *index = (struct get_index_u16 *) insn->data;
1453
1454 dbg_printf("op get index u16\n");
1455 /* Pop 1, push 1 */
1456 ret = specialize_get_index(bytecode, insn, index->index,
1457 vstack_ax(stack), sizeof(*index));
1458 if (ret)
1459 goto end;
1460 next_pc += sizeof(struct load_op) + sizeof(struct get_index_u16);
1461 break;
1462 }
1463
1464 case FILTER_OP_GET_INDEX_U64:
1465 {
1466 struct load_op *insn = (struct load_op *) pc;
1467 struct get_index_u64 *index = (struct get_index_u64 *) insn->data;
1468
1469 dbg_printf("op get index u64\n");
1470 /* Pop 1, push 1 */
1471 ret = specialize_get_index(bytecode, insn, index->index,
1472 vstack_ax(stack), sizeof(*index));
1473 if (ret)
1474 goto end;
1475 next_pc += sizeof(struct load_op) + sizeof(struct get_index_u64);
1476 break;
1477 }
1478
97b58163
MD
1479 }
1480 }
1481end:
1482 return ret;
1483}
This page took 0.089318 seconds and 4 git commands to generate.