common: move bytecode utilities from filter to its own file
[lttng-tools.git] / src / common / bytecode / bytecode.c
1 /*
2 * Copyright 2020 EfficiOS, Inc.
3 *
4 * SPDX-License-Identifier: GPL-2.0-only
5 *
6 */
7
8 #include "bytecode.h"
9
10 #include <errno.h>
11
12 #include "common/align.h"
13
14 #define INIT_ALLOC_SIZE 4
15
16 static inline int get_count_order(unsigned int count)
17 {
18 int order;
19
20 order = lttng_fls(count) - 1;
21 if (count & (count - 1))
22 order++;
23 return order;
24 }
25
26 LTTNG_HIDDEN
27 int bytecode_init(struct lttng_filter_bytecode_alloc **fb)
28 {
29 uint32_t alloc_len;
30
31 alloc_len = sizeof(struct lttng_filter_bytecode_alloc) + INIT_ALLOC_SIZE;
32 *fb = calloc(alloc_len, 1);
33 if (!*fb) {
34 return -ENOMEM;
35 } else {
36 (*fb)->alloc_len = alloc_len;
37 return 0;
38 }
39 }
40
41 LTTNG_HIDDEN
42 int32_t bytecode_reserve(struct lttng_filter_bytecode_alloc **fb, uint32_t align, uint32_t len)
43 {
44 int32_t ret;
45 uint32_t padding = offset_align((*fb)->b.len, align);
46 uint32_t new_len = (*fb)->b.len + padding + len;
47 uint32_t new_alloc_len = sizeof(struct lttng_filter_bytecode_alloc) + new_len;
48 uint32_t old_alloc_len = (*fb)->alloc_len;
49
50 if (new_len > LTTNG_FILTER_MAX_LEN)
51 return -EINVAL;
52
53 if (new_alloc_len > old_alloc_len) {
54 struct lttng_filter_bytecode_alloc *newptr;
55
56 new_alloc_len =
57 max_t(uint32_t, 1U << get_count_order(new_alloc_len), old_alloc_len << 1);
58 newptr = realloc(*fb, new_alloc_len);
59 if (!newptr)
60 return -ENOMEM;
61 *fb = newptr;
62 /* We zero directly the memory from start of allocation. */
63 memset(&((char *) *fb)[old_alloc_len], 0, new_alloc_len - old_alloc_len);
64 (*fb)->alloc_len = new_alloc_len;
65 }
66 (*fb)->b.len += padding;
67 ret = (*fb)->b.len;
68 (*fb)->b.len += len;
69 return ret;
70 }
71
72 LTTNG_HIDDEN
73 int bytecode_push(struct lttng_filter_bytecode_alloc **fb, const void *data,
74 uint32_t align, uint32_t len)
75 {
76 int32_t offset;
77
78 offset = bytecode_reserve(fb, align, len);
79 if (offset < 0)
80 return offset;
81 memcpy(&(*fb)->b.data[offset], data, len);
82 return 0;
83 }
84
85 LTTNG_HIDDEN
86 int bytecode_push_logical(struct lttng_filter_bytecode_alloc **fb,
87 struct logical_op *data,
88 uint32_t align, uint32_t len,
89 uint16_t *skip_offset)
90 {
91 int32_t offset;
92
93 offset = bytecode_reserve(fb, align, len);
94 if (offset < 0)
95 return offset;
96 memcpy(&(*fb)->b.data[offset], data, len);
97 *skip_offset =
98 (void *) &((struct logical_op *) &(*fb)->b.data[offset])->skip_offset
99 - (void *) &(*fb)->b.data[0];
100 return 0;
101 }
This page took 0.041819 seconds and 4 git commands to generate.