2 * Copyright 2020 EfficiOS, Inc.
4 * SPDX-License-Identifier: LGPL-2.1-only
8 #include "event-expr-to-bytecode.h"
11 #include <lttng/event-expr.h>
12 #include <common/bytecode/bytecode.h>
13 #include <common/error.h>
16 int event_expr_to_bytecode_recursive(const struct lttng_event_expr
*expr
,
17 struct lttng_bytecode_alloc
**bytecode
,
18 struct lttng_bytecode_alloc
**bytecode_reloc
)
21 enum lttng_event_expr_status event_expr_status
;
23 switch (lttng_event_expr_get_type(expr
)) {
24 case LTTNG_EVENT_EXPR_TYPE_EVENT_PAYLOAD_FIELD
:
28 status
= bytecode_push_get_payload_root(bytecode
);
30 ERR("Failed to get payload root from bytecode");
34 name
= lttng_event_expr_event_payload_field_get_name(expr
);
36 ERR("Failed to get payload field name from event expression");
41 status
= bytecode_push_get_symbol(bytecode
, bytecode_reloc
, name
);
43 ERR("Failed to push 'get symbol %s' in bytecode", name
);
49 case LTTNG_EVENT_EXPR_TYPE_CHANNEL_CONTEXT_FIELD
:
53 status
= bytecode_push_get_context_root(bytecode
);
55 ERR("Failed to get context root from bytecode");
59 name
= lttng_event_expr_channel_context_field_get_name(expr
);
61 ERR("Failed to get channel context field name from event expression");
66 status
= bytecode_push_get_symbol(bytecode
, bytecode_reloc
, name
);
68 ERR("Failed to push 'get symbol %s' in bytecode", name
);
74 case LTTNG_EVENT_EXPR_TYPE_APP_SPECIFIC_CONTEXT_FIELD
:
78 const char *provider_name
, *type_name
;
80 status
= bytecode_push_get_app_context_root(bytecode
);
82 ERR("Failed to get application context root from bytecode");
86 provider_name
= lttng_event_expr_app_specific_context_field_get_provider_name(
89 ERR("Failed to get application context provider name from event expression");
94 type_name
= lttng_event_expr_app_specific_context_field_get_type_name(
97 ERR("Failed to get application context type name from event expression");
103 * Reconstitute the app context field name from its two parts.
105 ret
= asprintf(&name
, "%s:%s", provider_name
, type_name
);
107 PERROR("Failed to format application specific context: provider_name = '%s', type_name = '%s'",
108 provider_name
, type_name
);
113 status
= bytecode_push_get_symbol(
114 bytecode
, bytecode_reloc
, name
);
117 ERR("Failed to push 'get symbol %s' in bytecode", name
);
123 case LTTNG_EVENT_EXPR_TYPE_ARRAY_FIELD_ELEMENT
:
126 const struct lttng_event_expr
*parent
;
128 parent
= lttng_event_expr_array_field_element_get_parent_expr(
131 ERR("Failed to get parent expression from array event expression");
136 status
= event_expr_to_bytecode_recursive(
137 parent
, bytecode
, bytecode_reloc
);
142 event_expr_status
= lttng_event_expr_array_field_element_get_index(
144 if (event_expr_status
!= LTTNG_EVENT_EXPR_STATUS_OK
) {
145 ERR("Failed to get array field element index from event expression");
150 status
= bytecode_push_get_index_u64(bytecode
, index
);
152 ERR("Failed to push 'get index %u' in bytecode", index
);
168 int lttng_event_expr_to_bytecode(const struct lttng_event_expr
*expr
,
169 struct lttng_bytecode
**bytecode_out
)
172 struct return_op ret_insn
;
173 struct lttng_bytecode_alloc
*bytecode
= NULL
;
174 struct lttng_bytecode_alloc
*bytecode_reloc
= NULL
;
176 status
= bytecode_init(&bytecode
);
178 ERR("Failed to initialize bytecode");
182 status
= bytecode_init(&bytecode_reloc
);
184 ERR("Failed to initialize relocation bytecode");
188 status
= event_expr_to_bytecode_recursive(
189 expr
, &bytecode
, &bytecode_reloc
);
191 /* Errors already logged. */
195 ret_insn
.op
= BYTECODE_OP_RETURN
;
196 bytecode_push(&bytecode
, &ret_insn
, 1, sizeof(ret_insn
));
198 /* Append symbol table to bytecode. */
199 bytecode
->b
.reloc_table_offset
= bytecode_get_len(&bytecode
->b
);
200 status
= bytecode_push(&bytecode
, bytecode_reloc
->b
.data
, 1,
201 bytecode_get_len(&bytecode_reloc
->b
));
203 ERR("Failed to push symbol table to bytecode");
207 /* Copy the `lttng_bytecode` out of the `lttng_bytecode_alloc`. */
208 *bytecode_out
= lttng_bytecode_copy(&bytecode
->b
);
209 if (!*bytecode_out
) {
219 if (bytecode_reloc
) {
220 free(bytecode_reloc
);