Fix: pass private data to context callbacks
[lttng-ust.git] / liblttng-ust / lttng-bytecode-validator.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 validator.
97b58163
MD
7 */
8
bf956ec0 9#define _LGPL_SOURCE
b4051ad8 10#include <stddef.h>
fb31eb73 11#include <stdint.h>
bf956ec0 12#include <time.h>
97b58163 13
10544ee8 14#include "rculfhash.h"
fb31eb73 15
04aa13f8 16#include "lttng-bytecode.h"
bf956ec0 17#include "lttng-hash-helper.h"
3151a51d 18#include "string-utils.h"
92495593 19#include "ust-events-internal.h"
ddabe860 20#include "ust-helper.h"
bf956ec0 21
0305960f
MD
22/*
23 * Number of merge points for hash table size. Hash table initialized to
24 * that size, and we do not resize, because we do not want to trigger
25 * RCU worker thread execution: fall-back on linear traversal if number
26 * of merge points exceeds this value.
27 */
28#define DEFAULT_NR_MERGE_POINTS 128
29#define MIN_NR_BUCKETS 128
30#define MAX_NR_BUCKETS 128
31
bf956ec0
MD
32/* merge point table node */
33struct lfht_mp_node {
10544ee8 34 struct lttng_ust_lfht_node node;
bf956ec0
MD
35
36 /* Context at merge point */
0305960f 37 struct vstack stack;
bf956ec0
MD
38 unsigned long target_pc;
39};
40
41static unsigned long lttng_hash_seed;
42static unsigned int lttng_hash_seed_ready;
43
44static
10544ee8 45int lttng_hash_match(struct lttng_ust_lfht_node *node, const void *key)
bf956ec0
MD
46{
47 struct lfht_mp_node *mp_node =
48 caa_container_of(node, struct lfht_mp_node, node);
49 unsigned long key_pc = (unsigned long) key;
50
51 if (mp_node->target_pc == key_pc)
52 return 1;
53 else
54 return 0;
55}
56
57static
71c1ceeb
MD
58int merge_points_compare(const struct vstack *stacka,
59 const struct vstack *stackb)
60{
61 int i, len;
62
63 if (stacka->top != stackb->top)
64 return 1;
65 len = stacka->top + 1;
66 assert(len >= 0);
67 for (i = 0; i < len; i++) {
53569322
MD
68 if (stacka->e[i].type != REG_UNKNOWN
69 && stackb->e[i].type != REG_UNKNOWN
70 && stacka->e[i].type != stackb->e[i].type)
71c1ceeb
MD
71 return 1;
72 }
73 return 0;
74}
75
76static
10544ee8 77int merge_point_add_check(struct lttng_ust_lfht *ht, unsigned long target_pc,
0305960f 78 const struct vstack *stack)
bf956ec0
MD
79{
80 struct lfht_mp_node *node;
22389ecb 81 unsigned long hash = lttng_hash_mix((const char *) target_pc,
bf956ec0
MD
82 sizeof(target_pc),
83 lttng_hash_seed);
10544ee8 84 struct lttng_ust_lfht_node *ret;
bf956ec0 85
04aa13f8 86 dbg_printf("Bytecode: adding merge point at offset %lu, hash %lu\n",
bf956ec0
MD
87 target_pc, hash);
88 node = zmalloc(sizeof(struct lfht_mp_node));
89 if (!node)
90 return -ENOMEM;
91 node->target_pc = target_pc;
0305960f 92 memcpy(&node->stack, stack, sizeof(node->stack));
10544ee8 93 ret = lttng_ust_lfht_add_unique(ht, hash, lttng_hash_match,
22389ecb 94 (const char *) target_pc, &node->node);
71c1ceeb
MD
95 if (ret != &node->node) {
96 struct lfht_mp_node *ret_mp =
97 caa_container_of(ret, struct lfht_mp_node, node);
98
99 /* Key already present */
04aa13f8 100 dbg_printf("Bytecode: compare merge points for offset %lu, hash %lu\n",
71c1ceeb
MD
101 target_pc, hash);
102 free(node);
103 if (merge_points_compare(stack, &ret_mp->stack)) {
104 ERR("Merge points differ for offset %lu\n",
105 target_pc);
106 return -EINVAL;
107 }
108 }
bf956ec0
MD
109 return 0;
110}
111
112/*
0305960f 113 * Binary comparators use top of stack and top of stack -1.
53569322
MD
114 * Return 0 if typing is known to match, 1 if typing is dynamic
115 * (unknown), negative error value on error.
bf956ec0 116 */
97b58163 117static
04aa13f8 118int bin_op_compare_check(struct vstack *stack, bytecode_opcode_t opcode,
3151a51d 119 const char *str)
97b58163 120{
0305960f 121 if (unlikely(!vstack_ax(stack) || !vstack_bx(stack)))
53569322 122 goto error_empty;
0305960f
MD
123
124 switch (vstack_ax(stack)->type) {
97b58163 125 default:
53569322 126 goto error_type;
97b58163 127
53569322
MD
128 case REG_UNKNOWN:
129 goto unknown;
97b58163 130 case REG_STRING:
0305960f 131 switch (vstack_bx(stack)->type) {
97b58163 132 default:
53569322 133 goto error_type;
97b58163 134
53569322
MD
135 case REG_UNKNOWN:
136 goto unknown;
97b58163
MD
137 case REG_STRING:
138 break;
3151a51d 139 case REG_STAR_GLOB_STRING:
04aa13f8 140 if (opcode != BYTECODE_OP_EQ && opcode != BYTECODE_OP_NE) {
3151a51d
PP
141 goto error_mismatch;
142 }
143 break;
144 case REG_S64:
d97f9b78 145 case REG_U64:
3151a51d
PP
146 case REG_DOUBLE:
147 goto error_mismatch;
148 }
149 break;
150 case REG_STAR_GLOB_STRING:
151 switch (vstack_bx(stack)->type) {
152 default:
153 goto error_type;
154
155 case REG_UNKNOWN:
156 goto unknown;
157 case REG_STRING:
04aa13f8 158 if (opcode != BYTECODE_OP_EQ && opcode != BYTECODE_OP_NE) {
3151a51d
PP
159 goto error_mismatch;
160 }
161 break;
162 case REG_STAR_GLOB_STRING:
97b58163 163 case REG_S64:
d97f9b78 164 case REG_U64:
97b58163
MD
165 case REG_DOUBLE:
166 goto error_mismatch;
167 }
168 break;
169 case REG_S64:
d97f9b78 170 case REG_U64:
97b58163 171 case REG_DOUBLE:
0305960f 172 switch (vstack_bx(stack)->type) {
97b58163 173 default:
53569322 174 goto error_type;
97b58163 175
53569322
MD
176 case REG_UNKNOWN:
177 goto unknown;
97b58163 178 case REG_STRING:
3151a51d 179 case REG_STAR_GLOB_STRING:
97b58163 180 goto error_mismatch;
97b58163 181 case REG_S64:
d97f9b78 182 case REG_U64:
97b58163
MD
183 case REG_DOUBLE:
184 break;
185 }
186 break;
187 }
188 return 0;
189
53569322
MD
190unknown:
191 return 1;
0305960f 192
97b58163
MD
193error_mismatch:
194 ERR("type mismatch for '%s' binary operator\n", str);
195 return -EINVAL;
53569322
MD
196
197error_empty:
198 ERR("empty stack for '%s' binary operator\n", str);
199 return -EINVAL;
200
201error_type:
202 ERR("unknown type for '%s' binary operator\n", str);
203 return -EINVAL;
97b58163
MD
204}
205
47e5f13e
MD
206/*
207 * Binary bitwise operators use top of stack and top of stack -1.
208 * Return 0 if typing is known to match, 1 if typing is dynamic
209 * (unknown), negative error value on error.
210 */
211static
2208d8b5
MJ
212int bin_op_bitwise_check(struct vstack *stack,
213 bytecode_opcode_t opcode __attribute__((unused)),
47e5f13e
MD
214 const char *str)
215{
216 if (unlikely(!vstack_ax(stack) || !vstack_bx(stack)))
217 goto error_empty;
218
219 switch (vstack_ax(stack)->type) {
220 default:
221 goto error_type;
222
223 case REG_UNKNOWN:
224 goto unknown;
225 case REG_S64:
d97f9b78 226 case REG_U64:
47e5f13e
MD
227 switch (vstack_bx(stack)->type) {
228 default:
229 goto error_type;
230
231 case REG_UNKNOWN:
232 goto unknown;
233 case REG_S64:
d97f9b78 234 case REG_U64:
47e5f13e
MD
235 break;
236 }
237 break;
238 }
239 return 0;
240
241unknown:
242 return 1;
243
244error_empty:
245 ERR("empty stack for '%s' binary operator\n", str);
246 return -EINVAL;
247
248error_type:
249 ERR("unknown type for '%s' binary operator\n", str);
250 return -EINVAL;
251}
252
253static
254int validate_get_symbol(struct bytecode_runtime *bytecode,
255 const struct get_symbol *sym)
256{
257 const char *str, *str_limit;
258 size_t len_limit;
259
a2e4d05e 260 if (sym->offset >= bytecode->p.bc->bc.len - bytecode->p.bc->bc.reloc_offset)
47e5f13e
MD
261 return -EINVAL;
262
a2e4d05e
MD
263 str = bytecode->p.bc->bc.data + bytecode->p.bc->bc.reloc_offset + sym->offset;
264 str_limit = bytecode->p.bc->bc.data + bytecode->p.bc->bc.len;
47e5f13e
MD
265 len_limit = str_limit - str;
266 if (strnlen(str, len_limit) == len_limit)
267 return -EINVAL;
268 return 0;
269}
270
97b58163
MD
271/*
272 * Validate bytecode range overflow within the validation pass.
273 * Called for each instruction encountered.
274 */
275static
276int bytecode_validate_overflow(struct bytecode_runtime *bytecode,
22389ecb 277 char *start_pc, char *pc)
97b58163
MD
278{
279 int ret = 0;
280
04aa13f8
FD
281 switch (*(bytecode_opcode_t *) pc) {
282 case BYTECODE_OP_UNKNOWN:
97b58163
MD
283 default:
284 {
285 ERR("unknown bytecode op %u\n",
04aa13f8 286 (unsigned int) *(bytecode_opcode_t *) pc);
97b58163
MD
287 ret = -EINVAL;
288 break;
289 }
290
04aa13f8
FD
291 case BYTECODE_OP_RETURN:
292 case BYTECODE_OP_RETURN_S64:
97b58163
MD
293 {
294 if (unlikely(pc + sizeof(struct return_op)
295 > start_pc + bytecode->len)) {
82513dbe 296 ret = -ERANGE;
97b58163
MD
297 }
298 break;
299 }
300
301 /* binary */
04aa13f8
FD
302 case BYTECODE_OP_MUL:
303 case BYTECODE_OP_DIV:
304 case BYTECODE_OP_MOD:
305 case BYTECODE_OP_PLUS:
306 case BYTECODE_OP_MINUS:
97b58163
MD
307 {
308 ERR("unsupported bytecode op %u\n",
04aa13f8 309 (unsigned int) *(bytecode_opcode_t *) pc);
97b58163
MD
310 ret = -EINVAL;
311 break;
312 }
313
04aa13f8
FD
314 case BYTECODE_OP_EQ:
315 case BYTECODE_OP_NE:
316 case BYTECODE_OP_GT:
317 case BYTECODE_OP_LT:
318 case BYTECODE_OP_GE:
319 case BYTECODE_OP_LE:
320 case BYTECODE_OP_EQ_STRING:
321 case BYTECODE_OP_NE_STRING:
322 case BYTECODE_OP_GT_STRING:
323 case BYTECODE_OP_LT_STRING:
324 case BYTECODE_OP_GE_STRING:
325 case BYTECODE_OP_LE_STRING:
326 case BYTECODE_OP_EQ_STAR_GLOB_STRING:
327 case BYTECODE_OP_NE_STAR_GLOB_STRING:
328 case BYTECODE_OP_EQ_S64:
329 case BYTECODE_OP_NE_S64:
330 case BYTECODE_OP_GT_S64:
331 case BYTECODE_OP_LT_S64:
332 case BYTECODE_OP_GE_S64:
333 case BYTECODE_OP_LE_S64:
334 case BYTECODE_OP_EQ_DOUBLE:
335 case BYTECODE_OP_NE_DOUBLE:
336 case BYTECODE_OP_GT_DOUBLE:
337 case BYTECODE_OP_LT_DOUBLE:
338 case BYTECODE_OP_GE_DOUBLE:
339 case BYTECODE_OP_LE_DOUBLE:
340 case BYTECODE_OP_EQ_DOUBLE_S64:
341 case BYTECODE_OP_NE_DOUBLE_S64:
342 case BYTECODE_OP_GT_DOUBLE_S64:
343 case BYTECODE_OP_LT_DOUBLE_S64:
344 case BYTECODE_OP_GE_DOUBLE_S64:
345 case BYTECODE_OP_LE_DOUBLE_S64:
346 case BYTECODE_OP_EQ_S64_DOUBLE:
347 case BYTECODE_OP_NE_S64_DOUBLE:
348 case BYTECODE_OP_GT_S64_DOUBLE:
349 case BYTECODE_OP_LT_S64_DOUBLE:
350 case BYTECODE_OP_GE_S64_DOUBLE:
351 case BYTECODE_OP_LE_S64_DOUBLE:
352 case BYTECODE_OP_BIT_RSHIFT:
353 case BYTECODE_OP_BIT_LSHIFT:
354 case BYTECODE_OP_BIT_AND:
355 case BYTECODE_OP_BIT_OR:
356 case BYTECODE_OP_BIT_XOR:
97b58163
MD
357 {
358 if (unlikely(pc + sizeof(struct binary_op)
359 > start_pc + bytecode->len)) {
82513dbe 360 ret = -ERANGE;
97b58163
MD
361 }
362 break;
363 }
364
365 /* unary */
04aa13f8
FD
366 case BYTECODE_OP_UNARY_PLUS:
367 case BYTECODE_OP_UNARY_MINUS:
368 case BYTECODE_OP_UNARY_NOT:
369 case BYTECODE_OP_UNARY_PLUS_S64:
370 case BYTECODE_OP_UNARY_MINUS_S64:
371 case BYTECODE_OP_UNARY_NOT_S64:
372 case BYTECODE_OP_UNARY_PLUS_DOUBLE:
373 case BYTECODE_OP_UNARY_MINUS_DOUBLE:
374 case BYTECODE_OP_UNARY_NOT_DOUBLE:
375 case BYTECODE_OP_UNARY_BIT_NOT:
97b58163
MD
376 {
377 if (unlikely(pc + sizeof(struct unary_op)
378 > start_pc + bytecode->len)) {
82513dbe 379 ret = -ERANGE;
97b58163
MD
380 }
381 break;
382 }
383
384 /* logical */
04aa13f8
FD
385 case BYTECODE_OP_AND:
386 case BYTECODE_OP_OR:
97b58163
MD
387 {
388 if (unlikely(pc + sizeof(struct logical_op)
389 > start_pc + bytecode->len)) {
82513dbe 390 ret = -ERANGE;
97b58163
MD
391 }
392 break;
393 }
394
77aa5901 395 /* load field ref */
04aa13f8 396 case BYTECODE_OP_LOAD_FIELD_REF:
97b58163
MD
397 {
398 ERR("Unknown field ref type\n");
399 ret = -EINVAL;
400 break;
401 }
47e5f13e 402
77aa5901 403 /* get context ref */
04aa13f8
FD
404 case BYTECODE_OP_GET_CONTEXT_REF:
405 case BYTECODE_OP_LOAD_FIELD_REF_STRING:
406 case BYTECODE_OP_LOAD_FIELD_REF_SEQUENCE:
407 case BYTECODE_OP_LOAD_FIELD_REF_S64:
408 case BYTECODE_OP_LOAD_FIELD_REF_DOUBLE:
409 case BYTECODE_OP_GET_CONTEXT_REF_STRING:
410 case BYTECODE_OP_GET_CONTEXT_REF_S64:
411 case BYTECODE_OP_GET_CONTEXT_REF_DOUBLE:
97b58163
MD
412 {
413 if (unlikely(pc + sizeof(struct load_op) + sizeof(struct field_ref)
414 > start_pc + bytecode->len)) {
82513dbe 415 ret = -ERANGE;
97b58163
MD
416 }
417 break;
418 }
419
77aa5901 420 /* load from immediate operand */
04aa13f8
FD
421 case BYTECODE_OP_LOAD_STRING:
422 case BYTECODE_OP_LOAD_STAR_GLOB_STRING:
97b58163
MD
423 {
424 struct load_op *insn = (struct load_op *) pc;
425 uint32_t str_len, maxlen;
426
427 if (unlikely(pc + sizeof(struct load_op)
428 > start_pc + bytecode->len)) {
82513dbe 429 ret = -ERANGE;
97b58163
MD
430 break;
431 }
432
433 maxlen = start_pc + bytecode->len - pc - sizeof(struct load_op);
434 str_len = strnlen(insn->data, maxlen);
435 if (unlikely(str_len >= maxlen)) {
436 /* Final '\0' not found within range */
82513dbe 437 ret = -ERANGE;
97b58163
MD
438 }
439 break;
440 }
441
04aa13f8 442 case BYTECODE_OP_LOAD_S64:
97b58163
MD
443 {
444 if (unlikely(pc + sizeof(struct load_op) + sizeof(struct literal_numeric)
445 > start_pc + bytecode->len)) {
82513dbe 446 ret = -ERANGE;
97b58163
MD
447 }
448 break;
449 }
450
04aa13f8 451 case BYTECODE_OP_LOAD_DOUBLE:
97b58163
MD
452 {
453 if (unlikely(pc + sizeof(struct load_op) + sizeof(struct literal_double)
454 > start_pc + bytecode->len)) {
82513dbe 455 ret = -ERANGE;
97b58163
MD
456 }
457 break;
458 }
459
04aa13f8
FD
460 case BYTECODE_OP_CAST_TO_S64:
461 case BYTECODE_OP_CAST_DOUBLE_TO_S64:
462 case BYTECODE_OP_CAST_NOP:
97b58163
MD
463 {
464 if (unlikely(pc + sizeof(struct cast_op)
465 > start_pc + bytecode->len)) {
82513dbe 466 ret = -ERANGE;
97b58163
MD
467 }
468 break;
469 }
77aa5901 470
47e5f13e
MD
471 /*
472 * Instructions for recursive traversal through composed types.
473 */
04aa13f8
FD
474 case BYTECODE_OP_GET_CONTEXT_ROOT:
475 case BYTECODE_OP_GET_APP_CONTEXT_ROOT:
476 case BYTECODE_OP_GET_PAYLOAD_ROOT:
477 case BYTECODE_OP_LOAD_FIELD:
478 case BYTECODE_OP_LOAD_FIELD_S8:
479 case BYTECODE_OP_LOAD_FIELD_S16:
480 case BYTECODE_OP_LOAD_FIELD_S32:
481 case BYTECODE_OP_LOAD_FIELD_S64:
482 case BYTECODE_OP_LOAD_FIELD_U8:
483 case BYTECODE_OP_LOAD_FIELD_U16:
484 case BYTECODE_OP_LOAD_FIELD_U32:
485 case BYTECODE_OP_LOAD_FIELD_U64:
486 case BYTECODE_OP_LOAD_FIELD_STRING:
487 case BYTECODE_OP_LOAD_FIELD_SEQUENCE:
488 case BYTECODE_OP_LOAD_FIELD_DOUBLE:
47e5f13e
MD
489 if (unlikely(pc + sizeof(struct load_op)
490 > start_pc + bytecode->len)) {
491 ret = -ERANGE;
492 }
493 break;
494
04aa13f8 495 case BYTECODE_OP_GET_SYMBOL:
47e5f13e
MD
496 {
497 struct load_op *insn = (struct load_op *) pc;
498 struct get_symbol *sym = (struct get_symbol *) insn->data;
499
500 if (unlikely(pc + sizeof(struct load_op) + sizeof(struct get_symbol)
501 > start_pc + bytecode->len)) {
502 ret = -ERANGE;
90732639 503 break;
47e5f13e
MD
504 }
505 ret = validate_get_symbol(bytecode, sym);
506 break;
507 }
508
04aa13f8 509 case BYTECODE_OP_GET_SYMBOL_FIELD:
47e5f13e
MD
510 ERR("Unexpected get symbol field");
511 ret = -EINVAL;
512 break;
513
04aa13f8 514 case BYTECODE_OP_GET_INDEX_U16:
47e5f13e
MD
515 if (unlikely(pc + sizeof(struct load_op) + sizeof(struct get_index_u16)
516 > start_pc + bytecode->len)) {
517 ret = -ERANGE;
518 }
519 break;
520
04aa13f8 521 case BYTECODE_OP_GET_INDEX_U64:
47e5f13e
MD
522 if (unlikely(pc + sizeof(struct load_op) + sizeof(struct get_index_u64)
523 > start_pc + bytecode->len)) {
524 ret = -ERANGE;
525 }
526 break;
97b58163
MD
527 }
528
529 return ret;
530}
531
bf956ec0 532static
10544ee8 533unsigned long delete_all_nodes(struct lttng_ust_lfht *ht)
97b58163 534{
10544ee8 535 struct lttng_ust_lfht_iter iter;
bf956ec0
MD
536 struct lfht_mp_node *node;
537 unsigned long nr_nodes = 0;
97b58163 538
10544ee8 539 lttng_ust_lfht_for_each_entry(ht, &iter, node, node) {
bf956ec0
MD
540 int ret;
541
10544ee8 542 ret = lttng_ust_lfht_del(ht, lttng_ust_lfht_iter_get_node(&iter));
bf956ec0
MD
543 assert(!ret);
544 /* note: this hash table is never used concurrently */
545 free(node);
546 nr_nodes++;
97b58163 547 }
bf956ec0
MD
548 return nr_nodes;
549}
97b58163 550
bf956ec0
MD
551/*
552 * Return value:
53569322 553 * >=0: success
bf956ec0
MD
554 * <0: error
555 */
556static
2208d8b5
MJ
557int validate_instruction_context(
558 struct bytecode_runtime *bytecode __attribute__((unused)),
0305960f 559 struct vstack *stack,
22389ecb
MD
560 char *start_pc,
561 char *pc)
bf956ec0
MD
562{
563 int ret = 0;
04aa13f8 564 const bytecode_opcode_t opcode = *(bytecode_opcode_t *) pc;
bf956ec0 565
3151a51d 566 switch (opcode) {
04aa13f8 567 case BYTECODE_OP_UNKNOWN:
bf956ec0
MD
568 default:
569 {
570 ERR("unknown bytecode op %u\n",
04aa13f8 571 (unsigned int) *(bytecode_opcode_t *) pc);
bf956ec0
MD
572 ret = -EINVAL;
573 goto end;
574 }
575
04aa13f8
FD
576 case BYTECODE_OP_RETURN:
577 case BYTECODE_OP_RETURN_S64:
bf956ec0
MD
578 {
579 goto end;
580 }
581
582 /* binary */
04aa13f8
FD
583 case BYTECODE_OP_MUL:
584 case BYTECODE_OP_DIV:
585 case BYTECODE_OP_MOD:
586 case BYTECODE_OP_PLUS:
587 case BYTECODE_OP_MINUS:
bf956ec0
MD
588 {
589 ERR("unsupported bytecode op %u\n",
3151a51d 590 (unsigned int) opcode);
bf956ec0
MD
591 ret = -EINVAL;
592 goto end;
593 }
97b58163 594
04aa13f8 595 case BYTECODE_OP_EQ:
bf956ec0 596 {
3151a51d 597 ret = bin_op_compare_check(stack, opcode, "==");
53569322 598 if (ret < 0)
bf956ec0
MD
599 goto end;
600 break;
601 }
04aa13f8 602 case BYTECODE_OP_NE:
bf956ec0 603 {
3151a51d 604 ret = bin_op_compare_check(stack, opcode, "!=");
53569322 605 if (ret < 0)
bf956ec0
MD
606 goto end;
607 break;
608 }
04aa13f8 609 case BYTECODE_OP_GT:
bf956ec0 610 {
3151a51d 611 ret = bin_op_compare_check(stack, opcode, ">");
53569322 612 if (ret < 0)
bf956ec0
MD
613 goto end;
614 break;
615 }
04aa13f8 616 case BYTECODE_OP_LT:
bf956ec0 617 {
3151a51d 618 ret = bin_op_compare_check(stack, opcode, "<");
53569322 619 if (ret < 0)
bf956ec0
MD
620 goto end;
621 break;
622 }
04aa13f8 623 case BYTECODE_OP_GE:
bf956ec0 624 {
3151a51d 625 ret = bin_op_compare_check(stack, opcode, ">=");
53569322 626 if (ret < 0)
bf956ec0
MD
627 goto end;
628 break;
629 }
04aa13f8 630 case BYTECODE_OP_LE:
bf956ec0 631 {
3151a51d 632 ret = bin_op_compare_check(stack, opcode, "<=");
53569322 633 if (ret < 0)
97b58163 634 goto end;
bf956ec0
MD
635 break;
636 }
97b58163 637
04aa13f8
FD
638 case BYTECODE_OP_EQ_STRING:
639 case BYTECODE_OP_NE_STRING:
640 case BYTECODE_OP_GT_STRING:
641 case BYTECODE_OP_LT_STRING:
642 case BYTECODE_OP_GE_STRING:
643 case BYTECODE_OP_LE_STRING:
bf956ec0 644 {
0305960f
MD
645 if (!vstack_ax(stack) || !vstack_bx(stack)) {
646 ERR("Empty stack\n");
647 ret = -EINVAL;
648 goto end;
649 }
650 if (vstack_ax(stack)->type != REG_STRING
651 || vstack_bx(stack)->type != REG_STRING) {
bf956ec0 652 ERR("Unexpected register type for string comparator\n");
97b58163
MD
653 ret = -EINVAL;
654 goto end;
97b58163 655 }
bf956ec0
MD
656 break;
657 }
97b58163 658
04aa13f8
FD
659 case BYTECODE_OP_EQ_STAR_GLOB_STRING:
660 case BYTECODE_OP_NE_STAR_GLOB_STRING:
3151a51d
PP
661 {
662 if (!vstack_ax(stack) || !vstack_bx(stack)) {
663 ERR("Empty stack\n");
664 ret = -EINVAL;
665 goto end;
666 }
667 if (vstack_ax(stack)->type != REG_STAR_GLOB_STRING
668 && vstack_bx(stack)->type != REG_STAR_GLOB_STRING) {
669 ERR("Unexpected register type for globbing pattern comparator\n");
670 ret = -EINVAL;
671 goto end;
672 }
673 break;
674 }
675
04aa13f8
FD
676 case BYTECODE_OP_EQ_S64:
677 case BYTECODE_OP_NE_S64:
678 case BYTECODE_OP_GT_S64:
679 case BYTECODE_OP_LT_S64:
680 case BYTECODE_OP_GE_S64:
681 case BYTECODE_OP_LE_S64:
bf956ec0 682 {
0305960f
MD
683 if (!vstack_ax(stack) || !vstack_bx(stack)) {
684 ERR("Empty stack\n");
685 ret = -EINVAL;
686 goto end;
687 }
d97f9b78
MD
688 switch (vstack_ax(stack)->type) {
689 case REG_S64:
690 case REG_U64:
691 break;
692 default:
693 ERR("Unexpected register type for s64 comparator\n");
694 ret = -EINVAL;
695 goto end;
696 }
697 switch (vstack_bx(stack)->type) {
698 case REG_S64:
699 case REG_U64:
700 break;
701 default:
bf956ec0
MD
702 ERR("Unexpected register type for s64 comparator\n");
703 ret = -EINVAL;
704 goto end;
97b58163 705 }
bf956ec0
MD
706 break;
707 }
97b58163 708
04aa13f8
FD
709 case BYTECODE_OP_EQ_DOUBLE:
710 case BYTECODE_OP_NE_DOUBLE:
711 case BYTECODE_OP_GT_DOUBLE:
712 case BYTECODE_OP_LT_DOUBLE:
713 case BYTECODE_OP_GE_DOUBLE:
714 case BYTECODE_OP_LE_DOUBLE:
bf956ec0 715 {
0305960f
MD
716 if (!vstack_ax(stack) || !vstack_bx(stack)) {
717 ERR("Empty stack\n");
718 ret = -EINVAL;
719 goto end;
720 }
dbea82ec
MD
721 if (vstack_ax(stack)->type != REG_DOUBLE && vstack_bx(stack)->type != REG_DOUBLE) {
722 ERR("Double operator should have two double registers\n");
bf956ec0
MD
723 ret = -EINVAL;
724 goto end;
97b58163 725 }
dbea82ec
MD
726 break;
727 }
728
04aa13f8
FD
729 case BYTECODE_OP_EQ_DOUBLE_S64:
730 case BYTECODE_OP_NE_DOUBLE_S64:
731 case BYTECODE_OP_GT_DOUBLE_S64:
732 case BYTECODE_OP_LT_DOUBLE_S64:
733 case BYTECODE_OP_GE_DOUBLE_S64:
734 case BYTECODE_OP_LE_DOUBLE_S64:
dbea82ec
MD
735 {
736 if (!vstack_ax(stack) || !vstack_bx(stack)) {
737 ERR("Empty stack\n");
738 ret = -EINVAL;
739 goto end;
740 }
d97f9b78
MD
741 switch (vstack_ax(stack)->type) {
742 case REG_S64:
743 case REG_U64:
744 break;
745 default:
746 ERR("Double-S64 operator has unexpected register types\n");
747 ret = -EINVAL;
748 goto end;
749 }
750 switch (vstack_bx(stack)->type) {
751 case REG_DOUBLE:
752 break;
753 default:
dbea82ec
MD
754 ERR("Double-S64 operator has unexpected register types\n");
755 ret = -EINVAL;
756 goto end;
757 }
758 break;
759 }
760
04aa13f8
FD
761 case BYTECODE_OP_EQ_S64_DOUBLE:
762 case BYTECODE_OP_NE_S64_DOUBLE:
763 case BYTECODE_OP_GT_S64_DOUBLE:
764 case BYTECODE_OP_LT_S64_DOUBLE:
765 case BYTECODE_OP_GE_S64_DOUBLE:
766 case BYTECODE_OP_LE_S64_DOUBLE:
dbea82ec
MD
767 {
768 if (!vstack_ax(stack) || !vstack_bx(stack)) {
769 ERR("Empty stack\n");
770 ret = -EINVAL;
771 goto end;
772 }
d97f9b78
MD
773 switch (vstack_ax(stack)->type) {
774 case REG_DOUBLE:
775 break;
776 default:
777 ERR("S64-Double operator has unexpected register types\n");
778 ret = -EINVAL;
779 goto end;
780 }
781 switch (vstack_bx(stack)->type) {
782 case REG_S64:
783 case REG_U64:
784 break;
785 default:
dbea82ec 786 ERR("S64-Double operator has unexpected register types\n");
bf956ec0
MD
787 ret = -EINVAL;
788 goto end;
97b58163 789 }
bf956ec0
MD
790 break;
791 }
97b58163 792
04aa13f8 793 case BYTECODE_OP_BIT_RSHIFT:
0039e2d8
MD
794 ret = bin_op_bitwise_check(stack, opcode, ">>");
795 if (ret < 0)
796 goto end;
797 break;
04aa13f8 798 case BYTECODE_OP_BIT_LSHIFT:
0039e2d8
MD
799 ret = bin_op_bitwise_check(stack, opcode, "<<");
800 if (ret < 0)
801 goto end;
802 break;
04aa13f8 803 case BYTECODE_OP_BIT_AND:
47e5f13e
MD
804 ret = bin_op_bitwise_check(stack, opcode, "&");
805 if (ret < 0)
806 goto end;
807 break;
04aa13f8 808 case BYTECODE_OP_BIT_OR:
47e5f13e
MD
809 ret = bin_op_bitwise_check(stack, opcode, "|");
810 if (ret < 0)
811 goto end;
812 break;
04aa13f8 813 case BYTECODE_OP_BIT_XOR:
47e5f13e
MD
814 ret = bin_op_bitwise_check(stack, opcode, "^");
815 if (ret < 0)
816 goto end;
817 break;
818
bf956ec0 819 /* unary */
04aa13f8
FD
820 case BYTECODE_OP_UNARY_PLUS:
821 case BYTECODE_OP_UNARY_MINUS:
822 case BYTECODE_OP_UNARY_NOT:
bf956ec0 823 {
0305960f
MD
824 if (!vstack_ax(stack)) {
825 ERR("Empty stack\n");
bf956ec0
MD
826 ret = -EINVAL;
827 goto end;
828 }
0305960f 829 switch (vstack_ax(stack)->type) {
bf956ec0
MD
830 default:
831 ERR("unknown register type\n");
832 ret = -EINVAL;
833 goto end;
97b58163 834
bf956ec0 835 case REG_STRING:
3151a51d 836 case REG_STAR_GLOB_STRING:
bf956ec0
MD
837 ERR("Unary op can only be applied to numeric or floating point registers\n");
838 ret = -EINVAL;
839 goto end;
840 case REG_S64:
841 break;
d97f9b78
MD
842 case REG_U64:
843 break;
bf956ec0 844 case REG_DOUBLE:
97b58163 845 break;
53569322
MD
846 case REG_UNKNOWN:
847 break;
97b58163 848 }
bf956ec0
MD
849 break;
850 }
04aa13f8 851 case BYTECODE_OP_UNARY_BIT_NOT:
0039e2d8
MD
852 {
853 if (!vstack_ax(stack)) {
854 ERR("Empty stack\n");
855 ret = -EINVAL;
856 goto end;
857 }
858 switch (vstack_ax(stack)->type) {
859 default:
860 ERR("unknown register type\n");
861 ret = -EINVAL;
862 goto end;
863
864 case REG_STRING:
865 case REG_STAR_GLOB_STRING:
866 case REG_DOUBLE:
867 ERR("Unary bitwise op can only be applied to numeric registers\n");
868 ret = -EINVAL;
869 goto end;
870 case REG_S64:
871 break;
d97f9b78
MD
872 case REG_U64:
873 break;
0039e2d8
MD
874 case REG_UNKNOWN:
875 break;
876 }
877 break;
878 }
97b58163 879
04aa13f8
FD
880 case BYTECODE_OP_UNARY_PLUS_S64:
881 case BYTECODE_OP_UNARY_MINUS_S64:
882 case BYTECODE_OP_UNARY_NOT_S64:
bf956ec0 883 {
0305960f
MD
884 if (!vstack_ax(stack)) {
885 ERR("Empty stack\n");
bf956ec0
MD
886 ret = -EINVAL;
887 goto end;
888 }
d97f9b78
MD
889 if (vstack_ax(stack)->type != REG_S64 &&
890 vstack_ax(stack)->type != REG_U64) {
bf956ec0
MD
891 ERR("Invalid register type\n");
892 ret = -EINVAL;
893 goto end;
97b58163 894 }
bf956ec0
MD
895 break;
896 }
97b58163 897
04aa13f8
FD
898 case BYTECODE_OP_UNARY_PLUS_DOUBLE:
899 case BYTECODE_OP_UNARY_MINUS_DOUBLE:
900 case BYTECODE_OP_UNARY_NOT_DOUBLE:
bf956ec0 901 {
0305960f
MD
902 if (!vstack_ax(stack)) {
903 ERR("Empty stack\n");
bf956ec0
MD
904 ret = -EINVAL;
905 goto end;
97b58163 906 }
0305960f 907 if (vstack_ax(stack)->type != REG_DOUBLE) {
bf956ec0
MD
908 ERR("Invalid register type\n");
909 ret = -EINVAL;
910 goto end;
911 }
912 break;
913 }
97b58163 914
bf956ec0 915 /* logical */
04aa13f8
FD
916 case BYTECODE_OP_AND:
917 case BYTECODE_OP_OR:
bf956ec0
MD
918 {
919 struct logical_op *insn = (struct logical_op *) pc;
97b58163 920
0305960f
MD
921 if (!vstack_ax(stack)) {
922 ERR("Empty stack\n");
923 ret = -EINVAL;
924 goto end;
925 }
53569322 926 if (vstack_ax(stack)->type != REG_S64
d97f9b78 927 && vstack_ax(stack)->type != REG_U64
53569322 928 && vstack_ax(stack)->type != REG_UNKNOWN) {
d97f9b78 929 ERR("Logical comparator expects S64, U64 or dynamic register\n");
bf956ec0
MD
930 ret = -EINVAL;
931 goto end;
97b58163
MD
932 }
933
bf956ec0
MD
934 dbg_printf("Validate jumping to bytecode offset %u\n",
935 (unsigned int) insn->skip_offset);
936 if (unlikely(start_pc + insn->skip_offset <= pc)) {
937 ERR("Loops are not allowed in bytecode\n");
97b58163
MD
938 ret = -EINVAL;
939 goto end;
940 }
bf956ec0
MD
941 break;
942 }
97b58163 943
77aa5901 944 /* load field ref */
04aa13f8 945 case BYTECODE_OP_LOAD_FIELD_REF:
bf956ec0
MD
946 {
947 ERR("Unknown field ref type\n");
948 ret = -EINVAL;
949 goto end;
950 }
04aa13f8
FD
951 case BYTECODE_OP_LOAD_FIELD_REF_STRING:
952 case BYTECODE_OP_LOAD_FIELD_REF_SEQUENCE:
bf956ec0
MD
953 {
954 struct load_op *insn = (struct load_op *) pc;
955 struct field_ref *ref = (struct field_ref *) insn->data;
956
bf956ec0
MD
957 dbg_printf("Validate load field ref offset %u type string\n",
958 ref->offset);
959 break;
960 }
04aa13f8 961 case BYTECODE_OP_LOAD_FIELD_REF_S64:
bf956ec0
MD
962 {
963 struct load_op *insn = (struct load_op *) pc;
964 struct field_ref *ref = (struct field_ref *) insn->data;
97b58163 965
bf956ec0
MD
966 dbg_printf("Validate load field ref offset %u type s64\n",
967 ref->offset);
968 break;
969 }
04aa13f8 970 case BYTECODE_OP_LOAD_FIELD_REF_DOUBLE:
bf956ec0
MD
971 {
972 struct load_op *insn = (struct load_op *) pc;
973 struct field_ref *ref = (struct field_ref *) insn->data;
97b58163 974
bf956ec0
MD
975 dbg_printf("Validate load field ref offset %u type double\n",
976 ref->offset);
977 break;
978 }
97b58163 979
77aa5901 980 /* load from immediate operand */
04aa13f8
FD
981 case BYTECODE_OP_LOAD_STRING:
982 case BYTECODE_OP_LOAD_STAR_GLOB_STRING:
bf956ec0 983 {
bf956ec0
MD
984 break;
985 }
97b58163 986
04aa13f8 987 case BYTECODE_OP_LOAD_S64:
bf956ec0 988 {
bf956ec0
MD
989 break;
990 }
97b58163 991
04aa13f8 992 case BYTECODE_OP_LOAD_DOUBLE:
bf956ec0 993 {
bf956ec0
MD
994 break;
995 }
97b58163 996
04aa13f8
FD
997 case BYTECODE_OP_CAST_TO_S64:
998 case BYTECODE_OP_CAST_DOUBLE_TO_S64:
bf956ec0
MD
999 {
1000 struct cast_op *insn = (struct cast_op *) pc;
97b58163 1001
0305960f
MD
1002 if (!vstack_ax(stack)) {
1003 ERR("Empty stack\n");
bf956ec0
MD
1004 ret = -EINVAL;
1005 goto end;
1006 }
0305960f 1007 switch (vstack_ax(stack)->type) {
bf956ec0
MD
1008 default:
1009 ERR("unknown register type\n");
1010 ret = -EINVAL;
1011 goto end;
97b58163 1012
bf956ec0 1013 case REG_STRING:
3151a51d 1014 case REG_STAR_GLOB_STRING:
bf956ec0
MD
1015 ERR("Cast op can only be applied to numeric or floating point registers\n");
1016 ret = -EINVAL;
1017 goto end;
1018 case REG_S64:
1019 break;
d97f9b78
MD
1020 case REG_U64:
1021 break;
bf956ec0
MD
1022 case REG_DOUBLE:
1023 break;
53569322
MD
1024 case REG_UNKNOWN:
1025 break;
bf956ec0 1026 }
04aa13f8 1027 if (insn->op == BYTECODE_OP_CAST_DOUBLE_TO_S64) {
0305960f 1028 if (vstack_ax(stack)->type != REG_DOUBLE) {
bf956ec0 1029 ERR("Cast expects double\n");
97b58163
MD
1030 ret = -EINVAL;
1031 goto end;
97b58163 1032 }
97b58163 1033 }
bf956ec0
MD
1034 break;
1035 }
04aa13f8 1036 case BYTECODE_OP_CAST_NOP:
bf956ec0
MD
1037 {
1038 break;
1039 }
1040
77aa5901 1041 /* get context ref */
04aa13f8 1042 case BYTECODE_OP_GET_CONTEXT_REF:
77aa5901 1043 {
53569322
MD
1044 struct load_op *insn = (struct load_op *) pc;
1045 struct field_ref *ref = (struct field_ref *) insn->data;
1046
1047 dbg_printf("Validate get context ref offset %u type dynamic\n",
1048 ref->offset);
1049 break;
77aa5901 1050 }
04aa13f8 1051 case BYTECODE_OP_GET_CONTEXT_REF_STRING:
77aa5901
MD
1052 {
1053 struct load_op *insn = (struct load_op *) pc;
1054 struct field_ref *ref = (struct field_ref *) insn->data;
1055
1056 dbg_printf("Validate get context ref offset %u type string\n",
1057 ref->offset);
1058 break;
1059 }
04aa13f8 1060 case BYTECODE_OP_GET_CONTEXT_REF_S64:
77aa5901
MD
1061 {
1062 struct load_op *insn = (struct load_op *) pc;
1063 struct field_ref *ref = (struct field_ref *) insn->data;
1064
1065 dbg_printf("Validate get context ref offset %u type s64\n",
1066 ref->offset);
1067 break;
1068 }
04aa13f8 1069 case BYTECODE_OP_GET_CONTEXT_REF_DOUBLE:
77aa5901
MD
1070 {
1071 struct load_op *insn = (struct load_op *) pc;
1072 struct field_ref *ref = (struct field_ref *) insn->data;
1073
1074 dbg_printf("Validate get context ref offset %u type double\n",
1075 ref->offset);
1076 break;
1077 }
1078
47e5f13e
MD
1079 /*
1080 * Instructions for recursive traversal through composed types.
1081 */
04aa13f8 1082 case BYTECODE_OP_GET_CONTEXT_ROOT:
47e5f13e
MD
1083 {
1084 dbg_printf("Validate get context root\n");
1085 break;
1086 }
04aa13f8 1087 case BYTECODE_OP_GET_APP_CONTEXT_ROOT:
47e5f13e
MD
1088 {
1089 dbg_printf("Validate get app context root\n");
1090 break;
1091 }
04aa13f8 1092 case BYTECODE_OP_GET_PAYLOAD_ROOT:
47e5f13e
MD
1093 {
1094 dbg_printf("Validate get payload root\n");
1095 break;
1096 }
04aa13f8 1097 case BYTECODE_OP_LOAD_FIELD:
47e5f13e
MD
1098 {
1099 /*
1100 * We tolerate that field type is unknown at validation,
1101 * because we are performing the load specialization in
1102 * a phase after validation.
1103 */
1104 dbg_printf("Validate load field\n");
1105 break;
1106 }
04aa13f8 1107 case BYTECODE_OP_LOAD_FIELD_S8:
47e5f13e
MD
1108 {
1109 dbg_printf("Validate load field s8\n");
1110 break;
1111 }
04aa13f8 1112 case BYTECODE_OP_LOAD_FIELD_S16:
47e5f13e
MD
1113 {
1114 dbg_printf("Validate load field s16\n");
1115 break;
1116 }
04aa13f8 1117 case BYTECODE_OP_LOAD_FIELD_S32:
47e5f13e
MD
1118 {
1119 dbg_printf("Validate load field s32\n");
1120 break;
1121 }
04aa13f8 1122 case BYTECODE_OP_LOAD_FIELD_S64:
47e5f13e
MD
1123 {
1124 dbg_printf("Validate load field s64\n");
1125 break;
1126 }
04aa13f8 1127 case BYTECODE_OP_LOAD_FIELD_U8:
47e5f13e
MD
1128 {
1129 dbg_printf("Validate load field u8\n");
1130 break;
1131 }
04aa13f8 1132 case BYTECODE_OP_LOAD_FIELD_U16:
47e5f13e
MD
1133 {
1134 dbg_printf("Validate load field u16\n");
1135 break;
1136 }
04aa13f8 1137 case BYTECODE_OP_LOAD_FIELD_U32:
47e5f13e
MD
1138 {
1139 dbg_printf("Validate load field u32\n");
1140 break;
1141 }
04aa13f8 1142 case BYTECODE_OP_LOAD_FIELD_U64:
47e5f13e
MD
1143 {
1144 dbg_printf("Validate load field u64\n");
1145 break;
1146 }
04aa13f8 1147 case BYTECODE_OP_LOAD_FIELD_STRING:
47e5f13e
MD
1148 {
1149 dbg_printf("Validate load field string\n");
1150 break;
1151 }
04aa13f8 1152 case BYTECODE_OP_LOAD_FIELD_SEQUENCE:
47e5f13e
MD
1153 {
1154 dbg_printf("Validate load field sequence\n");
1155 break;
1156 }
04aa13f8 1157 case BYTECODE_OP_LOAD_FIELD_DOUBLE:
47e5f13e
MD
1158 {
1159 dbg_printf("Validate load field double\n");
1160 break;
1161 }
1162
04aa13f8 1163 case BYTECODE_OP_GET_SYMBOL:
47e5f13e
MD
1164 {
1165 struct load_op *insn = (struct load_op *) pc;
1166 struct get_symbol *sym = (struct get_symbol *) insn->data;
1167
1168 dbg_printf("Validate get symbol offset %u\n", sym->offset);
1169 break;
1170 }
1171
04aa13f8 1172 case BYTECODE_OP_GET_SYMBOL_FIELD:
47e5f13e
MD
1173 {
1174 struct load_op *insn = (struct load_op *) pc;
1175 struct get_symbol *sym = (struct get_symbol *) insn->data;
1176
1177 dbg_printf("Validate get symbol field offset %u\n", sym->offset);
1178 break;
1179 }
1180
04aa13f8 1181 case BYTECODE_OP_GET_INDEX_U16:
47e5f13e
MD
1182 {
1183 struct load_op *insn = (struct load_op *) pc;
1184 struct get_index_u16 *get_index = (struct get_index_u16 *) insn->data;
1185
1186 dbg_printf("Validate get index u16 index %u\n", get_index->index);
1187 break;
1188 }
1189
04aa13f8 1190 case BYTECODE_OP_GET_INDEX_U64:
47e5f13e
MD
1191 {
1192 struct load_op *insn = (struct load_op *) pc;
1193 struct get_index_u64 *get_index = (struct get_index_u64 *) insn->data;
1194
1195 dbg_printf("Validate get index u64 index %" PRIu64 "\n", get_index->index);
1196 break;
1197 }
bf956ec0
MD
1198 }
1199end:
1200 return ret;
1201}
1202
1203/*
1204 * Return value:
1205 * 0: success
1206 * <0: error
1207 */
1208static
1209int validate_instruction_all_contexts(struct bytecode_runtime *bytecode,
10544ee8 1210 struct lttng_ust_lfht *merge_points,
0305960f 1211 struct vstack *stack,
22389ecb
MD
1212 char *start_pc,
1213 char *pc)
bf956ec0
MD
1214{
1215 int ret;
1216 unsigned long target_pc = pc - start_pc;
10544ee8
MD
1217 struct lttng_ust_lfht_iter iter;
1218 struct lttng_ust_lfht_node *node;
71c1ceeb 1219 struct lfht_mp_node *mp_node;
bf956ec0
MD
1220 unsigned long hash;
1221
1222 /* Validate the context resulting from the previous instruction */
0305960f 1223 ret = validate_instruction_context(bytecode, stack, start_pc, pc);
53569322 1224 if (ret < 0)
bf956ec0
MD
1225 return ret;
1226
1227 /* Validate merge points */
22389ecb 1228 hash = lttng_hash_mix((const char *) target_pc, sizeof(target_pc),
bf956ec0 1229 lttng_hash_seed);
10544ee8 1230 lttng_ust_lfht_lookup(merge_points, hash, lttng_hash_match,
22389ecb 1231 (const char *) target_pc, &iter);
10544ee8 1232 node = lttng_ust_lfht_iter_get_node(&iter);
71c1ceeb
MD
1233 if (node) {
1234 mp_node = caa_container_of(node, struct lfht_mp_node, node);
3151a51d 1235
04aa13f8 1236 dbg_printf("Bytecode: validate merge point at offset %lu\n",
bf956ec0 1237 target_pc);
71c1ceeb
MD
1238 if (merge_points_compare(stack, &mp_node->stack)) {
1239 ERR("Merge points differ for offset %lu\n",
1240 target_pc);
1241 return -EINVAL;
1242 }
bf956ec0 1243 /* Once validated, we can remove the merge point */
04aa13f8 1244 dbg_printf("Bytecode: remove merge point at offset %lu\n",
bf956ec0 1245 target_pc);
10544ee8 1246 ret = lttng_ust_lfht_del(merge_points, node);
bf956ec0
MD
1247 assert(!ret);
1248 }
1249 return 0;
1250}
1251
1252/*
1253 * Return value:
1254 * >0: going to next insn.
1255 * 0: success, stop iteration.
1256 * <0: error
1257 */
1258static
2208d8b5 1259int exec_insn(struct bytecode_runtime *bytecode __attribute__((unused)),
10544ee8 1260 struct lttng_ust_lfht *merge_points,
0305960f 1261 struct vstack *stack,
22389ecb
MD
1262 char **_next_pc,
1263 char *pc)
bf956ec0
MD
1264{
1265 int ret = 1;
22389ecb 1266 char *next_pc = *_next_pc;
bf956ec0 1267
04aa13f8
FD
1268 switch (*(bytecode_opcode_t *) pc) {
1269 case BYTECODE_OP_UNKNOWN:
bf956ec0
MD
1270 default:
1271 {
1272 ERR("unknown bytecode op %u\n",
04aa13f8 1273 (unsigned int) *(bytecode_opcode_t *) pc);
bf956ec0
MD
1274 ret = -EINVAL;
1275 goto end;
1276 }
1277
04aa13f8 1278 case BYTECODE_OP_RETURN:
bf956ec0 1279 {
71c1ceeb
MD
1280 if (!vstack_ax(stack)) {
1281 ERR("Empty stack\n");
1282 ret = -EINVAL;
1283 goto end;
1284 }
47e5f13e
MD
1285 switch (vstack_ax(stack)->type) {
1286 case REG_S64:
d97f9b78 1287 case REG_U64:
09f78acb
FD
1288 case REG_DOUBLE:
1289 case REG_STRING:
1290 case REG_PTR:
47e5f13e
MD
1291 case REG_UNKNOWN:
1292 break;
1293 default:
1294 ERR("Unexpected register type %d at end of bytecode\n",
1295 (int) vstack_ax(stack)->type);
1296 ret = -EINVAL;
1297 goto end;
1298 }
1299
bf956ec0
MD
1300 ret = 0;
1301 goto end;
1302 }
04aa13f8 1303 case BYTECODE_OP_RETURN_S64:
93c591bb
MD
1304 {
1305 if (!vstack_ax(stack)) {
1306 ERR("Empty stack\n");
1307 ret = -EINVAL;
1308 goto end;
1309 }
1310 switch (vstack_ax(stack)->type) {
1311 case REG_S64:
d97f9b78 1312 case REG_U64:
93c591bb
MD
1313 break;
1314 default:
1315 case REG_UNKNOWN:
1316 ERR("Unexpected register type %d at end of bytecode\n",
1317 (int) vstack_ax(stack)->type);
1318 ret = -EINVAL;
1319 goto end;
1320 }
1321
1322 ret = 0;
1323 goto end;
1324 }
bf956ec0
MD
1325
1326 /* binary */
04aa13f8
FD
1327 case BYTECODE_OP_MUL:
1328 case BYTECODE_OP_DIV:
1329 case BYTECODE_OP_MOD:
1330 case BYTECODE_OP_PLUS:
1331 case BYTECODE_OP_MINUS:
bf956ec0
MD
1332 {
1333 ERR("unsupported bytecode op %u\n",
04aa13f8 1334 (unsigned int) *(bytecode_opcode_t *) pc);
bf956ec0
MD
1335 ret = -EINVAL;
1336 goto end;
1337 }
1338
04aa13f8
FD
1339 case BYTECODE_OP_EQ:
1340 case BYTECODE_OP_NE:
1341 case BYTECODE_OP_GT:
1342 case BYTECODE_OP_LT:
1343 case BYTECODE_OP_GE:
1344 case BYTECODE_OP_LE:
1345 case BYTECODE_OP_EQ_STRING:
1346 case BYTECODE_OP_NE_STRING:
1347 case BYTECODE_OP_GT_STRING:
1348 case BYTECODE_OP_LT_STRING:
1349 case BYTECODE_OP_GE_STRING:
1350 case BYTECODE_OP_LE_STRING:
1351 case BYTECODE_OP_EQ_STAR_GLOB_STRING:
1352 case BYTECODE_OP_NE_STAR_GLOB_STRING:
1353 case BYTECODE_OP_EQ_S64:
1354 case BYTECODE_OP_NE_S64:
1355 case BYTECODE_OP_GT_S64:
1356 case BYTECODE_OP_LT_S64:
1357 case BYTECODE_OP_GE_S64:
1358 case BYTECODE_OP_LE_S64:
1359 case BYTECODE_OP_EQ_DOUBLE:
1360 case BYTECODE_OP_NE_DOUBLE:
1361 case BYTECODE_OP_GT_DOUBLE:
1362 case BYTECODE_OP_LT_DOUBLE:
1363 case BYTECODE_OP_GE_DOUBLE:
1364 case BYTECODE_OP_LE_DOUBLE:
1365 case BYTECODE_OP_EQ_DOUBLE_S64:
1366 case BYTECODE_OP_NE_DOUBLE_S64:
1367 case BYTECODE_OP_GT_DOUBLE_S64:
1368 case BYTECODE_OP_LT_DOUBLE_S64:
1369 case BYTECODE_OP_GE_DOUBLE_S64:
1370 case BYTECODE_OP_LE_DOUBLE_S64:
1371 case BYTECODE_OP_EQ_S64_DOUBLE:
1372 case BYTECODE_OP_NE_S64_DOUBLE:
1373 case BYTECODE_OP_GT_S64_DOUBLE:
1374 case BYTECODE_OP_LT_S64_DOUBLE:
1375 case BYTECODE_OP_GE_S64_DOUBLE:
1376 case BYTECODE_OP_LE_S64_DOUBLE:
d97f9b78
MD
1377 {
1378 /* Pop 2, push 1 */
1379 if (vstack_pop(stack)) {
1380 ret = -EINVAL;
1381 goto end;
1382 }
1383 if (!vstack_ax(stack)) {
1384 ERR("Empty stack\n");
1385 ret = -EINVAL;
1386 goto end;
1387 }
1388 switch (vstack_ax(stack)->type) {
1389 case REG_S64:
1390 case REG_U64:
1391 case REG_DOUBLE:
1392 case REG_STRING:
1393 case REG_STAR_GLOB_STRING:
1394 case REG_UNKNOWN:
1395 break;
1396 default:
1397 ERR("Unexpected register type %d for operation\n",
1398 (int) vstack_ax(stack)->type);
1399 ret = -EINVAL;
1400 goto end;
1401 }
1402
1403 vstack_ax(stack)->type = REG_S64;
1404 next_pc += sizeof(struct binary_op);
1405 break;
1406 }
1407
04aa13f8
FD
1408 case BYTECODE_OP_BIT_RSHIFT:
1409 case BYTECODE_OP_BIT_LSHIFT:
1410 case BYTECODE_OP_BIT_AND:
1411 case BYTECODE_OP_BIT_OR:
1412 case BYTECODE_OP_BIT_XOR:
bf956ec0 1413 {
0305960f
MD
1414 /* Pop 2, push 1 */
1415 if (vstack_pop(stack)) {
1416 ret = -EINVAL;
1417 goto end;
1418 }
1419 if (!vstack_ax(stack)) {
1420 ERR("Empty stack\n");
1421 ret = -EINVAL;
1422 goto end;
1423 }
47e5f13e
MD
1424 switch (vstack_ax(stack)->type) {
1425 case REG_S64:
d97f9b78 1426 case REG_U64:
47e5f13e
MD
1427 case REG_DOUBLE:
1428 case REG_STRING:
1429 case REG_STAR_GLOB_STRING:
1430 case REG_UNKNOWN:
1431 break;
1432 default:
1433 ERR("Unexpected register type %d for operation\n",
1434 (int) vstack_ax(stack)->type);
1435 ret = -EINVAL;
1436 goto end;
1437 }
1438
d97f9b78 1439 vstack_ax(stack)->type = REG_U64;
bf956ec0
MD
1440 next_pc += sizeof(struct binary_op);
1441 break;
1442 }
1443
1444 /* unary */
04aa13f8
FD
1445 case BYTECODE_OP_UNARY_PLUS:
1446 case BYTECODE_OP_UNARY_MINUS:
53569322
MD
1447 {
1448 /* Pop 1, push 1 */
1449 if (!vstack_ax(stack)) {
1450 ERR("Empty stack\n");
1451 ret = -EINVAL;
1452 goto end;
1453 }
47e5f13e
MD
1454 switch (vstack_ax(stack)->type) {
1455 case REG_UNKNOWN:
1456 case REG_DOUBLE:
1457 case REG_S64:
d97f9b78 1458 case REG_U64:
47e5f13e
MD
1459 break;
1460 default:
1461 ERR("Unexpected register type %d for operation\n",
1462 (int) vstack_ax(stack)->type);
1463 ret = -EINVAL;
1464 goto end;
1465 }
53569322
MD
1466 vstack_ax(stack)->type = REG_UNKNOWN;
1467 next_pc += sizeof(struct unary_op);
1468 break;
1469 }
1470
04aa13f8
FD
1471 case BYTECODE_OP_UNARY_PLUS_S64:
1472 case BYTECODE_OP_UNARY_MINUS_S64:
1473 case BYTECODE_OP_UNARY_NOT_S64:
47e5f13e
MD
1474 {
1475 /* Pop 1, push 1 */
1476 if (!vstack_ax(stack)) {
1477 ERR("Empty stack\n");
1478 ret = -EINVAL;
1479 goto end;
1480 }
1481 switch (vstack_ax(stack)->type) {
1482 case REG_S64:
d97f9b78 1483 case REG_U64:
47e5f13e
MD
1484 break;
1485 default:
1486 ERR("Unexpected register type %d for operation\n",
1487 (int) vstack_ax(stack)->type);
1488 ret = -EINVAL;
1489 goto end;
1490 }
1491
47e5f13e
MD
1492 next_pc += sizeof(struct unary_op);
1493 break;
1494 }
1495
04aa13f8 1496 case BYTECODE_OP_UNARY_NOT:
47e5f13e
MD
1497 {
1498 /* Pop 1, push 1 */
1499 if (!vstack_ax(stack)) {
1500 ERR("Empty stack\n");
1501 ret = -EINVAL;
1502 goto end;
1503 }
1504 switch (vstack_ax(stack)->type) {
1505 case REG_UNKNOWN:
1506 case REG_DOUBLE:
1507 case REG_S64:
d97f9b78 1508 case REG_U64:
47e5f13e
MD
1509 break;
1510 default:
1511 ERR("Unexpected register type %d for operation\n",
1512 (int) vstack_ax(stack)->type);
1513 ret = -EINVAL;
1514 goto end;
1515 }
1516
47e5f13e
MD
1517 next_pc += sizeof(struct unary_op);
1518 break;
1519 }
1520
04aa13f8 1521 case BYTECODE_OP_UNARY_BIT_NOT:
0039e2d8
MD
1522 {
1523 /* Pop 1, push 1 */
1524 if (!vstack_ax(stack)) {
1525 ERR("Empty stack\n");
1526 ret = -EINVAL;
1527 goto end;
1528 }
1529 switch (vstack_ax(stack)->type) {
1530 case REG_UNKNOWN:
1531 case REG_S64:
d97f9b78 1532 case REG_U64:
0039e2d8
MD
1533 break;
1534 case REG_DOUBLE:
1535 default:
1536 ERR("Unexpected register type %d for operation\n",
1537 (int) vstack_ax(stack)->type);
1538 ret = -EINVAL;
1539 goto end;
1540 }
1541
d97f9b78 1542 vstack_ax(stack)->type = REG_U64;
0039e2d8
MD
1543 next_pc += sizeof(struct unary_op);
1544 break;
1545 }
1546
04aa13f8 1547 case BYTECODE_OP_UNARY_NOT_DOUBLE:
bf956ec0 1548 {
0305960f
MD
1549 /* Pop 1, push 1 */
1550 if (!vstack_ax(stack)) {
1551 ERR("Empty stack\n");
1552 ret = -EINVAL;
1553 goto end;
1554 }
47e5f13e
MD
1555 switch (vstack_ax(stack)->type) {
1556 case REG_DOUBLE:
1557 break;
1558 default:
1559 ERR("Incorrect register type %d for operation\n",
1560 (int) vstack_ax(stack)->type);
1561 ret = -EINVAL;
1562 goto end;
1563 }
1564
0305960f 1565 vstack_ax(stack)->type = REG_S64;
bf956ec0
MD
1566 next_pc += sizeof(struct unary_op);
1567 break;
1568 }
1569
04aa13f8
FD
1570 case BYTECODE_OP_UNARY_PLUS_DOUBLE:
1571 case BYTECODE_OP_UNARY_MINUS_DOUBLE:
bf956ec0 1572 {
0305960f
MD
1573 /* Pop 1, push 1 */
1574 if (!vstack_ax(stack)) {
1575 ERR("Empty stack\n");
1576 ret = -EINVAL;
1577 goto end;
1578 }
47e5f13e
MD
1579 switch (vstack_ax(stack)->type) {
1580 case REG_DOUBLE:
1581 break;
1582 default:
1583 ERR("Incorrect register type %d for operation\n",
1584 (int) vstack_ax(stack)->type);
1585 ret = -EINVAL;
1586 goto end;
1587 }
1588
0305960f 1589 vstack_ax(stack)->type = REG_DOUBLE;
bf956ec0
MD
1590 next_pc += sizeof(struct unary_op);
1591 break;
1592 }
1593
1594 /* logical */
04aa13f8
FD
1595 case BYTECODE_OP_AND:
1596 case BYTECODE_OP_OR:
bf956ec0
MD
1597 {
1598 struct logical_op *insn = (struct logical_op *) pc;
1599 int merge_ret;
1600
1601 /* Add merge point to table */
71c1ceeb
MD
1602 merge_ret = merge_point_add_check(merge_points,
1603 insn->skip_offset, stack);
bf956ec0
MD
1604 if (merge_ret) {
1605 ret = merge_ret;
1606 goto end;
97b58163 1607 }
47e5f13e
MD
1608
1609 if (!vstack_ax(stack)) {
1610 ERR("Empty stack\n");
1611 ret = -EINVAL;
1612 goto end;
1613 }
1614 /* There is always a cast-to-s64 operation before a or/and op. */
1615 switch (vstack_ax(stack)->type) {
1616 case REG_S64:
d97f9b78 1617 case REG_U64:
47e5f13e
MD
1618 break;
1619 default:
1620 ERR("Incorrect register type %d for operation\n",
1621 (int) vstack_ax(stack)->type);
1622 ret = -EINVAL;
1623 goto end;
1624 }
1625
bf956ec0 1626 /* Continue to next instruction */
71c1ceeb
MD
1627 /* Pop 1 when jump not taken */
1628 if (vstack_pop(stack)) {
1629 ret = -EINVAL;
1630 goto end;
1631 }
bf956ec0
MD
1632 next_pc += sizeof(struct logical_op);
1633 break;
1634 }
1635
77aa5901 1636 /* load field ref */
04aa13f8 1637 case BYTECODE_OP_LOAD_FIELD_REF:
bf956ec0
MD
1638 {
1639 ERR("Unknown field ref type\n");
1640 ret = -EINVAL;
1641 goto end;
1642 }
77aa5901 1643 /* get context ref */
04aa13f8 1644 case BYTECODE_OP_GET_CONTEXT_REF:
77aa5901 1645 {
53569322
MD
1646 if (vstack_push(stack)) {
1647 ret = -EINVAL;
1648 goto end;
1649 }
1650 vstack_ax(stack)->type = REG_UNKNOWN;
1651 next_pc += sizeof(struct load_op) + sizeof(struct field_ref);
1652 break;
77aa5901 1653 }
04aa13f8
FD
1654 case BYTECODE_OP_LOAD_FIELD_REF_STRING:
1655 case BYTECODE_OP_LOAD_FIELD_REF_SEQUENCE:
1656 case BYTECODE_OP_GET_CONTEXT_REF_STRING:
bf956ec0 1657 {
0305960f
MD
1658 if (vstack_push(stack)) {
1659 ret = -EINVAL;
1660 goto end;
1661 }
1662 vstack_ax(stack)->type = REG_STRING;
bf956ec0
MD
1663 next_pc += sizeof(struct load_op) + sizeof(struct field_ref);
1664 break;
1665 }
04aa13f8
FD
1666 case BYTECODE_OP_LOAD_FIELD_REF_S64:
1667 case BYTECODE_OP_GET_CONTEXT_REF_S64:
bf956ec0 1668 {
0305960f
MD
1669 if (vstack_push(stack)) {
1670 ret = -EINVAL;
1671 goto end;
1672 }
1673 vstack_ax(stack)->type = REG_S64;
bf956ec0
MD
1674 next_pc += sizeof(struct load_op) + sizeof(struct field_ref);
1675 break;
1676 }
04aa13f8
FD
1677 case BYTECODE_OP_LOAD_FIELD_REF_DOUBLE:
1678 case BYTECODE_OP_GET_CONTEXT_REF_DOUBLE:
bf956ec0 1679 {
0305960f
MD
1680 if (vstack_push(stack)) {
1681 ret = -EINVAL;
1682 goto end;
1683 }
1684 vstack_ax(stack)->type = REG_DOUBLE;
bf956ec0
MD
1685 next_pc += sizeof(struct load_op) + sizeof(struct field_ref);
1686 break;
1687 }
1688
77aa5901 1689 /* load from immediate operand */
04aa13f8 1690 case BYTECODE_OP_LOAD_STRING:
bf956ec0
MD
1691 {
1692 struct load_op *insn = (struct load_op *) pc;
1693
0305960f
MD
1694 if (vstack_push(stack)) {
1695 ret = -EINVAL;
1696 goto end;
1697 }
1698 vstack_ax(stack)->type = REG_STRING;
bf956ec0
MD
1699 next_pc += sizeof(struct load_op) + strlen(insn->data) + 1;
1700 break;
1701 }
1702
04aa13f8 1703 case BYTECODE_OP_LOAD_STAR_GLOB_STRING:
3151a51d
PP
1704 {
1705 struct load_op *insn = (struct load_op *) pc;
1706
1707 if (vstack_push(stack)) {
1708 ret = -EINVAL;
1709 goto end;
1710 }
1711 vstack_ax(stack)->type = REG_STAR_GLOB_STRING;
1712 next_pc += sizeof(struct load_op) + strlen(insn->data) + 1;
1713 break;
1714 }
1715
04aa13f8 1716 case BYTECODE_OP_LOAD_S64:
bf956ec0 1717 {
0305960f
MD
1718 if (vstack_push(stack)) {
1719 ret = -EINVAL;
1720 goto end;
1721 }
1722 vstack_ax(stack)->type = REG_S64;
bf956ec0
MD
1723 next_pc += sizeof(struct load_op)
1724 + sizeof(struct literal_numeric);
1725 break;
1726 }
1727
04aa13f8 1728 case BYTECODE_OP_LOAD_DOUBLE:
bf956ec0 1729 {
0305960f
MD
1730 if (vstack_push(stack)) {
1731 ret = -EINVAL;
1732 goto end;
1733 }
1734 vstack_ax(stack)->type = REG_DOUBLE;
bf956ec0
MD
1735 next_pc += sizeof(struct load_op)
1736 + sizeof(struct literal_double);
1737 break;
1738 }
1739
04aa13f8
FD
1740 case BYTECODE_OP_CAST_TO_S64:
1741 case BYTECODE_OP_CAST_DOUBLE_TO_S64:
bf956ec0 1742 {
0305960f
MD
1743 /* Pop 1, push 1 */
1744 if (!vstack_ax(stack)) {
1745 ERR("Empty stack\n");
1746 ret = -EINVAL;
1747 goto end;
1748 }
47e5f13e
MD
1749 switch (vstack_ax(stack)->type) {
1750 case REG_S64:
d97f9b78 1751 case REG_U64:
47e5f13e
MD
1752 case REG_DOUBLE:
1753 case REG_UNKNOWN:
1754 break;
1755 default:
1756 ERR("Incorrect register type %d for cast\n",
1757 (int) vstack_ax(stack)->type);
1758 ret = -EINVAL;
1759 goto end;
1760 }
0305960f 1761 vstack_ax(stack)->type = REG_S64;
bf956ec0
MD
1762 next_pc += sizeof(struct cast_op);
1763 break;
1764 }
04aa13f8 1765 case BYTECODE_OP_CAST_NOP:
bf956ec0
MD
1766 {
1767 next_pc += sizeof(struct cast_op);
1768 break;
1769 }
97b58163 1770
47e5f13e
MD
1771 /*
1772 * Instructions for recursive traversal through composed types.
1773 */
04aa13f8
FD
1774 case BYTECODE_OP_GET_CONTEXT_ROOT:
1775 case BYTECODE_OP_GET_APP_CONTEXT_ROOT:
1776 case BYTECODE_OP_GET_PAYLOAD_ROOT:
47e5f13e
MD
1777 {
1778 if (vstack_push(stack)) {
1779 ret = -EINVAL;
1780 goto end;
1781 }
1782 vstack_ax(stack)->type = REG_PTR;
1783 next_pc += sizeof(struct load_op);
1784 break;
1785 }
1786
04aa13f8 1787 case BYTECODE_OP_LOAD_FIELD:
47e5f13e
MD
1788 {
1789 /* Pop 1, push 1 */
1790 if (!vstack_ax(stack)) {
1791 ERR("Empty stack\n");
1792 ret = -EINVAL;
1793 goto end;
1794 }
1795 if (vstack_ax(stack)->type != REG_PTR) {
1796 ERR("Expecting pointer on top of stack\n");
1797 ret = -EINVAL;
1798 goto end;
1799 }
1800 vstack_ax(stack)->type = REG_UNKNOWN;
1801 next_pc += sizeof(struct load_op);
1802 break;
1803 }
1804
04aa13f8
FD
1805 case BYTECODE_OP_LOAD_FIELD_S8:
1806 case BYTECODE_OP_LOAD_FIELD_S16:
1807 case BYTECODE_OP_LOAD_FIELD_S32:
1808 case BYTECODE_OP_LOAD_FIELD_S64:
d97f9b78
MD
1809 {
1810 /* Pop 1, push 1 */
1811 if (!vstack_ax(stack)) {
1812 ERR("Empty stack\n");
1813 ret = -EINVAL;
1814 goto end;
1815 }
1816 if (vstack_ax(stack)->type != REG_PTR) {
1817 ERR("Expecting pointer on top of stack\n");
1818 ret = -EINVAL;
1819 goto end;
1820 }
1821 vstack_ax(stack)->type = REG_S64;
1822 next_pc += sizeof(struct load_op);
1823 break;
1824 }
1825
04aa13f8
FD
1826 case BYTECODE_OP_LOAD_FIELD_U8:
1827 case BYTECODE_OP_LOAD_FIELD_U16:
1828 case BYTECODE_OP_LOAD_FIELD_U32:
1829 case BYTECODE_OP_LOAD_FIELD_U64:
47e5f13e
MD
1830 {
1831 /* Pop 1, push 1 */
1832 if (!vstack_ax(stack)) {
1833 ERR("Empty stack\n");
1834 ret = -EINVAL;
1835 goto end;
1836 }
1837 if (vstack_ax(stack)->type != REG_PTR) {
1838 ERR("Expecting pointer on top of stack\n");
1839 ret = -EINVAL;
1840 goto end;
1841 }
d97f9b78 1842 vstack_ax(stack)->type = REG_U64;
47e5f13e
MD
1843 next_pc += sizeof(struct load_op);
1844 break;
1845 }
1846
04aa13f8
FD
1847 case BYTECODE_OP_LOAD_FIELD_STRING:
1848 case BYTECODE_OP_LOAD_FIELD_SEQUENCE:
47e5f13e
MD
1849 {
1850 /* Pop 1, push 1 */
1851 if (!vstack_ax(stack)) {
1852 ERR("Empty stack\n");
1853 ret = -EINVAL;
1854 goto end;
1855 }
1856 if (vstack_ax(stack)->type != REG_PTR) {
1857 ERR("Expecting pointer on top of stack\n");
1858 ret = -EINVAL;
1859 goto end;
1860 }
1861 vstack_ax(stack)->type = REG_STRING;
1862 next_pc += sizeof(struct load_op);
1863 break;
1864 }
1865
04aa13f8 1866 case BYTECODE_OP_LOAD_FIELD_DOUBLE:
47e5f13e
MD
1867 {
1868 /* Pop 1, push 1 */
1869 if (!vstack_ax(stack)) {
1870 ERR("Empty stack\n");
1871 ret = -EINVAL;
1872 goto end;
1873 }
1874 if (vstack_ax(stack)->type != REG_PTR) {
1875 ERR("Expecting pointer on top of stack\n");
1876 ret = -EINVAL;
1877 goto end;
1878 }
1879 vstack_ax(stack)->type = REG_DOUBLE;
1880 next_pc += sizeof(struct load_op);
1881 break;
1882 }
1883
04aa13f8
FD
1884 case BYTECODE_OP_GET_SYMBOL:
1885 case BYTECODE_OP_GET_SYMBOL_FIELD:
47e5f13e
MD
1886 {
1887 /* Pop 1, push 1 */
1888 if (!vstack_ax(stack)) {
1889 ERR("Empty stack\n");
1890 ret = -EINVAL;
1891 goto end;
1892 }
1893 if (vstack_ax(stack)->type != REG_PTR) {
1894 ERR("Expecting pointer on top of stack\n");
1895 ret = -EINVAL;
1896 goto end;
1897 }
1898 next_pc += sizeof(struct load_op) + sizeof(struct get_symbol);
1899 break;
1900 }
1901
04aa13f8 1902 case BYTECODE_OP_GET_INDEX_U16:
47e5f13e
MD
1903 {
1904 /* Pop 1, push 1 */
1905 if (!vstack_ax(stack)) {
1906 ERR("Empty stack\n");
1907 ret = -EINVAL;
1908 goto end;
1909 }
1910 if (vstack_ax(stack)->type != REG_PTR) {
1911 ERR("Expecting pointer on top of stack\n");
1912 ret = -EINVAL;
1913 goto end;
1914 }
1915 next_pc += sizeof(struct load_op) + sizeof(struct get_index_u16);
1916 break;
1917 }
1918
04aa13f8 1919 case BYTECODE_OP_GET_INDEX_U64:
47e5f13e
MD
1920 {
1921 /* Pop 1, push 1 */
1922 if (!vstack_ax(stack)) {
1923 ERR("Empty stack\n");
1924 ret = -EINVAL;
1925 goto end;
1926 }
1927 if (vstack_ax(stack)->type != REG_PTR) {
1928 ERR("Expecting pointer on top of stack\n");
1929 ret = -EINVAL;
1930 goto end;
1931 }
1932 next_pc += sizeof(struct load_op) + sizeof(struct get_index_u64);
1933 break;
1934 }
1935
bf956ec0
MD
1936 }
1937end:
1938 *_next_pc = next_pc;
1939 return ret;
1940}
1941
1942/*
1943 * Never called concurrently (hash seed is shared).
1944 */
04aa13f8 1945int lttng_bytecode_validate(struct bytecode_runtime *bytecode)
bf956ec0 1946{
10544ee8 1947 struct lttng_ust_lfht *merge_points;
22389ecb 1948 char *pc, *next_pc, *start_pc;
bf956ec0 1949 int ret = -EINVAL;
0305960f 1950 struct vstack stack;
bf956ec0 1951
0305960f 1952 vstack_init(&stack);
bf956ec0
MD
1953
1954 if (!lttng_hash_seed_ready) {
1955 lttng_hash_seed = time(NULL);
1956 lttng_hash_seed_ready = 1;
1957 }
1958 /*
1959 * Note: merge_points hash table used by single thread, and
1960 * never concurrently resized. Therefore, we can use it without
1961 * holding RCU read-side lock and free nodes without using
1962 * call_rcu.
1963 */
10544ee8 1964 merge_points = lttng_ust_lfht_new(DEFAULT_NR_MERGE_POINTS,
bf956ec0
MD
1965 MIN_NR_BUCKETS, MAX_NR_BUCKETS,
1966 0, NULL);
1967 if (!merge_points) {
1968 ERR("Error allocating hash table for bytecode validation\n");
1969 return -ENOMEM;
1970 }
47e5f13e 1971 start_pc = &bytecode->code[0];
bf956ec0
MD
1972 for (pc = next_pc = start_pc; pc - start_pc < bytecode->len;
1973 pc = next_pc) {
82513dbe
MD
1974 ret = bytecode_validate_overflow(bytecode, start_pc, pc);
1975 if (ret != 0) {
1976 if (ret == -ERANGE)
04aa13f8 1977 ERR("Bytecode overflow\n");
bf956ec0 1978 goto end;
97b58163 1979 }
bf956ec0 1980 dbg_printf("Validating op %s (%u)\n",
bf617e20 1981 lttng_bytecode_print_op((unsigned int) *(bytecode_opcode_t *) pc),
04aa13f8 1982 (unsigned int) *(bytecode_opcode_t *) pc);
bf956ec0
MD
1983
1984 /*
1985 * For each instruction, validate the current context
1986 * (traversal of entire execution flow), and validate
53569322 1987 * all merge points targeting this instruction.
bf956ec0
MD
1988 */
1989 ret = validate_instruction_all_contexts(bytecode, merge_points,
0305960f 1990 &stack, start_pc, pc);
bf956ec0
MD
1991 if (ret)
1992 goto end;
0305960f 1993 ret = exec_insn(bytecode, merge_points, &stack, &next_pc, pc);
bf956ec0
MD
1994 if (ret <= 0)
1995 goto end;
97b58163
MD
1996 }
1997end:
bf956ec0
MD
1998 if (delete_all_nodes(merge_points)) {
1999 if (!ret) {
2000 ERR("Unexpected merge points\n");
2001 ret = -EINVAL;
2002 }
2003 }
10544ee8 2004 if (lttng_ust_lfht_destroy(merge_points)) {
bf956ec0
MD
2005 ERR("Error destroying hash table\n");
2006 }
97b58163
MD
2007 return ret;
2008}
This page took 0.13017 seconds and 4 git commands to generate.