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