2 * SPDX-License-Identifier: MIT
4 * Copyright (C) 2010-2016 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
6 * LTTng UST bytecode validator.
14 #include "rculfhash.h"
16 #include "lttng-bytecode.h"
17 #include "lttng-hash-helper.h"
18 #include "string-utils.h"
19 #include "ust-events-internal.h"
20 #include "ust-helper.h"
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.
28 #define DEFAULT_NR_MERGE_POINTS 128
29 #define MIN_NR_BUCKETS 128
30 #define MAX_NR_BUCKETS 128
32 /* merge point table node */
34 struct lttng_ust_lfht_node node
;
36 /* Context at merge point */
38 unsigned long target_pc
;
41 static unsigned long lttng_hash_seed
;
42 static unsigned int lttng_hash_seed_ready
;
45 int lttng_hash_match(struct lttng_ust_lfht_node
*node
, const void *key
)
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
;
51 if (mp_node
->target_pc
== key_pc
)
58 int merge_points_compare(const struct vstack
*stacka
,
59 const struct vstack
*stackb
)
63 if (stacka
->top
!= stackb
->top
)
65 len
= stacka
->top
+ 1;
67 for (i
= 0; i
< len
; i
++) {
68 if (stacka
->e
[i
].type
!= REG_UNKNOWN
69 && stackb
->e
[i
].type
!= REG_UNKNOWN
70 && stacka
->e
[i
].type
!= stackb
->e
[i
].type
)
77 int merge_point_add_check(struct lttng_ust_lfht
*ht
, unsigned long target_pc
,
78 const struct vstack
*stack
)
80 struct lfht_mp_node
*node
;
81 unsigned long hash
= lttng_hash_mix((const char *) target_pc
,
84 struct lttng_ust_lfht_node
*ret
;
86 dbg_printf("Bytecode: adding merge point at offset %lu, hash %lu\n",
88 node
= zmalloc(sizeof(struct lfht_mp_node
));
91 node
->target_pc
= target_pc
;
92 memcpy(&node
->stack
, stack
, sizeof(node
->stack
));
93 ret
= lttng_ust_lfht_add_unique(ht
, hash
, lttng_hash_match
,
94 (const char *) target_pc
, &node
->node
);
95 if (ret
!= &node
->node
) {
96 struct lfht_mp_node
*ret_mp
=
97 caa_container_of(ret
, struct lfht_mp_node
, node
);
99 /* Key already present */
100 dbg_printf("Bytecode: compare merge points for offset %lu, hash %lu\n",
103 if (merge_points_compare(stack
, &ret_mp
->stack
)) {
104 ERR("Merge points differ for offset %lu\n",
113 * Binary comparators use top of stack and top of stack -1.
114 * Return 0 if typing is known to match, 1 if typing is dynamic
115 * (unknown), negative error value on error.
118 int bin_op_compare_check(struct vstack
*stack
, bytecode_opcode_t opcode
,
121 if (unlikely(!vstack_ax(stack
) || !vstack_bx(stack
)))
124 switch (vstack_ax(stack
)->type
) {
131 switch (vstack_bx(stack
)->type
) {
139 case REG_STAR_GLOB_STRING
:
140 if (opcode
!= BYTECODE_OP_EQ
&& opcode
!= BYTECODE_OP_NE
) {
150 case REG_STAR_GLOB_STRING
:
151 switch (vstack_bx(stack
)->type
) {
158 if (opcode
!= BYTECODE_OP_EQ
&& opcode
!= BYTECODE_OP_NE
) {
162 case REG_STAR_GLOB_STRING
:
172 switch (vstack_bx(stack
)->type
) {
179 case REG_STAR_GLOB_STRING
:
194 ERR("type mismatch for '%s' binary operator\n", str
);
198 ERR("empty stack for '%s' binary operator\n", str
);
202 ERR("unknown type for '%s' binary operator\n", str
);
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.
212 int bin_op_bitwise_check(struct vstack
*stack
, bytecode_opcode_t opcode
,
215 if (unlikely(!vstack_ax(stack
) || !vstack_bx(stack
)))
218 switch (vstack_ax(stack
)->type
) {
226 switch (vstack_bx(stack
)->type
) {
244 ERR("empty stack for '%s' binary operator\n", str
);
248 ERR("unknown type for '%s' binary operator\n", str
);
253 int validate_get_symbol(struct bytecode_runtime
*bytecode
,
254 const struct get_symbol
*sym
)
256 const char *str
, *str_limit
;
259 if (sym
->offset
>= bytecode
->p
.bc
->bc
.len
- bytecode
->p
.bc
->bc
.reloc_offset
)
262 str
= bytecode
->p
.bc
->bc
.data
+ bytecode
->p
.bc
->bc
.reloc_offset
+ sym
->offset
;
263 str_limit
= bytecode
->p
.bc
->bc
.data
+ bytecode
->p
.bc
->bc
.len
;
264 len_limit
= str_limit
- str
;
265 if (strnlen(str
, len_limit
) == len_limit
)
271 * Validate bytecode range overflow within the validation pass.
272 * Called for each instruction encountered.
275 int bytecode_validate_overflow(struct bytecode_runtime
*bytecode
,
276 char *start_pc
, char *pc
)
280 switch (*(bytecode_opcode_t
*) pc
) {
281 case BYTECODE_OP_UNKNOWN
:
284 ERR("unknown bytecode op %u\n",
285 (unsigned int) *(bytecode_opcode_t
*) pc
);
290 case BYTECODE_OP_RETURN
:
291 case BYTECODE_OP_RETURN_S64
:
293 if (unlikely(pc
+ sizeof(struct return_op
)
294 > start_pc
+ bytecode
->len
)) {
301 case BYTECODE_OP_MUL
:
302 case BYTECODE_OP_DIV
:
303 case BYTECODE_OP_MOD
:
304 case BYTECODE_OP_PLUS
:
305 case BYTECODE_OP_MINUS
:
307 ERR("unsupported bytecode op %u\n",
308 (unsigned int) *(bytecode_opcode_t
*) pc
);
319 case BYTECODE_OP_EQ_STRING
:
320 case BYTECODE_OP_NE_STRING
:
321 case BYTECODE_OP_GT_STRING
:
322 case BYTECODE_OP_LT_STRING
:
323 case BYTECODE_OP_GE_STRING
:
324 case BYTECODE_OP_LE_STRING
:
325 case BYTECODE_OP_EQ_STAR_GLOB_STRING
:
326 case BYTECODE_OP_NE_STAR_GLOB_STRING
:
327 case BYTECODE_OP_EQ_S64
:
328 case BYTECODE_OP_NE_S64
:
329 case BYTECODE_OP_GT_S64
:
330 case BYTECODE_OP_LT_S64
:
331 case BYTECODE_OP_GE_S64
:
332 case BYTECODE_OP_LE_S64
:
333 case BYTECODE_OP_EQ_DOUBLE
:
334 case BYTECODE_OP_NE_DOUBLE
:
335 case BYTECODE_OP_GT_DOUBLE
:
336 case BYTECODE_OP_LT_DOUBLE
:
337 case BYTECODE_OP_GE_DOUBLE
:
338 case BYTECODE_OP_LE_DOUBLE
:
339 case BYTECODE_OP_EQ_DOUBLE_S64
:
340 case BYTECODE_OP_NE_DOUBLE_S64
:
341 case BYTECODE_OP_GT_DOUBLE_S64
:
342 case BYTECODE_OP_LT_DOUBLE_S64
:
343 case BYTECODE_OP_GE_DOUBLE_S64
:
344 case BYTECODE_OP_LE_DOUBLE_S64
:
345 case BYTECODE_OP_EQ_S64_DOUBLE
:
346 case BYTECODE_OP_NE_S64_DOUBLE
:
347 case BYTECODE_OP_GT_S64_DOUBLE
:
348 case BYTECODE_OP_LT_S64_DOUBLE
:
349 case BYTECODE_OP_GE_S64_DOUBLE
:
350 case BYTECODE_OP_LE_S64_DOUBLE
:
351 case BYTECODE_OP_BIT_RSHIFT
:
352 case BYTECODE_OP_BIT_LSHIFT
:
353 case BYTECODE_OP_BIT_AND
:
354 case BYTECODE_OP_BIT_OR
:
355 case BYTECODE_OP_BIT_XOR
:
357 if (unlikely(pc
+ sizeof(struct binary_op
)
358 > start_pc
+ bytecode
->len
)) {
365 case BYTECODE_OP_UNARY_PLUS
:
366 case BYTECODE_OP_UNARY_MINUS
:
367 case BYTECODE_OP_UNARY_NOT
:
368 case BYTECODE_OP_UNARY_PLUS_S64
:
369 case BYTECODE_OP_UNARY_MINUS_S64
:
370 case BYTECODE_OP_UNARY_NOT_S64
:
371 case BYTECODE_OP_UNARY_PLUS_DOUBLE
:
372 case BYTECODE_OP_UNARY_MINUS_DOUBLE
:
373 case BYTECODE_OP_UNARY_NOT_DOUBLE
:
374 case BYTECODE_OP_UNARY_BIT_NOT
:
376 if (unlikely(pc
+ sizeof(struct unary_op
)
377 > start_pc
+ bytecode
->len
)) {
384 case BYTECODE_OP_AND
:
387 if (unlikely(pc
+ sizeof(struct logical_op
)
388 > start_pc
+ bytecode
->len
)) {
395 case BYTECODE_OP_LOAD_FIELD_REF
:
397 ERR("Unknown field ref type\n");
402 /* get context ref */
403 case BYTECODE_OP_GET_CONTEXT_REF
:
404 case BYTECODE_OP_LOAD_FIELD_REF_STRING
:
405 case BYTECODE_OP_LOAD_FIELD_REF_SEQUENCE
:
406 case BYTECODE_OP_LOAD_FIELD_REF_S64
:
407 case BYTECODE_OP_LOAD_FIELD_REF_DOUBLE
:
408 case BYTECODE_OP_GET_CONTEXT_REF_STRING
:
409 case BYTECODE_OP_GET_CONTEXT_REF_S64
:
410 case BYTECODE_OP_GET_CONTEXT_REF_DOUBLE
:
412 if (unlikely(pc
+ sizeof(struct load_op
) + sizeof(struct field_ref
)
413 > start_pc
+ bytecode
->len
)) {
419 /* load from immediate operand */
420 case BYTECODE_OP_LOAD_STRING
:
421 case BYTECODE_OP_LOAD_STAR_GLOB_STRING
:
423 struct load_op
*insn
= (struct load_op
*) pc
;
424 uint32_t str_len
, maxlen
;
426 if (unlikely(pc
+ sizeof(struct load_op
)
427 > start_pc
+ bytecode
->len
)) {
432 maxlen
= start_pc
+ bytecode
->len
- pc
- sizeof(struct load_op
);
433 str_len
= strnlen(insn
->data
, maxlen
);
434 if (unlikely(str_len
>= maxlen
)) {
435 /* Final '\0' not found within range */
441 case BYTECODE_OP_LOAD_S64
:
443 if (unlikely(pc
+ sizeof(struct load_op
) + sizeof(struct literal_numeric
)
444 > start_pc
+ bytecode
->len
)) {
450 case BYTECODE_OP_LOAD_DOUBLE
:
452 if (unlikely(pc
+ sizeof(struct load_op
) + sizeof(struct literal_double
)
453 > start_pc
+ bytecode
->len
)) {
459 case BYTECODE_OP_CAST_TO_S64
:
460 case BYTECODE_OP_CAST_DOUBLE_TO_S64
:
461 case BYTECODE_OP_CAST_NOP
:
463 if (unlikely(pc
+ sizeof(struct cast_op
)
464 > start_pc
+ bytecode
->len
)) {
471 * Instructions for recursive traversal through composed types.
473 case BYTECODE_OP_GET_CONTEXT_ROOT
:
474 case BYTECODE_OP_GET_APP_CONTEXT_ROOT
:
475 case BYTECODE_OP_GET_PAYLOAD_ROOT
:
476 case BYTECODE_OP_LOAD_FIELD
:
477 case BYTECODE_OP_LOAD_FIELD_S8
:
478 case BYTECODE_OP_LOAD_FIELD_S16
:
479 case BYTECODE_OP_LOAD_FIELD_S32
:
480 case BYTECODE_OP_LOAD_FIELD_S64
:
481 case BYTECODE_OP_LOAD_FIELD_U8
:
482 case BYTECODE_OP_LOAD_FIELD_U16
:
483 case BYTECODE_OP_LOAD_FIELD_U32
:
484 case BYTECODE_OP_LOAD_FIELD_U64
:
485 case BYTECODE_OP_LOAD_FIELD_STRING
:
486 case BYTECODE_OP_LOAD_FIELD_SEQUENCE
:
487 case BYTECODE_OP_LOAD_FIELD_DOUBLE
:
488 if (unlikely(pc
+ sizeof(struct load_op
)
489 > start_pc
+ bytecode
->len
)) {
494 case BYTECODE_OP_GET_SYMBOL
:
496 struct load_op
*insn
= (struct load_op
*) pc
;
497 struct get_symbol
*sym
= (struct get_symbol
*) insn
->data
;
499 if (unlikely(pc
+ sizeof(struct load_op
) + sizeof(struct get_symbol
)
500 > start_pc
+ bytecode
->len
)) {
504 ret
= validate_get_symbol(bytecode
, sym
);
508 case BYTECODE_OP_GET_SYMBOL_FIELD
:
509 ERR("Unexpected get symbol field");
513 case BYTECODE_OP_GET_INDEX_U16
:
514 if (unlikely(pc
+ sizeof(struct load_op
) + sizeof(struct get_index_u16
)
515 > start_pc
+ bytecode
->len
)) {
520 case BYTECODE_OP_GET_INDEX_U64
:
521 if (unlikely(pc
+ sizeof(struct load_op
) + sizeof(struct get_index_u64
)
522 > start_pc
+ bytecode
->len
)) {
532 unsigned long delete_all_nodes(struct lttng_ust_lfht
*ht
)
534 struct lttng_ust_lfht_iter iter
;
535 struct lfht_mp_node
*node
;
536 unsigned long nr_nodes
= 0;
538 lttng_ust_lfht_for_each_entry(ht
, &iter
, node
, node
) {
541 ret
= lttng_ust_lfht_del(ht
, lttng_ust_lfht_iter_get_node(&iter
));
543 /* note: this hash table is never used concurrently */
556 int validate_instruction_context(struct bytecode_runtime
*bytecode
,
557 struct vstack
*stack
,
562 const bytecode_opcode_t opcode
= *(bytecode_opcode_t
*) pc
;
565 case BYTECODE_OP_UNKNOWN
:
568 ERR("unknown bytecode op %u\n",
569 (unsigned int) *(bytecode_opcode_t
*) pc
);
574 case BYTECODE_OP_RETURN
:
575 case BYTECODE_OP_RETURN_S64
:
581 case BYTECODE_OP_MUL
:
582 case BYTECODE_OP_DIV
:
583 case BYTECODE_OP_MOD
:
584 case BYTECODE_OP_PLUS
:
585 case BYTECODE_OP_MINUS
:
587 ERR("unsupported bytecode op %u\n",
588 (unsigned int) opcode
);
595 ret
= bin_op_compare_check(stack
, opcode
, "==");
602 ret
= bin_op_compare_check(stack
, opcode
, "!=");
609 ret
= bin_op_compare_check(stack
, opcode
, ">");
616 ret
= bin_op_compare_check(stack
, opcode
, "<");
623 ret
= bin_op_compare_check(stack
, opcode
, ">=");
630 ret
= bin_op_compare_check(stack
, opcode
, "<=");
636 case BYTECODE_OP_EQ_STRING
:
637 case BYTECODE_OP_NE_STRING
:
638 case BYTECODE_OP_GT_STRING
:
639 case BYTECODE_OP_LT_STRING
:
640 case BYTECODE_OP_GE_STRING
:
641 case BYTECODE_OP_LE_STRING
:
643 if (!vstack_ax(stack
) || !vstack_bx(stack
)) {
644 ERR("Empty stack\n");
648 if (vstack_ax(stack
)->type
!= REG_STRING
649 || vstack_bx(stack
)->type
!= REG_STRING
) {
650 ERR("Unexpected register type for string comparator\n");
657 case BYTECODE_OP_EQ_STAR_GLOB_STRING
:
658 case BYTECODE_OP_NE_STAR_GLOB_STRING
:
660 if (!vstack_ax(stack
) || !vstack_bx(stack
)) {
661 ERR("Empty stack\n");
665 if (vstack_ax(stack
)->type
!= REG_STAR_GLOB_STRING
666 && vstack_bx(stack
)->type
!= REG_STAR_GLOB_STRING
) {
667 ERR("Unexpected register type for globbing pattern comparator\n");
674 case BYTECODE_OP_EQ_S64
:
675 case BYTECODE_OP_NE_S64
:
676 case BYTECODE_OP_GT_S64
:
677 case BYTECODE_OP_LT_S64
:
678 case BYTECODE_OP_GE_S64
:
679 case BYTECODE_OP_LE_S64
:
681 if (!vstack_ax(stack
) || !vstack_bx(stack
)) {
682 ERR("Empty stack\n");
686 switch (vstack_ax(stack
)->type
) {
691 ERR("Unexpected register type for s64 comparator\n");
695 switch (vstack_bx(stack
)->type
) {
700 ERR("Unexpected register type for s64 comparator\n");
707 case BYTECODE_OP_EQ_DOUBLE
:
708 case BYTECODE_OP_NE_DOUBLE
:
709 case BYTECODE_OP_GT_DOUBLE
:
710 case BYTECODE_OP_LT_DOUBLE
:
711 case BYTECODE_OP_GE_DOUBLE
:
712 case BYTECODE_OP_LE_DOUBLE
:
714 if (!vstack_ax(stack
) || !vstack_bx(stack
)) {
715 ERR("Empty stack\n");
719 if (vstack_ax(stack
)->type
!= REG_DOUBLE
&& vstack_bx(stack
)->type
!= REG_DOUBLE
) {
720 ERR("Double operator should have two double registers\n");
727 case BYTECODE_OP_EQ_DOUBLE_S64
:
728 case BYTECODE_OP_NE_DOUBLE_S64
:
729 case BYTECODE_OP_GT_DOUBLE_S64
:
730 case BYTECODE_OP_LT_DOUBLE_S64
:
731 case BYTECODE_OP_GE_DOUBLE_S64
:
732 case BYTECODE_OP_LE_DOUBLE_S64
:
734 if (!vstack_ax(stack
) || !vstack_bx(stack
)) {
735 ERR("Empty stack\n");
739 switch (vstack_ax(stack
)->type
) {
744 ERR("Double-S64 operator has unexpected register types\n");
748 switch (vstack_bx(stack
)->type
) {
752 ERR("Double-S64 operator has unexpected register types\n");
759 case BYTECODE_OP_EQ_S64_DOUBLE
:
760 case BYTECODE_OP_NE_S64_DOUBLE
:
761 case BYTECODE_OP_GT_S64_DOUBLE
:
762 case BYTECODE_OP_LT_S64_DOUBLE
:
763 case BYTECODE_OP_GE_S64_DOUBLE
:
764 case BYTECODE_OP_LE_S64_DOUBLE
:
766 if (!vstack_ax(stack
) || !vstack_bx(stack
)) {
767 ERR("Empty stack\n");
771 switch (vstack_ax(stack
)->type
) {
775 ERR("S64-Double operator has unexpected register types\n");
779 switch (vstack_bx(stack
)->type
) {
784 ERR("S64-Double operator has unexpected register types\n");
791 case BYTECODE_OP_BIT_RSHIFT
:
792 ret
= bin_op_bitwise_check(stack
, opcode
, ">>");
796 case BYTECODE_OP_BIT_LSHIFT
:
797 ret
= bin_op_bitwise_check(stack
, opcode
, "<<");
801 case BYTECODE_OP_BIT_AND
:
802 ret
= bin_op_bitwise_check(stack
, opcode
, "&");
806 case BYTECODE_OP_BIT_OR
:
807 ret
= bin_op_bitwise_check(stack
, opcode
, "|");
811 case BYTECODE_OP_BIT_XOR
:
812 ret
= bin_op_bitwise_check(stack
, opcode
, "^");
818 case BYTECODE_OP_UNARY_PLUS
:
819 case BYTECODE_OP_UNARY_MINUS
:
820 case BYTECODE_OP_UNARY_NOT
:
822 if (!vstack_ax(stack
)) {
823 ERR("Empty stack\n");
827 switch (vstack_ax(stack
)->type
) {
829 ERR("unknown register type\n");
834 case REG_STAR_GLOB_STRING
:
835 ERR("Unary op can only be applied to numeric or floating point registers\n");
849 case BYTECODE_OP_UNARY_BIT_NOT
:
851 if (!vstack_ax(stack
)) {
852 ERR("Empty stack\n");
856 switch (vstack_ax(stack
)->type
) {
858 ERR("unknown register type\n");
863 case REG_STAR_GLOB_STRING
:
865 ERR("Unary bitwise op can only be applied to numeric registers\n");
878 case BYTECODE_OP_UNARY_PLUS_S64
:
879 case BYTECODE_OP_UNARY_MINUS_S64
:
880 case BYTECODE_OP_UNARY_NOT_S64
:
882 if (!vstack_ax(stack
)) {
883 ERR("Empty stack\n");
887 if (vstack_ax(stack
)->type
!= REG_S64
&&
888 vstack_ax(stack
)->type
!= REG_U64
) {
889 ERR("Invalid register type\n");
896 case BYTECODE_OP_UNARY_PLUS_DOUBLE
:
897 case BYTECODE_OP_UNARY_MINUS_DOUBLE
:
898 case BYTECODE_OP_UNARY_NOT_DOUBLE
:
900 if (!vstack_ax(stack
)) {
901 ERR("Empty stack\n");
905 if (vstack_ax(stack
)->type
!= REG_DOUBLE
) {
906 ERR("Invalid register type\n");
914 case BYTECODE_OP_AND
:
917 struct logical_op
*insn
= (struct logical_op
*) pc
;
919 if (!vstack_ax(stack
)) {
920 ERR("Empty stack\n");
924 if (vstack_ax(stack
)->type
!= REG_S64
925 && vstack_ax(stack
)->type
!= REG_U64
926 && vstack_ax(stack
)->type
!= REG_UNKNOWN
) {
927 ERR("Logical comparator expects S64, U64 or dynamic register\n");
932 dbg_printf("Validate jumping to bytecode offset %u\n",
933 (unsigned int) insn
->skip_offset
);
934 if (unlikely(start_pc
+ insn
->skip_offset
<= pc
)) {
935 ERR("Loops are not allowed in bytecode\n");
943 case BYTECODE_OP_LOAD_FIELD_REF
:
945 ERR("Unknown field ref type\n");
949 case BYTECODE_OP_LOAD_FIELD_REF_STRING
:
950 case BYTECODE_OP_LOAD_FIELD_REF_SEQUENCE
:
952 struct load_op
*insn
= (struct load_op
*) pc
;
953 struct field_ref
*ref
= (struct field_ref
*) insn
->data
;
955 dbg_printf("Validate load field ref offset %u type string\n",
959 case BYTECODE_OP_LOAD_FIELD_REF_S64
:
961 struct load_op
*insn
= (struct load_op
*) pc
;
962 struct field_ref
*ref
= (struct field_ref
*) insn
->data
;
964 dbg_printf("Validate load field ref offset %u type s64\n",
968 case BYTECODE_OP_LOAD_FIELD_REF_DOUBLE
:
970 struct load_op
*insn
= (struct load_op
*) pc
;
971 struct field_ref
*ref
= (struct field_ref
*) insn
->data
;
973 dbg_printf("Validate load field ref offset %u type double\n",
978 /* load from immediate operand */
979 case BYTECODE_OP_LOAD_STRING
:
980 case BYTECODE_OP_LOAD_STAR_GLOB_STRING
:
985 case BYTECODE_OP_LOAD_S64
:
990 case BYTECODE_OP_LOAD_DOUBLE
:
995 case BYTECODE_OP_CAST_TO_S64
:
996 case BYTECODE_OP_CAST_DOUBLE_TO_S64
:
998 struct cast_op
*insn
= (struct cast_op
*) pc
;
1000 if (!vstack_ax(stack
)) {
1001 ERR("Empty stack\n");
1005 switch (vstack_ax(stack
)->type
) {
1007 ERR("unknown register type\n");
1012 case REG_STAR_GLOB_STRING
:
1013 ERR("Cast op can only be applied to numeric or floating point registers\n");
1025 if (insn
->op
== BYTECODE_OP_CAST_DOUBLE_TO_S64
) {
1026 if (vstack_ax(stack
)->type
!= REG_DOUBLE
) {
1027 ERR("Cast expects double\n");
1034 case BYTECODE_OP_CAST_NOP
:
1039 /* get context ref */
1040 case BYTECODE_OP_GET_CONTEXT_REF
:
1042 struct load_op
*insn
= (struct load_op
*) pc
;
1043 struct field_ref
*ref
= (struct field_ref
*) insn
->data
;
1045 dbg_printf("Validate get context ref offset %u type dynamic\n",
1049 case BYTECODE_OP_GET_CONTEXT_REF_STRING
:
1051 struct load_op
*insn
= (struct load_op
*) pc
;
1052 struct field_ref
*ref
= (struct field_ref
*) insn
->data
;
1054 dbg_printf("Validate get context ref offset %u type string\n",
1058 case BYTECODE_OP_GET_CONTEXT_REF_S64
:
1060 struct load_op
*insn
= (struct load_op
*) pc
;
1061 struct field_ref
*ref
= (struct field_ref
*) insn
->data
;
1063 dbg_printf("Validate get context ref offset %u type s64\n",
1067 case BYTECODE_OP_GET_CONTEXT_REF_DOUBLE
:
1069 struct load_op
*insn
= (struct load_op
*) pc
;
1070 struct field_ref
*ref
= (struct field_ref
*) insn
->data
;
1072 dbg_printf("Validate get context ref offset %u type double\n",
1078 * Instructions for recursive traversal through composed types.
1080 case BYTECODE_OP_GET_CONTEXT_ROOT
:
1082 dbg_printf("Validate get context root\n");
1085 case BYTECODE_OP_GET_APP_CONTEXT_ROOT
:
1087 dbg_printf("Validate get app context root\n");
1090 case BYTECODE_OP_GET_PAYLOAD_ROOT
:
1092 dbg_printf("Validate get payload root\n");
1095 case BYTECODE_OP_LOAD_FIELD
:
1098 * We tolerate that field type is unknown at validation,
1099 * because we are performing the load specialization in
1100 * a phase after validation.
1102 dbg_printf("Validate load field\n");
1105 case BYTECODE_OP_LOAD_FIELD_S8
:
1107 dbg_printf("Validate load field s8\n");
1110 case BYTECODE_OP_LOAD_FIELD_S16
:
1112 dbg_printf("Validate load field s16\n");
1115 case BYTECODE_OP_LOAD_FIELD_S32
:
1117 dbg_printf("Validate load field s32\n");
1120 case BYTECODE_OP_LOAD_FIELD_S64
:
1122 dbg_printf("Validate load field s64\n");
1125 case BYTECODE_OP_LOAD_FIELD_U8
:
1127 dbg_printf("Validate load field u8\n");
1130 case BYTECODE_OP_LOAD_FIELD_U16
:
1132 dbg_printf("Validate load field u16\n");
1135 case BYTECODE_OP_LOAD_FIELD_U32
:
1137 dbg_printf("Validate load field u32\n");
1140 case BYTECODE_OP_LOAD_FIELD_U64
:
1142 dbg_printf("Validate load field u64\n");
1145 case BYTECODE_OP_LOAD_FIELD_STRING
:
1147 dbg_printf("Validate load field string\n");
1150 case BYTECODE_OP_LOAD_FIELD_SEQUENCE
:
1152 dbg_printf("Validate load field sequence\n");
1155 case BYTECODE_OP_LOAD_FIELD_DOUBLE
:
1157 dbg_printf("Validate load field double\n");
1161 case BYTECODE_OP_GET_SYMBOL
:
1163 struct load_op
*insn
= (struct load_op
*) pc
;
1164 struct get_symbol
*sym
= (struct get_symbol
*) insn
->data
;
1166 dbg_printf("Validate get symbol offset %u\n", sym
->offset
);
1170 case BYTECODE_OP_GET_SYMBOL_FIELD
:
1172 struct load_op
*insn
= (struct load_op
*) pc
;
1173 struct get_symbol
*sym
= (struct get_symbol
*) insn
->data
;
1175 dbg_printf("Validate get symbol field offset %u\n", sym
->offset
);
1179 case BYTECODE_OP_GET_INDEX_U16
:
1181 struct load_op
*insn
= (struct load_op
*) pc
;
1182 struct get_index_u16
*get_index
= (struct get_index_u16
*) insn
->data
;
1184 dbg_printf("Validate get index u16 index %u\n", get_index
->index
);
1188 case BYTECODE_OP_GET_INDEX_U64
:
1190 struct load_op
*insn
= (struct load_op
*) pc
;
1191 struct get_index_u64
*get_index
= (struct get_index_u64
*) insn
->data
;
1193 dbg_printf("Validate get index u64 index %" PRIu64
"\n", get_index
->index
);
1207 int validate_instruction_all_contexts(struct bytecode_runtime
*bytecode
,
1208 struct lttng_ust_lfht
*merge_points
,
1209 struct vstack
*stack
,
1214 unsigned long target_pc
= pc
- start_pc
;
1215 struct lttng_ust_lfht_iter iter
;
1216 struct lttng_ust_lfht_node
*node
;
1217 struct lfht_mp_node
*mp_node
;
1220 /* Validate the context resulting from the previous instruction */
1221 ret
= validate_instruction_context(bytecode
, stack
, start_pc
, pc
);
1225 /* Validate merge points */
1226 hash
= lttng_hash_mix((const char *) target_pc
, sizeof(target_pc
),
1228 lttng_ust_lfht_lookup(merge_points
, hash
, lttng_hash_match
,
1229 (const char *) target_pc
, &iter
);
1230 node
= lttng_ust_lfht_iter_get_node(&iter
);
1232 mp_node
= caa_container_of(node
, struct lfht_mp_node
, node
);
1234 dbg_printf("Bytecode: validate merge point at offset %lu\n",
1236 if (merge_points_compare(stack
, &mp_node
->stack
)) {
1237 ERR("Merge points differ for offset %lu\n",
1241 /* Once validated, we can remove the merge point */
1242 dbg_printf("Bytecode: remove merge point at offset %lu\n",
1244 ret
= lttng_ust_lfht_del(merge_points
, node
);
1252 * >0: going to next insn.
1253 * 0: success, stop iteration.
1257 int exec_insn(struct bytecode_runtime
*bytecode
,
1258 struct lttng_ust_lfht
*merge_points
,
1259 struct vstack
*stack
,
1264 char *next_pc
= *_next_pc
;
1266 switch (*(bytecode_opcode_t
*) pc
) {
1267 case BYTECODE_OP_UNKNOWN
:
1270 ERR("unknown bytecode op %u\n",
1271 (unsigned int) *(bytecode_opcode_t
*) pc
);
1276 case BYTECODE_OP_RETURN
:
1278 if (!vstack_ax(stack
)) {
1279 ERR("Empty stack\n");
1283 switch (vstack_ax(stack
)->type
) {
1292 ERR("Unexpected register type %d at end of bytecode\n",
1293 (int) vstack_ax(stack
)->type
);
1301 case BYTECODE_OP_RETURN_S64
:
1303 if (!vstack_ax(stack
)) {
1304 ERR("Empty stack\n");
1308 switch (vstack_ax(stack
)->type
) {
1314 ERR("Unexpected register type %d at end of bytecode\n",
1315 (int) vstack_ax(stack
)->type
);
1325 case BYTECODE_OP_MUL
:
1326 case BYTECODE_OP_DIV
:
1327 case BYTECODE_OP_MOD
:
1328 case BYTECODE_OP_PLUS
:
1329 case BYTECODE_OP_MINUS
:
1331 ERR("unsupported bytecode op %u\n",
1332 (unsigned int) *(bytecode_opcode_t
*) pc
);
1337 case BYTECODE_OP_EQ
:
1338 case BYTECODE_OP_NE
:
1339 case BYTECODE_OP_GT
:
1340 case BYTECODE_OP_LT
:
1341 case BYTECODE_OP_GE
:
1342 case BYTECODE_OP_LE
:
1343 case BYTECODE_OP_EQ_STRING
:
1344 case BYTECODE_OP_NE_STRING
:
1345 case BYTECODE_OP_GT_STRING
:
1346 case BYTECODE_OP_LT_STRING
:
1347 case BYTECODE_OP_GE_STRING
:
1348 case BYTECODE_OP_LE_STRING
:
1349 case BYTECODE_OP_EQ_STAR_GLOB_STRING
:
1350 case BYTECODE_OP_NE_STAR_GLOB_STRING
:
1351 case BYTECODE_OP_EQ_S64
:
1352 case BYTECODE_OP_NE_S64
:
1353 case BYTECODE_OP_GT_S64
:
1354 case BYTECODE_OP_LT_S64
:
1355 case BYTECODE_OP_GE_S64
:
1356 case BYTECODE_OP_LE_S64
:
1357 case BYTECODE_OP_EQ_DOUBLE
:
1358 case BYTECODE_OP_NE_DOUBLE
:
1359 case BYTECODE_OP_GT_DOUBLE
:
1360 case BYTECODE_OP_LT_DOUBLE
:
1361 case BYTECODE_OP_GE_DOUBLE
:
1362 case BYTECODE_OP_LE_DOUBLE
:
1363 case BYTECODE_OP_EQ_DOUBLE_S64
:
1364 case BYTECODE_OP_NE_DOUBLE_S64
:
1365 case BYTECODE_OP_GT_DOUBLE_S64
:
1366 case BYTECODE_OP_LT_DOUBLE_S64
:
1367 case BYTECODE_OP_GE_DOUBLE_S64
:
1368 case BYTECODE_OP_LE_DOUBLE_S64
:
1369 case BYTECODE_OP_EQ_S64_DOUBLE
:
1370 case BYTECODE_OP_NE_S64_DOUBLE
:
1371 case BYTECODE_OP_GT_S64_DOUBLE
:
1372 case BYTECODE_OP_LT_S64_DOUBLE
:
1373 case BYTECODE_OP_GE_S64_DOUBLE
:
1374 case BYTECODE_OP_LE_S64_DOUBLE
:
1377 if (vstack_pop(stack
)) {
1381 if (!vstack_ax(stack
)) {
1382 ERR("Empty stack\n");
1386 switch (vstack_ax(stack
)->type
) {
1391 case REG_STAR_GLOB_STRING
:
1395 ERR("Unexpected register type %d for operation\n",
1396 (int) vstack_ax(stack
)->type
);
1401 vstack_ax(stack
)->type
= REG_S64
;
1402 next_pc
+= sizeof(struct binary_op
);
1406 case BYTECODE_OP_BIT_RSHIFT
:
1407 case BYTECODE_OP_BIT_LSHIFT
:
1408 case BYTECODE_OP_BIT_AND
:
1409 case BYTECODE_OP_BIT_OR
:
1410 case BYTECODE_OP_BIT_XOR
:
1413 if (vstack_pop(stack
)) {
1417 if (!vstack_ax(stack
)) {
1418 ERR("Empty stack\n");
1422 switch (vstack_ax(stack
)->type
) {
1427 case REG_STAR_GLOB_STRING
:
1431 ERR("Unexpected register type %d for operation\n",
1432 (int) vstack_ax(stack
)->type
);
1437 vstack_ax(stack
)->type
= REG_U64
;
1438 next_pc
+= sizeof(struct binary_op
);
1443 case BYTECODE_OP_UNARY_PLUS
:
1444 case BYTECODE_OP_UNARY_MINUS
:
1447 if (!vstack_ax(stack
)) {
1448 ERR("Empty stack\n");
1452 switch (vstack_ax(stack
)->type
) {
1459 ERR("Unexpected register type %d for operation\n",
1460 (int) vstack_ax(stack
)->type
);
1464 vstack_ax(stack
)->type
= REG_UNKNOWN
;
1465 next_pc
+= sizeof(struct unary_op
);
1469 case BYTECODE_OP_UNARY_PLUS_S64
:
1470 case BYTECODE_OP_UNARY_MINUS_S64
:
1471 case BYTECODE_OP_UNARY_NOT_S64
:
1474 if (!vstack_ax(stack
)) {
1475 ERR("Empty stack\n");
1479 switch (vstack_ax(stack
)->type
) {
1484 ERR("Unexpected register type %d for operation\n",
1485 (int) vstack_ax(stack
)->type
);
1490 next_pc
+= sizeof(struct unary_op
);
1494 case BYTECODE_OP_UNARY_NOT
:
1497 if (!vstack_ax(stack
)) {
1498 ERR("Empty stack\n");
1502 switch (vstack_ax(stack
)->type
) {
1509 ERR("Unexpected register type %d for operation\n",
1510 (int) vstack_ax(stack
)->type
);
1515 next_pc
+= sizeof(struct unary_op
);
1519 case BYTECODE_OP_UNARY_BIT_NOT
:
1522 if (!vstack_ax(stack
)) {
1523 ERR("Empty stack\n");
1527 switch (vstack_ax(stack
)->type
) {
1534 ERR("Unexpected register type %d for operation\n",
1535 (int) vstack_ax(stack
)->type
);
1540 vstack_ax(stack
)->type
= REG_U64
;
1541 next_pc
+= sizeof(struct unary_op
);
1545 case BYTECODE_OP_UNARY_NOT_DOUBLE
:
1548 if (!vstack_ax(stack
)) {
1549 ERR("Empty stack\n");
1553 switch (vstack_ax(stack
)->type
) {
1557 ERR("Incorrect register type %d for operation\n",
1558 (int) vstack_ax(stack
)->type
);
1563 vstack_ax(stack
)->type
= REG_S64
;
1564 next_pc
+= sizeof(struct unary_op
);
1568 case BYTECODE_OP_UNARY_PLUS_DOUBLE
:
1569 case BYTECODE_OP_UNARY_MINUS_DOUBLE
:
1572 if (!vstack_ax(stack
)) {
1573 ERR("Empty stack\n");
1577 switch (vstack_ax(stack
)->type
) {
1581 ERR("Incorrect register type %d for operation\n",
1582 (int) vstack_ax(stack
)->type
);
1587 vstack_ax(stack
)->type
= REG_DOUBLE
;
1588 next_pc
+= sizeof(struct unary_op
);
1593 case BYTECODE_OP_AND
:
1594 case BYTECODE_OP_OR
:
1596 struct logical_op
*insn
= (struct logical_op
*) pc
;
1599 /* Add merge point to table */
1600 merge_ret
= merge_point_add_check(merge_points
,
1601 insn
->skip_offset
, stack
);
1607 if (!vstack_ax(stack
)) {
1608 ERR("Empty stack\n");
1612 /* There is always a cast-to-s64 operation before a or/and op. */
1613 switch (vstack_ax(stack
)->type
) {
1618 ERR("Incorrect register type %d for operation\n",
1619 (int) vstack_ax(stack
)->type
);
1624 /* Continue to next instruction */
1625 /* Pop 1 when jump not taken */
1626 if (vstack_pop(stack
)) {
1630 next_pc
+= sizeof(struct logical_op
);
1634 /* load field ref */
1635 case BYTECODE_OP_LOAD_FIELD_REF
:
1637 ERR("Unknown field ref type\n");
1641 /* get context ref */
1642 case BYTECODE_OP_GET_CONTEXT_REF
:
1644 if (vstack_push(stack
)) {
1648 vstack_ax(stack
)->type
= REG_UNKNOWN
;
1649 next_pc
+= sizeof(struct load_op
) + sizeof(struct field_ref
);
1652 case BYTECODE_OP_LOAD_FIELD_REF_STRING
:
1653 case BYTECODE_OP_LOAD_FIELD_REF_SEQUENCE
:
1654 case BYTECODE_OP_GET_CONTEXT_REF_STRING
:
1656 if (vstack_push(stack
)) {
1660 vstack_ax(stack
)->type
= REG_STRING
;
1661 next_pc
+= sizeof(struct load_op
) + sizeof(struct field_ref
);
1664 case BYTECODE_OP_LOAD_FIELD_REF_S64
:
1665 case BYTECODE_OP_GET_CONTEXT_REF_S64
:
1667 if (vstack_push(stack
)) {
1671 vstack_ax(stack
)->type
= REG_S64
;
1672 next_pc
+= sizeof(struct load_op
) + sizeof(struct field_ref
);
1675 case BYTECODE_OP_LOAD_FIELD_REF_DOUBLE
:
1676 case BYTECODE_OP_GET_CONTEXT_REF_DOUBLE
:
1678 if (vstack_push(stack
)) {
1682 vstack_ax(stack
)->type
= REG_DOUBLE
;
1683 next_pc
+= sizeof(struct load_op
) + sizeof(struct field_ref
);
1687 /* load from immediate operand */
1688 case BYTECODE_OP_LOAD_STRING
:
1690 struct load_op
*insn
= (struct load_op
*) pc
;
1692 if (vstack_push(stack
)) {
1696 vstack_ax(stack
)->type
= REG_STRING
;
1697 next_pc
+= sizeof(struct load_op
) + strlen(insn
->data
) + 1;
1701 case BYTECODE_OP_LOAD_STAR_GLOB_STRING
:
1703 struct load_op
*insn
= (struct load_op
*) pc
;
1705 if (vstack_push(stack
)) {
1709 vstack_ax(stack
)->type
= REG_STAR_GLOB_STRING
;
1710 next_pc
+= sizeof(struct load_op
) + strlen(insn
->data
) + 1;
1714 case BYTECODE_OP_LOAD_S64
:
1716 if (vstack_push(stack
)) {
1720 vstack_ax(stack
)->type
= REG_S64
;
1721 next_pc
+= sizeof(struct load_op
)
1722 + sizeof(struct literal_numeric
);
1726 case BYTECODE_OP_LOAD_DOUBLE
:
1728 if (vstack_push(stack
)) {
1732 vstack_ax(stack
)->type
= REG_DOUBLE
;
1733 next_pc
+= sizeof(struct load_op
)
1734 + sizeof(struct literal_double
);
1738 case BYTECODE_OP_CAST_TO_S64
:
1739 case BYTECODE_OP_CAST_DOUBLE_TO_S64
:
1742 if (!vstack_ax(stack
)) {
1743 ERR("Empty stack\n");
1747 switch (vstack_ax(stack
)->type
) {
1754 ERR("Incorrect register type %d for cast\n",
1755 (int) vstack_ax(stack
)->type
);
1759 vstack_ax(stack
)->type
= REG_S64
;
1760 next_pc
+= sizeof(struct cast_op
);
1763 case BYTECODE_OP_CAST_NOP
:
1765 next_pc
+= sizeof(struct cast_op
);
1770 * Instructions for recursive traversal through composed types.
1772 case BYTECODE_OP_GET_CONTEXT_ROOT
:
1773 case BYTECODE_OP_GET_APP_CONTEXT_ROOT
:
1774 case BYTECODE_OP_GET_PAYLOAD_ROOT
:
1776 if (vstack_push(stack
)) {
1780 vstack_ax(stack
)->type
= REG_PTR
;
1781 next_pc
+= sizeof(struct load_op
);
1785 case BYTECODE_OP_LOAD_FIELD
:
1788 if (!vstack_ax(stack
)) {
1789 ERR("Empty stack\n");
1793 if (vstack_ax(stack
)->type
!= REG_PTR
) {
1794 ERR("Expecting pointer on top of stack\n");
1798 vstack_ax(stack
)->type
= REG_UNKNOWN
;
1799 next_pc
+= sizeof(struct load_op
);
1803 case BYTECODE_OP_LOAD_FIELD_S8
:
1804 case BYTECODE_OP_LOAD_FIELD_S16
:
1805 case BYTECODE_OP_LOAD_FIELD_S32
:
1806 case BYTECODE_OP_LOAD_FIELD_S64
:
1809 if (!vstack_ax(stack
)) {
1810 ERR("Empty stack\n");
1814 if (vstack_ax(stack
)->type
!= REG_PTR
) {
1815 ERR("Expecting pointer on top of stack\n");
1819 vstack_ax(stack
)->type
= REG_S64
;
1820 next_pc
+= sizeof(struct load_op
);
1824 case BYTECODE_OP_LOAD_FIELD_U8
:
1825 case BYTECODE_OP_LOAD_FIELD_U16
:
1826 case BYTECODE_OP_LOAD_FIELD_U32
:
1827 case BYTECODE_OP_LOAD_FIELD_U64
:
1830 if (!vstack_ax(stack
)) {
1831 ERR("Empty stack\n");
1835 if (vstack_ax(stack
)->type
!= REG_PTR
) {
1836 ERR("Expecting pointer on top of stack\n");
1840 vstack_ax(stack
)->type
= REG_U64
;
1841 next_pc
+= sizeof(struct load_op
);
1845 case BYTECODE_OP_LOAD_FIELD_STRING
:
1846 case BYTECODE_OP_LOAD_FIELD_SEQUENCE
:
1849 if (!vstack_ax(stack
)) {
1850 ERR("Empty stack\n");
1854 if (vstack_ax(stack
)->type
!= REG_PTR
) {
1855 ERR("Expecting pointer on top of stack\n");
1859 vstack_ax(stack
)->type
= REG_STRING
;
1860 next_pc
+= sizeof(struct load_op
);
1864 case BYTECODE_OP_LOAD_FIELD_DOUBLE
:
1867 if (!vstack_ax(stack
)) {
1868 ERR("Empty stack\n");
1872 if (vstack_ax(stack
)->type
!= REG_PTR
) {
1873 ERR("Expecting pointer on top of stack\n");
1877 vstack_ax(stack
)->type
= REG_DOUBLE
;
1878 next_pc
+= sizeof(struct load_op
);
1882 case BYTECODE_OP_GET_SYMBOL
:
1883 case BYTECODE_OP_GET_SYMBOL_FIELD
:
1886 if (!vstack_ax(stack
)) {
1887 ERR("Empty stack\n");
1891 if (vstack_ax(stack
)->type
!= REG_PTR
) {
1892 ERR("Expecting pointer on top of stack\n");
1896 next_pc
+= sizeof(struct load_op
) + sizeof(struct get_symbol
);
1900 case BYTECODE_OP_GET_INDEX_U16
:
1903 if (!vstack_ax(stack
)) {
1904 ERR("Empty stack\n");
1908 if (vstack_ax(stack
)->type
!= REG_PTR
) {
1909 ERR("Expecting pointer on top of stack\n");
1913 next_pc
+= sizeof(struct load_op
) + sizeof(struct get_index_u16
);
1917 case BYTECODE_OP_GET_INDEX_U64
:
1920 if (!vstack_ax(stack
)) {
1921 ERR("Empty stack\n");
1925 if (vstack_ax(stack
)->type
!= REG_PTR
) {
1926 ERR("Expecting pointer on top of stack\n");
1930 next_pc
+= sizeof(struct load_op
) + sizeof(struct get_index_u64
);
1936 *_next_pc
= next_pc
;
1941 * Never called concurrently (hash seed is shared).
1943 int lttng_bytecode_validate(struct bytecode_runtime
*bytecode
)
1945 struct lttng_ust_lfht
*merge_points
;
1946 char *pc
, *next_pc
, *start_pc
;
1948 struct vstack stack
;
1950 vstack_init(&stack
);
1952 if (!lttng_hash_seed_ready
) {
1953 lttng_hash_seed
= time(NULL
);
1954 lttng_hash_seed_ready
= 1;
1957 * Note: merge_points hash table used by single thread, and
1958 * never concurrently resized. Therefore, we can use it without
1959 * holding RCU read-side lock and free nodes without using
1962 merge_points
= lttng_ust_lfht_new(DEFAULT_NR_MERGE_POINTS
,
1963 MIN_NR_BUCKETS
, MAX_NR_BUCKETS
,
1965 if (!merge_points
) {
1966 ERR("Error allocating hash table for bytecode validation\n");
1969 start_pc
= &bytecode
->code
[0];
1970 for (pc
= next_pc
= start_pc
; pc
- start_pc
< bytecode
->len
;
1972 ret
= bytecode_validate_overflow(bytecode
, start_pc
, pc
);
1975 ERR("Bytecode overflow\n");
1978 dbg_printf("Validating op %s (%u)\n",
1979 lttng_bytecode_print_op((unsigned int) *(bytecode_opcode_t
*) pc
),
1980 (unsigned int) *(bytecode_opcode_t
*) pc
);
1983 * For each instruction, validate the current context
1984 * (traversal of entire execution flow), and validate
1985 * all merge points targeting this instruction.
1987 ret
= validate_instruction_all_contexts(bytecode
, merge_points
,
1988 &stack
, start_pc
, pc
);
1991 ret
= exec_insn(bytecode
, merge_points
, &stack
, &next_pc
, pc
);
1996 if (delete_all_nodes(merge_points
)) {
1998 ERR("Unexpected merge points\n");
2002 if (lttng_ust_lfht_destroy(merge_points
)) {
2003 ERR("Error destroying hash table\n");