Refactoring: bytecode interpreter ABI
[lttng-ust.git] / liblttng-ust / lttng-bytecode-interpreter.c
1 /*
2 * SPDX-License-Identifier: MIT
3 *
4 * Copyright (C) 2010-2016 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
5 *
6 * LTTng UST bytecode interpreter.
7 */
8
9 #define _LGPL_SOURCE
10 #include <stddef.h>
11 #include <stdint.h>
12
13 #include <lttng/urcu/pointer.h>
14 #include <lttng/ust-endian.h>
15 #include <lttng/ust-events.h>
16 #include "ust-events-internal.h"
17
18 #include "lttng-bytecode.h"
19 #include "string-utils.h"
20
21
22 /*
23 * -1: wildcard found.
24 * -2: unknown escape char.
25 * 0: normal char.
26 */
27
28 static
29 int parse_char(const char **p)
30 {
31 switch (**p) {
32 case '\\':
33 (*p)++;
34 switch (**p) {
35 case '\\':
36 case '*':
37 return 0;
38 default:
39 return -2;
40 }
41 case '*':
42 return -1;
43 default:
44 return 0;
45 }
46 }
47
48 /*
49 * Returns SIZE_MAX if the string is null-terminated, or the number of
50 * characters if not.
51 */
52 static
53 size_t get_str_or_seq_len(const struct estack_entry *entry)
54 {
55 return entry->u.s.seq_len;
56 }
57
58 static
59 int stack_star_glob_match(struct estack *stack, int top, const char *cmp_type)
60 {
61 const char *pattern;
62 const char *candidate;
63 size_t pattern_len;
64 size_t candidate_len;
65
66 /* Find out which side is the pattern vs. the candidate. */
67 if (estack_ax(stack, top)->u.s.literal_type == ESTACK_STRING_LITERAL_TYPE_STAR_GLOB) {
68 pattern = estack_ax(stack, top)->u.s.str;
69 pattern_len = get_str_or_seq_len(estack_ax(stack, top));
70 candidate = estack_bx(stack, top)->u.s.str;
71 candidate_len = get_str_or_seq_len(estack_bx(stack, top));
72 } else {
73 pattern = estack_bx(stack, top)->u.s.str;
74 pattern_len = get_str_or_seq_len(estack_bx(stack, top));
75 candidate = estack_ax(stack, top)->u.s.str;
76 candidate_len = get_str_or_seq_len(estack_ax(stack, top));
77 }
78
79 /* Perform the match. Returns 0 when the result is true. */
80 return !strutils_star_glob_match(pattern, pattern_len, candidate,
81 candidate_len);
82 }
83
84 static
85 int stack_strcmp(struct estack *stack, int top, const char *cmp_type)
86 {
87 const char *p = estack_bx(stack, top)->u.s.str, *q = estack_ax(stack, top)->u.s.str;
88 int ret;
89 int diff;
90
91 for (;;) {
92 int escaped_r0 = 0;
93
94 if (unlikely(p - estack_bx(stack, top)->u.s.str >= estack_bx(stack, top)->u.s.seq_len || *p == '\0')) {
95 if (q - estack_ax(stack, top)->u.s.str >= estack_ax(stack, top)->u.s.seq_len || *q == '\0') {
96 return 0;
97 } else {
98 if (estack_ax(stack, top)->u.s.literal_type ==
99 ESTACK_STRING_LITERAL_TYPE_PLAIN) {
100 ret = parse_char(&q);
101 if (ret == -1)
102 return 0;
103 }
104 return -1;
105 }
106 }
107 if (unlikely(q - estack_ax(stack, top)->u.s.str >= estack_ax(stack, top)->u.s.seq_len || *q == '\0')) {
108 if (estack_bx(stack, top)->u.s.literal_type ==
109 ESTACK_STRING_LITERAL_TYPE_PLAIN) {
110 ret = parse_char(&p);
111 if (ret == -1)
112 return 0;
113 }
114 return 1;
115 }
116 if (estack_bx(stack, top)->u.s.literal_type ==
117 ESTACK_STRING_LITERAL_TYPE_PLAIN) {
118 ret = parse_char(&p);
119 if (ret == -1) {
120 return 0;
121 } else if (ret == -2) {
122 escaped_r0 = 1;
123 }
124 /* else compare both char */
125 }
126 if (estack_ax(stack, top)->u.s.literal_type ==
127 ESTACK_STRING_LITERAL_TYPE_PLAIN) {
128 ret = parse_char(&q);
129 if (ret == -1) {
130 return 0;
131 } else if (ret == -2) {
132 if (!escaped_r0)
133 return -1;
134 } else {
135 if (escaped_r0)
136 return 1;
137 }
138 } else {
139 if (escaped_r0)
140 return 1;
141 }
142 diff = *p - *q;
143 if (diff != 0)
144 break;
145 p++;
146 q++;
147 }
148 return diff;
149 }
150
151 int lttng_bytecode_interpret_error(struct lttng_ust_bytecode_runtime *bytecode_runtime,
152 const char *stack_data,
153 void *ctx)
154 {
155 return LTTNG_UST_BYTECODE_INTERPRETER_ERROR;
156 }
157
158 #ifdef INTERPRETER_USE_SWITCH
159
160 /*
161 * Fallback for compilers that do not support taking address of labels.
162 */
163
164 #define START_OP \
165 start_pc = &bytecode->data[0]; \
166 for (pc = next_pc = start_pc; pc - start_pc < bytecode->len; \
167 pc = next_pc) { \
168 dbg_printf("Executing op %s (%u)\n", \
169 lttng_bytecode_print_op((unsigned int) *(bytecode_opcode_t *) pc), \
170 (unsigned int) *(bytecode_opcode_t *) pc); \
171 switch (*(bytecode_opcode_t *) pc) {
172
173 #define OP(name) jump_target_##name: __attribute__((unused)); \
174 case name
175
176 #define PO break
177
178 #define END_OP } \
179 }
180
181 #define JUMP_TO(name) \
182 goto jump_target_##name
183
184 #else
185
186 /*
187 * Dispatch-table based interpreter.
188 */
189
190 #define START_OP \
191 start_pc = &bytecode->code[0]; \
192 pc = next_pc = start_pc; \
193 if (unlikely(pc - start_pc >= bytecode->len)) \
194 goto end; \
195 goto *dispatch[*(bytecode_opcode_t *) pc];
196
197 #define OP(name) \
198 LABEL_##name
199
200 #define PO \
201 pc = next_pc; \
202 goto *dispatch[*(bytecode_opcode_t *) pc];
203
204 #define END_OP
205
206 #define JUMP_TO(name) \
207 goto LABEL_##name
208
209 #endif
210
211 #define IS_INTEGER_REGISTER(reg_type) \
212 (reg_type == REG_U64 || reg_type == REG_S64)
213
214 static int context_get_index(struct lttng_ust_ctx *ctx,
215 struct load_ptr *ptr,
216 uint32_t idx)
217 {
218
219 struct lttng_ust_ctx_field *ctx_field;
220 struct lttng_ust_event_field *field;
221 struct lttng_ust_ctx_value v;
222
223 ctx_field = ctx->fields[idx];
224 field = ctx_field->event_field;
225 ptr->type = LOAD_OBJECT;
226 ptr->field = field;
227
228 switch (field->type->type) {
229 case lttng_ust_type_integer:
230 ctx_field->get_value(ctx_field, &v);
231 if (lttng_ust_get_type_integer(field->type)->signedness) {
232 ptr->object_type = OBJECT_TYPE_S64;
233 ptr->u.s64 = v.u.s64;
234 ptr->ptr = &ptr->u.s64;
235 } else {
236 ptr->object_type = OBJECT_TYPE_U64;
237 ptr->u.u64 = v.u.s64; /* Cast. */
238 ptr->ptr = &ptr->u.u64;
239 }
240 break;
241 case lttng_ust_type_enum:
242 {
243 const struct lttng_ust_type_integer *itype;
244
245 itype = lttng_ust_get_type_integer(lttng_ust_get_type_enum(field->type)->container_type);
246 ctx_field->get_value(ctx_field, &v);
247 if (itype->signedness) {
248 ptr->object_type = OBJECT_TYPE_SIGNED_ENUM;
249 ptr->u.s64 = v.u.s64;
250 ptr->ptr = &ptr->u.s64;
251 } else {
252 ptr->object_type = OBJECT_TYPE_UNSIGNED_ENUM;
253 ptr->u.u64 = v.u.s64; /* Cast. */
254 ptr->ptr = &ptr->u.u64;
255 }
256 break;
257 }
258 case lttng_ust_type_array:
259 if (lttng_ust_get_type_array(field->type)->elem_type->type != lttng_ust_type_integer) {
260 ERR("Array nesting only supports integer types.");
261 return -EINVAL;
262 }
263 if (lttng_ust_get_type_array(field->type)->encoding == lttng_ust_string_encoding_none) {
264 ERR("Only string arrays are supported for contexts.");
265 return -EINVAL;
266 }
267 ptr->object_type = OBJECT_TYPE_STRING;
268 ctx_field->get_value(ctx_field, &v);
269 ptr->ptr = v.u.str;
270 break;
271 case lttng_ust_type_sequence:
272 if (lttng_ust_get_type_sequence(field->type)->elem_type->type != lttng_ust_type_integer) {
273 ERR("Sequence nesting only supports integer types.");
274 return -EINVAL;
275 }
276 if (lttng_ust_get_type_sequence(field->type)->encoding == lttng_ust_string_encoding_none) {
277 ERR("Only string sequences are supported for contexts.");
278 return -EINVAL;
279 }
280 ptr->object_type = OBJECT_TYPE_STRING;
281 ctx_field->get_value(ctx_field, &v);
282 ptr->ptr = v.u.str;
283 break;
284 case lttng_ust_type_string:
285 ptr->object_type = OBJECT_TYPE_STRING;
286 ctx_field->get_value(ctx_field, &v);
287 ptr->ptr = v.u.str;
288 break;
289 case lttng_ust_type_float:
290 ptr->object_type = OBJECT_TYPE_DOUBLE;
291 ctx_field->get_value(ctx_field, &v);
292 ptr->u.d = v.u.d;
293 ptr->ptr = &ptr->u.d;
294 break;
295 case lttng_ust_type_dynamic:
296 ctx_field->get_value(ctx_field, &v);
297 switch (v.sel) {
298 case LTTNG_UST_DYNAMIC_TYPE_NONE:
299 return -EINVAL;
300 case LTTNG_UST_DYNAMIC_TYPE_U8:
301 case LTTNG_UST_DYNAMIC_TYPE_U16:
302 case LTTNG_UST_DYNAMIC_TYPE_U32:
303 case LTTNG_UST_DYNAMIC_TYPE_U64:
304 ptr->object_type = OBJECT_TYPE_U64;
305 ptr->u.u64 = v.u.u64;
306 ptr->ptr = &ptr->u.u64;
307 dbg_printf("context get index dynamic u64 %" PRIi64 "\n", ptr->u.u64);
308 break;
309 case LTTNG_UST_DYNAMIC_TYPE_S8:
310 case LTTNG_UST_DYNAMIC_TYPE_S16:
311 case LTTNG_UST_DYNAMIC_TYPE_S32:
312 case LTTNG_UST_DYNAMIC_TYPE_S64:
313 ptr->object_type = OBJECT_TYPE_S64;
314 ptr->u.s64 = v.u.s64;
315 ptr->ptr = &ptr->u.s64;
316 dbg_printf("context get index dynamic s64 %" PRIi64 "\n", ptr->u.s64);
317 break;
318 case LTTNG_UST_DYNAMIC_TYPE_FLOAT:
319 case LTTNG_UST_DYNAMIC_TYPE_DOUBLE:
320 ptr->object_type = OBJECT_TYPE_DOUBLE;
321 ptr->u.d = v.u.d;
322 ptr->ptr = &ptr->u.d;
323 dbg_printf("context get index dynamic double %g\n", ptr->u.d);
324 break;
325 case LTTNG_UST_DYNAMIC_TYPE_STRING:
326 ptr->object_type = OBJECT_TYPE_STRING;
327 ptr->ptr = v.u.str;
328 dbg_printf("context get index dynamic string %s\n", (const char *) ptr->ptr);
329 break;
330 default:
331 dbg_printf("Interpreter warning: unknown dynamic type (%d).\n", (int) v.sel);
332 return -EINVAL;
333 }
334 break;
335 default:
336 ERR("Unknown type: %d", (int) field->type->type);
337 return -EINVAL;
338 }
339 return 0;
340 }
341
342 static int dynamic_get_index(struct lttng_ust_ctx *ctx,
343 struct bytecode_runtime *runtime,
344 uint64_t index, struct estack_entry *stack_top)
345 {
346 int ret;
347 const struct bytecode_get_index_data *gid;
348
349 gid = (const struct bytecode_get_index_data *) &runtime->data[index];
350 switch (stack_top->u.ptr.type) {
351 case LOAD_OBJECT:
352 switch (stack_top->u.ptr.object_type) {
353 case OBJECT_TYPE_ARRAY:
354 {
355 const char *ptr;
356
357 assert(gid->offset < gid->array_len);
358 /* Skip count (unsigned long) */
359 ptr = *(const char **) (stack_top->u.ptr.ptr + sizeof(unsigned long));
360 ptr = ptr + gid->offset;
361 stack_top->u.ptr.ptr = ptr;
362 stack_top->u.ptr.object_type = gid->elem.type;
363 stack_top->u.ptr.rev_bo = gid->elem.rev_bo;
364 assert(stack_top->u.ptr.field->type->type == lttng_ust_type_array);
365 stack_top->u.ptr.field = NULL;
366 break;
367 }
368 case OBJECT_TYPE_SEQUENCE:
369 {
370 const char *ptr;
371 size_t ptr_seq_len;
372
373 ptr = *(const char **) (stack_top->u.ptr.ptr + sizeof(unsigned long));
374 ptr_seq_len = *(unsigned long *) stack_top->u.ptr.ptr;
375 if (gid->offset >= gid->elem.len * ptr_seq_len) {
376 ret = -EINVAL;
377 goto end;
378 }
379 ptr = ptr + gid->offset;
380 stack_top->u.ptr.ptr = ptr;
381 stack_top->u.ptr.object_type = gid->elem.type;
382 stack_top->u.ptr.rev_bo = gid->elem.rev_bo;
383 assert(stack_top->u.ptr.field->type->type == lttng_ust_type_sequence);
384 stack_top->u.ptr.field = NULL;
385 break;
386 }
387 case OBJECT_TYPE_STRUCT:
388 ERR("Nested structures are not supported yet.");
389 ret = -EINVAL;
390 goto end;
391 case OBJECT_TYPE_VARIANT:
392 default:
393 ERR("Unexpected get index type %d",
394 (int) stack_top->u.ptr.object_type);
395 ret = -EINVAL;
396 goto end;
397 }
398 break;
399 case LOAD_ROOT_CONTEXT:
400 case LOAD_ROOT_APP_CONTEXT: /* Fall-through */
401 {
402 ret = context_get_index(ctx,
403 &stack_top->u.ptr,
404 gid->ctx_index);
405 if (ret) {
406 goto end;
407 }
408 break;
409 }
410 case LOAD_ROOT_PAYLOAD:
411 stack_top->u.ptr.ptr += gid->offset;
412 if (gid->elem.type == OBJECT_TYPE_STRING)
413 stack_top->u.ptr.ptr = *(const char * const *) stack_top->u.ptr.ptr;
414 stack_top->u.ptr.object_type = gid->elem.type;
415 stack_top->u.ptr.type = LOAD_OBJECT;
416 stack_top->u.ptr.field = gid->field;
417 stack_top->u.ptr.rev_bo = gid->elem.rev_bo;
418 break;
419 }
420
421 stack_top->type = REG_PTR;
422
423 return 0;
424
425 end:
426 return ret;
427 }
428
429 static int dynamic_load_field(struct estack_entry *stack_top)
430 {
431 int ret;
432
433 switch (stack_top->u.ptr.type) {
434 case LOAD_OBJECT:
435 break;
436 case LOAD_ROOT_CONTEXT:
437 case LOAD_ROOT_APP_CONTEXT:
438 case LOAD_ROOT_PAYLOAD:
439 default:
440 dbg_printf("Interpreter warning: cannot load root, missing field name.\n");
441 ret = -EINVAL;
442 goto end;
443 }
444 switch (stack_top->u.ptr.object_type) {
445 case OBJECT_TYPE_S8:
446 dbg_printf("op load field s8\n");
447 stack_top->u.v = *(int8_t *) stack_top->u.ptr.ptr;
448 stack_top->type = REG_S64;
449 break;
450 case OBJECT_TYPE_S16:
451 {
452 int16_t tmp;
453
454 dbg_printf("op load field s16\n");
455 tmp = *(int16_t *) stack_top->u.ptr.ptr;
456 if (stack_top->u.ptr.rev_bo)
457 tmp = bswap_16(tmp);
458 stack_top->u.v = tmp;
459 stack_top->type = REG_S64;
460 break;
461 }
462 case OBJECT_TYPE_S32:
463 {
464 int32_t tmp;
465
466 dbg_printf("op load field s32\n");
467 tmp = *(int32_t *) stack_top->u.ptr.ptr;
468 if (stack_top->u.ptr.rev_bo)
469 tmp = bswap_32(tmp);
470 stack_top->u.v = tmp;
471 stack_top->type = REG_S64;
472 break;
473 }
474 case OBJECT_TYPE_S64:
475 {
476 int64_t tmp;
477
478 dbg_printf("op load field s64\n");
479 tmp = *(int64_t *) stack_top->u.ptr.ptr;
480 if (stack_top->u.ptr.rev_bo)
481 tmp = bswap_64(tmp);
482 stack_top->u.v = tmp;
483 stack_top->type = REG_S64;
484 break;
485 }
486 case OBJECT_TYPE_SIGNED_ENUM:
487 {
488 int64_t tmp;
489
490 dbg_printf("op load field signed enumeration\n");
491 tmp = *(int64_t *) stack_top->u.ptr.ptr;
492 if (stack_top->u.ptr.rev_bo)
493 tmp = bswap_64(tmp);
494 stack_top->u.v = tmp;
495 stack_top->type = REG_S64;
496 break;
497 }
498 case OBJECT_TYPE_U8:
499 dbg_printf("op load field u8\n");
500 stack_top->u.v = *(uint8_t *) stack_top->u.ptr.ptr;
501 stack_top->type = REG_U64;
502 break;
503 case OBJECT_TYPE_U16:
504 {
505 uint16_t tmp;
506
507 dbg_printf("op load field u16\n");
508 tmp = *(uint16_t *) stack_top->u.ptr.ptr;
509 if (stack_top->u.ptr.rev_bo)
510 tmp = bswap_16(tmp);
511 stack_top->u.v = tmp;
512 stack_top->type = REG_U64;
513 break;
514 }
515 case OBJECT_TYPE_U32:
516 {
517 uint32_t tmp;
518
519 dbg_printf("op load field u32\n");
520 tmp = *(uint32_t *) stack_top->u.ptr.ptr;
521 if (stack_top->u.ptr.rev_bo)
522 tmp = bswap_32(tmp);
523 stack_top->u.v = tmp;
524 stack_top->type = REG_U64;
525 break;
526 }
527 case OBJECT_TYPE_U64:
528 {
529 uint64_t tmp;
530
531 dbg_printf("op load field u64\n");
532 tmp = *(uint64_t *) stack_top->u.ptr.ptr;
533 if (stack_top->u.ptr.rev_bo)
534 tmp = bswap_64(tmp);
535 stack_top->u.v = tmp;
536 stack_top->type = REG_U64;
537 break;
538 }
539 case OBJECT_TYPE_UNSIGNED_ENUM:
540 {
541 uint64_t tmp;
542
543 dbg_printf("op load field unsigned enumeration\n");
544 tmp = *(uint64_t *) stack_top->u.ptr.ptr;
545 if (stack_top->u.ptr.rev_bo)
546 tmp = bswap_64(tmp);
547 stack_top->u.v = tmp;
548 stack_top->type = REG_U64;
549 break;
550 }
551 case OBJECT_TYPE_DOUBLE:
552 memcpy(&stack_top->u.d,
553 stack_top->u.ptr.ptr,
554 sizeof(struct literal_double));
555 stack_top->type = REG_DOUBLE;
556 break;
557 case OBJECT_TYPE_STRING:
558 {
559 const char *str;
560
561 dbg_printf("op load field string\n");
562 str = (const char *) stack_top->u.ptr.ptr;
563 stack_top->u.s.str = str;
564 if (unlikely(!stack_top->u.s.str)) {
565 dbg_printf("Interpreter warning: loading a NULL string.\n");
566 ret = -EINVAL;
567 goto end;
568 }
569 stack_top->u.s.seq_len = SIZE_MAX;
570 stack_top->u.s.literal_type =
571 ESTACK_STRING_LITERAL_TYPE_NONE;
572 stack_top->type = REG_STRING;
573 break;
574 }
575 case OBJECT_TYPE_STRING_SEQUENCE:
576 {
577 const char *ptr;
578
579 dbg_printf("op load field string sequence\n");
580 ptr = stack_top->u.ptr.ptr;
581 stack_top->u.s.seq_len = *(unsigned long *) ptr;
582 stack_top->u.s.str = *(const char **) (ptr + sizeof(unsigned long));
583 stack_top->type = REG_STRING;
584 if (unlikely(!stack_top->u.s.str)) {
585 dbg_printf("Interpreter warning: loading a NULL sequence.\n");
586 ret = -EINVAL;
587 goto end;
588 }
589 stack_top->u.s.literal_type =
590 ESTACK_STRING_LITERAL_TYPE_NONE;
591 break;
592 }
593 case OBJECT_TYPE_DYNAMIC:
594 /*
595 * Dynamic types in context are looked up
596 * by context get index.
597 */
598 ret = -EINVAL;
599 goto end;
600 case OBJECT_TYPE_SEQUENCE:
601 case OBJECT_TYPE_ARRAY:
602 case OBJECT_TYPE_STRUCT:
603 case OBJECT_TYPE_VARIANT:
604 ERR("Sequences, arrays, struct and variant cannot be loaded (nested types).");
605 ret = -EINVAL;
606 goto end;
607 }
608 return 0;
609
610 end:
611 return ret;
612 }
613
614 static
615 int lttng_bytecode_interpret_format_output(struct estack_entry *ax,
616 struct lttng_interpreter_output *output)
617 {
618 int ret;
619
620 again:
621 switch (ax->type) {
622 case REG_S64:
623 output->type = LTTNG_INTERPRETER_TYPE_S64;
624 output->u.s = ax->u.v;
625 break;
626 case REG_U64:
627 output->type = LTTNG_INTERPRETER_TYPE_U64;
628 output->u.u = (uint64_t) ax->u.v;
629 break;
630 case REG_DOUBLE:
631 output->type = LTTNG_INTERPRETER_TYPE_DOUBLE;
632 output->u.d = ax->u.d;
633 break;
634 case REG_STRING:
635 output->type = LTTNG_INTERPRETER_TYPE_STRING;
636 output->u.str.str = ax->u.s.str;
637 output->u.str.len = ax->u.s.seq_len;
638 break;
639 case REG_PTR:
640 switch (ax->u.ptr.object_type) {
641 case OBJECT_TYPE_S8:
642 case OBJECT_TYPE_S16:
643 case OBJECT_TYPE_S32:
644 case OBJECT_TYPE_S64:
645 case OBJECT_TYPE_U8:
646 case OBJECT_TYPE_U16:
647 case OBJECT_TYPE_U32:
648 case OBJECT_TYPE_U64:
649 case OBJECT_TYPE_DOUBLE:
650 case OBJECT_TYPE_STRING:
651 case OBJECT_TYPE_STRING_SEQUENCE:
652 ret = dynamic_load_field(ax);
653 if (ret)
654 return ret;
655 /* Retry after loading ptr into stack top. */
656 goto again;
657 case OBJECT_TYPE_SEQUENCE:
658 output->type = LTTNG_INTERPRETER_TYPE_SEQUENCE;
659 output->u.sequence.ptr = *(const char **) (ax->u.ptr.ptr + sizeof(unsigned long));
660 output->u.sequence.nr_elem = *(unsigned long *) ax->u.ptr.ptr;
661 output->u.sequence.nested_type = lttng_ust_get_type_sequence(ax->u.ptr.field->type)->elem_type;
662 break;
663 case OBJECT_TYPE_ARRAY:
664 /* Skip count (unsigned long) */
665 output->type = LTTNG_INTERPRETER_TYPE_SEQUENCE;
666 output->u.sequence.ptr = *(const char **) (ax->u.ptr.ptr + sizeof(unsigned long));
667 output->u.sequence.nr_elem = lttng_ust_get_type_array(ax->u.ptr.field->type)->length;
668 output->u.sequence.nested_type = lttng_ust_get_type_array(ax->u.ptr.field->type)->elem_type;
669 break;
670 case OBJECT_TYPE_SIGNED_ENUM:
671 ret = dynamic_load_field(ax);
672 if (ret)
673 return ret;
674 output->type = LTTNG_INTERPRETER_TYPE_SIGNED_ENUM;
675 output->u.s = ax->u.v;
676 break;
677 case OBJECT_TYPE_UNSIGNED_ENUM:
678 ret = dynamic_load_field(ax);
679 if (ret)
680 return ret;
681 output->type = LTTNG_INTERPRETER_TYPE_UNSIGNED_ENUM;
682 output->u.u = ax->u.v;
683 break;
684 case OBJECT_TYPE_STRUCT:
685 case OBJECT_TYPE_VARIANT:
686 default:
687 return -EINVAL;
688 }
689
690 break;
691 case REG_STAR_GLOB_STRING:
692 case REG_UNKNOWN:
693 default:
694 return -EINVAL;
695 }
696
697 return 0;
698 }
699
700 /*
701 * For `output` equal to NULL:
702 * Return 0 (discard), or raise the 0x1 flag (log event).
703 * Currently, other flags are kept for future extensions and have no
704 * effect.
705 * For `output` not equal to NULL:
706 * Return 0 on success, negative error value on error.
707 */
708 int lttng_bytecode_interpret(struct lttng_ust_bytecode_runtime *ust_bytecode,
709 const char *interpreter_stack_data,
710 void *caller_ctx)
711 {
712 struct bytecode_runtime *bytecode = caa_container_of(ust_bytecode, struct bytecode_runtime, p);
713 struct lttng_ust_ctx *ctx = lttng_ust_rcu_dereference(*ust_bytecode->priv->pctx);
714 void *pc, *next_pc, *start_pc;
715 int ret = -EINVAL, retval = 0;
716 struct estack _stack;
717 struct estack *stack = &_stack;
718 register int64_t ax = 0, bx = 0;
719 register enum entry_type ax_t = REG_UNKNOWN, bx_t = REG_UNKNOWN;
720 register int top = INTERPRETER_STACK_EMPTY;
721 #ifndef INTERPRETER_USE_SWITCH
722 static void *dispatch[NR_BYTECODE_OPS] = {
723 [ BYTECODE_OP_UNKNOWN ] = &&LABEL_BYTECODE_OP_UNKNOWN,
724
725 [ BYTECODE_OP_RETURN ] = &&LABEL_BYTECODE_OP_RETURN,
726
727 /* binary */
728 [ BYTECODE_OP_MUL ] = &&LABEL_BYTECODE_OP_MUL,
729 [ BYTECODE_OP_DIV ] = &&LABEL_BYTECODE_OP_DIV,
730 [ BYTECODE_OP_MOD ] = &&LABEL_BYTECODE_OP_MOD,
731 [ BYTECODE_OP_PLUS ] = &&LABEL_BYTECODE_OP_PLUS,
732 [ BYTECODE_OP_MINUS ] = &&LABEL_BYTECODE_OP_MINUS,
733 [ BYTECODE_OP_BIT_RSHIFT ] = &&LABEL_BYTECODE_OP_BIT_RSHIFT,
734 [ BYTECODE_OP_BIT_LSHIFT ] = &&LABEL_BYTECODE_OP_BIT_LSHIFT,
735 [ BYTECODE_OP_BIT_AND ] = &&LABEL_BYTECODE_OP_BIT_AND,
736 [ BYTECODE_OP_BIT_OR ] = &&LABEL_BYTECODE_OP_BIT_OR,
737 [ BYTECODE_OP_BIT_XOR ] = &&LABEL_BYTECODE_OP_BIT_XOR,
738
739 /* binary comparators */
740 [ BYTECODE_OP_EQ ] = &&LABEL_BYTECODE_OP_EQ,
741 [ BYTECODE_OP_NE ] = &&LABEL_BYTECODE_OP_NE,
742 [ BYTECODE_OP_GT ] = &&LABEL_BYTECODE_OP_GT,
743 [ BYTECODE_OP_LT ] = &&LABEL_BYTECODE_OP_LT,
744 [ BYTECODE_OP_GE ] = &&LABEL_BYTECODE_OP_GE,
745 [ BYTECODE_OP_LE ] = &&LABEL_BYTECODE_OP_LE,
746
747 /* string binary comparator */
748 [ BYTECODE_OP_EQ_STRING ] = &&LABEL_BYTECODE_OP_EQ_STRING,
749 [ BYTECODE_OP_NE_STRING ] = &&LABEL_BYTECODE_OP_NE_STRING,
750 [ BYTECODE_OP_GT_STRING ] = &&LABEL_BYTECODE_OP_GT_STRING,
751 [ BYTECODE_OP_LT_STRING ] = &&LABEL_BYTECODE_OP_LT_STRING,
752 [ BYTECODE_OP_GE_STRING ] = &&LABEL_BYTECODE_OP_GE_STRING,
753 [ BYTECODE_OP_LE_STRING ] = &&LABEL_BYTECODE_OP_LE_STRING,
754
755 /* globbing pattern binary comparator */
756 [ BYTECODE_OP_EQ_STAR_GLOB_STRING ] = &&LABEL_BYTECODE_OP_EQ_STAR_GLOB_STRING,
757 [ BYTECODE_OP_NE_STAR_GLOB_STRING ] = &&LABEL_BYTECODE_OP_NE_STAR_GLOB_STRING,
758
759 /* s64 binary comparator */
760 [ BYTECODE_OP_EQ_S64 ] = &&LABEL_BYTECODE_OP_EQ_S64,
761 [ BYTECODE_OP_NE_S64 ] = &&LABEL_BYTECODE_OP_NE_S64,
762 [ BYTECODE_OP_GT_S64 ] = &&LABEL_BYTECODE_OP_GT_S64,
763 [ BYTECODE_OP_LT_S64 ] = &&LABEL_BYTECODE_OP_LT_S64,
764 [ BYTECODE_OP_GE_S64 ] = &&LABEL_BYTECODE_OP_GE_S64,
765 [ BYTECODE_OP_LE_S64 ] = &&LABEL_BYTECODE_OP_LE_S64,
766
767 /* double binary comparator */
768 [ BYTECODE_OP_EQ_DOUBLE ] = &&LABEL_BYTECODE_OP_EQ_DOUBLE,
769 [ BYTECODE_OP_NE_DOUBLE ] = &&LABEL_BYTECODE_OP_NE_DOUBLE,
770 [ BYTECODE_OP_GT_DOUBLE ] = &&LABEL_BYTECODE_OP_GT_DOUBLE,
771 [ BYTECODE_OP_LT_DOUBLE ] = &&LABEL_BYTECODE_OP_LT_DOUBLE,
772 [ BYTECODE_OP_GE_DOUBLE ] = &&LABEL_BYTECODE_OP_GE_DOUBLE,
773 [ BYTECODE_OP_LE_DOUBLE ] = &&LABEL_BYTECODE_OP_LE_DOUBLE,
774
775 /* Mixed S64-double binary comparators */
776 [ BYTECODE_OP_EQ_DOUBLE_S64 ] = &&LABEL_BYTECODE_OP_EQ_DOUBLE_S64,
777 [ BYTECODE_OP_NE_DOUBLE_S64 ] = &&LABEL_BYTECODE_OP_NE_DOUBLE_S64,
778 [ BYTECODE_OP_GT_DOUBLE_S64 ] = &&LABEL_BYTECODE_OP_GT_DOUBLE_S64,
779 [ BYTECODE_OP_LT_DOUBLE_S64 ] = &&LABEL_BYTECODE_OP_LT_DOUBLE_S64,
780 [ BYTECODE_OP_GE_DOUBLE_S64 ] = &&LABEL_BYTECODE_OP_GE_DOUBLE_S64,
781 [ BYTECODE_OP_LE_DOUBLE_S64 ] = &&LABEL_BYTECODE_OP_LE_DOUBLE_S64,
782
783 [ BYTECODE_OP_EQ_S64_DOUBLE ] = &&LABEL_BYTECODE_OP_EQ_S64_DOUBLE,
784 [ BYTECODE_OP_NE_S64_DOUBLE ] = &&LABEL_BYTECODE_OP_NE_S64_DOUBLE,
785 [ BYTECODE_OP_GT_S64_DOUBLE ] = &&LABEL_BYTECODE_OP_GT_S64_DOUBLE,
786 [ BYTECODE_OP_LT_S64_DOUBLE ] = &&LABEL_BYTECODE_OP_LT_S64_DOUBLE,
787 [ BYTECODE_OP_GE_S64_DOUBLE ] = &&LABEL_BYTECODE_OP_GE_S64_DOUBLE,
788 [ BYTECODE_OP_LE_S64_DOUBLE ] = &&LABEL_BYTECODE_OP_LE_S64_DOUBLE,
789
790 /* unary */
791 [ BYTECODE_OP_UNARY_PLUS ] = &&LABEL_BYTECODE_OP_UNARY_PLUS,
792 [ BYTECODE_OP_UNARY_MINUS ] = &&LABEL_BYTECODE_OP_UNARY_MINUS,
793 [ BYTECODE_OP_UNARY_NOT ] = &&LABEL_BYTECODE_OP_UNARY_NOT,
794 [ BYTECODE_OP_UNARY_PLUS_S64 ] = &&LABEL_BYTECODE_OP_UNARY_PLUS_S64,
795 [ BYTECODE_OP_UNARY_MINUS_S64 ] = &&LABEL_BYTECODE_OP_UNARY_MINUS_S64,
796 [ BYTECODE_OP_UNARY_NOT_S64 ] = &&LABEL_BYTECODE_OP_UNARY_NOT_S64,
797 [ BYTECODE_OP_UNARY_PLUS_DOUBLE ] = &&LABEL_BYTECODE_OP_UNARY_PLUS_DOUBLE,
798 [ BYTECODE_OP_UNARY_MINUS_DOUBLE ] = &&LABEL_BYTECODE_OP_UNARY_MINUS_DOUBLE,
799 [ BYTECODE_OP_UNARY_NOT_DOUBLE ] = &&LABEL_BYTECODE_OP_UNARY_NOT_DOUBLE,
800
801 /* logical */
802 [ BYTECODE_OP_AND ] = &&LABEL_BYTECODE_OP_AND,
803 [ BYTECODE_OP_OR ] = &&LABEL_BYTECODE_OP_OR,
804
805 /* load field ref */
806 [ BYTECODE_OP_LOAD_FIELD_REF ] = &&LABEL_BYTECODE_OP_LOAD_FIELD_REF,
807 [ BYTECODE_OP_LOAD_FIELD_REF_STRING ] = &&LABEL_BYTECODE_OP_LOAD_FIELD_REF_STRING,
808 [ BYTECODE_OP_LOAD_FIELD_REF_SEQUENCE ] = &&LABEL_BYTECODE_OP_LOAD_FIELD_REF_SEQUENCE,
809 [ BYTECODE_OP_LOAD_FIELD_REF_S64 ] = &&LABEL_BYTECODE_OP_LOAD_FIELD_REF_S64,
810 [ BYTECODE_OP_LOAD_FIELD_REF_DOUBLE ] = &&LABEL_BYTECODE_OP_LOAD_FIELD_REF_DOUBLE,
811
812 /* load from immediate operand */
813 [ BYTECODE_OP_LOAD_STRING ] = &&LABEL_BYTECODE_OP_LOAD_STRING,
814 [ BYTECODE_OP_LOAD_STAR_GLOB_STRING ] = &&LABEL_BYTECODE_OP_LOAD_STAR_GLOB_STRING,
815 [ BYTECODE_OP_LOAD_S64 ] = &&LABEL_BYTECODE_OP_LOAD_S64,
816 [ BYTECODE_OP_LOAD_DOUBLE ] = &&LABEL_BYTECODE_OP_LOAD_DOUBLE,
817
818 /* cast */
819 [ BYTECODE_OP_CAST_TO_S64 ] = &&LABEL_BYTECODE_OP_CAST_TO_S64,
820 [ BYTECODE_OP_CAST_DOUBLE_TO_S64 ] = &&LABEL_BYTECODE_OP_CAST_DOUBLE_TO_S64,
821 [ BYTECODE_OP_CAST_NOP ] = &&LABEL_BYTECODE_OP_CAST_NOP,
822
823 /* get context ref */
824 [ BYTECODE_OP_GET_CONTEXT_REF ] = &&LABEL_BYTECODE_OP_GET_CONTEXT_REF,
825 [ BYTECODE_OP_GET_CONTEXT_REF_STRING ] = &&LABEL_BYTECODE_OP_GET_CONTEXT_REF_STRING,
826 [ BYTECODE_OP_GET_CONTEXT_REF_S64 ] = &&LABEL_BYTECODE_OP_GET_CONTEXT_REF_S64,
827 [ BYTECODE_OP_GET_CONTEXT_REF_DOUBLE ] = &&LABEL_BYTECODE_OP_GET_CONTEXT_REF_DOUBLE,
828
829 /* Instructions for recursive traversal through composed types. */
830 [ BYTECODE_OP_GET_CONTEXT_ROOT ] = &&LABEL_BYTECODE_OP_GET_CONTEXT_ROOT,
831 [ BYTECODE_OP_GET_APP_CONTEXT_ROOT ] = &&LABEL_BYTECODE_OP_GET_APP_CONTEXT_ROOT,
832 [ BYTECODE_OP_GET_PAYLOAD_ROOT ] = &&LABEL_BYTECODE_OP_GET_PAYLOAD_ROOT,
833
834 [ BYTECODE_OP_GET_SYMBOL ] = &&LABEL_BYTECODE_OP_GET_SYMBOL,
835 [ BYTECODE_OP_GET_SYMBOL_FIELD ] = &&LABEL_BYTECODE_OP_GET_SYMBOL_FIELD,
836 [ BYTECODE_OP_GET_INDEX_U16 ] = &&LABEL_BYTECODE_OP_GET_INDEX_U16,
837 [ BYTECODE_OP_GET_INDEX_U64 ] = &&LABEL_BYTECODE_OP_GET_INDEX_U64,
838
839 [ BYTECODE_OP_LOAD_FIELD ] = &&LABEL_BYTECODE_OP_LOAD_FIELD,
840 [ BYTECODE_OP_LOAD_FIELD_S8 ] = &&LABEL_BYTECODE_OP_LOAD_FIELD_S8,
841 [ BYTECODE_OP_LOAD_FIELD_S16 ] = &&LABEL_BYTECODE_OP_LOAD_FIELD_S16,
842 [ BYTECODE_OP_LOAD_FIELD_S32 ] = &&LABEL_BYTECODE_OP_LOAD_FIELD_S32,
843 [ BYTECODE_OP_LOAD_FIELD_S64 ] = &&LABEL_BYTECODE_OP_LOAD_FIELD_S64,
844 [ BYTECODE_OP_LOAD_FIELD_U8 ] = &&LABEL_BYTECODE_OP_LOAD_FIELD_U8,
845 [ BYTECODE_OP_LOAD_FIELD_U16 ] = &&LABEL_BYTECODE_OP_LOAD_FIELD_U16,
846 [ BYTECODE_OP_LOAD_FIELD_U32 ] = &&LABEL_BYTECODE_OP_LOAD_FIELD_U32,
847 [ BYTECODE_OP_LOAD_FIELD_U64 ] = &&LABEL_BYTECODE_OP_LOAD_FIELD_U64,
848 [ BYTECODE_OP_LOAD_FIELD_STRING ] = &&LABEL_BYTECODE_OP_LOAD_FIELD_STRING,
849 [ BYTECODE_OP_LOAD_FIELD_SEQUENCE ] = &&LABEL_BYTECODE_OP_LOAD_FIELD_SEQUENCE,
850 [ BYTECODE_OP_LOAD_FIELD_DOUBLE ] = &&LABEL_BYTECODE_OP_LOAD_FIELD_DOUBLE,
851
852 [ BYTECODE_OP_UNARY_BIT_NOT ] = &&LABEL_BYTECODE_OP_UNARY_BIT_NOT,
853
854 [ BYTECODE_OP_RETURN_S64 ] = &&LABEL_BYTECODE_OP_RETURN_S64,
855 };
856 #endif /* #ifndef INTERPRETER_USE_SWITCH */
857
858 START_OP
859
860 OP(BYTECODE_OP_UNKNOWN):
861 OP(BYTECODE_OP_LOAD_FIELD_REF):
862 #ifdef INTERPRETER_USE_SWITCH
863 default:
864 #endif /* INTERPRETER_USE_SWITCH */
865 ERR("unknown bytecode op %u",
866 (unsigned int) *(bytecode_opcode_t *) pc);
867 ret = -EINVAL;
868 goto end;
869
870 OP(BYTECODE_OP_RETURN):
871 /* LTTNG_UST_BYTECODE_INTERPRETER_ERROR or LTTNG_UST_BYTECODE_INTERPRETER_OK */
872 /* Handle dynamic typing. */
873 switch (estack_ax_t) {
874 case REG_S64:
875 case REG_U64:
876 retval = !!estack_ax_v;
877 break;
878 case REG_DOUBLE:
879 case REG_STRING:
880 case REG_PTR:
881 if (ust_bytecode->priv->type != LTTNG_UST_BYTECODE_TYPE_CAPTURE) {
882 ret = -EINVAL;
883 goto end;
884 }
885 retval = 0;
886 break;
887 case REG_STAR_GLOB_STRING:
888 case REG_UNKNOWN:
889 default:
890 ret = -EINVAL;
891 goto end;
892 }
893 ret = 0;
894 goto end;
895
896 OP(BYTECODE_OP_RETURN_S64):
897 /* LTTNG_UST_BYTECODE_INTERPRETER_ERROR or LTTNG_UST_BYTECODE_INTERPRETER_OK */
898 retval = !!estack_ax_v;
899 ret = 0;
900 goto end;
901
902 /* binary */
903 OP(BYTECODE_OP_MUL):
904 OP(BYTECODE_OP_DIV):
905 OP(BYTECODE_OP_MOD):
906 OP(BYTECODE_OP_PLUS):
907 OP(BYTECODE_OP_MINUS):
908 ERR("unsupported bytecode op %u",
909 (unsigned int) *(bytecode_opcode_t *) pc);
910 ret = -EINVAL;
911 goto end;
912
913 OP(BYTECODE_OP_EQ):
914 {
915 /* Dynamic typing. */
916 switch (estack_ax_t) {
917 case REG_S64: /* Fall-through */
918 case REG_U64:
919 switch (estack_bx_t) {
920 case REG_S64: /* Fall-through */
921 case REG_U64:
922 JUMP_TO(BYTECODE_OP_EQ_S64);
923 case REG_DOUBLE:
924 JUMP_TO(BYTECODE_OP_EQ_DOUBLE_S64);
925 case REG_STRING: /* Fall-through */
926 case REG_STAR_GLOB_STRING:
927 ret = -EINVAL;
928 goto end;
929 default:
930 ERR("Unknown interpreter register type (%d)",
931 (int) estack_bx_t);
932 ret = -EINVAL;
933 goto end;
934 }
935 break;
936 case REG_DOUBLE:
937 switch (estack_bx_t) {
938 case REG_S64: /* Fall-through */
939 case REG_U64:
940 JUMP_TO(BYTECODE_OP_EQ_S64_DOUBLE);
941 case REG_DOUBLE:
942 JUMP_TO(BYTECODE_OP_EQ_DOUBLE);
943 case REG_STRING: /* Fall-through */
944 case REG_STAR_GLOB_STRING:
945 ret = -EINVAL;
946 goto end;
947 default:
948 ERR("Unknown interpreter register type (%d)",
949 (int) estack_bx_t);
950 ret = -EINVAL;
951 goto end;
952 }
953 break;
954 case REG_STRING:
955 switch (estack_bx_t) {
956 case REG_S64: /* Fall-through */
957 case REG_U64: /* Fall-through */
958 case REG_DOUBLE:
959 ret = -EINVAL;
960 goto end;
961 case REG_STRING:
962 JUMP_TO(BYTECODE_OP_EQ_STRING);
963 case REG_STAR_GLOB_STRING:
964 JUMP_TO(BYTECODE_OP_EQ_STAR_GLOB_STRING);
965 default:
966 ERR("Unknown interpreter register type (%d)",
967 (int) estack_bx_t);
968 ret = -EINVAL;
969 goto end;
970 }
971 break;
972 case REG_STAR_GLOB_STRING:
973 switch (estack_bx_t) {
974 case REG_S64: /* Fall-through */
975 case REG_U64: /* Fall-through */
976 case REG_DOUBLE:
977 ret = -EINVAL;
978 goto end;
979 case REG_STRING:
980 JUMP_TO(BYTECODE_OP_EQ_STAR_GLOB_STRING);
981 case REG_STAR_GLOB_STRING:
982 ret = -EINVAL;
983 goto end;
984 default:
985 ERR("Unknown interpreter register type (%d)",
986 (int) estack_bx_t);
987 ret = -EINVAL;
988 goto end;
989 }
990 break;
991 default:
992 ERR("Unknown interpreter register type (%d)",
993 (int) estack_ax_t);
994 ret = -EINVAL;
995 goto end;
996 }
997 }
998 OP(BYTECODE_OP_NE):
999 {
1000 /* Dynamic typing. */
1001 switch (estack_ax_t) {
1002 case REG_S64: /* Fall-through */
1003 case REG_U64:
1004 switch (estack_bx_t) {
1005 case REG_S64: /* Fall-through */
1006 case REG_U64:
1007 JUMP_TO(BYTECODE_OP_NE_S64);
1008 case REG_DOUBLE:
1009 JUMP_TO(BYTECODE_OP_NE_DOUBLE_S64);
1010 case REG_STRING: /* Fall-through */
1011 case REG_STAR_GLOB_STRING:
1012 ret = -EINVAL;
1013 goto end;
1014 default:
1015 ERR("Unknown interpreter register type (%d)",
1016 (int) estack_bx_t);
1017 ret = -EINVAL;
1018 goto end;
1019 }
1020 break;
1021 case REG_DOUBLE:
1022 switch (estack_bx_t) {
1023 case REG_S64: /* Fall-through */
1024 case REG_U64:
1025 JUMP_TO(BYTECODE_OP_NE_S64_DOUBLE);
1026 case REG_DOUBLE:
1027 JUMP_TO(BYTECODE_OP_NE_DOUBLE);
1028 case REG_STRING: /* Fall-through */
1029 case REG_STAR_GLOB_STRING:
1030 ret = -EINVAL;
1031 goto end;
1032 default:
1033 ERR("Unknown interpreter register type (%d)",
1034 (int) estack_bx_t);
1035 ret = -EINVAL;
1036 goto end;
1037 }
1038 break;
1039 case REG_STRING:
1040 switch (estack_bx_t) {
1041 case REG_S64: /* Fall-through */
1042 case REG_U64:
1043 case REG_DOUBLE:
1044 ret = -EINVAL;
1045 goto end;
1046 case REG_STRING:
1047 JUMP_TO(BYTECODE_OP_NE_STRING);
1048 case REG_STAR_GLOB_STRING:
1049 JUMP_TO(BYTECODE_OP_NE_STAR_GLOB_STRING);
1050 default:
1051 ERR("Unknown interpreter register type (%d)",
1052 (int) estack_bx_t);
1053 ret = -EINVAL;
1054 goto end;
1055 }
1056 break;
1057 case REG_STAR_GLOB_STRING:
1058 switch (estack_bx_t) {
1059 case REG_S64: /* Fall-through */
1060 case REG_U64:
1061 case REG_DOUBLE:
1062 ret = -EINVAL;
1063 goto end;
1064 case REG_STRING:
1065 JUMP_TO(BYTECODE_OP_NE_STAR_GLOB_STRING);
1066 case REG_STAR_GLOB_STRING:
1067 ret = -EINVAL;
1068 goto end;
1069 default:
1070 ERR("Unknown interpreter register type (%d)",
1071 (int) estack_bx_t);
1072 ret = -EINVAL;
1073 goto end;
1074 }
1075 break;
1076 default:
1077 ERR("Unknown interpreter register type (%d)",
1078 (int) estack_ax_t);
1079 ret = -EINVAL;
1080 goto end;
1081 }
1082 }
1083 OP(BYTECODE_OP_GT):
1084 {
1085 /* Dynamic typing. */
1086 switch (estack_ax_t) {
1087 case REG_S64: /* Fall-through */
1088 case REG_U64:
1089 switch (estack_bx_t) {
1090 case REG_S64: /* Fall-through */
1091 case REG_U64:
1092 JUMP_TO(BYTECODE_OP_GT_S64);
1093 case REG_DOUBLE:
1094 JUMP_TO(BYTECODE_OP_GT_DOUBLE_S64);
1095 case REG_STRING: /* Fall-through */
1096 case REG_STAR_GLOB_STRING:
1097 ret = -EINVAL;
1098 goto end;
1099 default:
1100 ERR("Unknown interpreter register type (%d)",
1101 (int) estack_bx_t);
1102 ret = -EINVAL;
1103 goto end;
1104 }
1105 break;
1106 case REG_DOUBLE:
1107 switch (estack_bx_t) {
1108 case REG_S64: /* Fall-through */
1109 case REG_U64:
1110 JUMP_TO(BYTECODE_OP_GT_S64_DOUBLE);
1111 case REG_DOUBLE:
1112 JUMP_TO(BYTECODE_OP_GT_DOUBLE);
1113 case REG_STRING: /* Fall-through */
1114 case REG_STAR_GLOB_STRING:
1115 ret = -EINVAL;
1116 goto end;
1117 default:
1118 ERR("Unknown interpreter register type (%d)",
1119 (int) estack_bx_t);
1120 ret = -EINVAL;
1121 goto end;
1122 }
1123 break;
1124 case REG_STRING:
1125 switch (estack_bx_t) {
1126 case REG_S64: /* Fall-through */
1127 case REG_U64: /* Fall-through */
1128 case REG_DOUBLE: /* Fall-through */
1129 case REG_STAR_GLOB_STRING:
1130 ret = -EINVAL;
1131 goto end;
1132 case REG_STRING:
1133 JUMP_TO(BYTECODE_OP_GT_STRING);
1134 default:
1135 ERR("Unknown interpreter register type (%d)",
1136 (int) estack_bx_t);
1137 ret = -EINVAL;
1138 goto end;
1139 }
1140 break;
1141 default:
1142 ERR("Unknown interpreter register type (%d)",
1143 (int) estack_ax_t);
1144 ret = -EINVAL;
1145 goto end;
1146 }
1147 }
1148 OP(BYTECODE_OP_LT):
1149 {
1150 /* Dynamic typing. */
1151 switch (estack_ax_t) {
1152 case REG_S64: /* Fall-through */
1153 case REG_U64:
1154 switch (estack_bx_t) {
1155 case REG_S64: /* Fall-through */
1156 case REG_U64:
1157 JUMP_TO(BYTECODE_OP_LT_S64);
1158 case REG_DOUBLE:
1159 JUMP_TO(BYTECODE_OP_LT_DOUBLE_S64);
1160 case REG_STRING: /* Fall-through */
1161 case REG_STAR_GLOB_STRING:
1162 ret = -EINVAL;
1163 goto end;
1164 default:
1165 ERR("Unknown interpreter register type (%d)",
1166 (int) estack_bx_t);
1167 ret = -EINVAL;
1168 goto end;
1169 }
1170 break;
1171 case REG_DOUBLE:
1172 switch (estack_bx_t) {
1173 case REG_S64: /* Fall-through */
1174 case REG_U64:
1175 JUMP_TO(BYTECODE_OP_LT_S64_DOUBLE);
1176 case REG_DOUBLE:
1177 JUMP_TO(BYTECODE_OP_LT_DOUBLE);
1178 case REG_STRING: /* Fall-through */
1179 case REG_STAR_GLOB_STRING:
1180 ret = -EINVAL;
1181 goto end;
1182 default:
1183 ERR("Unknown interpreter register type (%d)",
1184 (int) estack_bx_t);
1185 ret = -EINVAL;
1186 goto end;
1187 }
1188 break;
1189 case REG_STRING:
1190 switch (estack_bx_t) {
1191 case REG_S64: /* Fall-through */
1192 case REG_U64: /* Fall-through */
1193 case REG_DOUBLE: /* Fall-through */
1194 case REG_STAR_GLOB_STRING:
1195 ret = -EINVAL;
1196 goto end;
1197 case REG_STRING:
1198 JUMP_TO(BYTECODE_OP_LT_STRING);
1199 default:
1200 ERR("Unknown interpreter register type (%d)",
1201 (int) estack_bx_t);
1202 ret = -EINVAL;
1203 goto end;
1204 }
1205 break;
1206 default:
1207 ERR("Unknown interpreter register type (%d)",
1208 (int) estack_ax_t);
1209 ret = -EINVAL;
1210 goto end;
1211 }
1212 }
1213 OP(BYTECODE_OP_GE):
1214 {
1215 /* Dynamic typing. */
1216 switch (estack_ax_t) {
1217 case REG_S64: /* Fall-through */
1218 case REG_U64:
1219 switch (estack_bx_t) {
1220 case REG_S64: /* Fall-through */
1221 case REG_U64:
1222 JUMP_TO(BYTECODE_OP_GE_S64);
1223 case REG_DOUBLE:
1224 JUMP_TO(BYTECODE_OP_GE_DOUBLE_S64);
1225 case REG_STRING: /* Fall-through */
1226 case REG_STAR_GLOB_STRING:
1227 ret = -EINVAL;
1228 goto end;
1229 default:
1230 ERR("Unknown interpreter register type (%d)",
1231 (int) estack_bx_t);
1232 ret = -EINVAL;
1233 goto end;
1234 }
1235 break;
1236 case REG_DOUBLE:
1237 switch (estack_bx_t) {
1238 case REG_S64: /* Fall-through */
1239 case REG_U64:
1240 JUMP_TO(BYTECODE_OP_GE_S64_DOUBLE);
1241 case REG_DOUBLE:
1242 JUMP_TO(BYTECODE_OP_GE_DOUBLE);
1243 case REG_STRING: /* Fall-through */
1244 case REG_STAR_GLOB_STRING:
1245 ret = -EINVAL;
1246 goto end;
1247 default:
1248 ERR("Unknown interpreter register type (%d)",
1249 (int) estack_bx_t);
1250 ret = -EINVAL;
1251 goto end;
1252 }
1253 break;
1254 case REG_STRING:
1255 switch (estack_bx_t) {
1256 case REG_S64: /* Fall-through */
1257 case REG_U64: /* Fall-through */
1258 case REG_DOUBLE: /* Fall-through */
1259 case REG_STAR_GLOB_STRING:
1260 ret = -EINVAL;
1261 goto end;
1262 case REG_STRING:
1263 JUMP_TO(BYTECODE_OP_GE_STRING);
1264 default:
1265 ERR("Unknown interpreter register type (%d)",
1266 (int) estack_bx_t);
1267 ret = -EINVAL;
1268 goto end;
1269 }
1270 break;
1271 default:
1272 ERR("Unknown interpreter register type (%d)",
1273 (int) estack_ax_t);
1274 ret = -EINVAL;
1275 goto end;
1276 }
1277 }
1278 OP(BYTECODE_OP_LE):
1279 {
1280 /* Dynamic typing. */
1281 switch (estack_ax_t) {
1282 case REG_S64: /* Fall-through */
1283 case REG_U64:
1284 switch (estack_bx_t) {
1285 case REG_S64: /* Fall-through */
1286 case REG_U64:
1287 JUMP_TO(BYTECODE_OP_LE_S64);
1288 case REG_DOUBLE:
1289 JUMP_TO(BYTECODE_OP_LE_DOUBLE_S64);
1290 case REG_STRING: /* Fall-through */
1291 case REG_STAR_GLOB_STRING:
1292 ret = -EINVAL;
1293 goto end;
1294 default:
1295 ERR("Unknown interpreter register type (%d)",
1296 (int) estack_bx_t);
1297 ret = -EINVAL;
1298 goto end;
1299 }
1300 break;
1301 case REG_DOUBLE:
1302 switch (estack_bx_t) {
1303 case REG_S64: /* Fall-through */
1304 case REG_U64:
1305 JUMP_TO(BYTECODE_OP_LE_S64_DOUBLE);
1306 case REG_DOUBLE:
1307 JUMP_TO(BYTECODE_OP_LE_DOUBLE);
1308 case REG_STRING: /* Fall-through */
1309 case REG_STAR_GLOB_STRING:
1310 ret = -EINVAL;
1311 goto end;
1312 default:
1313 ERR("Unknown interpreter register type (%d)",
1314 (int) estack_bx_t);
1315 ret = -EINVAL;
1316 goto end;
1317 }
1318 break;
1319 case REG_STRING:
1320 switch (estack_bx_t) {
1321 case REG_S64: /* Fall-through */
1322 case REG_U64: /* Fall-through */
1323 case REG_DOUBLE: /* Fall-through */
1324 case REG_STAR_GLOB_STRING:
1325 ret = -EINVAL;
1326 goto end;
1327 case REG_STRING:
1328 JUMP_TO(BYTECODE_OP_LE_STRING);
1329 default:
1330 ERR("Unknown interpreter register type (%d)",
1331 (int) estack_bx_t);
1332 ret = -EINVAL;
1333 goto end;
1334 }
1335 break;
1336 default:
1337 ERR("Unknown interpreter register type (%d)",
1338 (int) estack_ax_t);
1339 ret = -EINVAL;
1340 goto end;
1341 }
1342 }
1343
1344 OP(BYTECODE_OP_EQ_STRING):
1345 {
1346 int res;
1347
1348 res = (stack_strcmp(stack, top, "==") == 0);
1349 estack_pop(stack, top, ax, bx, ax_t, bx_t);
1350 estack_ax_v = res;
1351 estack_ax_t = REG_S64;
1352 next_pc += sizeof(struct binary_op);
1353 PO;
1354 }
1355 OP(BYTECODE_OP_NE_STRING):
1356 {
1357 int res;
1358
1359 res = (stack_strcmp(stack, top, "!=") != 0);
1360 estack_pop(stack, top, ax, bx, ax_t, bx_t);
1361 estack_ax_v = res;
1362 estack_ax_t = REG_S64;
1363 next_pc += sizeof(struct binary_op);
1364 PO;
1365 }
1366 OP(BYTECODE_OP_GT_STRING):
1367 {
1368 int res;
1369
1370 res = (stack_strcmp(stack, top, ">") > 0);
1371 estack_pop(stack, top, ax, bx, ax_t, bx_t);
1372 estack_ax_v = res;
1373 estack_ax_t = REG_S64;
1374 next_pc += sizeof(struct binary_op);
1375 PO;
1376 }
1377 OP(BYTECODE_OP_LT_STRING):
1378 {
1379 int res;
1380
1381 res = (stack_strcmp(stack, top, "<") < 0);
1382 estack_pop(stack, top, ax, bx, ax_t, bx_t);
1383 estack_ax_v = res;
1384 estack_ax_t = REG_S64;
1385 next_pc += sizeof(struct binary_op);
1386 PO;
1387 }
1388 OP(BYTECODE_OP_GE_STRING):
1389 {
1390 int res;
1391
1392 res = (stack_strcmp(stack, top, ">=") >= 0);
1393 estack_pop(stack, top, ax, bx, ax_t, bx_t);
1394 estack_ax_v = res;
1395 estack_ax_t = REG_S64;
1396 next_pc += sizeof(struct binary_op);
1397 PO;
1398 }
1399 OP(BYTECODE_OP_LE_STRING):
1400 {
1401 int res;
1402
1403 res = (stack_strcmp(stack, top, "<=") <= 0);
1404 estack_pop(stack, top, ax, bx, ax_t, bx_t);
1405 estack_ax_v = res;
1406 estack_ax_t = REG_S64;
1407 next_pc += sizeof(struct binary_op);
1408 PO;
1409 }
1410
1411 OP(BYTECODE_OP_EQ_STAR_GLOB_STRING):
1412 {
1413 int res;
1414
1415 res = (stack_star_glob_match(stack, top, "==") == 0);
1416 estack_pop(stack, top, ax, bx, ax_t, bx_t);
1417 estack_ax_v = res;
1418 estack_ax_t = REG_S64;
1419 next_pc += sizeof(struct binary_op);
1420 PO;
1421 }
1422 OP(BYTECODE_OP_NE_STAR_GLOB_STRING):
1423 {
1424 int res;
1425
1426 res = (stack_star_glob_match(stack, top, "!=") != 0);
1427 estack_pop(stack, top, ax, bx, ax_t, bx_t);
1428 estack_ax_v = res;
1429 estack_ax_t = REG_S64;
1430 next_pc += sizeof(struct binary_op);
1431 PO;
1432 }
1433
1434 OP(BYTECODE_OP_EQ_S64):
1435 {
1436 int res;
1437
1438 res = (estack_bx_v == estack_ax_v);
1439 estack_pop(stack, top, ax, bx, ax_t, bx_t);
1440 estack_ax_v = res;
1441 estack_ax_t = REG_S64;
1442 next_pc += sizeof(struct binary_op);
1443 PO;
1444 }
1445 OP(BYTECODE_OP_NE_S64):
1446 {
1447 int res;
1448
1449 res = (estack_bx_v != estack_ax_v);
1450 estack_pop(stack, top, ax, bx, ax_t, bx_t);
1451 estack_ax_v = res;
1452 estack_ax_t = REG_S64;
1453 next_pc += sizeof(struct binary_op);
1454 PO;
1455 }
1456 OP(BYTECODE_OP_GT_S64):
1457 {
1458 int res;
1459
1460 res = (estack_bx_v > estack_ax_v);
1461 estack_pop(stack, top, ax, bx, ax_t, bx_t);
1462 estack_ax_v = res;
1463 estack_ax_t = REG_S64;
1464 next_pc += sizeof(struct binary_op);
1465 PO;
1466 }
1467 OP(BYTECODE_OP_LT_S64):
1468 {
1469 int res;
1470
1471 res = (estack_bx_v < estack_ax_v);
1472 estack_pop(stack, top, ax, bx, ax_t, bx_t);
1473 estack_ax_v = res;
1474 estack_ax_t = REG_S64;
1475 next_pc += sizeof(struct binary_op);
1476 PO;
1477 }
1478 OP(BYTECODE_OP_GE_S64):
1479 {
1480 int res;
1481
1482 res = (estack_bx_v >= estack_ax_v);
1483 estack_pop(stack, top, ax, bx, ax_t, bx_t);
1484 estack_ax_v = res;
1485 estack_ax_t = REG_S64;
1486 next_pc += sizeof(struct binary_op);
1487 PO;
1488 }
1489 OP(BYTECODE_OP_LE_S64):
1490 {
1491 int res;
1492
1493 res = (estack_bx_v <= estack_ax_v);
1494 estack_pop(stack, top, ax, bx, ax_t, bx_t);
1495 estack_ax_v = res;
1496 estack_ax_t = REG_S64;
1497 next_pc += sizeof(struct binary_op);
1498 PO;
1499 }
1500
1501 OP(BYTECODE_OP_EQ_DOUBLE):
1502 {
1503 int res;
1504
1505 res = (estack_bx(stack, top)->u.d == estack_ax(stack, top)->u.d);
1506 estack_pop(stack, top, ax, bx, ax_t, bx_t);
1507 estack_ax_v = res;
1508 estack_ax_t = REG_S64;
1509 next_pc += sizeof(struct binary_op);
1510 PO;
1511 }
1512 OP(BYTECODE_OP_NE_DOUBLE):
1513 {
1514 int res;
1515
1516 res = (estack_bx(stack, top)->u.d != estack_ax(stack, top)->u.d);
1517 estack_pop(stack, top, ax, bx, ax_t, bx_t);
1518 estack_ax_v = res;
1519 estack_ax_t = REG_S64;
1520 next_pc += sizeof(struct binary_op);
1521 PO;
1522 }
1523 OP(BYTECODE_OP_GT_DOUBLE):
1524 {
1525 int res;
1526
1527 res = (estack_bx(stack, top)->u.d > estack_ax(stack, top)->u.d);
1528 estack_pop(stack, top, ax, bx, ax_t, bx_t);
1529 estack_ax_v = res;
1530 estack_ax_t = REG_S64;
1531 next_pc += sizeof(struct binary_op);
1532 PO;
1533 }
1534 OP(BYTECODE_OP_LT_DOUBLE):
1535 {
1536 int res;
1537
1538 res = (estack_bx(stack, top)->u.d < estack_ax(stack, top)->u.d);
1539 estack_pop(stack, top, ax, bx, ax_t, bx_t);
1540 estack_ax_v = res;
1541 estack_ax_t = REG_S64;
1542 next_pc += sizeof(struct binary_op);
1543 PO;
1544 }
1545 OP(BYTECODE_OP_GE_DOUBLE):
1546 {
1547 int res;
1548
1549 res = (estack_bx(stack, top)->u.d >= estack_ax(stack, top)->u.d);
1550 estack_pop(stack, top, ax, bx, ax_t, bx_t);
1551 estack_ax_v = res;
1552 estack_ax_t = REG_S64;
1553 next_pc += sizeof(struct binary_op);
1554 PO;
1555 }
1556 OP(BYTECODE_OP_LE_DOUBLE):
1557 {
1558 int res;
1559
1560 res = (estack_bx(stack, top)->u.d <= estack_ax(stack, top)->u.d);
1561 estack_pop(stack, top, ax, bx, ax_t, bx_t);
1562 estack_ax_v = res;
1563 estack_ax_t = REG_S64;
1564 next_pc += sizeof(struct binary_op);
1565 PO;
1566 }
1567
1568 /* Mixed S64-double binary comparators */
1569 OP(BYTECODE_OP_EQ_DOUBLE_S64):
1570 {
1571 int res;
1572
1573 res = (estack_bx(stack, top)->u.d == estack_ax_v);
1574 estack_pop(stack, top, ax, bx, ax_t, bx_t);
1575 estack_ax_v = res;
1576 estack_ax_t = REG_S64;
1577 next_pc += sizeof(struct binary_op);
1578 PO;
1579 }
1580 OP(BYTECODE_OP_NE_DOUBLE_S64):
1581 {
1582 int res;
1583
1584 res = (estack_bx(stack, top)->u.d != estack_ax_v);
1585 estack_pop(stack, top, ax, bx, ax_t, bx_t);
1586 estack_ax_v = res;
1587 estack_ax_t = REG_S64;
1588 next_pc += sizeof(struct binary_op);
1589 PO;
1590 }
1591 OP(BYTECODE_OP_GT_DOUBLE_S64):
1592 {
1593 int res;
1594
1595 res = (estack_bx(stack, top)->u.d > estack_ax_v);
1596 estack_pop(stack, top, ax, bx, ax_t, bx_t);
1597 estack_ax_v = res;
1598 estack_ax_t = REG_S64;
1599 next_pc += sizeof(struct binary_op);
1600 PO;
1601 }
1602 OP(BYTECODE_OP_LT_DOUBLE_S64):
1603 {
1604 int res;
1605
1606 res = (estack_bx(stack, top)->u.d < estack_ax_v);
1607 estack_pop(stack, top, ax, bx, ax_t, bx_t);
1608 estack_ax_v = res;
1609 estack_ax_t = REG_S64;
1610 next_pc += sizeof(struct binary_op);
1611 PO;
1612 }
1613 OP(BYTECODE_OP_GE_DOUBLE_S64):
1614 {
1615 int res;
1616
1617 res = (estack_bx(stack, top)->u.d >= estack_ax_v);
1618 estack_pop(stack, top, ax, bx, ax_t, bx_t);
1619 estack_ax_v = res;
1620 estack_ax_t = REG_S64;
1621 next_pc += sizeof(struct binary_op);
1622 PO;
1623 }
1624 OP(BYTECODE_OP_LE_DOUBLE_S64):
1625 {
1626 int res;
1627
1628 res = (estack_bx(stack, top)->u.d <= estack_ax_v);
1629 estack_pop(stack, top, ax, bx, ax_t, bx_t);
1630 estack_ax_v = res;
1631 estack_ax_t = REG_S64;
1632 next_pc += sizeof(struct binary_op);
1633 PO;
1634 }
1635
1636 OP(BYTECODE_OP_EQ_S64_DOUBLE):
1637 {
1638 int res;
1639
1640 res = (estack_bx_v == estack_ax(stack, top)->u.d);
1641 estack_pop(stack, top, ax, bx, ax_t, bx_t);
1642 estack_ax_v = res;
1643 estack_ax_t = REG_S64;
1644 next_pc += sizeof(struct binary_op);
1645 PO;
1646 }
1647 OP(BYTECODE_OP_NE_S64_DOUBLE):
1648 {
1649 int res;
1650
1651 res = (estack_bx_v != estack_ax(stack, top)->u.d);
1652 estack_pop(stack, top, ax, bx, ax_t, bx_t);
1653 estack_ax_v = res;
1654 estack_ax_t = REG_S64;
1655 next_pc += sizeof(struct binary_op);
1656 PO;
1657 }
1658 OP(BYTECODE_OP_GT_S64_DOUBLE):
1659 {
1660 int res;
1661
1662 res = (estack_bx_v > estack_ax(stack, top)->u.d);
1663 estack_pop(stack, top, ax, bx, ax_t, bx_t);
1664 estack_ax_v = res;
1665 estack_ax_t = REG_S64;
1666 next_pc += sizeof(struct binary_op);
1667 PO;
1668 }
1669 OP(BYTECODE_OP_LT_S64_DOUBLE):
1670 {
1671 int res;
1672
1673 res = (estack_bx_v < estack_ax(stack, top)->u.d);
1674 estack_pop(stack, top, ax, bx, ax_t, bx_t);
1675 estack_ax_v = res;
1676 estack_ax_t = REG_S64;
1677 next_pc += sizeof(struct binary_op);
1678 PO;
1679 }
1680 OP(BYTECODE_OP_GE_S64_DOUBLE):
1681 {
1682 int res;
1683
1684 res = (estack_bx_v >= estack_ax(stack, top)->u.d);
1685 estack_pop(stack, top, ax, bx, ax_t, bx_t);
1686 estack_ax_v = res;
1687 estack_ax_t = REG_S64;
1688 next_pc += sizeof(struct binary_op);
1689 PO;
1690 }
1691 OP(BYTECODE_OP_LE_S64_DOUBLE):
1692 {
1693 int res;
1694
1695 res = (estack_bx_v <= estack_ax(stack, top)->u.d);
1696 estack_pop(stack, top, ax, bx, ax_t, bx_t);
1697 estack_ax_v = res;
1698 estack_ax_t = REG_S64;
1699 next_pc += sizeof(struct binary_op);
1700 PO;
1701 }
1702 OP(BYTECODE_OP_BIT_RSHIFT):
1703 {
1704 int64_t res;
1705
1706 if (!IS_INTEGER_REGISTER(estack_ax_t) || !IS_INTEGER_REGISTER(estack_bx_t)) {
1707 ret = -EINVAL;
1708 goto end;
1709 }
1710
1711 /* Catch undefined behavior. */
1712 if (caa_unlikely(estack_ax_v < 0 || estack_ax_v >= 64)) {
1713 ret = -EINVAL;
1714 goto end;
1715 }
1716 res = ((uint64_t) estack_bx_v >> (uint32_t) estack_ax_v);
1717 estack_pop(stack, top, ax, bx, ax_t, bx_t);
1718 estack_ax_v = res;
1719 estack_ax_t = REG_U64;
1720 next_pc += sizeof(struct binary_op);
1721 PO;
1722 }
1723 OP(BYTECODE_OP_BIT_LSHIFT):
1724 {
1725 int64_t res;
1726
1727 if (!IS_INTEGER_REGISTER(estack_ax_t) || !IS_INTEGER_REGISTER(estack_bx_t)) {
1728 ret = -EINVAL;
1729 goto end;
1730 }
1731
1732 /* Catch undefined behavior. */
1733 if (caa_unlikely(estack_ax_v < 0 || estack_ax_v >= 64)) {
1734 ret = -EINVAL;
1735 goto end;
1736 }
1737 res = ((uint64_t) estack_bx_v << (uint32_t) estack_ax_v);
1738 estack_pop(stack, top, ax, bx, ax_t, bx_t);
1739 estack_ax_v = res;
1740 estack_ax_t = REG_U64;
1741 next_pc += sizeof(struct binary_op);
1742 PO;
1743 }
1744 OP(BYTECODE_OP_BIT_AND):
1745 {
1746 int64_t res;
1747
1748 if (!IS_INTEGER_REGISTER(estack_ax_t) || !IS_INTEGER_REGISTER(estack_bx_t)) {
1749 ret = -EINVAL;
1750 goto end;
1751 }
1752
1753 res = ((uint64_t) estack_bx_v & (uint64_t) estack_ax_v);
1754 estack_pop(stack, top, ax, bx, ax_t, bx_t);
1755 estack_ax_v = res;
1756 estack_ax_t = REG_U64;
1757 next_pc += sizeof(struct binary_op);
1758 PO;
1759 }
1760 OP(BYTECODE_OP_BIT_OR):
1761 {
1762 int64_t res;
1763
1764 if (!IS_INTEGER_REGISTER(estack_ax_t) || !IS_INTEGER_REGISTER(estack_bx_t)) {
1765 ret = -EINVAL;
1766 goto end;
1767 }
1768
1769 res = ((uint64_t) estack_bx_v | (uint64_t) estack_ax_v);
1770 estack_pop(stack, top, ax, bx, ax_t, bx_t);
1771 estack_ax_v = res;
1772 estack_ax_t = REG_U64;
1773 next_pc += sizeof(struct binary_op);
1774 PO;
1775 }
1776 OP(BYTECODE_OP_BIT_XOR):
1777 {
1778 int64_t res;
1779
1780 if (!IS_INTEGER_REGISTER(estack_ax_t) || !IS_INTEGER_REGISTER(estack_bx_t)) {
1781 ret = -EINVAL;
1782 goto end;
1783 }
1784
1785 res = ((uint64_t) estack_bx_v ^ (uint64_t) estack_ax_v);
1786 estack_pop(stack, top, ax, bx, ax_t, bx_t);
1787 estack_ax_v = res;
1788 estack_ax_t = REG_U64;
1789 next_pc += sizeof(struct binary_op);
1790 PO;
1791 }
1792
1793 /* unary */
1794 OP(BYTECODE_OP_UNARY_PLUS):
1795 {
1796 /* Dynamic typing. */
1797 switch (estack_ax_t) {
1798 case REG_S64: /* Fall-through. */
1799 case REG_U64:
1800 JUMP_TO(BYTECODE_OP_UNARY_PLUS_S64);
1801 case REG_DOUBLE:
1802 JUMP_TO(BYTECODE_OP_UNARY_PLUS_DOUBLE);
1803 case REG_STRING: /* Fall-through */
1804 case REG_STAR_GLOB_STRING:
1805 ret = -EINVAL;
1806 goto end;
1807 default:
1808 ERR("Unknown interpreter register type (%d)",
1809 (int) estack_ax_t);
1810 ret = -EINVAL;
1811 goto end;
1812 }
1813 }
1814 OP(BYTECODE_OP_UNARY_MINUS):
1815 {
1816 /* Dynamic typing. */
1817 switch (estack_ax_t) {
1818 case REG_S64: /* Fall-through. */
1819 case REG_U64:
1820 JUMP_TO(BYTECODE_OP_UNARY_MINUS_S64);
1821 case REG_DOUBLE:
1822 JUMP_TO(BYTECODE_OP_UNARY_MINUS_DOUBLE);
1823 case REG_STRING: /* Fall-through */
1824 case REG_STAR_GLOB_STRING:
1825 ret = -EINVAL;
1826 goto end;
1827 default:
1828 ERR("Unknown interpreter register type (%d)",
1829 (int) estack_ax_t);
1830 ret = -EINVAL;
1831 goto end;
1832 }
1833 }
1834 OP(BYTECODE_OP_UNARY_NOT):
1835 {
1836 /* Dynamic typing. */
1837 switch (estack_ax_t) {
1838 case REG_S64: /* Fall-through. */
1839 case REG_U64:
1840 JUMP_TO(BYTECODE_OP_UNARY_NOT_S64);
1841 case REG_DOUBLE:
1842 JUMP_TO(BYTECODE_OP_UNARY_NOT_DOUBLE);
1843 case REG_STRING: /* Fall-through */
1844 case REG_STAR_GLOB_STRING:
1845 ret = -EINVAL;
1846 goto end;
1847 default:
1848 ERR("Unknown interpreter register type (%d)",
1849 (int) estack_ax_t);
1850 ret = -EINVAL;
1851 goto end;
1852 }
1853 next_pc += sizeof(struct unary_op);
1854 PO;
1855 }
1856
1857 OP(BYTECODE_OP_UNARY_BIT_NOT):
1858 {
1859 /* Dynamic typing. */
1860 if (!IS_INTEGER_REGISTER(estack_ax_t)) {
1861 ret = -EINVAL;
1862 goto end;
1863 }
1864
1865 estack_ax_v = ~(uint64_t) estack_ax_v;
1866 estack_ax_t = REG_U64;
1867 next_pc += sizeof(struct unary_op);
1868 PO;
1869 }
1870
1871 OP(BYTECODE_OP_UNARY_PLUS_S64):
1872 OP(BYTECODE_OP_UNARY_PLUS_DOUBLE):
1873 {
1874 next_pc += sizeof(struct unary_op);
1875 PO;
1876 }
1877 OP(BYTECODE_OP_UNARY_MINUS_S64):
1878 {
1879 estack_ax_v = -estack_ax_v;
1880 next_pc += sizeof(struct unary_op);
1881 PO;
1882 }
1883 OP(BYTECODE_OP_UNARY_MINUS_DOUBLE):
1884 {
1885 estack_ax(stack, top)->u.d = -estack_ax(stack, top)->u.d;
1886 next_pc += sizeof(struct unary_op);
1887 PO;
1888 }
1889 OP(BYTECODE_OP_UNARY_NOT_S64):
1890 {
1891 estack_ax_v = !estack_ax_v;
1892 estack_ax_t = REG_S64;
1893 next_pc += sizeof(struct unary_op);
1894 PO;
1895 }
1896 OP(BYTECODE_OP_UNARY_NOT_DOUBLE):
1897 {
1898 estack_ax_v = !estack_ax(stack, top)->u.d;
1899 estack_ax_t = REG_S64;
1900 next_pc += sizeof(struct unary_op);
1901 PO;
1902 }
1903
1904 /* logical */
1905 OP(BYTECODE_OP_AND):
1906 {
1907 struct logical_op *insn = (struct logical_op *) pc;
1908
1909 if (estack_ax_t != REG_S64 && estack_ax_t != REG_U64) {
1910 ret = -EINVAL;
1911 goto end;
1912 }
1913 /* If AX is 0, skip and evaluate to 0 */
1914 if (unlikely(estack_ax_v == 0)) {
1915 dbg_printf("Jumping to bytecode offset %u\n",
1916 (unsigned int) insn->skip_offset);
1917 next_pc = start_pc + insn->skip_offset;
1918 } else {
1919 /* Pop 1 when jump not taken */
1920 estack_pop(stack, top, ax, bx, ax_t, bx_t);
1921 next_pc += sizeof(struct logical_op);
1922 }
1923 PO;
1924 }
1925 OP(BYTECODE_OP_OR):
1926 {
1927 struct logical_op *insn = (struct logical_op *) pc;
1928
1929 if (estack_ax_t != REG_S64 && estack_ax_t != REG_U64) {
1930 ret = -EINVAL;
1931 goto end;
1932 }
1933 /* If AX is nonzero, skip and evaluate to 1 */
1934 if (unlikely(estack_ax_v != 0)) {
1935 estack_ax_v = 1;
1936 dbg_printf("Jumping to bytecode offset %u\n",
1937 (unsigned int) insn->skip_offset);
1938 next_pc = start_pc + insn->skip_offset;
1939 } else {
1940 /* Pop 1 when jump not taken */
1941 estack_pop(stack, top, ax, bx, ax_t, bx_t);
1942 next_pc += sizeof(struct logical_op);
1943 }
1944 PO;
1945 }
1946
1947
1948 /* load field ref */
1949 OP(BYTECODE_OP_LOAD_FIELD_REF_STRING):
1950 {
1951 struct load_op *insn = (struct load_op *) pc;
1952 struct field_ref *ref = (struct field_ref *) insn->data;
1953
1954 dbg_printf("load field ref offset %u type string\n",
1955 ref->offset);
1956 estack_push(stack, top, ax, bx, ax_t, bx_t);
1957 estack_ax(stack, top)->u.s.str =
1958 *(const char * const *) &interpreter_stack_data[ref->offset];
1959 if (unlikely(!estack_ax(stack, top)->u.s.str)) {
1960 dbg_printf("Interpreter warning: loading a NULL string.\n");
1961 ret = -EINVAL;
1962 goto end;
1963 }
1964 estack_ax(stack, top)->u.s.seq_len = SIZE_MAX;
1965 estack_ax(stack, top)->u.s.literal_type =
1966 ESTACK_STRING_LITERAL_TYPE_NONE;
1967 estack_ax_t = REG_STRING;
1968 dbg_printf("ref load string %s\n", estack_ax(stack, top)->u.s.str);
1969 next_pc += sizeof(struct load_op) + sizeof(struct field_ref);
1970 PO;
1971 }
1972
1973 OP(BYTECODE_OP_LOAD_FIELD_REF_SEQUENCE):
1974 {
1975 struct load_op *insn = (struct load_op *) pc;
1976 struct field_ref *ref = (struct field_ref *) insn->data;
1977
1978 dbg_printf("load field ref offset %u type sequence\n",
1979 ref->offset);
1980 estack_push(stack, top, ax, bx, ax_t, bx_t);
1981 estack_ax(stack, top)->u.s.seq_len =
1982 *(unsigned long *) &interpreter_stack_data[ref->offset];
1983 estack_ax(stack, top)->u.s.str =
1984 *(const char **) (&interpreter_stack_data[ref->offset
1985 + sizeof(unsigned long)]);
1986 estack_ax_t = REG_STRING;
1987 if (unlikely(!estack_ax(stack, top)->u.s.str)) {
1988 dbg_printf("Interpreter warning: loading a NULL sequence.\n");
1989 ret = -EINVAL;
1990 goto end;
1991 }
1992 estack_ax(stack, top)->u.s.literal_type =
1993 ESTACK_STRING_LITERAL_TYPE_NONE;
1994 next_pc += sizeof(struct load_op) + sizeof(struct field_ref);
1995 PO;
1996 }
1997
1998 OP(BYTECODE_OP_LOAD_FIELD_REF_S64):
1999 {
2000 struct load_op *insn = (struct load_op *) pc;
2001 struct field_ref *ref = (struct field_ref *) insn->data;
2002
2003 dbg_printf("load field ref offset %u type s64\n",
2004 ref->offset);
2005 estack_push(stack, top, ax, bx, ax_t, bx_t);
2006 estack_ax_v =
2007 ((struct literal_numeric *) &interpreter_stack_data[ref->offset])->v;
2008 estack_ax_t = REG_S64;
2009 dbg_printf("ref load s64 %" PRIi64 "\n", estack_ax_v);
2010 next_pc += sizeof(struct load_op) + sizeof(struct field_ref);
2011 PO;
2012 }
2013
2014 OP(BYTECODE_OP_LOAD_FIELD_REF_DOUBLE):
2015 {
2016 struct load_op *insn = (struct load_op *) pc;
2017 struct field_ref *ref = (struct field_ref *) insn->data;
2018
2019 dbg_printf("load field ref offset %u type double\n",
2020 ref->offset);
2021 estack_push(stack, top, ax, bx, ax_t, bx_t);
2022 memcpy(&estack_ax(stack, top)->u.d, &interpreter_stack_data[ref->offset],
2023 sizeof(struct literal_double));
2024 estack_ax_t = REG_DOUBLE;
2025 dbg_printf("ref load double %g\n", estack_ax(stack, top)->u.d);
2026 next_pc += sizeof(struct load_op) + sizeof(struct field_ref);
2027 PO;
2028 }
2029
2030 /* load from immediate operand */
2031 OP(BYTECODE_OP_LOAD_STRING):
2032 {
2033 struct load_op *insn = (struct load_op *) pc;
2034
2035 dbg_printf("load string %s\n", insn->data);
2036 estack_push(stack, top, ax, bx, ax_t, bx_t);
2037 estack_ax(stack, top)->u.s.str = insn->data;
2038 estack_ax(stack, top)->u.s.seq_len = SIZE_MAX;
2039 estack_ax(stack, top)->u.s.literal_type =
2040 ESTACK_STRING_LITERAL_TYPE_PLAIN;
2041 estack_ax_t = REG_STRING;
2042 next_pc += sizeof(struct load_op) + strlen(insn->data) + 1;
2043 PO;
2044 }
2045
2046 OP(BYTECODE_OP_LOAD_STAR_GLOB_STRING):
2047 {
2048 struct load_op *insn = (struct load_op *) pc;
2049
2050 dbg_printf("load globbing pattern %s\n", insn->data);
2051 estack_push(stack, top, ax, bx, ax_t, bx_t);
2052 estack_ax(stack, top)->u.s.str = insn->data;
2053 estack_ax(stack, top)->u.s.seq_len = SIZE_MAX;
2054 estack_ax(stack, top)->u.s.literal_type =
2055 ESTACK_STRING_LITERAL_TYPE_STAR_GLOB;
2056 estack_ax_t = REG_STAR_GLOB_STRING;
2057 next_pc += sizeof(struct load_op) + strlen(insn->data) + 1;
2058 PO;
2059 }
2060
2061 OP(BYTECODE_OP_LOAD_S64):
2062 {
2063 struct load_op *insn = (struct load_op *) pc;
2064
2065 estack_push(stack, top, ax, bx, ax_t, bx_t);
2066 estack_ax_v = ((struct literal_numeric *) insn->data)->v;
2067 estack_ax_t = REG_S64;
2068 dbg_printf("load s64 %" PRIi64 "\n", estack_ax_v);
2069 next_pc += sizeof(struct load_op)
2070 + sizeof(struct literal_numeric);
2071 PO;
2072 }
2073
2074 OP(BYTECODE_OP_LOAD_DOUBLE):
2075 {
2076 struct load_op *insn = (struct load_op *) pc;
2077
2078 estack_push(stack, top, ax, bx, ax_t, bx_t);
2079 memcpy(&estack_ax(stack, top)->u.d, insn->data,
2080 sizeof(struct literal_double));
2081 estack_ax_t = REG_DOUBLE;
2082 dbg_printf("load double %g\n", estack_ax(stack, top)->u.d);
2083 next_pc += sizeof(struct load_op)
2084 + sizeof(struct literal_double);
2085 PO;
2086 }
2087
2088 /* cast */
2089 OP(BYTECODE_OP_CAST_TO_S64):
2090 {
2091 /* Dynamic typing. */
2092 switch (estack_ax_t) {
2093 case REG_S64:
2094 JUMP_TO(BYTECODE_OP_CAST_NOP);
2095 case REG_DOUBLE:
2096 JUMP_TO(BYTECODE_OP_CAST_DOUBLE_TO_S64);
2097 case REG_U64:
2098 estack_ax_t = REG_S64;
2099 next_pc += sizeof(struct cast_op);
2100 case REG_STRING: /* Fall-through */
2101 case REG_STAR_GLOB_STRING:
2102 ret = -EINVAL;
2103 goto end;
2104 default:
2105 ERR("Unknown interpreter register type (%d)",
2106 (int) estack_ax_t);
2107 ret = -EINVAL;
2108 goto end;
2109 }
2110 }
2111
2112 OP(BYTECODE_OP_CAST_DOUBLE_TO_S64):
2113 {
2114 estack_ax_v = (int64_t) estack_ax(stack, top)->u.d;
2115 estack_ax_t = REG_S64;
2116 next_pc += sizeof(struct cast_op);
2117 PO;
2118 }
2119
2120 OP(BYTECODE_OP_CAST_NOP):
2121 {
2122 next_pc += sizeof(struct cast_op);
2123 PO;
2124 }
2125
2126 /* get context ref */
2127 OP(BYTECODE_OP_GET_CONTEXT_REF):
2128 {
2129 struct load_op *insn = (struct load_op *) pc;
2130 struct field_ref *ref = (struct field_ref *) insn->data;
2131 struct lttng_ust_ctx_field *ctx_field;
2132 struct lttng_ust_ctx_value v;
2133
2134 dbg_printf("get context ref offset %u type dynamic\n",
2135 ref->offset);
2136 ctx_field = ctx->fields[ref->offset];
2137 ctx_field->get_value(ctx_field, &v);
2138 estack_push(stack, top, ax, bx, ax_t, bx_t);
2139 switch (v.sel) {
2140 case LTTNG_UST_DYNAMIC_TYPE_NONE:
2141 ret = -EINVAL;
2142 goto end;
2143 case LTTNG_UST_DYNAMIC_TYPE_S64:
2144 estack_ax_v = v.u.s64;
2145 estack_ax_t = REG_S64;
2146 dbg_printf("ref get context dynamic s64 %" PRIi64 "\n", estack_ax_v);
2147 break;
2148 case LTTNG_UST_DYNAMIC_TYPE_DOUBLE:
2149 estack_ax(stack, top)->u.d = v.u.d;
2150 estack_ax_t = REG_DOUBLE;
2151 dbg_printf("ref get context dynamic double %g\n", estack_ax(stack, top)->u.d);
2152 break;
2153 case LTTNG_UST_DYNAMIC_TYPE_STRING:
2154 estack_ax(stack, top)->u.s.str = v.u.str;
2155 if (unlikely(!estack_ax(stack, top)->u.s.str)) {
2156 dbg_printf("Interpreter warning: loading a NULL string.\n");
2157 ret = -EINVAL;
2158 goto end;
2159 }
2160 estack_ax(stack, top)->u.s.seq_len = SIZE_MAX;
2161 estack_ax(stack, top)->u.s.literal_type =
2162 ESTACK_STRING_LITERAL_TYPE_NONE;
2163 dbg_printf("ref get context dynamic string %s\n", estack_ax(stack, top)->u.s.str);
2164 estack_ax_t = REG_STRING;
2165 break;
2166 default:
2167 dbg_printf("Interpreter warning: unknown dynamic type (%d).\n", (int) v.sel);
2168 ret = -EINVAL;
2169 goto end;
2170 }
2171 next_pc += sizeof(struct load_op) + sizeof(struct field_ref);
2172 PO;
2173 }
2174
2175 OP(BYTECODE_OP_GET_CONTEXT_REF_STRING):
2176 {
2177 struct load_op *insn = (struct load_op *) pc;
2178 struct field_ref *ref = (struct field_ref *) insn->data;
2179 struct lttng_ust_ctx_field *ctx_field;
2180 struct lttng_ust_ctx_value v;
2181
2182 dbg_printf("get context ref offset %u type string\n",
2183 ref->offset);
2184 ctx_field = ctx->fields[ref->offset];
2185 ctx_field->get_value(ctx_field, &v);
2186 estack_push(stack, top, ax, bx, ax_t, bx_t);
2187 estack_ax(stack, top)->u.s.str = v.u.str;
2188 if (unlikely(!estack_ax(stack, top)->u.s.str)) {
2189 dbg_printf("Interpreter warning: loading a NULL string.\n");
2190 ret = -EINVAL;
2191 goto end;
2192 }
2193 estack_ax(stack, top)->u.s.seq_len = SIZE_MAX;
2194 estack_ax(stack, top)->u.s.literal_type =
2195 ESTACK_STRING_LITERAL_TYPE_NONE;
2196 estack_ax_t = REG_STRING;
2197 dbg_printf("ref get context string %s\n", estack_ax(stack, top)->u.s.str);
2198 next_pc += sizeof(struct load_op) + sizeof(struct field_ref);
2199 PO;
2200 }
2201
2202 OP(BYTECODE_OP_GET_CONTEXT_REF_S64):
2203 {
2204 struct load_op *insn = (struct load_op *) pc;
2205 struct field_ref *ref = (struct field_ref *) insn->data;
2206 struct lttng_ust_ctx_field *ctx_field;
2207 struct lttng_ust_ctx_value v;
2208
2209 dbg_printf("get context ref offset %u type s64\n",
2210 ref->offset);
2211 ctx_field = ctx->fields[ref->offset];
2212 ctx_field->get_value(ctx_field, &v);
2213 estack_push(stack, top, ax, bx, ax_t, bx_t);
2214 estack_ax_v = v.u.s64;
2215 estack_ax_t = REG_S64;
2216 dbg_printf("ref get context s64 %" PRIi64 "\n", estack_ax_v);
2217 next_pc += sizeof(struct load_op) + sizeof(struct field_ref);
2218 PO;
2219 }
2220
2221 OP(BYTECODE_OP_GET_CONTEXT_REF_DOUBLE):
2222 {
2223 struct load_op *insn = (struct load_op *) pc;
2224 struct field_ref *ref = (struct field_ref *) insn->data;
2225 struct lttng_ust_ctx_field *ctx_field;
2226 struct lttng_ust_ctx_value v;
2227
2228 dbg_printf("get context ref offset %u type double\n",
2229 ref->offset);
2230 ctx_field = ctx->fields[ref->offset];
2231 ctx_field->get_value(ctx_field, &v);
2232 estack_push(stack, top, ax, bx, ax_t, bx_t);
2233 memcpy(&estack_ax(stack, top)->u.d, &v.u.d, sizeof(struct literal_double));
2234 estack_ax_t = REG_DOUBLE;
2235 dbg_printf("ref get context double %g\n", estack_ax(stack, top)->u.d);
2236 next_pc += sizeof(struct load_op) + sizeof(struct field_ref);
2237 PO;
2238 }
2239
2240 OP(BYTECODE_OP_GET_CONTEXT_ROOT):
2241 {
2242 dbg_printf("op get context root\n");
2243 estack_push(stack, top, ax, bx, ax_t, bx_t);
2244 estack_ax(stack, top)->u.ptr.type = LOAD_ROOT_CONTEXT;
2245 /* "field" only needed for variants. */
2246 estack_ax(stack, top)->u.ptr.field = NULL;
2247 estack_ax_t = REG_PTR;
2248 next_pc += sizeof(struct load_op);
2249 PO;
2250 }
2251
2252 OP(BYTECODE_OP_GET_APP_CONTEXT_ROOT):
2253 {
2254 dbg_printf("op get app context root\n");
2255 estack_push(stack, top, ax, bx, ax_t, bx_t);
2256 estack_ax(stack, top)->u.ptr.type = LOAD_ROOT_APP_CONTEXT;
2257 /* "field" only needed for variants. */
2258 estack_ax(stack, top)->u.ptr.field = NULL;
2259 estack_ax_t = REG_PTR;
2260 next_pc += sizeof(struct load_op);
2261 PO;
2262 }
2263
2264 OP(BYTECODE_OP_GET_PAYLOAD_ROOT):
2265 {
2266 dbg_printf("op get app payload root\n");
2267 estack_push(stack, top, ax, bx, ax_t, bx_t);
2268 estack_ax(stack, top)->u.ptr.type = LOAD_ROOT_PAYLOAD;
2269 estack_ax(stack, top)->u.ptr.ptr = interpreter_stack_data;
2270 /* "field" only needed for variants. */
2271 estack_ax(stack, top)->u.ptr.field = NULL;
2272 estack_ax_t = REG_PTR;
2273 next_pc += sizeof(struct load_op);
2274 PO;
2275 }
2276
2277 OP(BYTECODE_OP_GET_SYMBOL):
2278 {
2279 dbg_printf("op get symbol\n");
2280 switch (estack_ax(stack, top)->u.ptr.type) {
2281 case LOAD_OBJECT:
2282 ERR("Nested fields not implemented yet.");
2283 ret = -EINVAL;
2284 goto end;
2285 case LOAD_ROOT_CONTEXT:
2286 case LOAD_ROOT_APP_CONTEXT:
2287 case LOAD_ROOT_PAYLOAD:
2288 /*
2289 * symbol lookup is performed by
2290 * specialization.
2291 */
2292 ret = -EINVAL;
2293 goto end;
2294 }
2295 next_pc += sizeof(struct load_op) + sizeof(struct get_symbol);
2296 PO;
2297 }
2298
2299 OP(BYTECODE_OP_GET_SYMBOL_FIELD):
2300 {
2301 /*
2302 * Used for first variant encountered in a
2303 * traversal. Variants are not implemented yet.
2304 */
2305 ret = -EINVAL;
2306 goto end;
2307 }
2308
2309 OP(BYTECODE_OP_GET_INDEX_U16):
2310 {
2311 struct load_op *insn = (struct load_op *) pc;
2312 struct get_index_u16 *index = (struct get_index_u16 *) insn->data;
2313
2314 dbg_printf("op get index u16\n");
2315 ret = dynamic_get_index(ctx, bytecode, index->index, estack_ax(stack, top));
2316 if (ret)
2317 goto end;
2318 estack_ax_v = estack_ax(stack, top)->u.v;
2319 estack_ax_t = estack_ax(stack, top)->type;
2320 next_pc += sizeof(struct load_op) + sizeof(struct get_index_u16);
2321 PO;
2322 }
2323
2324 OP(BYTECODE_OP_GET_INDEX_U64):
2325 {
2326 struct load_op *insn = (struct load_op *) pc;
2327 struct get_index_u64 *index = (struct get_index_u64 *) insn->data;
2328
2329 dbg_printf("op get index u64\n");
2330 ret = dynamic_get_index(ctx, bytecode, index->index, estack_ax(stack, top));
2331 if (ret)
2332 goto end;
2333 estack_ax_v = estack_ax(stack, top)->u.v;
2334 estack_ax_t = estack_ax(stack, top)->type;
2335 next_pc += sizeof(struct load_op) + sizeof(struct get_index_u64);
2336 PO;
2337 }
2338
2339 OP(BYTECODE_OP_LOAD_FIELD):
2340 {
2341 dbg_printf("op load field\n");
2342 ret = dynamic_load_field(estack_ax(stack, top));
2343 if (ret)
2344 goto end;
2345 estack_ax_v = estack_ax(stack, top)->u.v;
2346 estack_ax_t = estack_ax(stack, top)->type;
2347 next_pc += sizeof(struct load_op);
2348 PO;
2349 }
2350
2351 OP(BYTECODE_OP_LOAD_FIELD_S8):
2352 {
2353 dbg_printf("op load field s8\n");
2354
2355 estack_ax_v = *(int8_t *) estack_ax(stack, top)->u.ptr.ptr;
2356 estack_ax_t = REG_S64;
2357 next_pc += sizeof(struct load_op);
2358 PO;
2359 }
2360 OP(BYTECODE_OP_LOAD_FIELD_S16):
2361 {
2362 dbg_printf("op load field s16\n");
2363
2364 estack_ax_v = *(int16_t *) estack_ax(stack, top)->u.ptr.ptr;
2365 estack_ax_t = REG_S64;
2366 next_pc += sizeof(struct load_op);
2367 PO;
2368 }
2369 OP(BYTECODE_OP_LOAD_FIELD_S32):
2370 {
2371 dbg_printf("op load field s32\n");
2372
2373 estack_ax_v = *(int32_t *) estack_ax(stack, top)->u.ptr.ptr;
2374 estack_ax_t = REG_S64;
2375 next_pc += sizeof(struct load_op);
2376 PO;
2377 }
2378 OP(BYTECODE_OP_LOAD_FIELD_S64):
2379 {
2380 dbg_printf("op load field s64\n");
2381
2382 estack_ax_v = *(int64_t *) estack_ax(stack, top)->u.ptr.ptr;
2383 estack_ax_t = REG_S64;
2384 next_pc += sizeof(struct load_op);
2385 PO;
2386 }
2387 OP(BYTECODE_OP_LOAD_FIELD_U8):
2388 {
2389 dbg_printf("op load field u8\n");
2390
2391 estack_ax_v = *(uint8_t *) estack_ax(stack, top)->u.ptr.ptr;
2392 estack_ax_t = REG_U64;
2393 next_pc += sizeof(struct load_op);
2394 PO;
2395 }
2396 OP(BYTECODE_OP_LOAD_FIELD_U16):
2397 {
2398 dbg_printf("op load field u16\n");
2399
2400 estack_ax_v = *(uint16_t *) estack_ax(stack, top)->u.ptr.ptr;
2401 estack_ax_t = REG_U64;
2402 next_pc += sizeof(struct load_op);
2403 PO;
2404 }
2405 OP(BYTECODE_OP_LOAD_FIELD_U32):
2406 {
2407 dbg_printf("op load field u32\n");
2408
2409 estack_ax_v = *(uint32_t *) estack_ax(stack, top)->u.ptr.ptr;
2410 estack_ax_t = REG_U64;
2411 next_pc += sizeof(struct load_op);
2412 PO;
2413 }
2414 OP(BYTECODE_OP_LOAD_FIELD_U64):
2415 {
2416 dbg_printf("op load field u64\n");
2417
2418 estack_ax_v = *(uint64_t *) estack_ax(stack, top)->u.ptr.ptr;
2419 estack_ax_t = REG_U64;
2420 next_pc += sizeof(struct load_op);
2421 PO;
2422 }
2423 OP(BYTECODE_OP_LOAD_FIELD_DOUBLE):
2424 {
2425 dbg_printf("op load field double\n");
2426
2427 memcpy(&estack_ax(stack, top)->u.d,
2428 estack_ax(stack, top)->u.ptr.ptr,
2429 sizeof(struct literal_double));
2430 estack_ax(stack, top)->type = REG_DOUBLE;
2431 next_pc += sizeof(struct load_op);
2432 PO;
2433 }
2434
2435 OP(BYTECODE_OP_LOAD_FIELD_STRING):
2436 {
2437 const char *str;
2438
2439 dbg_printf("op load field string\n");
2440 str = (const char *) estack_ax(stack, top)->u.ptr.ptr;
2441 estack_ax(stack, top)->u.s.str = str;
2442 if (unlikely(!estack_ax(stack, top)->u.s.str)) {
2443 dbg_printf("Interpreter warning: loading a NULL string.\n");
2444 ret = -EINVAL;
2445 goto end;
2446 }
2447 estack_ax(stack, top)->u.s.seq_len = SIZE_MAX;
2448 estack_ax(stack, top)->u.s.literal_type =
2449 ESTACK_STRING_LITERAL_TYPE_NONE;
2450 estack_ax(stack, top)->type = REG_STRING;
2451 next_pc += sizeof(struct load_op);
2452 PO;
2453 }
2454
2455 OP(BYTECODE_OP_LOAD_FIELD_SEQUENCE):
2456 {
2457 const char *ptr;
2458
2459 dbg_printf("op load field string sequence\n");
2460 ptr = estack_ax(stack, top)->u.ptr.ptr;
2461 estack_ax(stack, top)->u.s.seq_len = *(unsigned long *) ptr;
2462 estack_ax(stack, top)->u.s.str = *(const char **) (ptr + sizeof(unsigned long));
2463 estack_ax(stack, top)->type = REG_STRING;
2464 if (unlikely(!estack_ax(stack, top)->u.s.str)) {
2465 dbg_printf("Interpreter warning: loading a NULL sequence.\n");
2466 ret = -EINVAL;
2467 goto end;
2468 }
2469 estack_ax(stack, top)->u.s.literal_type =
2470 ESTACK_STRING_LITERAL_TYPE_NONE;
2471 next_pc += sizeof(struct load_op);
2472 PO;
2473 }
2474
2475 END_OP
2476 end:
2477 /* No need to prepare output if an error occurred. */
2478 if (ret)
2479 return LTTNG_UST_BYTECODE_INTERPRETER_ERROR;
2480
2481 /* Prepare output. */
2482 switch (ust_bytecode->priv->type) {
2483 case LTTNG_UST_BYTECODE_TYPE_FILTER:
2484 {
2485 struct lttng_ust_bytecode_filter_ctx *filter_ctx =
2486 (struct lttng_ust_bytecode_filter_ctx *) caller_ctx;
2487 if (retval)
2488 filter_ctx->result = LTTNG_UST_BYTECODE_FILTER_ACCEPT;
2489 else
2490 filter_ctx->result = LTTNG_UST_BYTECODE_FILTER_REJECT;
2491 break;
2492 }
2493 case LTTNG_UST_BYTECODE_TYPE_CAPTURE:
2494 ret = lttng_bytecode_interpret_format_output(estack_ax(stack, top),
2495 (struct lttng_interpreter_output *) caller_ctx);
2496 break;
2497 default:
2498 ret = -EINVAL;
2499 break;
2500 }
2501 if (ret)
2502 return LTTNG_UST_BYTECODE_INTERPRETER_ERROR;
2503 else
2504 return LTTNG_UST_BYTECODE_INTERPRETER_OK;
2505 }
2506
2507 #undef START_OP
2508 #undef OP
2509 #undef PO
2510 #undef END_OP
This page took 0.103575 seconds and 4 git commands to generate.