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