common: move bytecode utilities from filter to its own file
[lttng-tools.git] / src / common / bytecode / bytecode.c
CommitLineData
0ae3cfc6
SM
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
16static 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
26LTTNG_HIDDEN
27int 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
41LTTNG_HIDDEN
42int32_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
72LTTNG_HIDDEN
73int 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
85LTTNG_HIDDEN
86int 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.025999 seconds and 4 git commands to generate.