Visibility hidden by default
[babeltrace.git] / src / plugins / ctf / common / metadata / ctf-meta-validate.cpp
1 /*
2 * SPDX-License-Identifier: MIT
3 *
4 * Copyright 2018 Philippe Proulx <pproulx@efficios.com>
5 */
6
7 #define BT_COMP_LOG_SELF_COMP (log_cfg->self_comp)
8 #define BT_COMP_LOG_SELF_COMP_CLASS (log_cfg->self_comp_class)
9 #define BT_LOG_OUTPUT_LEVEL (log_cfg->log_level)
10 #define BT_LOG_TAG "PLUGIN/CTF/META/VALIDATE"
11 #include "logging/comp-logging.h"
12
13 #include <babeltrace2/babeltrace.h>
14 #include "common/macros.h"
15 #include "common/assert.h"
16 #include <glib.h>
17 #include <stdint.h>
18 #include <string.h>
19 #include <inttypes.h>
20
21 #include "ctf-meta-visitors.hpp"
22 #include "logging.hpp"
23
24 static int validate_stream_class(struct ctf_stream_class *sc, struct meta_log_config *log_cfg)
25 {
26 int ret = 0;
27 struct ctf_field_class_int *int_fc;
28 struct ctf_field_class *fc;
29
30 if (sc->is_translated) {
31 goto end;
32 }
33
34 fc = ctf_field_class_struct_borrow_member_field_class_by_name(
35 ctf_field_class_as_struct(sc->packet_context_fc), "timestamp_begin");
36 if (fc) {
37 if (fc->type != CTF_FIELD_CLASS_TYPE_INT && fc->type != CTF_FIELD_CLASS_TYPE_ENUM) {
38 _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE(
39 "Invalid packet context field class: "
40 "`timestamp_begin` member is not an integer field class.");
41 goto invalid;
42 }
43
44 int_fc = ctf_field_class_as_int(fc);
45
46 if (int_fc->is_signed) {
47 _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Invalid packet context field class: "
48 "`timestamp_begin` member is signed.");
49 goto invalid;
50 }
51 }
52
53 fc = ctf_field_class_struct_borrow_member_field_class_by_name(
54 ctf_field_class_as_struct(sc->packet_context_fc), "timestamp_end");
55 if (fc) {
56 if (fc->type != CTF_FIELD_CLASS_TYPE_INT && fc->type != CTF_FIELD_CLASS_TYPE_ENUM) {
57 _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE(
58 "Invalid packet context field class: "
59 "`timestamp_end` member is not an integer field class.");
60 goto invalid;
61 }
62
63 int_fc = ctf_field_class_as_int(fc);
64
65 if (int_fc->is_signed) {
66 _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Invalid packet context field class: "
67 "`timestamp_end` member is signed.");
68 goto invalid;
69 }
70 }
71
72 fc = ctf_field_class_struct_borrow_member_field_class_by_name(
73 ctf_field_class_as_struct(sc->packet_context_fc), "events_discarded");
74 if (fc) {
75 if (fc->type != CTF_FIELD_CLASS_TYPE_INT && fc->type != CTF_FIELD_CLASS_TYPE_ENUM) {
76 _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE(
77 "Invalid packet context field class: "
78 "`events_discarded` member is not an integer field class.");
79 goto invalid;
80 }
81
82 int_fc = ctf_field_class_as_int(fc);
83
84 if (int_fc->is_signed) {
85 _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Invalid packet context field class: "
86 "`events_discarded` member is signed.");
87 goto invalid;
88 }
89 }
90
91 fc = ctf_field_class_struct_borrow_member_field_class_by_name(
92 ctf_field_class_as_struct(sc->packet_context_fc), "packet_seq_num");
93 if (fc) {
94 if (fc->type != CTF_FIELD_CLASS_TYPE_INT && fc->type != CTF_FIELD_CLASS_TYPE_ENUM) {
95 _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE(
96 "Invalid packet context field class: "
97 "`packet_seq_num` member is not an integer field class.");
98 goto invalid;
99 }
100
101 int_fc = ctf_field_class_as_int(fc);
102
103 if (int_fc->is_signed) {
104 _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Invalid packet context field class: "
105 "`packet_seq_num` member is signed.");
106 goto invalid;
107 }
108 }
109
110 fc = ctf_field_class_struct_borrow_member_field_class_by_name(
111 ctf_field_class_as_struct(sc->packet_context_fc), "packet_size");
112 if (fc) {
113 if (fc->type != CTF_FIELD_CLASS_TYPE_INT && fc->type != CTF_FIELD_CLASS_TYPE_ENUM) {
114 _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE(
115 "Invalid packet context field class: "
116 "`packet_size` member is not an integer field class.");
117 goto invalid;
118 }
119
120 int_fc = ctf_field_class_as_int(fc);
121
122 if (int_fc->is_signed) {
123 _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Invalid packet context field class: "
124 "`packet_size` member is signed.");
125 goto invalid;
126 }
127 }
128
129 fc = ctf_field_class_struct_borrow_member_field_class_by_name(
130 ctf_field_class_as_struct(sc->packet_context_fc), "content_size");
131 if (fc) {
132 if (fc->type != CTF_FIELD_CLASS_TYPE_INT && fc->type != CTF_FIELD_CLASS_TYPE_ENUM) {
133 _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE(
134 "Invalid packet context field class: "
135 "`content_size` member is not an integer field class.");
136 goto invalid;
137 }
138
139 int_fc = ctf_field_class_as_int(fc);
140
141 if (int_fc->is_signed) {
142 _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Invalid packet context field class: "
143 "`content_size` member is signed.");
144 goto invalid;
145 }
146 }
147
148 fc = ctf_field_class_struct_borrow_member_field_class_by_name(
149 ctf_field_class_as_struct(sc->event_header_fc), "id");
150 if (fc) {
151 if (fc->type != CTF_FIELD_CLASS_TYPE_INT && fc->type != CTF_FIELD_CLASS_TYPE_ENUM) {
152 _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Invalid event header field class: "
153 "`id` member is not an integer field class.");
154 goto invalid;
155 }
156
157 int_fc = ctf_field_class_as_int(fc);
158
159 if (int_fc->is_signed) {
160 _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Invalid event header field class: "
161 "`id` member is signed.");
162 goto invalid;
163 }
164 } else {
165 if (sc->event_classes->len > 1) {
166 _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Invalid event header field class: "
167 "missing `id` member as there's "
168 "more than one event class.");
169 goto invalid;
170 }
171 }
172
173 goto end;
174
175 invalid:
176 ret = -1;
177
178 end:
179 return ret;
180 }
181
182 int ctf_trace_class_validate(struct ctf_trace_class *ctf_tc, struct meta_log_config *log_cfg)
183 {
184 int ret = 0;
185 struct ctf_field_class_int *int_fc;
186 uint64_t i;
187
188 if (!ctf_tc->is_translated) {
189 struct ctf_field_class *fc;
190
191 fc = ctf_field_class_struct_borrow_member_field_class_by_name(
192 ctf_field_class_as_struct(ctf_tc->packet_header_fc), "magic");
193 if (fc) {
194 struct ctf_named_field_class *named_fc = ctf_field_class_struct_borrow_member_by_index(
195 ctf_field_class_as_struct(ctf_tc->packet_header_fc), 0);
196
197 if (named_fc->fc != fc) {
198 _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Invalid packet header field class: "
199 "`magic` member is not the first member.");
200 goto invalid;
201 }
202
203 if (fc->type != CTF_FIELD_CLASS_TYPE_INT && fc->type != CTF_FIELD_CLASS_TYPE_ENUM) {
204 _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE(
205 "Invalid packet header field class: "
206 "`magic` member is not an integer field class.");
207 goto invalid;
208 }
209
210 int_fc = ctf_field_class_as_int(fc);
211
212 if (int_fc->is_signed) {
213 _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Invalid packet header field class: "
214 "`magic` member is signed.");
215 goto invalid;
216 }
217
218 if (int_fc->base.size != 32) {
219 _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Invalid packet header field class: "
220 "`magic` member is not 32-bit.");
221 goto invalid;
222 }
223 }
224
225 fc = ctf_field_class_struct_borrow_member_field_class_by_name(
226 ctf_field_class_as_struct(ctf_tc->packet_header_fc), "stream_id");
227 if (fc) {
228 if (fc->type != CTF_FIELD_CLASS_TYPE_INT && fc->type != CTF_FIELD_CLASS_TYPE_ENUM) {
229 _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE(
230 "Invalid packet header field class: "
231 "`stream_id` member is not an integer field class.");
232 goto invalid;
233 }
234
235 int_fc = ctf_field_class_as_int(fc);
236
237 if (int_fc->is_signed) {
238 _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Invalid packet header field class: "
239 "`stream_id` member is signed.");
240 goto invalid;
241 }
242 } else {
243 if (ctf_tc->stream_classes->len > 1) {
244 _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Invalid packet header field class: "
245 "missing `stream_id` member as there's "
246 "more than one stream class.");
247 goto invalid;
248 }
249 }
250
251 fc = ctf_field_class_struct_borrow_member_field_class_by_name(
252 ctf_field_class_as_struct(ctf_tc->packet_header_fc), "stream_instance_id");
253 if (fc) {
254 if (fc->type != CTF_FIELD_CLASS_TYPE_INT && fc->type != CTF_FIELD_CLASS_TYPE_ENUM) {
255 _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE(
256 "Invalid packet header field class: "
257 "`stream_instance_id` member is not an integer field class.");
258 goto invalid;
259 }
260
261 int_fc = ctf_field_class_as_int(fc);
262
263 if (int_fc->is_signed) {
264 _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Invalid packet header field class: "
265 "`stream_instance_id` member is signed.");
266 goto invalid;
267 }
268 }
269
270 fc = ctf_field_class_struct_borrow_member_field_class_by_name(
271 ctf_field_class_as_struct(ctf_tc->packet_header_fc), "uuid");
272 if (fc) {
273 if (fc->type != CTF_FIELD_CLASS_TYPE_ARRAY) {
274 _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE(
275 "Invalid packet header field class: "
276 "`uuid` member is not an array field class.");
277 goto invalid;
278 }
279
280 ctf_field_class_array *array_fc = ctf_field_class_as_array(fc);
281
282 if (array_fc->length != 16) {
283 _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE(
284 "Invalid packet header field class: "
285 "`uuid` member is not a 16-element array field class.");
286 goto invalid;
287 }
288
289 if (array_fc->base.elem_fc->type != CTF_FIELD_CLASS_TYPE_INT) {
290 _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE(
291 "Invalid packet header field class: "
292 "`uuid` member's element field class is not "
293 "an integer field class.");
294 goto invalid;
295 }
296
297 int_fc = ctf_field_class_as_int(array_fc->base.elem_fc);
298
299 if (int_fc->is_signed) {
300 _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Invalid packet header field class: "
301 "`uuid` member's element field class "
302 "is a signed integer field class.");
303 goto invalid;
304 }
305
306 if (int_fc->base.size != 8) {
307 _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Invalid packet header field class: "
308 "`uuid` member's element field class "
309 "is not an 8-bit integer field class.");
310 goto invalid;
311 }
312
313 if (int_fc->base.base.alignment != 8) {
314 _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Invalid packet header field class: "
315 "`uuid` member's element field class's "
316 "alignment is not 8.");
317 goto invalid;
318 }
319 }
320 }
321
322 for (i = 0; i < ctf_tc->stream_classes->len; i++) {
323 struct ctf_stream_class *sc = (ctf_stream_class *) ctf_tc->stream_classes->pdata[i];
324
325 ret = validate_stream_class(sc, log_cfg);
326 if (ret) {
327 _BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE("Invalid stream class: sc-id=%" PRIu64,
328 sc->id);
329 goto invalid;
330 }
331 }
332
333 goto end;
334
335 invalid:
336 ret = -1;
337
338 end:
339 return ret;
340 }
This page took 0.036805 seconds and 4 git commands to generate.