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