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