Fix: bytecode validator: reject specialized load instructions
[lttng-ust.git] / src / lib / lttng-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"
cecabda8 17#include "common/hash.h"
b8aa6f43 18#include "common/strutils.h"
36c52fff 19#include "lib/lttng-ust/events.h"
9d315d6d 20#include "common/macros.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 }
c7ef2e7d
MD
1107
1108 /*
1109 * Disallow already specialized bytecode op load field instructions to
1110 * ensure that the received bytecode does not read a memory area larger
1111 * than the memory targeted by the instrumentation.
1112 */
04aa13f8 1113 case BYTECODE_OP_LOAD_FIELD_S8:
04aa13f8 1114 case BYTECODE_OP_LOAD_FIELD_S16:
04aa13f8 1115 case BYTECODE_OP_LOAD_FIELD_S32:
04aa13f8 1116 case BYTECODE_OP_LOAD_FIELD_S64:
04aa13f8 1117 case BYTECODE_OP_LOAD_FIELD_U8:
04aa13f8 1118 case BYTECODE_OP_LOAD_FIELD_U16:
04aa13f8 1119 case BYTECODE_OP_LOAD_FIELD_U32:
04aa13f8 1120 case BYTECODE_OP_LOAD_FIELD_U64:
04aa13f8 1121 case BYTECODE_OP_LOAD_FIELD_STRING:
04aa13f8 1122 case BYTECODE_OP_LOAD_FIELD_SEQUENCE:
04aa13f8 1123 case BYTECODE_OP_LOAD_FIELD_DOUBLE:
47e5f13e 1124 {
c7ef2e7d
MD
1125 dbg_printf("Validate load field, reject specialized load instruction (%d)\n",
1126 (int) opcode);
1127 ret = -EINVAL;
1128 goto end;
47e5f13e
MD
1129 }
1130
04aa13f8 1131 case BYTECODE_OP_GET_SYMBOL:
47e5f13e
MD
1132 {
1133 struct load_op *insn = (struct load_op *) pc;
1134 struct get_symbol *sym = (struct get_symbol *) insn->data;
1135
1136 dbg_printf("Validate get symbol offset %u\n", sym->offset);
1137 break;
1138 }
1139
04aa13f8 1140 case BYTECODE_OP_GET_SYMBOL_FIELD:
47e5f13e
MD
1141 {
1142 struct load_op *insn = (struct load_op *) pc;
1143 struct get_symbol *sym = (struct get_symbol *) insn->data;
1144
1145 dbg_printf("Validate get symbol field offset %u\n", sym->offset);
1146 break;
1147 }
1148
04aa13f8 1149 case BYTECODE_OP_GET_INDEX_U16:
47e5f13e
MD
1150 {
1151 struct load_op *insn = (struct load_op *) pc;
1152 struct get_index_u16 *get_index = (struct get_index_u16 *) insn->data;
1153
1154 dbg_printf("Validate get index u16 index %u\n", get_index->index);
1155 break;
1156 }
1157
04aa13f8 1158 case BYTECODE_OP_GET_INDEX_U64:
47e5f13e
MD
1159 {
1160 struct load_op *insn = (struct load_op *) pc;
1161 struct get_index_u64 *get_index = (struct get_index_u64 *) insn->data;
1162
1163 dbg_printf("Validate get index u64 index %" PRIu64 "\n", get_index->index);
1164 break;
1165 }
bf956ec0
MD
1166 }
1167end:
1168 return ret;
1169}
1170
1171/*
1172 * Return value:
1173 * 0: success
1174 * <0: error
1175 */
1176static
1177int validate_instruction_all_contexts(struct bytecode_runtime *bytecode,
10544ee8 1178 struct lttng_ust_lfht *merge_points,
0305960f 1179 struct vstack *stack,
22389ecb
MD
1180 char *start_pc,
1181 char *pc)
bf956ec0
MD
1182{
1183 int ret;
1184 unsigned long target_pc = pc - start_pc;
10544ee8
MD
1185 struct lttng_ust_lfht_iter iter;
1186 struct lttng_ust_lfht_node *node;
71c1ceeb 1187 struct lfht_mp_node *mp_node;
bf956ec0
MD
1188 unsigned long hash;
1189
1190 /* Validate the context resulting from the previous instruction */
0305960f 1191 ret = validate_instruction_context(bytecode, stack, start_pc, pc);
53569322 1192 if (ret < 0)
bf956ec0
MD
1193 return ret;
1194
1195 /* Validate merge points */
22389ecb 1196 hash = lttng_hash_mix((const char *) target_pc, sizeof(target_pc),
bf956ec0 1197 lttng_hash_seed);
10544ee8 1198 lttng_ust_lfht_lookup(merge_points, hash, lttng_hash_match,
22389ecb 1199 (const char *) target_pc, &iter);
10544ee8 1200 node = lttng_ust_lfht_iter_get_node(&iter);
71c1ceeb
MD
1201 if (node) {
1202 mp_node = caa_container_of(node, struct lfht_mp_node, node);
3151a51d 1203
04aa13f8 1204 dbg_printf("Bytecode: validate merge point at offset %lu\n",
bf956ec0 1205 target_pc);
71c1ceeb
MD
1206 if (merge_points_compare(stack, &mp_node->stack)) {
1207 ERR("Merge points differ for offset %lu\n",
1208 target_pc);
1209 return -EINVAL;
1210 }
bf956ec0 1211 /* Once validated, we can remove the merge point */
04aa13f8 1212 dbg_printf("Bytecode: remove merge point at offset %lu\n",
bf956ec0 1213 target_pc);
10544ee8 1214 ret = lttng_ust_lfht_del(merge_points, node);
bf956ec0
MD
1215 assert(!ret);
1216 }
1217 return 0;
1218}
1219
1220/*
1221 * Return value:
1222 * >0: going to next insn.
1223 * 0: success, stop iteration.
1224 * <0: error
1225 */
1226static
2208d8b5 1227int exec_insn(struct bytecode_runtime *bytecode __attribute__((unused)),
10544ee8 1228 struct lttng_ust_lfht *merge_points,
0305960f 1229 struct vstack *stack,
22389ecb
MD
1230 char **_next_pc,
1231 char *pc)
bf956ec0
MD
1232{
1233 int ret = 1;
22389ecb 1234 char *next_pc = *_next_pc;
bf956ec0 1235
04aa13f8
FD
1236 switch (*(bytecode_opcode_t *) pc) {
1237 case BYTECODE_OP_UNKNOWN:
bf956ec0
MD
1238 default:
1239 {
1240 ERR("unknown bytecode op %u\n",
04aa13f8 1241 (unsigned int) *(bytecode_opcode_t *) pc);
bf956ec0
MD
1242 ret = -EINVAL;
1243 goto end;
1244 }
1245
04aa13f8 1246 case BYTECODE_OP_RETURN:
bf956ec0 1247 {
71c1ceeb
MD
1248 if (!vstack_ax(stack)) {
1249 ERR("Empty stack\n");
1250 ret = -EINVAL;
1251 goto end;
1252 }
47e5f13e
MD
1253 switch (vstack_ax(stack)->type) {
1254 case REG_S64:
d97f9b78 1255 case REG_U64:
09f78acb
FD
1256 case REG_DOUBLE:
1257 case REG_STRING:
1258 case REG_PTR:
47e5f13e
MD
1259 case REG_UNKNOWN:
1260 break;
1261 default:
1262 ERR("Unexpected register type %d at end of bytecode\n",
1263 (int) vstack_ax(stack)->type);
1264 ret = -EINVAL;
1265 goto end;
1266 }
1267
bf956ec0
MD
1268 ret = 0;
1269 goto end;
1270 }
04aa13f8 1271 case BYTECODE_OP_RETURN_S64:
93c591bb
MD
1272 {
1273 if (!vstack_ax(stack)) {
1274 ERR("Empty stack\n");
1275 ret = -EINVAL;
1276 goto end;
1277 }
1278 switch (vstack_ax(stack)->type) {
1279 case REG_S64:
d97f9b78 1280 case REG_U64:
93c591bb
MD
1281 break;
1282 default:
1283 case REG_UNKNOWN:
1284 ERR("Unexpected register type %d at end of bytecode\n",
1285 (int) vstack_ax(stack)->type);
1286 ret = -EINVAL;
1287 goto end;
1288 }
1289
1290 ret = 0;
1291 goto end;
1292 }
bf956ec0
MD
1293
1294 /* binary */
04aa13f8
FD
1295 case BYTECODE_OP_MUL:
1296 case BYTECODE_OP_DIV:
1297 case BYTECODE_OP_MOD:
1298 case BYTECODE_OP_PLUS:
1299 case BYTECODE_OP_MINUS:
bf956ec0
MD
1300 {
1301 ERR("unsupported bytecode op %u\n",
04aa13f8 1302 (unsigned int) *(bytecode_opcode_t *) pc);
bf956ec0
MD
1303 ret = -EINVAL;
1304 goto end;
1305 }
1306
04aa13f8
FD
1307 case BYTECODE_OP_EQ:
1308 case BYTECODE_OP_NE:
1309 case BYTECODE_OP_GT:
1310 case BYTECODE_OP_LT:
1311 case BYTECODE_OP_GE:
1312 case BYTECODE_OP_LE:
1313 case BYTECODE_OP_EQ_STRING:
1314 case BYTECODE_OP_NE_STRING:
1315 case BYTECODE_OP_GT_STRING:
1316 case BYTECODE_OP_LT_STRING:
1317 case BYTECODE_OP_GE_STRING:
1318 case BYTECODE_OP_LE_STRING:
1319 case BYTECODE_OP_EQ_STAR_GLOB_STRING:
1320 case BYTECODE_OP_NE_STAR_GLOB_STRING:
1321 case BYTECODE_OP_EQ_S64:
1322 case BYTECODE_OP_NE_S64:
1323 case BYTECODE_OP_GT_S64:
1324 case BYTECODE_OP_LT_S64:
1325 case BYTECODE_OP_GE_S64:
1326 case BYTECODE_OP_LE_S64:
1327 case BYTECODE_OP_EQ_DOUBLE:
1328 case BYTECODE_OP_NE_DOUBLE:
1329 case BYTECODE_OP_GT_DOUBLE:
1330 case BYTECODE_OP_LT_DOUBLE:
1331 case BYTECODE_OP_GE_DOUBLE:
1332 case BYTECODE_OP_LE_DOUBLE:
1333 case BYTECODE_OP_EQ_DOUBLE_S64:
1334 case BYTECODE_OP_NE_DOUBLE_S64:
1335 case BYTECODE_OP_GT_DOUBLE_S64:
1336 case BYTECODE_OP_LT_DOUBLE_S64:
1337 case BYTECODE_OP_GE_DOUBLE_S64:
1338 case BYTECODE_OP_LE_DOUBLE_S64:
1339 case BYTECODE_OP_EQ_S64_DOUBLE:
1340 case BYTECODE_OP_NE_S64_DOUBLE:
1341 case BYTECODE_OP_GT_S64_DOUBLE:
1342 case BYTECODE_OP_LT_S64_DOUBLE:
1343 case BYTECODE_OP_GE_S64_DOUBLE:
1344 case BYTECODE_OP_LE_S64_DOUBLE:
d97f9b78
MD
1345 {
1346 /* Pop 2, push 1 */
1347 if (vstack_pop(stack)) {
1348 ret = -EINVAL;
1349 goto end;
1350 }
1351 if (!vstack_ax(stack)) {
1352 ERR("Empty stack\n");
1353 ret = -EINVAL;
1354 goto end;
1355 }
1356 switch (vstack_ax(stack)->type) {
1357 case REG_S64:
1358 case REG_U64:
1359 case REG_DOUBLE:
1360 case REG_STRING:
1361 case REG_STAR_GLOB_STRING:
1362 case REG_UNKNOWN:
1363 break;
1364 default:
1365 ERR("Unexpected register type %d for operation\n",
1366 (int) vstack_ax(stack)->type);
1367 ret = -EINVAL;
1368 goto end;
1369 }
1370
1371 vstack_ax(stack)->type = REG_S64;
1372 next_pc += sizeof(struct binary_op);
1373 break;
1374 }
1375
04aa13f8
FD
1376 case BYTECODE_OP_BIT_RSHIFT:
1377 case BYTECODE_OP_BIT_LSHIFT:
1378 case BYTECODE_OP_BIT_AND:
1379 case BYTECODE_OP_BIT_OR:
1380 case BYTECODE_OP_BIT_XOR:
bf956ec0 1381 {
0305960f
MD
1382 /* Pop 2, push 1 */
1383 if (vstack_pop(stack)) {
1384 ret = -EINVAL;
1385 goto end;
1386 }
1387 if (!vstack_ax(stack)) {
1388 ERR("Empty stack\n");
1389 ret = -EINVAL;
1390 goto end;
1391 }
47e5f13e
MD
1392 switch (vstack_ax(stack)->type) {
1393 case REG_S64:
d97f9b78 1394 case REG_U64:
47e5f13e
MD
1395 case REG_DOUBLE:
1396 case REG_STRING:
1397 case REG_STAR_GLOB_STRING:
1398 case REG_UNKNOWN:
1399 break;
1400 default:
1401 ERR("Unexpected register type %d for operation\n",
1402 (int) vstack_ax(stack)->type);
1403 ret = -EINVAL;
1404 goto end;
1405 }
1406
d97f9b78 1407 vstack_ax(stack)->type = REG_U64;
bf956ec0
MD
1408 next_pc += sizeof(struct binary_op);
1409 break;
1410 }
1411
1412 /* unary */
04aa13f8
FD
1413 case BYTECODE_OP_UNARY_PLUS:
1414 case BYTECODE_OP_UNARY_MINUS:
53569322
MD
1415 {
1416 /* Pop 1, push 1 */
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_UNKNOWN:
1424 case REG_DOUBLE:
1425 case REG_S64:
d97f9b78 1426 case REG_U64:
47e5f13e
MD
1427 break;
1428 default:
1429 ERR("Unexpected register type %d for operation\n",
1430 (int) vstack_ax(stack)->type);
1431 ret = -EINVAL;
1432 goto end;
1433 }
53569322
MD
1434 vstack_ax(stack)->type = REG_UNKNOWN;
1435 next_pc += sizeof(struct unary_op);
1436 break;
1437 }
1438
04aa13f8
FD
1439 case BYTECODE_OP_UNARY_PLUS_S64:
1440 case BYTECODE_OP_UNARY_MINUS_S64:
1441 case BYTECODE_OP_UNARY_NOT_S64:
47e5f13e
MD
1442 {
1443 /* Pop 1, push 1 */
1444 if (!vstack_ax(stack)) {
1445 ERR("Empty stack\n");
1446 ret = -EINVAL;
1447 goto end;
1448 }
1449 switch (vstack_ax(stack)->type) {
1450 case REG_S64:
d97f9b78 1451 case REG_U64:
47e5f13e
MD
1452 break;
1453 default:
1454 ERR("Unexpected register type %d for operation\n",
1455 (int) vstack_ax(stack)->type);
1456 ret = -EINVAL;
1457 goto end;
1458 }
1459
47e5f13e
MD
1460 next_pc += sizeof(struct unary_op);
1461 break;
1462 }
1463
04aa13f8 1464 case BYTECODE_OP_UNARY_NOT:
47e5f13e
MD
1465 {
1466 /* Pop 1, push 1 */
1467 if (!vstack_ax(stack)) {
1468 ERR("Empty stack\n");
1469 ret = -EINVAL;
1470 goto end;
1471 }
1472 switch (vstack_ax(stack)->type) {
1473 case REG_UNKNOWN:
1474 case REG_DOUBLE:
1475 case REG_S64:
d97f9b78 1476 case REG_U64:
47e5f13e
MD
1477 break;
1478 default:
1479 ERR("Unexpected register type %d for operation\n",
1480 (int) vstack_ax(stack)->type);
1481 ret = -EINVAL;
1482 goto end;
1483 }
1484
47e5f13e
MD
1485 next_pc += sizeof(struct unary_op);
1486 break;
1487 }
1488
04aa13f8 1489 case BYTECODE_OP_UNARY_BIT_NOT:
0039e2d8
MD
1490 {
1491 /* Pop 1, push 1 */
1492 if (!vstack_ax(stack)) {
1493 ERR("Empty stack\n");
1494 ret = -EINVAL;
1495 goto end;
1496 }
1497 switch (vstack_ax(stack)->type) {
1498 case REG_UNKNOWN:
1499 case REG_S64:
d97f9b78 1500 case REG_U64:
0039e2d8
MD
1501 break;
1502 case REG_DOUBLE:
1503 default:
1504 ERR("Unexpected register type %d for operation\n",
1505 (int) vstack_ax(stack)->type);
1506 ret = -EINVAL;
1507 goto end;
1508 }
1509
d97f9b78 1510 vstack_ax(stack)->type = REG_U64;
0039e2d8
MD
1511 next_pc += sizeof(struct unary_op);
1512 break;
1513 }
1514
04aa13f8 1515 case BYTECODE_OP_UNARY_NOT_DOUBLE:
bf956ec0 1516 {
0305960f
MD
1517 /* Pop 1, push 1 */
1518 if (!vstack_ax(stack)) {
1519 ERR("Empty stack\n");
1520 ret = -EINVAL;
1521 goto end;
1522 }
47e5f13e
MD
1523 switch (vstack_ax(stack)->type) {
1524 case REG_DOUBLE:
1525 break;
1526 default:
1527 ERR("Incorrect register type %d for operation\n",
1528 (int) vstack_ax(stack)->type);
1529 ret = -EINVAL;
1530 goto end;
1531 }
1532
0305960f 1533 vstack_ax(stack)->type = REG_S64;
bf956ec0
MD
1534 next_pc += sizeof(struct unary_op);
1535 break;
1536 }
1537
04aa13f8
FD
1538 case BYTECODE_OP_UNARY_PLUS_DOUBLE:
1539 case BYTECODE_OP_UNARY_MINUS_DOUBLE:
bf956ec0 1540 {
0305960f
MD
1541 /* Pop 1, push 1 */
1542 if (!vstack_ax(stack)) {
1543 ERR("Empty stack\n");
1544 ret = -EINVAL;
1545 goto end;
1546 }
47e5f13e
MD
1547 switch (vstack_ax(stack)->type) {
1548 case REG_DOUBLE:
1549 break;
1550 default:
1551 ERR("Incorrect register type %d for operation\n",
1552 (int) vstack_ax(stack)->type);
1553 ret = -EINVAL;
1554 goto end;
1555 }
1556
0305960f 1557 vstack_ax(stack)->type = REG_DOUBLE;
bf956ec0
MD
1558 next_pc += sizeof(struct unary_op);
1559 break;
1560 }
1561
1562 /* logical */
04aa13f8
FD
1563 case BYTECODE_OP_AND:
1564 case BYTECODE_OP_OR:
bf956ec0
MD
1565 {
1566 struct logical_op *insn = (struct logical_op *) pc;
1567 int merge_ret;
1568
1569 /* Add merge point to table */
71c1ceeb
MD
1570 merge_ret = merge_point_add_check(merge_points,
1571 insn->skip_offset, stack);
bf956ec0
MD
1572 if (merge_ret) {
1573 ret = merge_ret;
1574 goto end;
97b58163 1575 }
47e5f13e
MD
1576
1577 if (!vstack_ax(stack)) {
1578 ERR("Empty stack\n");
1579 ret = -EINVAL;
1580 goto end;
1581 }
1582 /* There is always a cast-to-s64 operation before a or/and op. */
1583 switch (vstack_ax(stack)->type) {
1584 case REG_S64:
d97f9b78 1585 case REG_U64:
47e5f13e
MD
1586 break;
1587 default:
1588 ERR("Incorrect register type %d for operation\n",
1589 (int) vstack_ax(stack)->type);
1590 ret = -EINVAL;
1591 goto end;
1592 }
1593
bf956ec0 1594 /* Continue to next instruction */
71c1ceeb
MD
1595 /* Pop 1 when jump not taken */
1596 if (vstack_pop(stack)) {
1597 ret = -EINVAL;
1598 goto end;
1599 }
bf956ec0
MD
1600 next_pc += sizeof(struct logical_op);
1601 break;
1602 }
1603
77aa5901 1604 /* load field ref */
04aa13f8 1605 case BYTECODE_OP_LOAD_FIELD_REF:
bf956ec0
MD
1606 {
1607 ERR("Unknown field ref type\n");
1608 ret = -EINVAL;
1609 goto end;
1610 }
77aa5901 1611 /* get context ref */
04aa13f8 1612 case BYTECODE_OP_GET_CONTEXT_REF:
77aa5901 1613 {
53569322
MD
1614 if (vstack_push(stack)) {
1615 ret = -EINVAL;
1616 goto end;
1617 }
1618 vstack_ax(stack)->type = REG_UNKNOWN;
1619 next_pc += sizeof(struct load_op) + sizeof(struct field_ref);
1620 break;
77aa5901 1621 }
04aa13f8
FD
1622 case BYTECODE_OP_LOAD_FIELD_REF_STRING:
1623 case BYTECODE_OP_LOAD_FIELD_REF_SEQUENCE:
1624 case BYTECODE_OP_GET_CONTEXT_REF_STRING:
bf956ec0 1625 {
0305960f
MD
1626 if (vstack_push(stack)) {
1627 ret = -EINVAL;
1628 goto end;
1629 }
1630 vstack_ax(stack)->type = REG_STRING;
bf956ec0
MD
1631 next_pc += sizeof(struct load_op) + sizeof(struct field_ref);
1632 break;
1633 }
04aa13f8
FD
1634 case BYTECODE_OP_LOAD_FIELD_REF_S64:
1635 case BYTECODE_OP_GET_CONTEXT_REF_S64:
bf956ec0 1636 {
0305960f
MD
1637 if (vstack_push(stack)) {
1638 ret = -EINVAL;
1639 goto end;
1640 }
1641 vstack_ax(stack)->type = REG_S64;
bf956ec0
MD
1642 next_pc += sizeof(struct load_op) + sizeof(struct field_ref);
1643 break;
1644 }
04aa13f8
FD
1645 case BYTECODE_OP_LOAD_FIELD_REF_DOUBLE:
1646 case BYTECODE_OP_GET_CONTEXT_REF_DOUBLE:
bf956ec0 1647 {
0305960f
MD
1648 if (vstack_push(stack)) {
1649 ret = -EINVAL;
1650 goto end;
1651 }
1652 vstack_ax(stack)->type = REG_DOUBLE;
bf956ec0
MD
1653 next_pc += sizeof(struct load_op) + sizeof(struct field_ref);
1654 break;
1655 }
1656
77aa5901 1657 /* load from immediate operand */
04aa13f8 1658 case BYTECODE_OP_LOAD_STRING:
bf956ec0
MD
1659 {
1660 struct load_op *insn = (struct load_op *) pc;
1661
0305960f
MD
1662 if (vstack_push(stack)) {
1663 ret = -EINVAL;
1664 goto end;
1665 }
1666 vstack_ax(stack)->type = REG_STRING;
bf956ec0
MD
1667 next_pc += sizeof(struct load_op) + strlen(insn->data) + 1;
1668 break;
1669 }
1670
04aa13f8 1671 case BYTECODE_OP_LOAD_STAR_GLOB_STRING:
3151a51d
PP
1672 {
1673 struct load_op *insn = (struct load_op *) pc;
1674
1675 if (vstack_push(stack)) {
1676 ret = -EINVAL;
1677 goto end;
1678 }
1679 vstack_ax(stack)->type = REG_STAR_GLOB_STRING;
1680 next_pc += sizeof(struct load_op) + strlen(insn->data) + 1;
1681 break;
1682 }
1683
04aa13f8 1684 case BYTECODE_OP_LOAD_S64:
bf956ec0 1685 {
0305960f
MD
1686 if (vstack_push(stack)) {
1687 ret = -EINVAL;
1688 goto end;
1689 }
1690 vstack_ax(stack)->type = REG_S64;
bf956ec0
MD
1691 next_pc += sizeof(struct load_op)
1692 + sizeof(struct literal_numeric);
1693 break;
1694 }
1695
04aa13f8 1696 case BYTECODE_OP_LOAD_DOUBLE:
bf956ec0 1697 {
0305960f
MD
1698 if (vstack_push(stack)) {
1699 ret = -EINVAL;
1700 goto end;
1701 }
1702 vstack_ax(stack)->type = REG_DOUBLE;
bf956ec0
MD
1703 next_pc += sizeof(struct load_op)
1704 + sizeof(struct literal_double);
1705 break;
1706 }
1707
04aa13f8
FD
1708 case BYTECODE_OP_CAST_TO_S64:
1709 case BYTECODE_OP_CAST_DOUBLE_TO_S64:
bf956ec0 1710 {
0305960f
MD
1711 /* Pop 1, push 1 */
1712 if (!vstack_ax(stack)) {
1713 ERR("Empty stack\n");
1714 ret = -EINVAL;
1715 goto end;
1716 }
47e5f13e
MD
1717 switch (vstack_ax(stack)->type) {
1718 case REG_S64:
d97f9b78 1719 case REG_U64:
47e5f13e
MD
1720 case REG_DOUBLE:
1721 case REG_UNKNOWN:
1722 break;
1723 default:
1724 ERR("Incorrect register type %d for cast\n",
1725 (int) vstack_ax(stack)->type);
1726 ret = -EINVAL;
1727 goto end;
1728 }
0305960f 1729 vstack_ax(stack)->type = REG_S64;
bf956ec0
MD
1730 next_pc += sizeof(struct cast_op);
1731 break;
1732 }
04aa13f8 1733 case BYTECODE_OP_CAST_NOP:
bf956ec0
MD
1734 {
1735 next_pc += sizeof(struct cast_op);
1736 break;
1737 }
97b58163 1738
47e5f13e
MD
1739 /*
1740 * Instructions for recursive traversal through composed types.
1741 */
04aa13f8
FD
1742 case BYTECODE_OP_GET_CONTEXT_ROOT:
1743 case BYTECODE_OP_GET_APP_CONTEXT_ROOT:
1744 case BYTECODE_OP_GET_PAYLOAD_ROOT:
47e5f13e
MD
1745 {
1746 if (vstack_push(stack)) {
1747 ret = -EINVAL;
1748 goto end;
1749 }
1750 vstack_ax(stack)->type = REG_PTR;
1751 next_pc += sizeof(struct load_op);
1752 break;
1753 }
1754
04aa13f8 1755 case BYTECODE_OP_LOAD_FIELD:
47e5f13e
MD
1756 {
1757 /* Pop 1, push 1 */
1758 if (!vstack_ax(stack)) {
1759 ERR("Empty stack\n");
1760 ret = -EINVAL;
1761 goto end;
1762 }
1763 if (vstack_ax(stack)->type != REG_PTR) {
1764 ERR("Expecting pointer on top of stack\n");
1765 ret = -EINVAL;
1766 goto end;
1767 }
1768 vstack_ax(stack)->type = REG_UNKNOWN;
1769 next_pc += sizeof(struct load_op);
1770 break;
1771 }
1772
04aa13f8
FD
1773 case BYTECODE_OP_LOAD_FIELD_S8:
1774 case BYTECODE_OP_LOAD_FIELD_S16:
1775 case BYTECODE_OP_LOAD_FIELD_S32:
1776 case BYTECODE_OP_LOAD_FIELD_S64:
d97f9b78
MD
1777 {
1778 /* Pop 1, push 1 */
1779 if (!vstack_ax(stack)) {
1780 ERR("Empty stack\n");
1781 ret = -EINVAL;
1782 goto end;
1783 }
1784 if (vstack_ax(stack)->type != REG_PTR) {
1785 ERR("Expecting pointer on top of stack\n");
1786 ret = -EINVAL;
1787 goto end;
1788 }
1789 vstack_ax(stack)->type = REG_S64;
1790 next_pc += sizeof(struct load_op);
1791 break;
1792 }
1793
04aa13f8
FD
1794 case BYTECODE_OP_LOAD_FIELD_U8:
1795 case BYTECODE_OP_LOAD_FIELD_U16:
1796 case BYTECODE_OP_LOAD_FIELD_U32:
1797 case BYTECODE_OP_LOAD_FIELD_U64:
47e5f13e
MD
1798 {
1799 /* Pop 1, push 1 */
1800 if (!vstack_ax(stack)) {
1801 ERR("Empty stack\n");
1802 ret = -EINVAL;
1803 goto end;
1804 }
1805 if (vstack_ax(stack)->type != REG_PTR) {
1806 ERR("Expecting pointer on top of stack\n");
1807 ret = -EINVAL;
1808 goto end;
1809 }
d97f9b78 1810 vstack_ax(stack)->type = REG_U64;
47e5f13e
MD
1811 next_pc += sizeof(struct load_op);
1812 break;
1813 }
1814
04aa13f8
FD
1815 case BYTECODE_OP_LOAD_FIELD_STRING:
1816 case BYTECODE_OP_LOAD_FIELD_SEQUENCE:
47e5f13e
MD
1817 {
1818 /* Pop 1, push 1 */
1819 if (!vstack_ax(stack)) {
1820 ERR("Empty stack\n");
1821 ret = -EINVAL;
1822 goto end;
1823 }
1824 if (vstack_ax(stack)->type != REG_PTR) {
1825 ERR("Expecting pointer on top of stack\n");
1826 ret = -EINVAL;
1827 goto end;
1828 }
1829 vstack_ax(stack)->type = REG_STRING;
1830 next_pc += sizeof(struct load_op);
1831 break;
1832 }
1833
04aa13f8 1834 case BYTECODE_OP_LOAD_FIELD_DOUBLE:
47e5f13e
MD
1835 {
1836 /* Pop 1, push 1 */
1837 if (!vstack_ax(stack)) {
1838 ERR("Empty stack\n");
1839 ret = -EINVAL;
1840 goto end;
1841 }
1842 if (vstack_ax(stack)->type != REG_PTR) {
1843 ERR("Expecting pointer on top of stack\n");
1844 ret = -EINVAL;
1845 goto end;
1846 }
1847 vstack_ax(stack)->type = REG_DOUBLE;
1848 next_pc += sizeof(struct load_op);
1849 break;
1850 }
1851
04aa13f8
FD
1852 case BYTECODE_OP_GET_SYMBOL:
1853 case BYTECODE_OP_GET_SYMBOL_FIELD:
47e5f13e
MD
1854 {
1855 /* Pop 1, push 1 */
1856 if (!vstack_ax(stack)) {
1857 ERR("Empty stack\n");
1858 ret = -EINVAL;
1859 goto end;
1860 }
1861 if (vstack_ax(stack)->type != REG_PTR) {
1862 ERR("Expecting pointer on top of stack\n");
1863 ret = -EINVAL;
1864 goto end;
1865 }
1866 next_pc += sizeof(struct load_op) + sizeof(struct get_symbol);
1867 break;
1868 }
1869
04aa13f8 1870 case BYTECODE_OP_GET_INDEX_U16:
47e5f13e
MD
1871 {
1872 /* Pop 1, push 1 */
1873 if (!vstack_ax(stack)) {
1874 ERR("Empty stack\n");
1875 ret = -EINVAL;
1876 goto end;
1877 }
1878 if (vstack_ax(stack)->type != REG_PTR) {
1879 ERR("Expecting pointer on top of stack\n");
1880 ret = -EINVAL;
1881 goto end;
1882 }
1883 next_pc += sizeof(struct load_op) + sizeof(struct get_index_u16);
1884 break;
1885 }
1886
04aa13f8 1887 case BYTECODE_OP_GET_INDEX_U64:
47e5f13e
MD
1888 {
1889 /* Pop 1, push 1 */
1890 if (!vstack_ax(stack)) {
1891 ERR("Empty stack\n");
1892 ret = -EINVAL;
1893 goto end;
1894 }
1895 if (vstack_ax(stack)->type != REG_PTR) {
1896 ERR("Expecting pointer on top of stack\n");
1897 ret = -EINVAL;
1898 goto end;
1899 }
1900 next_pc += sizeof(struct load_op) + sizeof(struct get_index_u64);
1901 break;
1902 }
1903
bf956ec0
MD
1904 }
1905end:
1906 *_next_pc = next_pc;
1907 return ret;
1908}
1909
1910/*
1911 * Never called concurrently (hash seed is shared).
1912 */
04aa13f8 1913int lttng_bytecode_validate(struct bytecode_runtime *bytecode)
bf956ec0 1914{
10544ee8 1915 struct lttng_ust_lfht *merge_points;
22389ecb 1916 char *pc, *next_pc, *start_pc;
bf956ec0 1917 int ret = -EINVAL;
0305960f 1918 struct vstack stack;
bf956ec0 1919
0305960f 1920 vstack_init(&stack);
bf956ec0
MD
1921
1922 if (!lttng_hash_seed_ready) {
1923 lttng_hash_seed = time(NULL);
1924 lttng_hash_seed_ready = 1;
1925 }
1926 /*
1927 * Note: merge_points hash table used by single thread, and
1928 * never concurrently resized. Therefore, we can use it without
1929 * holding RCU read-side lock and free nodes without using
1930 * call_rcu.
1931 */
10544ee8 1932 merge_points = lttng_ust_lfht_new(DEFAULT_NR_MERGE_POINTS,
bf956ec0
MD
1933 MIN_NR_BUCKETS, MAX_NR_BUCKETS,
1934 0, NULL);
1935 if (!merge_points) {
1936 ERR("Error allocating hash table for bytecode validation\n");
1937 return -ENOMEM;
1938 }
47e5f13e 1939 start_pc = &bytecode->code[0];
bf956ec0
MD
1940 for (pc = next_pc = start_pc; pc - start_pc < bytecode->len;
1941 pc = next_pc) {
82513dbe
MD
1942 ret = bytecode_validate_overflow(bytecode, start_pc, pc);
1943 if (ret != 0) {
1944 if (ret == -ERANGE)
04aa13f8 1945 ERR("Bytecode overflow\n");
bf956ec0 1946 goto end;
97b58163 1947 }
bf956ec0 1948 dbg_printf("Validating op %s (%u)\n",
bf617e20 1949 lttng_bytecode_print_op((unsigned int) *(bytecode_opcode_t *) pc),
04aa13f8 1950 (unsigned int) *(bytecode_opcode_t *) pc);
bf956ec0
MD
1951
1952 /*
1953 * For each instruction, validate the current context
1954 * (traversal of entire execution flow), and validate
53569322 1955 * all merge points targeting this instruction.
bf956ec0
MD
1956 */
1957 ret = validate_instruction_all_contexts(bytecode, merge_points,
0305960f 1958 &stack, start_pc, pc);
bf956ec0
MD
1959 if (ret)
1960 goto end;
0305960f 1961 ret = exec_insn(bytecode, merge_points, &stack, &next_pc, pc);
bf956ec0
MD
1962 if (ret <= 0)
1963 goto end;
97b58163
MD
1964 }
1965end:
bf956ec0
MD
1966 if (delete_all_nodes(merge_points)) {
1967 if (!ret) {
1968 ERR("Unexpected merge points\n");
1969 ret = -EINVAL;
1970 }
1971 }
10544ee8 1972 if (lttng_ust_lfht_destroy(merge_points)) {
bf956ec0
MD
1973 ERR("Error destroying hash table\n");
1974 }
97b58163
MD
1975 return ret;
1976}
This page took 0.132736 seconds and 4 git commands to generate.