bytecode: add `REG_U64` interpreter register type
[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");
d97f9b78 160 stack_top->type = REG_U64;
47e5f13e
MD
161 insn->op = FILTER_OP_LOAD_FIELD_U8;
162 break;
163 case OBJECT_TYPE_U16:
164 dbg_printf("op load field u16\n");
d97f9b78 165 stack_top->type = REG_U64;
47e5f13e
MD
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");
d97f9b78 171 stack_top->type = REG_U64;
47e5f13e
MD
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");
d97f9b78 177 stack_top->type = REG_U64;
47e5f13e
MD
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;
d97f9b78 399
47e5f13e
MD
400 switch (field->type.atype) {
401 case atype_integer:
218deb69 402 if (field->type.u.integer.signedness)
47e5f13e
MD
403 load->object_type = OBJECT_TYPE_S64;
404 else
405 load->object_type = OBJECT_TYPE_U64;
406 load->rev_bo = false;
407 break;
408 case atype_enum:
218deb69 409 case atype_enum_nestable:
47e5f13e 410 {
218deb69 411 const struct lttng_integer_type *itype;
47e5f13e 412
218deb69
MD
413 if (field->type.atype == atype_enum) {
414 itype = &field->type.u.legacy.basic.enumeration.container_type;
415 } else {
416 itype = &field->type.u.enum_nestable.container_type->u.integer;
417 }
47e5f13e
MD
418 if (itype->signedness)
419 load->object_type = OBJECT_TYPE_S64;
420 else
421 load->object_type = OBJECT_TYPE_U64;
422 load->rev_bo = false;
423 break;
424 }
425 case atype_array:
218deb69
MD
426 if (field->type.u.legacy.array.elem_type.atype != atype_integer) {
427 ERR("Array nesting only supports integer types.");
428 return -EINVAL;
429 }
430 if (is_context) {
431 load->object_type = OBJECT_TYPE_STRING;
432 } else {
433 if (field->type.u.legacy.array.elem_type.u.basic.integer.encoding == lttng_encode_none) {
434 load->object_type = OBJECT_TYPE_ARRAY;
435 load->field = field;
436 } else {
437 load->object_type = OBJECT_TYPE_STRING_SEQUENCE;
438 }
439 }
440 break;
441 case atype_array_nestable:
442 if (field->type.u.array_nestable.elem_type->atype != atype_integer) {
47e5f13e
MD
443 ERR("Array nesting only supports integer types.");
444 return -EINVAL;
445 }
446 if (is_context) {
447 load->object_type = OBJECT_TYPE_STRING;
448 } else {
218deb69 449 if (field->type.u.array_nestable.elem_type->u.integer.encoding == lttng_encode_none) {
47e5f13e
MD
450 load->object_type = OBJECT_TYPE_ARRAY;
451 load->field = field;
452 } else {
453 load->object_type = OBJECT_TYPE_STRING_SEQUENCE;
454 }
455 }
456 break;
457 case atype_sequence:
218deb69
MD
458 if (field->type.u.legacy.sequence.elem_type.atype != atype_integer) {
459 ERR("Sequence nesting only supports integer types.");
460 return -EINVAL;
461 }
462 if (is_context) {
463 load->object_type = OBJECT_TYPE_STRING;
464 } else {
465 if (field->type.u.legacy.sequence.elem_type.u.basic.integer.encoding == lttng_encode_none) {
466 load->object_type = OBJECT_TYPE_SEQUENCE;
467 load->field = field;
468 } else {
469 load->object_type = OBJECT_TYPE_STRING_SEQUENCE;
470 }
471 }
472 break;
473 case atype_sequence_nestable:
474 if (field->type.u.sequence_nestable.elem_type->atype != atype_integer) {
47e5f13e
MD
475 ERR("Sequence nesting only supports integer types.");
476 return -EINVAL;
477 }
478 if (is_context) {
479 load->object_type = OBJECT_TYPE_STRING;
480 } else {
218deb69 481 if (field->type.u.sequence_nestable.elem_type->u.integer.encoding == lttng_encode_none) {
47e5f13e
MD
482 load->object_type = OBJECT_TYPE_SEQUENCE;
483 load->field = field;
484 } else {
485 load->object_type = OBJECT_TYPE_STRING_SEQUENCE;
486 }
487 }
488 break;
218deb69 489
47e5f13e
MD
490 case atype_string:
491 load->object_type = OBJECT_TYPE_STRING;
492 break;
493 case atype_float:
494 load->object_type = OBJECT_TYPE_DOUBLE;
495 break;
496 case atype_dynamic:
497 load->object_type = OBJECT_TYPE_DYNAMIC;
8d3190bd 498 break;
47e5f13e
MD
499 case atype_struct:
500 ERR("Structure type cannot be loaded.");
501 return -EINVAL;
502 default:
503 ERR("Unknown type: %d", (int) field->type.atype);
504 return -EINVAL;
505 }
506 return 0;
507}
508
b77aaa1b 509static int specialize_context_lookup(struct lttng_ctx *ctx,
47e5f13e
MD
510 struct bytecode_runtime *runtime,
511 struct load_op *insn,
512 struct vstack_load *load)
513{
514 int idx, ret;
515 struct lttng_ctx_field *ctx_field;
516 struct lttng_event_field *field;
517 struct filter_get_index_data gid;
518 ssize_t data_offset;
519
b77aaa1b 520 idx = specialize_context_lookup_name(ctx, runtime, insn);
47e5f13e
MD
521 if (idx < 0) {
522 return -ENOENT;
523 }
b77aaa1b 524 ctx_field = &ctx->fields[idx];
47e5f13e
MD
525 field = &ctx_field->event_field;
526 ret = specialize_load_object(field, load, true);
527 if (ret)
528 return ret;
529 /* Specialize each get_symbol into a get_index. */
530 insn->op = FILTER_OP_GET_INDEX_U16;
531 memset(&gid, 0, sizeof(gid));
532 gid.ctx_index = idx;
533 gid.elem.type = load->object_type;
534 data_offset = bytecode_push_data(runtime, &gid,
535 __alignof__(gid), sizeof(gid));
536 if (data_offset < 0) {
537 return -EINVAL;
538 }
539 ((struct get_index_u16 *) insn->data)->index = data_offset;
540 return 0;
541}
542
b77aaa1b 543static int specialize_app_context_lookup(struct lttng_ctx **pctx,
47e5f13e
MD
544 struct bytecode_runtime *runtime,
545 struct load_op *insn,
546 struct vstack_load *load)
547{
548 uint16_t offset;
549 const char *orig_name;
550 char *name = NULL;
551 int idx, ret;
552 struct lttng_ctx_field *ctx_field;
553 struct lttng_event_field *field;
554 struct filter_get_index_data gid;
555 ssize_t data_offset;
556
557 offset = ((struct get_symbol *) insn->data)->offset;
558 orig_name = runtime->p.bc->bc.data + runtime->p.bc->bc.reloc_offset + offset;
559 name = zmalloc(strlen(orig_name) + strlen("$app.") + 1);
560 if (!name) {
561 ret = -ENOMEM;
562 goto end;
563 }
564 strcpy(name, "$app.");
565 strcat(name, orig_name);
b77aaa1b 566 idx = lttng_get_context_index(*pctx, name);
47e5f13e
MD
567 if (idx < 0) {
568 assert(lttng_context_is_app(name));
569 ret = lttng_ust_add_app_context_to_ctx_rcu(name,
b77aaa1b 570 pctx);
47e5f13e
MD
571 if (ret)
572 return ret;
b77aaa1b 573 idx = lttng_get_context_index(*pctx, name);
47e5f13e
MD
574 if (idx < 0)
575 return -ENOENT;
576 }
b77aaa1b 577 ctx_field = &(*pctx)->fields[idx];
47e5f13e
MD
578 field = &ctx_field->event_field;
579 ret = specialize_load_object(field, load, true);
580 if (ret)
581 goto end;
582 /* Specialize each get_symbol into a get_index. */
583 insn->op = FILTER_OP_GET_INDEX_U16;
584 memset(&gid, 0, sizeof(gid));
585 gid.ctx_index = idx;
586 gid.elem.type = load->object_type;
587 data_offset = bytecode_push_data(runtime, &gid,
588 __alignof__(gid), sizeof(gid));
589 if (data_offset < 0) {
590 ret = -EINVAL;
591 goto end;
592 }
593 ((struct get_index_u16 *) insn->data)->index = data_offset;
594 ret = 0;
595end:
596 free(name);
597 return ret;
598}
599
53b9d7db 600static int specialize_payload_lookup(const struct lttng_event_desc *event_desc,
47e5f13e
MD
601 struct bytecode_runtime *runtime,
602 struct load_op *insn,
603 struct vstack_load *load)
604{
605 const char *name;
606 uint16_t offset;
47e5f13e
MD
607 unsigned int i, nr_fields;
608 bool found = false;
609 uint32_t field_offset = 0;
610 const struct lttng_event_field *field;
611 int ret;
612 struct filter_get_index_data gid;
613 ssize_t data_offset;
614
53b9d7db 615 nr_fields = event_desc->nr_fields;
47e5f13e
MD
616 offset = ((struct get_symbol *) insn->data)->offset;
617 name = runtime->p.bc->bc.data + runtime->p.bc->bc.reloc_offset + offset;
618 for (i = 0; i < nr_fields; i++) {
53b9d7db 619 field = &event_desc->fields[i];
218deb69
MD
620 if (field->u.ext.nofilter) {
621 continue;
622 }
47e5f13e
MD
623 if (!strcmp(field->name, name)) {
624 found = true;
625 break;
626 }
627 /* compute field offset on stack */
628 switch (field->type.atype) {
629 case atype_integer:
630 case atype_enum:
218deb69 631 case atype_enum_nestable:
47e5f13e
MD
632 field_offset += sizeof(int64_t);
633 break;
634 case atype_array:
218deb69 635 case atype_array_nestable:
47e5f13e 636 case atype_sequence:
218deb69 637 case atype_sequence_nestable:
47e5f13e
MD
638 field_offset += sizeof(unsigned long);
639 field_offset += sizeof(void *);
640 break;
641 case atype_string:
642 field_offset += sizeof(void *);
643 break;
644 case atype_float:
645 field_offset += sizeof(double);
646 break;
647 default:
648 ret = -EINVAL;
649 goto end;
650 }
651 }
652 if (!found) {
653 ret = -EINVAL;
654 goto end;
655 }
656
657 ret = specialize_load_object(field, load, false);
658 if (ret)
659 goto end;
660
661 /* Specialize each get_symbol into a get_index. */
662 insn->op = FILTER_OP_GET_INDEX_U16;
663 memset(&gid, 0, sizeof(gid));
664 gid.offset = field_offset;
665 gid.elem.type = load->object_type;
666 data_offset = bytecode_push_data(runtime, &gid,
667 __alignof__(gid), sizeof(gid));
668 if (data_offset < 0) {
669 ret = -EINVAL;
670 goto end;
671 }
672 ((struct get_index_u16 *) insn->data)->index = data_offset;
673 ret = 0;
674end:
675 return ret;
676}
677
53b9d7db 678int lttng_filter_specialize_bytecode(const struct lttng_event_desc *event_desc,
47e5f13e 679 struct bytecode_runtime *bytecode)
97b58163
MD
680{
681 void *pc, *next_pc, *start_pc;
682 int ret = -EINVAL;
0305960f
MD
683 struct vstack _stack;
684 struct vstack *stack = &_stack;
b77aaa1b 685 struct lttng_ctx **pctx = bytecode->p.pctx;
97b58163 686
0305960f 687 vstack_init(stack);
97b58163 688
47e5f13e 689 start_pc = &bytecode->code[0];
97b58163
MD
690 for (pc = next_pc = start_pc; pc - start_pc < bytecode->len;
691 pc = next_pc) {
692 switch (*(filter_opcode_t *) pc) {
693 case FILTER_OP_UNKNOWN:
694 default:
695 ERR("unknown bytecode op %u\n",
696 (unsigned int) *(filter_opcode_t *) pc);
697 ret = -EINVAL;
698 goto end;
699
700 case FILTER_OP_RETURN:
d97f9b78
MD
701 if (vstack_ax(stack)->type == REG_S64 ||
702 vstack_ax(stack)->type == REG_U64)
93c591bb
MD
703 *(filter_opcode_t *) pc = FILTER_OP_RETURN_S64;
704 ret = 0;
705 goto end;
706
707 case FILTER_OP_RETURN_S64:
d97f9b78
MD
708 if (vstack_ax(stack)->type != REG_S64 &&
709 vstack_ax(stack)->type != REG_U64) {
93c591bb
MD
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:
d97f9b78 752 case REG_U64:
53569322
MD
753 if (vstack_bx(stack)->type == REG_UNKNOWN)
754 break;
d97f9b78
MD
755 if (vstack_bx(stack)->type == REG_S64 ||
756 vstack_bx(stack)->type == REG_U64)
97b58163
MD
757 insn->op = FILTER_OP_EQ_S64;
758 else
dbea82ec 759 insn->op = FILTER_OP_EQ_DOUBLE_S64;
97b58163
MD
760 break;
761 case REG_DOUBLE:
53569322
MD
762 if (vstack_bx(stack)->type == REG_UNKNOWN)
763 break;
d97f9b78
MD
764 if (vstack_bx(stack)->type == REG_S64 ||
765 vstack_bx(stack)->type == REG_U64)
dbea82ec
MD
766 insn->op = FILTER_OP_EQ_S64_DOUBLE;
767 else
768 insn->op = FILTER_OP_EQ_DOUBLE;
97b58163 769 break;
53569322
MD
770 case REG_UNKNOWN:
771 break; /* Dynamic typing. */
97b58163 772 }
0305960f
MD
773 /* Pop 2, push 1 */
774 if (vstack_pop(stack)) {
775 ret = -EINVAL;
776 goto end;
777 }
778 vstack_ax(stack)->type = REG_S64;
97b58163
MD
779 next_pc += sizeof(struct binary_op);
780 break;
781 }
782
783 case FILTER_OP_NE:
784 {
785 struct binary_op *insn = (struct binary_op *) pc;
786
0305960f 787 switch(vstack_ax(stack)->type) {
97b58163
MD
788 default:
789 ERR("unknown register type\n");
790 ret = -EINVAL;
791 goto end;
792
793 case REG_STRING:
53569322
MD
794 if (vstack_bx(stack)->type == REG_UNKNOWN)
795 break;
3151a51d
PP
796 if (vstack_bx(stack)->type == REG_STAR_GLOB_STRING)
797 insn->op = FILTER_OP_NE_STAR_GLOB_STRING;
798 else
799 insn->op = FILTER_OP_NE_STRING;
800 break;
801 case REG_STAR_GLOB_STRING:
802 if (vstack_bx(stack)->type == REG_UNKNOWN)
803 break;
804 insn->op = FILTER_OP_NE_STAR_GLOB_STRING;
97b58163
MD
805 break;
806 case REG_S64:
d97f9b78 807 case REG_U64:
53569322
MD
808 if (vstack_bx(stack)->type == REG_UNKNOWN)
809 break;
d97f9b78
MD
810 if (vstack_bx(stack)->type == REG_S64 ||
811 vstack_bx(stack)->type == REG_U64)
97b58163
MD
812 insn->op = FILTER_OP_NE_S64;
813 else
dbea82ec 814 insn->op = FILTER_OP_NE_DOUBLE_S64;
97b58163
MD
815 break;
816 case REG_DOUBLE:
53569322
MD
817 if (vstack_bx(stack)->type == REG_UNKNOWN)
818 break;
d97f9b78
MD
819 if (vstack_bx(stack)->type == REG_S64 ||
820 vstack_bx(stack)->type == REG_U64)
dbea82ec
MD
821 insn->op = FILTER_OP_NE_S64_DOUBLE;
822 else
823 insn->op = FILTER_OP_NE_DOUBLE;
97b58163 824 break;
53569322
MD
825 case REG_UNKNOWN:
826 break; /* Dynamic typing. */
97b58163 827 }
0305960f
MD
828 /* Pop 2, push 1 */
829 if (vstack_pop(stack)) {
830 ret = -EINVAL;
831 goto end;
832 }
833 vstack_ax(stack)->type = REG_S64;
97b58163
MD
834 next_pc += sizeof(struct binary_op);
835 break;
836 }
837
838 case FILTER_OP_GT:
839 {
840 struct binary_op *insn = (struct binary_op *) pc;
841
0305960f 842 switch(vstack_ax(stack)->type) {
97b58163
MD
843 default:
844 ERR("unknown register type\n");
845 ret = -EINVAL;
846 goto end;
847
3151a51d
PP
848 case REG_STAR_GLOB_STRING:
849 ERR("invalid register type for > binary operator\n");
850 ret = -EINVAL;
851 goto end;
97b58163 852 case REG_STRING:
53569322
MD
853 if (vstack_bx(stack)->type == REG_UNKNOWN)
854 break;
97b58163
MD
855 insn->op = FILTER_OP_GT_STRING;
856 break;
857 case REG_S64:
d97f9b78 858 case REG_U64:
53569322
MD
859 if (vstack_bx(stack)->type == REG_UNKNOWN)
860 break;
d97f9b78
MD
861 if (vstack_bx(stack)->type == REG_S64 ||
862 vstack_bx(stack)->type == REG_U64)
97b58163
MD
863 insn->op = FILTER_OP_GT_S64;
864 else
dbea82ec 865 insn->op = FILTER_OP_GT_DOUBLE_S64;
97b58163
MD
866 break;
867 case REG_DOUBLE:
53569322
MD
868 if (vstack_bx(stack)->type == REG_UNKNOWN)
869 break;
d97f9b78
MD
870 if (vstack_bx(stack)->type == REG_S64 ||
871 vstack_bx(stack)->type == REG_U64)
dbea82ec
MD
872 insn->op = FILTER_OP_GT_S64_DOUBLE;
873 else
874 insn->op = FILTER_OP_GT_DOUBLE;
97b58163 875 break;
53569322
MD
876 case REG_UNKNOWN:
877 break; /* Dynamic typing. */
97b58163 878 }
0305960f
MD
879 /* Pop 2, push 1 */
880 if (vstack_pop(stack)) {
881 ret = -EINVAL;
882 goto end;
883 }
884 vstack_ax(stack)->type = REG_S64;
97b58163
MD
885 next_pc += sizeof(struct binary_op);
886 break;
887 }
888
889 case FILTER_OP_LT:
890 {
891 struct binary_op *insn = (struct binary_op *) pc;
892
0305960f 893 switch(vstack_ax(stack)->type) {
97b58163
MD
894 default:
895 ERR("unknown register type\n");
896 ret = -EINVAL;
897 goto end;
898
3151a51d
PP
899 case REG_STAR_GLOB_STRING:
900 ERR("invalid register type for < binary operator\n");
901 ret = -EINVAL;
902 goto end;
97b58163 903 case REG_STRING:
53569322
MD
904 if (vstack_bx(stack)->type == REG_UNKNOWN)
905 break;
97b58163
MD
906 insn->op = FILTER_OP_LT_STRING;
907 break;
908 case REG_S64:
d97f9b78 909 case REG_U64:
53569322
MD
910 if (vstack_bx(stack)->type == REG_UNKNOWN)
911 break;
d97f9b78
MD
912 if (vstack_bx(stack)->type == REG_S64 ||
913 vstack_bx(stack)->type == REG_U64)
97b58163
MD
914 insn->op = FILTER_OP_LT_S64;
915 else
dbea82ec 916 insn->op = FILTER_OP_LT_DOUBLE_S64;
97b58163
MD
917 break;
918 case REG_DOUBLE:
53569322
MD
919 if (vstack_bx(stack)->type == REG_UNKNOWN)
920 break;
d97f9b78
MD
921 if (vstack_bx(stack)->type == REG_S64 ||
922 vstack_bx(stack)->type == REG_U64)
dbea82ec
MD
923 insn->op = FILTER_OP_LT_S64_DOUBLE;
924 else
925 insn->op = FILTER_OP_LT_DOUBLE;
97b58163 926 break;
53569322
MD
927 case REG_UNKNOWN:
928 break; /* Dynamic typing. */
97b58163 929 }
0305960f
MD
930 /* Pop 2, push 1 */
931 if (vstack_pop(stack)) {
932 ret = -EINVAL;
933 goto end;
934 }
935 vstack_ax(stack)->type = REG_S64;
97b58163
MD
936 next_pc += sizeof(struct binary_op);
937 break;
938 }
939
940 case FILTER_OP_GE:
941 {
942 struct binary_op *insn = (struct binary_op *) pc;
943
0305960f 944 switch(vstack_ax(stack)->type) {
97b58163
MD
945 default:
946 ERR("unknown register type\n");
947 ret = -EINVAL;
948 goto end;
949
3151a51d
PP
950 case REG_STAR_GLOB_STRING:
951 ERR("invalid register type for >= binary operator\n");
952 ret = -EINVAL;
953 goto end;
97b58163 954 case REG_STRING:
53569322
MD
955 if (vstack_bx(stack)->type == REG_UNKNOWN)
956 break;
97b58163
MD
957 insn->op = FILTER_OP_GE_STRING;
958 break;
959 case REG_S64:
d97f9b78 960 case REG_U64:
53569322
MD
961 if (vstack_bx(stack)->type == REG_UNKNOWN)
962 break;
d97f9b78
MD
963 if (vstack_bx(stack)->type == REG_S64 ||
964 vstack_bx(stack)->type == REG_U64)
97b58163
MD
965 insn->op = FILTER_OP_GE_S64;
966 else
dbea82ec 967 insn->op = FILTER_OP_GE_DOUBLE_S64;
97b58163
MD
968 break;
969 case REG_DOUBLE:
53569322
MD
970 if (vstack_bx(stack)->type == REG_UNKNOWN)
971 break;
d97f9b78
MD
972 if (vstack_bx(stack)->type == REG_S64 ||
973 vstack_bx(stack)->type == REG_U64)
dbea82ec
MD
974 insn->op = FILTER_OP_GE_S64_DOUBLE;
975 else
976 insn->op = FILTER_OP_GE_DOUBLE;
97b58163 977 break;
53569322
MD
978 case REG_UNKNOWN:
979 break; /* Dynamic typing. */
97b58163 980 }
0305960f
MD
981 /* Pop 2, push 1 */
982 if (vstack_pop(stack)) {
983 ret = -EINVAL;
984 goto end;
985 }
d97f9b78 986 vstack_ax(stack)->type = REG_U64;
97b58163
MD
987 next_pc += sizeof(struct binary_op);
988 break;
989 }
990 case FILTER_OP_LE:
991 {
992 struct binary_op *insn = (struct binary_op *) pc;
993
0305960f 994 switch(vstack_ax(stack)->type) {
97b58163
MD
995 default:
996 ERR("unknown register type\n");
997 ret = -EINVAL;
998 goto end;
999
3151a51d
PP
1000 case REG_STAR_GLOB_STRING:
1001 ERR("invalid register type for <= binary operator\n");
1002 ret = -EINVAL;
1003 goto end;
97b58163 1004 case REG_STRING:
53569322
MD
1005 if (vstack_bx(stack)->type == REG_UNKNOWN)
1006 break;
97b58163
MD
1007 insn->op = FILTER_OP_LE_STRING;
1008 break;
1009 case REG_S64:
d97f9b78 1010 case REG_U64:
53569322
MD
1011 if (vstack_bx(stack)->type == REG_UNKNOWN)
1012 break;
d97f9b78
MD
1013 if (vstack_bx(stack)->type == REG_S64 ||
1014 vstack_bx(stack)->type == REG_U64)
97b58163
MD
1015 insn->op = FILTER_OP_LE_S64;
1016 else
dbea82ec 1017 insn->op = FILTER_OP_LE_DOUBLE_S64;
97b58163
MD
1018 break;
1019 case REG_DOUBLE:
53569322
MD
1020 if (vstack_bx(stack)->type == REG_UNKNOWN)
1021 break;
d97f9b78
MD
1022 if (vstack_bx(stack)->type == REG_S64 ||
1023 vstack_bx(stack)->type == REG_U64)
dbea82ec
MD
1024 insn->op = FILTER_OP_LE_S64_DOUBLE;
1025 else
1026 insn->op = FILTER_OP_LE_DOUBLE;
97b58163 1027 break;
53569322
MD
1028 case REG_UNKNOWN:
1029 break; /* Dynamic typing. */
97b58163 1030 }
0305960f 1031 vstack_ax(stack)->type = REG_S64;
97b58163
MD
1032 next_pc += sizeof(struct binary_op);
1033 break;
1034 }
1035
1036 case FILTER_OP_EQ_STRING:
1037 case FILTER_OP_NE_STRING:
1038 case FILTER_OP_GT_STRING:
1039 case FILTER_OP_LT_STRING:
1040 case FILTER_OP_GE_STRING:
1041 case FILTER_OP_LE_STRING:
3151a51d
PP
1042 case FILTER_OP_EQ_STAR_GLOB_STRING:
1043 case FILTER_OP_NE_STAR_GLOB_STRING:
97b58163
MD
1044 case FILTER_OP_EQ_S64:
1045 case FILTER_OP_NE_S64:
1046 case FILTER_OP_GT_S64:
1047 case FILTER_OP_LT_S64:
1048 case FILTER_OP_GE_S64:
1049 case FILTER_OP_LE_S64:
1050 case FILTER_OP_EQ_DOUBLE:
1051 case FILTER_OP_NE_DOUBLE:
1052 case FILTER_OP_GT_DOUBLE:
1053 case FILTER_OP_LT_DOUBLE:
1054 case FILTER_OP_GE_DOUBLE:
1055 case FILTER_OP_LE_DOUBLE:
dbea82ec
MD
1056 case FILTER_OP_EQ_DOUBLE_S64:
1057 case FILTER_OP_NE_DOUBLE_S64:
1058 case FILTER_OP_GT_DOUBLE_S64:
1059 case FILTER_OP_LT_DOUBLE_S64:
1060 case FILTER_OP_GE_DOUBLE_S64:
1061 case FILTER_OP_LE_DOUBLE_S64:
1062 case FILTER_OP_EQ_S64_DOUBLE:
1063 case FILTER_OP_NE_S64_DOUBLE:
1064 case FILTER_OP_GT_S64_DOUBLE:
1065 case FILTER_OP_LT_S64_DOUBLE:
1066 case FILTER_OP_GE_S64_DOUBLE:
1067 case FILTER_OP_LE_S64_DOUBLE:
d97f9b78
MD
1068 {
1069 /* Pop 2, push 1 */
1070 if (vstack_pop(stack)) {
1071 ret = -EINVAL;
1072 goto end;
1073 }
1074 vstack_ax(stack)->type = REG_S64;
1075 next_pc += sizeof(struct binary_op);
1076 break;
1077 }
1078
0039e2d8
MD
1079 case FILTER_OP_BIT_RSHIFT:
1080 case FILTER_OP_BIT_LSHIFT:
47e5f13e
MD
1081 case FILTER_OP_BIT_AND:
1082 case FILTER_OP_BIT_OR:
1083 case FILTER_OP_BIT_XOR:
97b58163 1084 {
0305960f
MD
1085 /* Pop 2, push 1 */
1086 if (vstack_pop(stack)) {
1087 ret = -EINVAL;
1088 goto end;
1089 }
1090 vstack_ax(stack)->type = REG_S64;
97b58163
MD
1091 next_pc += sizeof(struct binary_op);
1092 break;
1093 }
1094
1095 /* unary */
1096 case FILTER_OP_UNARY_PLUS:
1097 {
1098 struct unary_op *insn = (struct unary_op *) pc;
1099
0305960f 1100 switch(vstack_ax(stack)->type) {
97b58163
MD
1101 default:
1102 ERR("unknown register type\n");
1103 ret = -EINVAL;
1104 goto end;
1105
1106 case REG_S64:
d97f9b78 1107 case REG_U64:
97b58163
MD
1108 insn->op = FILTER_OP_UNARY_PLUS_S64;
1109 break;
1110 case REG_DOUBLE:
1111 insn->op = FILTER_OP_UNARY_PLUS_DOUBLE;
1112 break;
53569322
MD
1113 case REG_UNKNOWN: /* Dynamic typing. */
1114 break;
97b58163 1115 }
0305960f 1116 /* Pop 1, push 1 */
97b58163
MD
1117 next_pc += sizeof(struct unary_op);
1118 break;
1119 }
1120
1121 case FILTER_OP_UNARY_MINUS:
1122 {
1123 struct unary_op *insn = (struct unary_op *) pc;
1124
0305960f 1125 switch(vstack_ax(stack)->type) {
97b58163
MD
1126 default:
1127 ERR("unknown register type\n");
1128 ret = -EINVAL;
1129 goto end;
1130
1131 case REG_S64:
d97f9b78 1132 case REG_U64:
97b58163
MD
1133 insn->op = FILTER_OP_UNARY_MINUS_S64;
1134 break;
1135 case REG_DOUBLE:
1136 insn->op = FILTER_OP_UNARY_MINUS_DOUBLE;
1137 break;
53569322
MD
1138 case REG_UNKNOWN: /* Dynamic typing. */
1139 break;
97b58163 1140 }
0305960f 1141 /* Pop 1, push 1 */
97b58163
MD
1142 next_pc += sizeof(struct unary_op);
1143 break;
1144 }
1145
1146 case FILTER_OP_UNARY_NOT:
1147 {
1148 struct unary_op *insn = (struct unary_op *) pc;
1149
0305960f 1150 switch(vstack_ax(stack)->type) {
97b58163
MD
1151 default:
1152 ERR("unknown register type\n");
1153 ret = -EINVAL;
1154 goto end;
1155
1156 case REG_S64:
d97f9b78 1157 case REG_U64:
97b58163
MD
1158 insn->op = FILTER_OP_UNARY_NOT_S64;
1159 break;
1160 case REG_DOUBLE:
1161 insn->op = FILTER_OP_UNARY_NOT_DOUBLE;
1162 break;
53569322
MD
1163 case REG_UNKNOWN: /* Dynamic typing. */
1164 break;
97b58163 1165 }
0305960f 1166 /* Pop 1, push 1 */
97b58163
MD
1167 next_pc += sizeof(struct unary_op);
1168 break;
1169 }
1170
0039e2d8
MD
1171 case FILTER_OP_UNARY_BIT_NOT:
1172 {
1173 /* Pop 1, push 1 */
1174 next_pc += sizeof(struct unary_op);
1175 break;
1176 }
1177
97b58163
MD
1178 case FILTER_OP_UNARY_PLUS_S64:
1179 case FILTER_OP_UNARY_MINUS_S64:
1180 case FILTER_OP_UNARY_NOT_S64:
1181 case FILTER_OP_UNARY_PLUS_DOUBLE:
1182 case FILTER_OP_UNARY_MINUS_DOUBLE:
1183 case FILTER_OP_UNARY_NOT_DOUBLE:
1184 {
0305960f 1185 /* Pop 1, push 1 */
97b58163
MD
1186 next_pc += sizeof(struct unary_op);
1187 break;
1188 }
1189
1190 /* logical */
1191 case FILTER_OP_AND:
1192 case FILTER_OP_OR:
1193 {
b9f4cd79
MD
1194 /* Continue to next instruction */
1195 /* Pop 1 when jump not taken */
1196 if (vstack_pop(stack)) {
1197 ret = -EINVAL;
1198 goto end;
1199 }
97b58163
MD
1200 next_pc += sizeof(struct logical_op);
1201 break;
1202 }
1203
77aa5901 1204 /* load field ref */
97b58163
MD
1205 case FILTER_OP_LOAD_FIELD_REF:
1206 {
1207 ERR("Unknown field ref type\n");
1208 ret = -EINVAL;
1209 goto end;
1210 }
77aa5901
MD
1211 /* get context ref */
1212 case FILTER_OP_GET_CONTEXT_REF:
1213 {
53569322
MD
1214 if (vstack_push(stack)) {
1215 ret = -EINVAL;
1216 goto end;
1217 }
1218 vstack_ax(stack)->type = REG_UNKNOWN;
1219 next_pc += sizeof(struct load_op) + sizeof(struct field_ref);
1220 break;
77aa5901 1221 }
97b58163
MD
1222 case FILTER_OP_LOAD_FIELD_REF_STRING:
1223 case FILTER_OP_LOAD_FIELD_REF_SEQUENCE:
77aa5901 1224 case FILTER_OP_GET_CONTEXT_REF_STRING:
97b58163 1225 {
0305960f
MD
1226 if (vstack_push(stack)) {
1227 ret = -EINVAL;
1228 goto end;
1229 }
1230 vstack_ax(stack)->type = REG_STRING;
97b58163
MD
1231 next_pc += sizeof(struct load_op) + sizeof(struct field_ref);
1232 break;
1233 }
1234 case FILTER_OP_LOAD_FIELD_REF_S64:
77aa5901 1235 case FILTER_OP_GET_CONTEXT_REF_S64:
97b58163 1236 {
0305960f
MD
1237 if (vstack_push(stack)) {
1238 ret = -EINVAL;
1239 goto end;
1240 }
1241 vstack_ax(stack)->type = REG_S64;
97b58163
MD
1242 next_pc += sizeof(struct load_op) + sizeof(struct field_ref);
1243 break;
1244 }
1245 case FILTER_OP_LOAD_FIELD_REF_DOUBLE:
77aa5901 1246 case FILTER_OP_GET_CONTEXT_REF_DOUBLE:
97b58163 1247 {
0305960f
MD
1248 if (vstack_push(stack)) {
1249 ret = -EINVAL;
1250 goto end;
1251 }
1252 vstack_ax(stack)->type = REG_DOUBLE;
97b58163
MD
1253 next_pc += sizeof(struct load_op) + sizeof(struct field_ref);
1254 break;
1255 }
1256
77aa5901 1257 /* load from immediate operand */
97b58163
MD
1258 case FILTER_OP_LOAD_STRING:
1259 {
1260 struct load_op *insn = (struct load_op *) pc;
1261
0305960f
MD
1262 if (vstack_push(stack)) {
1263 ret = -EINVAL;
1264 goto end;
1265 }
1266 vstack_ax(stack)->type = REG_STRING;
97b58163
MD
1267 next_pc += sizeof(struct load_op) + strlen(insn->data) + 1;
1268 break;
1269 }
1270
3151a51d
PP
1271 case FILTER_OP_LOAD_STAR_GLOB_STRING:
1272 {
1273 struct load_op *insn = (struct load_op *) pc;
1274
1275 if (vstack_push(stack)) {
1276 ret = -EINVAL;
1277 goto end;
1278 }
1279 vstack_ax(stack)->type = REG_STAR_GLOB_STRING;
1280 next_pc += sizeof(struct load_op) + strlen(insn->data) + 1;
1281 break;
1282 }
1283
97b58163
MD
1284 case FILTER_OP_LOAD_S64:
1285 {
0305960f
MD
1286 if (vstack_push(stack)) {
1287 ret = -EINVAL;
1288 goto end;
1289 }
1290 vstack_ax(stack)->type = REG_S64;
97b58163
MD
1291 next_pc += sizeof(struct load_op)
1292 + sizeof(struct literal_numeric);
1293 break;
1294 }
1295
1296 case FILTER_OP_LOAD_DOUBLE:
1297 {
0305960f
MD
1298 if (vstack_push(stack)) {
1299 ret = -EINVAL;
1300 goto end;
1301 }
1302 vstack_ax(stack)->type = REG_DOUBLE;
97b58163
MD
1303 next_pc += sizeof(struct load_op)
1304 + sizeof(struct literal_double);
1305 break;
1306 }
1307
1308 /* cast */
1309 case FILTER_OP_CAST_TO_S64:
1310 {
1311 struct cast_op *insn = (struct cast_op *) pc;
1312
0305960f 1313 switch (vstack_ax(stack)->type) {
97b58163
MD
1314 default:
1315 ERR("unknown register type\n");
1316 ret = -EINVAL;
1317 goto end;
1318
1319 case REG_STRING:
3151a51d 1320 case REG_STAR_GLOB_STRING:
97b58163
MD
1321 ERR("Cast op can only be applied to numeric or floating point registers\n");
1322 ret = -EINVAL;
1323 goto end;
1324 case REG_S64:
1325 insn->op = FILTER_OP_CAST_NOP;
1326 break;
1327 case REG_DOUBLE:
1328 insn->op = FILTER_OP_CAST_DOUBLE_TO_S64;
1329 break;
53569322 1330 case REG_UNKNOWN:
d97f9b78 1331 case REG_U64:
53569322 1332 break;
97b58163 1333 }
0305960f
MD
1334 /* Pop 1, push 1 */
1335 vstack_ax(stack)->type = REG_S64;
97b58163
MD
1336 next_pc += sizeof(struct cast_op);
1337 break;
1338 }
1339 case FILTER_OP_CAST_DOUBLE_TO_S64:
1340 {
0305960f
MD
1341 /* Pop 1, push 1 */
1342 vstack_ax(stack)->type = REG_S64;
97b58163
MD
1343 next_pc += sizeof(struct cast_op);
1344 break;
1345 }
1346 case FILTER_OP_CAST_NOP:
1347 {
1348 next_pc += sizeof(struct cast_op);
1349 break;
1350 }
1351
47e5f13e
MD
1352 /*
1353 * Instructions for recursive traversal through composed types.
1354 */
1355 case FILTER_OP_GET_CONTEXT_ROOT:
1356 {
1357 if (vstack_push(stack)) {
1358 ret = -EINVAL;
1359 goto end;
1360 }
1361 vstack_ax(stack)->type = REG_PTR;
1362 vstack_ax(stack)->load.type = LOAD_ROOT_CONTEXT;
1363 next_pc += sizeof(struct load_op);
1364 break;
1365 }
1366 case FILTER_OP_GET_APP_CONTEXT_ROOT:
1367 {
1368 if (vstack_push(stack)) {
1369 ret = -EINVAL;
1370 goto end;
1371 }
1372 vstack_ax(stack)->type = REG_PTR;
1373 vstack_ax(stack)->load.type = LOAD_ROOT_APP_CONTEXT;
1374 next_pc += sizeof(struct load_op);
1375 break;
1376 }
1377 case FILTER_OP_GET_PAYLOAD_ROOT:
1378 {
1379 if (vstack_push(stack)) {
1380 ret = -EINVAL;
1381 goto end;
1382 }
1383 vstack_ax(stack)->type = REG_PTR;
1384 vstack_ax(stack)->load.type = LOAD_ROOT_PAYLOAD;
1385 next_pc += sizeof(struct load_op);
1386 break;
1387 }
1388
1389 case FILTER_OP_LOAD_FIELD:
1390 {
1391 struct load_op *insn = (struct load_op *) pc;
1392
1393 assert(vstack_ax(stack)->type == REG_PTR);
1394 /* Pop 1, push 1 */
1395 ret = specialize_load_field(vstack_ax(stack), insn);
1396 if (ret)
1397 goto end;
1398
1399 next_pc += sizeof(struct load_op);
1400 break;
1401 }
1402
1403 case FILTER_OP_LOAD_FIELD_S8:
1404 case FILTER_OP_LOAD_FIELD_S16:
1405 case FILTER_OP_LOAD_FIELD_S32:
1406 case FILTER_OP_LOAD_FIELD_S64:
d97f9b78
MD
1407 {
1408 /* Pop 1, push 1 */
1409 vstack_ax(stack)->type = REG_S64;
1410 next_pc += sizeof(struct load_op);
1411 break;
1412 }
1413
47e5f13e
MD
1414 case FILTER_OP_LOAD_FIELD_U8:
1415 case FILTER_OP_LOAD_FIELD_U16:
1416 case FILTER_OP_LOAD_FIELD_U32:
1417 case FILTER_OP_LOAD_FIELD_U64:
1418 {
1419 /* Pop 1, push 1 */
d97f9b78 1420 vstack_ax(stack)->type = REG_U64;
47e5f13e
MD
1421 next_pc += sizeof(struct load_op);
1422 break;
1423 }
1424
1425 case FILTER_OP_LOAD_FIELD_STRING:
1426 case FILTER_OP_LOAD_FIELD_SEQUENCE:
1427 {
1428 /* Pop 1, push 1 */
1429 vstack_ax(stack)->type = REG_STRING;
1430 next_pc += sizeof(struct load_op);
1431 break;
1432 }
1433
1434 case FILTER_OP_LOAD_FIELD_DOUBLE:
1435 {
1436 /* Pop 1, push 1 */
1437 vstack_ax(stack)->type = REG_DOUBLE;
1438 next_pc += sizeof(struct load_op);
1439 break;
1440 }
1441
1442 case FILTER_OP_GET_SYMBOL:
1443 {
1444 struct load_op *insn = (struct load_op *) pc;
1445
1446 dbg_printf("op get symbol\n");
1447 switch (vstack_ax(stack)->load.type) {
1448 case LOAD_OBJECT:
1449 ERR("Nested fields not implemented yet.");
1450 ret = -EINVAL;
1451 goto end;
1452 case LOAD_ROOT_CONTEXT:
1453 /* Lookup context field. */
b77aaa1b 1454 ret = specialize_context_lookup(*pctx,
47e5f13e
MD
1455 bytecode, insn,
1456 &vstack_ax(stack)->load);
1457 if (ret)
1458 goto end;
1459 break;
1460 case LOAD_ROOT_APP_CONTEXT:
1461 /* Lookup app context field. */
b77aaa1b 1462 ret = specialize_app_context_lookup(pctx,
47e5f13e
MD
1463 bytecode, insn,
1464 &vstack_ax(stack)->load);
1465 if (ret)
1466 goto end;
1467 break;
1468 case LOAD_ROOT_PAYLOAD:
1469 /* Lookup event payload field. */
53b9d7db 1470 ret = specialize_payload_lookup(event_desc,
47e5f13e
MD
1471 bytecode, insn,
1472 &vstack_ax(stack)->load);
1473 if (ret)
1474 goto end;
1475 break;
1476 }
1477 next_pc += sizeof(struct load_op) + sizeof(struct get_symbol);
1478 break;
1479 }
1480
1481 case FILTER_OP_GET_SYMBOL_FIELD:
1482 {
1483 /* Always generated by specialize phase. */
1484 ret = -EINVAL;
1485 goto end;
1486 }
1487
1488 case FILTER_OP_GET_INDEX_U16:
1489 {
1490 struct load_op *insn = (struct load_op *) pc;
1491 struct get_index_u16 *index = (struct get_index_u16 *) insn->data;
1492
1493 dbg_printf("op get index u16\n");
1494 /* Pop 1, push 1 */
1495 ret = specialize_get_index(bytecode, insn, index->index,
1496 vstack_ax(stack), sizeof(*index));
1497 if (ret)
1498 goto end;
1499 next_pc += sizeof(struct load_op) + sizeof(struct get_index_u16);
1500 break;
1501 }
1502
1503 case FILTER_OP_GET_INDEX_U64:
1504 {
1505 struct load_op *insn = (struct load_op *) pc;
1506 struct get_index_u64 *index = (struct get_index_u64 *) insn->data;
1507
1508 dbg_printf("op get index u64\n");
1509 /* Pop 1, push 1 */
1510 ret = specialize_get_index(bytecode, insn, index->index,
1511 vstack_ax(stack), sizeof(*index));
1512 if (ret)
1513 goto end;
1514 next_pc += sizeof(struct load_op) + sizeof(struct get_index_u64);
1515 break;
1516 }
1517
97b58163
MD
1518 }
1519 }
1520end:
1521 return ret;
1522}
This page took 0.132869 seconds and 4 git commands to generate.