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