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