SoW-2020-0002: Trace Hit Counters: trigger error reporting integration
[lttng-tools.git] / src / common / event-expr-to-bytecode.c
1 /*
2 * Copyright 2020 EfficiOS, Inc.
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
5 *
6 */
7
8 #include "event-expr-to-bytecode.h"
9
10 #include <stdio.h>
11 #include <lttng/event-expr.h>
12 #include <common/bytecode/bytecode.h>
13
14
15 static
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)
19 {
20 enum lttng_event_expr_status event_expr_status;
21 int status;
22
23 switch (lttng_event_expr_get_type(expr)) {
24 case LTTNG_EVENT_EXPR_TYPE_EVENT_PAYLOAD_FIELD:
25 {
26 const char *name;
27
28 status = bytecode_push_get_payload_root(bytecode);
29 if (status) {
30 goto end;
31 }
32
33 name = lttng_event_expr_event_payload_field_get_name(expr);
34 if (!name) {
35 status = -1;
36 goto end;
37 }
38
39 status = bytecode_push_get_symbol(bytecode, bytecode_reloc, name);
40 if (status) {
41 goto end;
42 }
43
44 break;
45 }
46
47 case LTTNG_EVENT_EXPR_TYPE_CHANNEL_CONTEXT_FIELD:
48 {
49 const char *name;
50
51 status = bytecode_push_get_context_root(bytecode);
52 if (status) {
53 goto end;
54 }
55
56 name = lttng_event_expr_channel_context_field_get_name(expr);
57 if (!name) {
58 status = -1;
59 goto end;
60 }
61
62 status = bytecode_push_get_symbol(bytecode, bytecode_reloc, name);
63 if (status) {
64 goto end;
65 }
66
67 break;
68 }
69
70 case LTTNG_EVENT_EXPR_TYPE_APP_SPECIFIC_CONTEXT_FIELD:
71 {
72 const char *provider_name, *type_name;
73 char *name = NULL;
74 int ret;
75
76 status = bytecode_push_get_app_context_root(bytecode);
77 if (status) {
78 goto end;
79 }
80
81 provider_name = lttng_event_expr_app_specific_context_field_get_provider_name(expr);
82 if (!provider_name) {
83 status = -1;
84 goto end;
85 }
86
87 type_name = lttng_event_expr_app_specific_context_field_get_type_name(expr);
88 if (!type_name) {
89 status = -1;
90 goto end;
91 }
92
93 /* Reconstitute the app context field name from its two parts. */
94 ret = asprintf(&name, "%s:%s", provider_name, type_name);
95 if (ret < 0) {
96 status = -1;
97 goto end;
98 }
99
100 status = bytecode_push_get_symbol(bytecode, bytecode_reloc, name);
101 free(name);
102 if (status) {
103 goto end;
104 }
105
106 break;
107 }
108
109 case LTTNG_EVENT_EXPR_TYPE_ARRAY_FIELD_ELEMENT:
110 {
111 const struct lttng_event_expr *parent;
112 unsigned int index;
113
114 parent = lttng_event_expr_array_field_element_get_parent_expr(expr);
115 if (!parent) {
116 status = -1;
117 goto end;
118 }
119
120 status = event_expr_to_bytecode_recursive(parent, bytecode, bytecode_reloc);
121 if (status) {
122 goto end;
123 }
124
125 event_expr_status = lttng_event_expr_array_field_element_get_index(
126 expr, &index);
127 if (event_expr_status != LTTNG_EVENT_EXPR_STATUS_OK) {
128 status = -1;
129 goto end;
130 }
131
132 status = bytecode_push_get_index_u64(bytecode, index);
133 if (status) {
134 goto end;
135 }
136
137 break;
138 }
139
140 default:
141 abort();
142 }
143
144 status = 0;
145 end:
146 return status;
147 }
148
149 LTTNG_HIDDEN
150 int lttng_event_expr_to_bytecode(const struct lttng_event_expr *expr,
151 struct lttng_bytecode **bytecode_out)
152 {
153 struct lttng_bytecode_alloc *bytecode = NULL;
154 struct lttng_bytecode_alloc *bytecode_reloc = NULL;
155 struct return_op ret_insn;
156 int status;
157
158 status = bytecode_init(&bytecode);
159 if (status) {
160 goto end;
161 }
162
163 status = bytecode_init(&bytecode_reloc);
164 if (status) {
165 goto end;
166 }
167
168 status = event_expr_to_bytecode_recursive (expr, &bytecode, &bytecode_reloc);
169 if (status) {
170 goto end;
171 }
172
173 ret_insn.op = BYTECODE_OP_RETURN;
174 bytecode_push(&bytecode, &ret_insn, 1, sizeof(ret_insn));
175
176 /* Append symbol table to bytecode. */
177 bytecode->b.reloc_table_offset = bytecode_get_len(&bytecode->b);
178 status = bytecode_push(&bytecode, bytecode_reloc->b.data,
179 1, bytecode_get_len(&bytecode_reloc->b));
180 if (status) {
181 goto end;
182 }
183
184 /* Copy the `lttng_bytecode` out of the `lttng_bytecode_alloc`. */
185 *bytecode_out = bytecode_copy(&bytecode->b);
186 if (!*bytecode_out) {
187 status = -1;
188 goto end;
189 }
190
191 end:
192 if (bytecode) {
193 free(bytecode);
194 }
195
196 if (bytecode_reloc) {
197 free(bytecode_reloc);
198 }
199
200 return status;
201 }
This page took 0.033629 seconds and 5 git commands to generate.