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