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:%s' in bytecode",
118 provider_name
, type_name
);
124 case LTTNG_EVENT_EXPR_TYPE_ARRAY_FIELD_ELEMENT
:
127 const struct lttng_event_expr
*parent
;
129 parent
= lttng_event_expr_array_field_element_get_parent_expr(
132 ERR("Failed to get parent expression from array event expression");
137 status
= event_expr_to_bytecode_recursive(
138 parent
, bytecode
, bytecode_reloc
);
143 event_expr_status
= lttng_event_expr_array_field_element_get_index(
145 if (event_expr_status
!= LTTNG_EVENT_EXPR_STATUS_OK
) {
146 ERR("Failed to get array field element index from event expression");
151 status
= bytecode_push_get_index_u64(bytecode
, index
);
153 ERR("Failed to push 'get index %u' in bytecode", index
);
169 int lttng_event_expr_to_bytecode(const struct lttng_event_expr
*expr
,
170 struct lttng_bytecode
**bytecode_out
)
173 struct return_op ret_insn
;
174 struct lttng_bytecode_alloc
*bytecode
= NULL
;
175 struct lttng_bytecode_alloc
*bytecode_reloc
= NULL
;
177 status
= bytecode_init(&bytecode
);
179 ERR("Failed to initialize bytecode");
183 status
= bytecode_init(&bytecode_reloc
);
185 ERR("Failed to initialize relocation bytecode");
189 status
= event_expr_to_bytecode_recursive(
190 expr
, &bytecode
, &bytecode_reloc
);
192 /* Errors already logged. */
196 ret_insn
.op
= BYTECODE_OP_RETURN
;
197 bytecode_push(&bytecode
, &ret_insn
, 1, sizeof(ret_insn
));
199 /* Append symbol table to bytecode. */
200 bytecode
->b
.reloc_table_offset
= bytecode_get_len(&bytecode
->b
);
201 status
= bytecode_push(&bytecode
, bytecode_reloc
->b
.data
, 1,
202 bytecode_get_len(&bytecode_reloc
->b
));
204 ERR("Failed to push symbol table to bytecode");
208 /* Copy the `lttng_bytecode` out of the `lttng_bytecode_alloc`. */
209 *bytecode_out
= lttng_bytecode_copy(&bytecode
->b
);
210 if (!*bytecode_out
) {
220 if (bytecode_reloc
) {
221 free(bytecode_reloc
);