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