ac1d2e9d653c33523a1a9e8b19c745e54e06fd60
[babeltrace.git] / plugins / ctf / common / metadata / visitor-generate-ir.c
1 /*
2 * ctf-visitor-generate-ir.c
3 *
4 * Common Trace Format metadata visitor (generates CTF IR objects).
5 *
6 * Based on older ctf-visitor-generate-io-struct.c.
7 *
8 * Copyright 2010 - Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
9 * Copyright 2015-2018 - Philippe Proulx <philippe.proulx@efficios.com>
10 *
11 * Permission is hereby granted, free of charge, to any person obtaining a copy
12 * of this software and associated documentation files (the "Software"), to deal
13 * in the Software without restriction, including without limitation the rights
14 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
15 * copies of the Software, and to permit persons to whom the Software is
16 * furnished to do so, subject to the following conditions:
17 *
18 * The above copyright notice and this permission notice shall be included in
19 * all copies or substantial portions of the Software.
20 *
21 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
24 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
26 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
27 * SOFTWARE.
28 */
29
30 #define BT_LOG_TAG "PLUGIN-CTF-METADATA-IR-VISITOR"
31 #include "logging.h"
32
33 #include <stdio.h>
34 #include <unistd.h>
35 #include <string.h>
36 #include <stdbool.h>
37 #include <stdlib.h>
38 #include <ctype.h>
39 #include <babeltrace/assert-internal.h>
40 #include <glib.h>
41 #include <inttypes.h>
42 #include <errno.h>
43 #include <babeltrace/common-internal.h>
44 #include <babeltrace/compat/uuid-internal.h>
45 #include <babeltrace/endian-internal.h>
46 #include <babeltrace/babeltrace.h>
47
48 #include "scanner.h"
49 #include "parser.h"
50 #include "ast.h"
51 #include "decoder.h"
52 #include "ctf-meta.h"
53 #include "ctf-meta-visitors.h"
54
55 /* Bit value (left shift) */
56 #define _BV(_val) (1 << (_val))
57
58 /* Bit is set in a set of bits */
59 #define _IS_SET(_set, _mask) (*(_set) & (_mask))
60
61 /* Set bit in a set of bits */
62 #define _SET(_set, _mask) (*(_set) |= (_mask))
63
64 /* Try to push scope, or go to the `error` label */
65 #define _TRY_PUSH_SCOPE_OR_GOTO_ERROR() \
66 do { \
67 ret = ctx_push_scope(ctx); \
68 if (ret) { \
69 BT_LOGE_STR("Cannot push scope."); \
70 goto error; \
71 } \
72 } while (0)
73
74 /* Bits for verifying existing attributes in various declarations */
75 enum {
76 _CLOCK_NAME_SET = _BV(0),
77 _CLOCK_UUID_SET = _BV(1),
78 _CLOCK_FREQ_SET = _BV(2),
79 _CLOCK_PRECISION_SET = _BV(3),
80 _CLOCK_OFFSET_S_SET = _BV(4),
81 _CLOCK_OFFSET_SET = _BV(5),
82 _CLOCK_ABSOLUTE_SET = _BV(6),
83 _CLOCK_DESCRIPTION_SET = _BV(7),
84 };
85
86 enum {
87 _INTEGER_ALIGN_SET = _BV(0),
88 _INTEGER_SIZE_SET = _BV(1),
89 _INTEGER_BASE_SET = _BV(2),
90 _INTEGER_ENCODING_SET = _BV(3),
91 _INTEGER_BYTE_ORDER_SET = _BV(4),
92 _INTEGER_SIGNED_SET = _BV(5),
93 _INTEGER_MAP_SET = _BV(6),
94 };
95
96 enum {
97 _FLOAT_ALIGN_SET = _BV(0),
98 _FLOAT_MANT_DIG_SET = _BV(1),
99 _FLOAT_EXP_DIG_SET = _BV(2),
100 _FLOAT_BYTE_ORDER_SET = _BV(3),
101 };
102
103 enum {
104 _STRING_ENCODING_SET = _BV(0),
105 };
106
107 enum {
108 _TRACE_MINOR_SET = _BV(0),
109 _TRACE_MAJOR_SET = _BV(1),
110 _TRACE_BYTE_ORDER_SET = _BV(2),
111 _TRACE_UUID_SET = _BV(3),
112 _TRACE_PACKET_HEADER_SET = _BV(4),
113 };
114
115 enum {
116 _STREAM_ID_SET = _BV(0),
117 _STREAM_PACKET_CONTEXT_SET = _BV(1),
118 _STREAM_EVENT_HEADER_SET = _BV(2),
119 _STREAM_EVENT_CONTEXT_SET = _BV(3),
120 };
121
122 enum {
123 _EVENT_NAME_SET = _BV(0),
124 _EVENT_ID_SET = _BV(1),
125 _EVENT_MODEL_EMF_URI_SET = _BV(2),
126 _EVENT_STREAM_ID_SET = _BV(3),
127 _EVENT_LOG_LEVEL_SET = _BV(4),
128 _EVENT_CONTEXT_SET = _BV(5),
129 _EVENT_FIELDS_SET = _BV(6),
130 };
131
132 enum loglevel {
133 LOG_LEVEL_EMERG = 0,
134 LOG_LEVEL_ALERT = 1,
135 LOG_LEVEL_CRIT = 2,
136 LOG_LEVEL_ERR = 3,
137 LOG_LEVEL_WARNING = 4,
138 LOG_LEVEL_NOTICE = 5,
139 LOG_LEVEL_INFO = 6,
140 LOG_LEVEL_DEBUG_SYSTEM = 7,
141 LOG_LEVEL_DEBUG_PROGRAM = 8,
142 LOG_LEVEL_DEBUG_PROCESS = 9,
143 LOG_LEVEL_DEBUG_MODULE = 10,
144 LOG_LEVEL_DEBUG_UNIT = 11,
145 LOG_LEVEL_DEBUG_FUNCTION = 12,
146 LOG_LEVEL_DEBUG_LINE = 13,
147 LOG_LEVEL_DEBUG = 14,
148 _NR_LOGLEVELS = 15,
149 };
150
151 /* Prefixes of class aliases */
152 #define _PREFIX_ALIAS 'a'
153 #define _PREFIX_ENUM 'e'
154 #define _PREFIX_STRUCT 's'
155 #define _PREFIX_VARIANT 'v'
156
157 /* First entry in a BT list */
158 #define _BT_LIST_FIRST_ENTRY(_ptr, _class, _member) \
159 bt_list_entry((_ptr)->next, _class, _member)
160
161 #define _BT_LOGE_DUP_ATTR(_node, _attr, _entity) \
162 _BT_LOGE_LINENO((_node)->lineno, \
163 "Duplicate attribute in %s: attr-name=\"%s\"", \
164 _entity, _attr)
165
166 #define _BT_LOGE_NODE(_node, _msg, args...) \
167 _BT_LOGE_LINENO((_node)->lineno, _msg, ## args)
168
169 #define _BT_LOGW_NODE(_node, _msg, args...) \
170 _BT_LOGW_LINENO((_node)->lineno, _msg, ## args)
171
172 #define _BT_LOGV_NODE(_node, _msg, args...) \
173 _BT_LOGV_LINENO((_node)->lineno, _msg, ## args)
174
175 /*
176 * Declaration scope of a visitor context. This represents a TSDL
177 * lexical scope, so that aliases and named structures, variants,
178 * and enumerations may be registered and looked up hierarchically.
179 */
180 struct ctx_decl_scope {
181 /*
182 * Alias name to field class.
183 *
184 * GQuark -> struct ctf_field_class * (owned by this)
185 */
186 GHashTable *decl_map;
187
188 /* Parent scope; NULL if this is the root declaration scope */
189 struct ctx_decl_scope *parent_scope;
190 };
191
192 /*
193 * Visitor context (private).
194 */
195 struct ctx {
196 /* Trace IR trace class being filled (owned by this) */
197 bt_trace_class *trace_class;
198
199 /* CTF meta trace being filled (owned by this) */
200 struct ctf_trace_class *ctf_tc;
201
202 /* Current declaration scope (top of the stack) (owned by this) */
203 struct ctx_decl_scope *current_scope;
204
205 /* True if trace declaration is visited */
206 bool is_trace_visited;
207
208 /* True if this is an LTTng trace */
209 bool is_lttng;
210
211 /* Config passed by the user */
212 struct ctf_metadata_decoder_config decoder_config;
213 };
214
215 /*
216 * Visitor (public).
217 */
218 struct ctf_visitor_generate_ir;
219
220 /**
221 * Creates a new declaration scope.
222 *
223 * @param par_scope Parent scope (NULL if creating a root scope)
224 * @returns New declaration scope, or NULL on error
225 */
226 static
227 struct ctx_decl_scope *ctx_decl_scope_create(struct ctx_decl_scope *par_scope)
228 {
229 struct ctx_decl_scope *scope;
230
231 scope = g_new(struct ctx_decl_scope, 1);
232 if (!scope) {
233 BT_LOGE_STR("Failed to allocate one declaration scope.");
234 goto end;
235 }
236
237 scope->decl_map = g_hash_table_new_full(g_direct_hash, g_direct_equal,
238 NULL, (GDestroyNotify) ctf_field_class_destroy);
239 scope->parent_scope = par_scope;
240
241 end:
242 return scope;
243 }
244
245 /**
246 * Destroys a declaration scope.
247 *
248 * This function does not destroy the parent scope.
249 *
250 * @param scope Scope to destroy
251 */
252 static
253 void ctx_decl_scope_destroy(struct ctx_decl_scope *scope)
254 {
255 if (!scope) {
256 goto end;
257 }
258
259 g_hash_table_destroy(scope->decl_map);
260 g_free(scope);
261
262 end:
263 return;
264 }
265
266 /**
267 * Returns the GQuark of a prefixed alias.
268 *
269 * @param prefix Prefix character
270 * @param name Name
271 * @returns Associated GQuark, or 0 on error
272 */
273 static
274 GQuark get_prefixed_named_quark(char prefix, const char *name)
275 {
276 GQuark qname = 0;
277
278 BT_ASSERT(name);
279
280 /* Prefix character + original string + '\0' */
281 char *prname = g_new(char, strlen(name) + 2);
282 if (!prname) {
283 BT_LOGE_STR("Failed to allocate a string.");
284 goto end;
285 }
286
287 sprintf(prname, "%c%s", prefix, name);
288 qname = g_quark_from_string(prname);
289 g_free(prname);
290
291 end:
292 return qname;
293 }
294
295 /**
296 * Looks up a prefixed class alias within a declaration scope.
297 *
298 * @param scope Declaration scope
299 * @param prefix Prefix character
300 * @param name Alias name
301 * @param levels Number of levels to dig into (-1 means infinite)
302 * @param copy True to return a copy
303 * @returns Declaration (owned by caller if \p copy is true),
304 * or NULL if not found
305 */
306 static
307 struct ctf_field_class *ctx_decl_scope_lookup_prefix_alias(
308 struct ctx_decl_scope *scope, char prefix, const char *name,
309 int levels, bool copy)
310 {
311 GQuark qname = 0;
312 int cur_levels = 0;
313 struct ctf_field_class *decl = NULL;
314 struct ctx_decl_scope *cur_scope = scope;
315
316 BT_ASSERT(scope);
317 BT_ASSERT(name);
318 qname = get_prefixed_named_quark(prefix, name);
319 if (!qname) {
320 goto end;
321 }
322
323 if (levels < 0) {
324 levels = INT_MAX;
325 }
326
327 while (cur_scope && cur_levels < levels) {
328 decl = g_hash_table_lookup(cur_scope->decl_map,
329 (gconstpointer) GUINT_TO_POINTER(qname));
330 if (decl) {
331 /* Caller's reference */
332 if (copy) {
333 decl = ctf_field_class_copy(decl);
334 BT_ASSERT(decl);
335 }
336
337 goto end;
338 }
339
340 cur_scope = cur_scope->parent_scope;
341 cur_levels++;
342 }
343
344 end:
345 return decl;
346 }
347
348 /**
349 * Looks up a class alias within a declaration scope.
350 *
351 * @param scope Declaration scope
352 * @param name Alias name
353 * @param levels Number of levels to dig into (-1 means infinite)
354 * @param copy True to return a copy
355 * @returns Declaration (owned by caller if \p copy is true),
356 * or NULL if not found
357 */
358 static
359 struct ctf_field_class *ctx_decl_scope_lookup_alias(
360 struct ctx_decl_scope *scope, const char *name, int levels,
361 bool copy)
362 {
363 return ctx_decl_scope_lookup_prefix_alias(scope, _PREFIX_ALIAS,
364 name, levels, copy);
365 }
366
367 /**
368 * Looks up an enumeration within a declaration scope.
369 *
370 * @param scope Declaration scope
371 * @param name Enumeration name
372 * @param levels Number of levels to dig into (-1 means infinite)
373 * @param copy True to return a copy
374 * @returns Declaration (owned by caller if \p copy is true),
375 * or NULL if not found
376 */
377 static
378 struct ctf_field_class_enum *ctx_decl_scope_lookup_enum(
379 struct ctx_decl_scope *scope, const char *name, int levels,
380 bool copy)
381 {
382 return (void *) ctx_decl_scope_lookup_prefix_alias(scope, _PREFIX_ENUM,
383 name, levels, copy);
384 }
385
386 /**
387 * Looks up a structure within a declaration scope.
388 *
389 * @param scope Declaration scope
390 * @param name Structure name
391 * @param levels Number of levels to dig into (-1 means infinite)
392 * @param copy True to return a copy
393 * @returns Declaration (owned by caller if \p copy is true),
394 * or NULL if not found
395 */
396 static
397 struct ctf_field_class_struct *ctx_decl_scope_lookup_struct(
398 struct ctx_decl_scope *scope, const char *name, int levels,
399 bool copy)
400 {
401 return (void *) ctx_decl_scope_lookup_prefix_alias(scope,
402 _PREFIX_STRUCT, name, levels, copy);
403 }
404
405 /**
406 * Looks up a variant within a declaration scope.
407 *
408 * @param scope Declaration scope
409 * @param name Variant name
410 * @param levels Number of levels to dig into (-1 means infinite)
411 * @param copy True to return a copy
412 * @returns Declaration (owned by caller if \p copy is true),
413 * or NULL if not found
414 */
415 static
416 struct ctf_field_class_variant *ctx_decl_scope_lookup_variant(
417 struct ctx_decl_scope *scope, const char *name, int levels,
418 bool copy)
419 {
420 return (void *) ctx_decl_scope_lookup_prefix_alias(scope,
421 _PREFIX_VARIANT, name, levels, copy);
422 }
423
424 /**
425 * Registers a prefixed class alias within a declaration scope.
426 *
427 * @param scope Declaration scope
428 * @param prefix Prefix character
429 * @param name Alias name (non-NULL)
430 * @param decl Field class to register (copied)
431 * @returns 0 if registration went okay, negative value otherwise
432 */
433 static
434 int ctx_decl_scope_register_prefix_alias(struct ctx_decl_scope *scope,
435 char prefix, const char *name, struct ctf_field_class *decl)
436 {
437 int ret = 0;
438 GQuark qname = 0;
439
440 BT_ASSERT(scope);
441 BT_ASSERT(name);
442 BT_ASSERT(decl);
443 qname = get_prefixed_named_quark(prefix, name);
444 if (!qname) {
445 ret = -ENOMEM;
446 goto end;
447 }
448
449 /* Make sure alias does not exist in local scope */
450 if (ctx_decl_scope_lookup_prefix_alias(scope, prefix, name, 1,
451 false)) {
452 ret = -EEXIST;
453 goto end;
454 }
455
456 decl = ctf_field_class_copy(decl);
457 BT_ASSERT(decl);
458 g_hash_table_insert(scope->decl_map, GUINT_TO_POINTER(qname), decl);
459
460 end:
461 return ret;
462 }
463
464 /**
465 * Registers a class alias within a declaration scope.
466 *
467 * @param scope Declaration scope
468 * @param name Alias name (non-NULL)
469 * @param decl Field class to register (copied)
470 * @returns 0 if registration went okay, negative value otherwise
471 */
472 static
473 int ctx_decl_scope_register_alias(struct ctx_decl_scope *scope,
474 const char *name, struct ctf_field_class *decl)
475 {
476 return ctx_decl_scope_register_prefix_alias(scope, _PREFIX_ALIAS,
477 name, (void *) decl);
478 }
479
480 /**
481 * Registers an enumeration declaration within a declaration scope.
482 *
483 * @param scope Declaration scope
484 * @param name Enumeration name (non-NULL)
485 * @param decl Enumeration field class to register (copied)
486 * @returns 0 if registration went okay, negative value otherwise
487 */
488 static
489 int ctx_decl_scope_register_enum(struct ctx_decl_scope *scope,
490 const char *name, struct ctf_field_class_enum *decl)
491 {
492 return ctx_decl_scope_register_prefix_alias(scope, _PREFIX_ENUM,
493 name, (void *) decl);
494 }
495
496 /**
497 * Registers a structure declaration within a declaration scope.
498 *
499 * @param scope Declaration scope
500 * @param name Structure name (non-NULL)
501 * @param decl Structure field class to register (copied)
502 * @returns 0 if registration went okay, negative value otherwise
503 */
504 static
505 int ctx_decl_scope_register_struct(struct ctx_decl_scope *scope,
506 const char *name, struct ctf_field_class_struct *decl)
507 {
508 return ctx_decl_scope_register_prefix_alias(scope, _PREFIX_STRUCT,
509 name, (void *) decl);
510 }
511
512 /**
513 * Registers a variant declaration within a declaration scope.
514 *
515 * @param scope Declaration scope
516 * @param name Variant name (non-NULL)
517 * @param decl Variant field class to register
518 * @returns 0 if registration went okay, negative value otherwise
519 */
520 static
521 int ctx_decl_scope_register_variant(struct ctx_decl_scope *scope,
522 const char *name, struct ctf_field_class_variant *decl)
523 {
524 return ctx_decl_scope_register_prefix_alias(scope, _PREFIX_VARIANT,
525 name, (void *) decl);
526 }
527
528 /**
529 * Destroys a visitor context.
530 *
531 * @param ctx Visitor context to destroy
532 */
533 static
534 void ctx_destroy(struct ctx *ctx)
535 {
536 struct ctx_decl_scope *scope;
537
538 if (!ctx) {
539 goto end;
540 }
541
542 scope = ctx->current_scope;
543
544 /*
545 * Destroy all scopes, from current one to the root scope.
546 */
547 while (scope) {
548 struct ctx_decl_scope *parent_scope = scope->parent_scope;
549
550 ctx_decl_scope_destroy(scope);
551 scope = parent_scope;
552 }
553
554 bt_trace_class_put_ref(ctx->trace_class);
555
556 if (ctx->ctf_tc) {
557 ctf_trace_class_destroy(ctx->ctf_tc);
558 }
559
560 g_free(ctx);
561
562 end:
563 return;
564 }
565
566 /**
567 * Creates a new visitor context.
568 *
569 * @param trace Associated trace
570 * @returns New visitor context, or NULL on error
571 */
572 static
573 struct ctx *ctx_create(bt_self_component_source *self_comp,
574 const struct ctf_metadata_decoder_config *decoder_config)
575 {
576 struct ctx *ctx = NULL;
577
578 BT_ASSERT(decoder_config);
579
580 ctx = g_new0(struct ctx, 1);
581 if (!ctx) {
582 BT_LOGE_STR("Failed to allocate one visitor context.");
583 goto error;
584 }
585
586 if (self_comp) {
587 ctx->trace_class = bt_trace_class_create(
588 bt_self_component_source_as_self_component(self_comp));
589 if (!ctx->trace_class) {
590 BT_LOGE_STR("Cannot create empty trace class.");
591 goto error;
592 }
593 }
594
595 ctx->ctf_tc = ctf_trace_class_create();
596 if (!ctx->ctf_tc) {
597 BT_LOGE_STR("Cannot create CTF trace class.");
598 goto error;
599 }
600
601 /* Root declaration scope */
602 ctx->current_scope = ctx_decl_scope_create(NULL);
603 if (!ctx->current_scope) {
604 BT_LOGE_STR("Cannot create declaration scope.");
605 goto error;
606 }
607
608 ctx->decoder_config = *decoder_config;
609 goto end;
610
611 error:
612 ctx_destroy(ctx);
613 ctx = NULL;
614
615 end:
616 return ctx;
617 }
618
619 /**
620 * Pushes a new declaration scope on top of a visitor context's
621 * declaration scope stack.
622 *
623 * @param ctx Visitor context
624 * @returns 0 on success, or a negative value on error
625 */
626 static
627 int ctx_push_scope(struct ctx *ctx)
628 {
629 int ret = 0;
630 struct ctx_decl_scope *new_scope;
631
632 BT_ASSERT(ctx);
633 new_scope = ctx_decl_scope_create(ctx->current_scope);
634 if (!new_scope) {
635 BT_LOGE_STR("Cannot create declaration scope.");
636 ret = -ENOMEM;
637 goto end;
638 }
639
640 ctx->current_scope = new_scope;
641
642 end:
643 return ret;
644 }
645
646 static
647 void ctx_pop_scope(struct ctx *ctx)
648 {
649 struct ctx_decl_scope *parent_scope = NULL;
650
651 BT_ASSERT(ctx);
652
653 if (!ctx->current_scope) {
654 goto end;
655 }
656
657 parent_scope = ctx->current_scope->parent_scope;
658 ctx_decl_scope_destroy(ctx->current_scope);
659 ctx->current_scope = parent_scope;
660
661 end:
662 return;
663 }
664
665 static
666 int visit_field_class_specifier_list(struct ctx *ctx, struct ctf_node *ts_list,
667 struct ctf_field_class **decl);
668
669 static
670 char *remove_underscores_from_field_ref(const char *field_ref)
671 {
672 const char *in_ch;
673 char *out_ch;
674 char *ret;
675 enum {
676 UNDERSCORE_REMOVE_STATE_REMOVE_NEXT_UNDERSCORE,
677 UNDERSCORE_REMOVE_STATE_DO_NOT_REMOVE_NEXT_UNDERSCORE,
678 } state = UNDERSCORE_REMOVE_STATE_REMOVE_NEXT_UNDERSCORE;
679
680 BT_ASSERT(field_ref);
681 ret = calloc(strlen(field_ref) + 1, 1);
682 if (!ret) {
683 BT_LOGE("Failed to allocate a string: size=%zu",
684 strlen(field_ref) + 1);
685 goto end;
686 }
687
688 in_ch = field_ref;
689 out_ch = ret;
690
691 while (*in_ch != '\0') {
692 switch (*in_ch) {
693 case ' ':
694 case '\t':
695 /* Remove whitespace */
696 in_ch++;
697 continue;
698 case '_':
699 if (state == UNDERSCORE_REMOVE_STATE_REMOVE_NEXT_UNDERSCORE) {
700 in_ch++;
701 state = UNDERSCORE_REMOVE_STATE_DO_NOT_REMOVE_NEXT_UNDERSCORE;
702 continue;
703 }
704
705 goto copy;
706 case '.':
707 state = UNDERSCORE_REMOVE_STATE_REMOVE_NEXT_UNDERSCORE;
708 goto copy;
709 default:
710 state = UNDERSCORE_REMOVE_STATE_DO_NOT_REMOVE_NEXT_UNDERSCORE;
711 goto copy;
712 }
713
714 copy:
715 *out_ch = *in_ch;
716 in_ch++;
717 out_ch++;
718 }
719
720 end:
721 return ret;
722 }
723
724 static
725 int is_unary_string(struct bt_list_head *head)
726 {
727 int ret = TRUE;
728 struct ctf_node *node;
729
730 bt_list_for_each_entry(node, head, siblings) {
731 if (node->type != NODE_UNARY_EXPRESSION) {
732 ret = FALSE;
733 }
734
735 if (node->u.unary_expression.type != UNARY_STRING) {
736 ret = FALSE;
737 }
738 }
739
740 return ret;
741 }
742
743 static
744 char *concatenate_unary_strings(struct bt_list_head *head)
745 {
746 int i = 0;
747 GString *str;
748 struct ctf_node *node;
749
750 str = g_string_new(NULL);
751 BT_ASSERT(str);
752
753 bt_list_for_each_entry(node, head, siblings) {
754 char *src_string;
755
756 if (
757 node->type != NODE_UNARY_EXPRESSION ||
758 node->u.unary_expression.type != UNARY_STRING ||
759 !(
760 (
761 node->u.unary_expression.link !=
762 UNARY_LINK_UNKNOWN
763 ) ^ (i == 0)
764 )
765 ) {
766 goto error;
767 }
768
769 switch (node->u.unary_expression.link) {
770 case UNARY_DOTLINK:
771 g_string_append(str, ".");
772 break;
773 case UNARY_ARROWLINK:
774 g_string_append(str, "->");
775 break;
776 case UNARY_DOTDOTDOT:
777 g_string_append(str, "...");
778 break;
779 default:
780 break;
781 }
782
783 src_string = node->u.unary_expression.u.string;
784 g_string_append(str, src_string);
785 i++;
786 }
787
788 /* Destroys the container, returns the underlying string */
789 return g_string_free(str, FALSE);
790
791 error:
792 /* This always returns NULL */
793 return g_string_free(str, TRUE);
794 }
795
796 static
797 const char *get_map_clock_name_value(struct bt_list_head *head)
798 {
799 int i = 0;
800 struct ctf_node *node;
801 const char *name = NULL;
802
803 bt_list_for_each_entry(node, head, siblings) {
804 char *src_string;
805 int uexpr_type = node->u.unary_expression.type;
806 int uexpr_link = node->u.unary_expression.link;
807 int cond = node->type != NODE_UNARY_EXPRESSION ||
808 uexpr_type != UNARY_STRING ||
809 !((uexpr_link != UNARY_LINK_UNKNOWN) ^ (i == 0));
810 if (cond) {
811 goto error;
812 }
813
814 /* Needs to be chained with . */
815 switch (node->u.unary_expression.link) {
816 case UNARY_DOTLINK:
817 break;
818 case UNARY_ARROWLINK:
819 case UNARY_DOTDOTDOT:
820 goto error;
821 default:
822 break;
823 }
824
825 src_string = node->u.unary_expression.u.string;
826
827 switch (i) {
828 case 0:
829 if (strcmp("clock", src_string)) {
830 goto error;
831 }
832 break;
833 case 1:
834 name = src_string;
835 break;
836 case 2:
837 if (strcmp("value", src_string)) {
838 goto error;
839 }
840 break;
841 default:
842 /* Extra identifier, unknown */
843 goto error;
844 }
845
846 i++;
847 }
848
849 return name;
850
851 error:
852 return NULL;
853 }
854
855 static
856 int is_unary_unsigned(struct bt_list_head *head)
857 {
858 int ret = TRUE;
859 struct ctf_node *node;
860
861 bt_list_for_each_entry(node, head, siblings) {
862 if (node->type != NODE_UNARY_EXPRESSION) {
863 ret = FALSE;
864 }
865
866 if (node->u.unary_expression.type != UNARY_UNSIGNED_CONSTANT) {
867 ret = FALSE;
868 }
869 }
870
871 return ret;
872 }
873
874 static
875 int get_unary_unsigned(struct bt_list_head *head, uint64_t *value)
876 {
877 int i = 0;
878 int ret = 0;
879 struct ctf_node *node;
880
881 *value = 0;
882
883 if (bt_list_empty(head)) {
884 ret = -1;
885 goto end;
886 }
887
888 bt_list_for_each_entry(node, head, siblings) {
889 int uexpr_type = node->u.unary_expression.type;
890 int uexpr_link = node->u.unary_expression.link;
891 int cond = node->type != NODE_UNARY_EXPRESSION ||
892 uexpr_type != UNARY_UNSIGNED_CONSTANT ||
893 uexpr_link != UNARY_LINK_UNKNOWN || i != 0;
894 if (cond) {
895 _BT_LOGE_NODE(node, "Invalid constant unsigned integer.");
896 ret = -EINVAL;
897 goto end;
898 }
899
900 *value = node->u.unary_expression.u.unsigned_constant;
901 i++;
902 }
903
904 end:
905 return ret;
906 }
907
908 static
909 int is_unary_signed(struct bt_list_head *head)
910 {
911 int ret = TRUE;
912 struct ctf_node *node;
913
914 bt_list_for_each_entry(node, head, siblings) {
915 if (node->type != NODE_UNARY_EXPRESSION) {
916 ret = FALSE;
917 }
918
919 if (node->u.unary_expression.type != UNARY_SIGNED_CONSTANT) {
920 ret = FALSE;
921 }
922 }
923
924 return ret;
925 }
926
927 static
928 int get_unary_signed(struct bt_list_head *head, int64_t *value)
929 {
930 int i = 0;
931 int ret = 0;
932 struct ctf_node *node;
933
934 bt_list_for_each_entry(node, head, siblings) {
935 int uexpr_type = node->u.unary_expression.type;
936 int uexpr_link = node->u.unary_expression.link;
937 int cond = node->type != NODE_UNARY_EXPRESSION ||
938 (uexpr_type != UNARY_UNSIGNED_CONSTANT &&
939 uexpr_type != UNARY_SIGNED_CONSTANT) ||
940 uexpr_link != UNARY_LINK_UNKNOWN || i != 0;
941 if (cond) {
942 ret = -EINVAL;
943 goto end;
944 }
945
946 switch (uexpr_type) {
947 case UNARY_UNSIGNED_CONSTANT:
948 *value = (int64_t)
949 node->u.unary_expression.u.unsigned_constant;
950 break;
951 case UNARY_SIGNED_CONSTANT:
952 *value = node->u.unary_expression.u.signed_constant;
953 break;
954 default:
955 ret = -EINVAL;
956 goto end;
957 }
958
959 i++;
960 }
961
962 end:
963 return ret;
964 }
965
966 static
967 int get_unary_uuid(struct bt_list_head *head, unsigned char *uuid)
968 {
969 int i = 0;
970 int ret = 0;
971 struct ctf_node *node;
972
973 bt_list_for_each_entry(node, head, siblings) {
974 int uexpr_type = node->u.unary_expression.type;
975 int uexpr_link = node->u.unary_expression.link;
976 const char *src_string;
977
978 if (node->type != NODE_UNARY_EXPRESSION ||
979 uexpr_type != UNARY_STRING ||
980 uexpr_link != UNARY_LINK_UNKNOWN ||
981 i != 0) {
982 ret = -EINVAL;
983 goto end;
984 }
985
986 src_string = node->u.unary_expression.u.string;
987 ret = bt_uuid_parse(src_string, uuid);
988 if (ret) {
989 _BT_LOGE_NODE(node,
990 "Cannot parse UUID: uuid=\"%s\"", src_string);
991 goto end;
992 }
993 }
994
995 end:
996 return ret;
997 }
998
999 static
1000 int get_boolean(struct ctf_node *unary_expr)
1001 {
1002 int ret = 0;
1003
1004 if (unary_expr->type != NODE_UNARY_EXPRESSION) {
1005 _BT_LOGE_NODE(unary_expr,
1006 "Expecting unary expression: node-type=%d",
1007 unary_expr->type);
1008 ret = -EINVAL;
1009 goto end;
1010 }
1011
1012 switch (unary_expr->u.unary_expression.type) {
1013 case UNARY_UNSIGNED_CONSTANT:
1014 ret = (unary_expr->u.unary_expression.u.unsigned_constant != 0);
1015 break;
1016 case UNARY_SIGNED_CONSTANT:
1017 ret = (unary_expr->u.unary_expression.u.signed_constant != 0);
1018 break;
1019 case UNARY_STRING:
1020 {
1021 const char *str = unary_expr->u.unary_expression.u.string;
1022
1023 if (!strcmp(str, "true") || !strcmp(str, "TRUE")) {
1024 ret = TRUE;
1025 } else if (!strcmp(str, "false") || !strcmp(str, "FALSE")) {
1026 ret = FALSE;
1027 } else {
1028 _BT_LOGE_NODE(unary_expr,
1029 "Unexpected boolean value: value=\"%s\"", str);
1030 ret = -EINVAL;
1031 goto end;
1032 }
1033 break;
1034 }
1035 default:
1036 _BT_LOGE_NODE(unary_expr,
1037 "Unexpected unary expression type: node-type=%d",
1038 unary_expr->u.unary_expression.type);
1039 ret = -EINVAL;
1040 goto end;
1041 }
1042
1043 end:
1044 return ret;
1045 }
1046
1047 static
1048 enum ctf_byte_order byte_order_from_unary_expr(struct ctf_node *unary_expr)
1049 {
1050 const char *str;
1051 enum ctf_byte_order bo = -1;
1052
1053 if (unary_expr->u.unary_expression.type != UNARY_STRING) {
1054 _BT_LOGE_NODE(unary_expr,
1055 "\"byte_order\" attribute: expecting `be`, `le`, `network`, or `native`.");
1056 goto end;
1057 }
1058
1059 str = unary_expr->u.unary_expression.u.string;
1060
1061 if (!strcmp(str, "be") || !strcmp(str, "network")) {
1062 bo = CTF_BYTE_ORDER_BIG;
1063 } else if (!strcmp(str, "le")) {
1064 bo = CTF_BYTE_ORDER_LITTLE;
1065 } else if (!strcmp(str, "native")) {
1066 bo = CTF_BYTE_ORDER_DEFAULT;
1067 } else {
1068 _BT_LOGE_NODE(unary_expr,
1069 "Unexpected \"byte_order\" attribute value: "
1070 "expecting `be`, `le`, `network`, or `native`: value=\"%s\"",
1071 str);
1072 goto end;
1073 }
1074
1075 end:
1076 return bo;
1077 }
1078
1079 static
1080 enum ctf_byte_order get_real_byte_order(struct ctx *ctx,
1081 struct ctf_node *uexpr)
1082 {
1083 enum ctf_byte_order bo = byte_order_from_unary_expr(uexpr);
1084
1085 if (bo == CTF_BYTE_ORDER_DEFAULT) {
1086 bo = ctx->ctf_tc->default_byte_order;
1087 }
1088
1089 return bo;
1090 }
1091
1092 static
1093 int is_align_valid(uint64_t align)
1094 {
1095 return (align != 0) && !(align & (align - UINT64_C(1)));
1096 }
1097
1098 static
1099 int get_class_specifier_name(struct ctx *ctx, struct ctf_node *cls_specifier,
1100 GString *str)
1101 {
1102 int ret = 0;
1103
1104 if (cls_specifier->type != NODE_TYPE_SPECIFIER) {
1105 _BT_LOGE_NODE(cls_specifier,
1106 "Unexpected node type: node-type=%d",
1107 cls_specifier->type);
1108 ret = -EINVAL;
1109 goto end;
1110 }
1111
1112 switch (cls_specifier->u.field_class_specifier.type) {
1113 case TYPESPEC_VOID:
1114 g_string_append(str, "void");
1115 break;
1116 case TYPESPEC_CHAR:
1117 g_string_append(str, "char");
1118 break;
1119 case TYPESPEC_SHORT:
1120 g_string_append(str, "short");
1121 break;
1122 case TYPESPEC_INT:
1123 g_string_append(str, "int");
1124 break;
1125 case TYPESPEC_LONG:
1126 g_string_append(str, "long");
1127 break;
1128 case TYPESPEC_FLOAT:
1129 g_string_append(str, "float");
1130 break;
1131 case TYPESPEC_DOUBLE:
1132 g_string_append(str, "double");
1133 break;
1134 case TYPESPEC_SIGNED:
1135 g_string_append(str, "signed");
1136 break;
1137 case TYPESPEC_UNSIGNED:
1138 g_string_append(str, "unsigned");
1139 break;
1140 case TYPESPEC_BOOL:
1141 g_string_append(str, "bool");
1142 break;
1143 case TYPESPEC_COMPLEX:
1144 g_string_append(str, "_Complex");
1145 break;
1146 case TYPESPEC_IMAGINARY:
1147 g_string_append(str, "_Imaginary");
1148 break;
1149 case TYPESPEC_CONST:
1150 g_string_append(str, "const");
1151 break;
1152 case TYPESPEC_ID_TYPE:
1153 if (cls_specifier->u.field_class_specifier.id_type) {
1154 g_string_append(str,
1155 cls_specifier->u.field_class_specifier.id_type);
1156 }
1157 break;
1158 case TYPESPEC_STRUCT:
1159 {
1160 struct ctf_node *node = cls_specifier->u.field_class_specifier.node;
1161
1162 if (!node->u._struct.name) {
1163 _BT_LOGE_NODE(node, "Unexpected empty structure field class name.");
1164 ret = -EINVAL;
1165 goto end;
1166 }
1167
1168 g_string_append(str, "struct ");
1169 g_string_append(str, node->u._struct.name);
1170 break;
1171 }
1172 case TYPESPEC_VARIANT:
1173 {
1174 struct ctf_node *node = cls_specifier->u.field_class_specifier.node;
1175
1176 if (!node->u.variant.name) {
1177 _BT_LOGE_NODE(node, "Unexpected empty variant field class name.");
1178 ret = -EINVAL;
1179 goto end;
1180 }
1181
1182 g_string_append(str, "variant ");
1183 g_string_append(str, node->u.variant.name);
1184 break;
1185 }
1186 case TYPESPEC_ENUM:
1187 {
1188 struct ctf_node *node = cls_specifier->u.field_class_specifier.node;
1189
1190 if (!node->u._enum.enum_id) {
1191 _BT_LOGE_NODE(node,
1192 "Unexpected empty enumeration field class (`enum`) name.");
1193 ret = -EINVAL;
1194 goto end;
1195 }
1196
1197 g_string_append(str, "enum ");
1198 g_string_append(str, node->u._enum.enum_id);
1199 break;
1200 }
1201 case TYPESPEC_FLOATING_POINT:
1202 case TYPESPEC_INTEGER:
1203 case TYPESPEC_STRING:
1204 default:
1205 _BT_LOGE_NODE(cls_specifier->u.field_class_specifier.node,
1206 "Unexpected field class specifier type: %d",
1207 cls_specifier->u.field_class_specifier.type);
1208 ret = -EINVAL;
1209 goto end;
1210 }
1211
1212 end:
1213 return ret;
1214 }
1215
1216 static
1217 int get_class_specifier_list_name(struct ctx *ctx,
1218 struct ctf_node *cls_specifier_list, GString *str)
1219 {
1220 int ret = 0;
1221 struct ctf_node *iter;
1222 int alias_item_nr = 0;
1223 struct bt_list_head *head =
1224 &cls_specifier_list->u.field_class_specifier_list.head;
1225
1226 bt_list_for_each_entry(iter, head, siblings) {
1227 if (alias_item_nr != 0) {
1228 g_string_append(str, " ");
1229 }
1230
1231 alias_item_nr++;
1232 ret = get_class_specifier_name(ctx, iter, str);
1233 if (ret) {
1234 goto end;
1235 }
1236 }
1237
1238 end:
1239 return ret;
1240 }
1241
1242 static
1243 GQuark create_class_alias_identifier(struct ctx *ctx,
1244 struct ctf_node *cls_specifier_list,
1245 struct ctf_node *node_field_class_declarator)
1246 {
1247 int ret;
1248 char *str_c;
1249 GString *str;
1250 GQuark qalias = 0;
1251 struct ctf_node *iter;
1252 struct bt_list_head *pointers =
1253 &node_field_class_declarator->u.field_class_declarator.pointers;
1254
1255 str = g_string_new("");
1256 ret = get_class_specifier_list_name(ctx, cls_specifier_list, str);
1257 if (ret) {
1258 g_string_free(str, TRUE);
1259 goto end;
1260 }
1261
1262 bt_list_for_each_entry(iter, pointers, siblings) {
1263 g_string_append(str, " *");
1264
1265 if (iter->u.pointer.const_qualifier) {
1266 g_string_append(str, " const");
1267 }
1268 }
1269
1270 str_c = g_string_free(str, FALSE);
1271 qalias = g_quark_from_string(str_c);
1272 g_free(str_c);
1273
1274 end:
1275 return qalias;
1276 }
1277
1278 static
1279 int visit_field_class_declarator(struct ctx *ctx,
1280 struct ctf_node *cls_specifier_list,
1281 GQuark *field_name, struct ctf_node *node_field_class_declarator,
1282 struct ctf_field_class **field_decl,
1283 struct ctf_field_class *nested_decl)
1284 {
1285 /*
1286 * During this whole function, nested_decl is always OURS,
1287 * whereas field_decl is an output which we create, but
1288 * belongs to the caller (it is moved).
1289 */
1290 int ret = 0;
1291 *field_decl = NULL;
1292
1293 /* Validate field class declarator node */
1294 if (node_field_class_declarator) {
1295 if (node_field_class_declarator->u.field_class_declarator.type ==
1296 TYPEDEC_UNKNOWN) {
1297 _BT_LOGE_NODE(node_field_class_declarator,
1298 "Unexpected field class declarator type: type=%d",
1299 node_field_class_declarator->u.field_class_declarator.type);
1300 ret = -EINVAL;
1301 goto error;
1302 }
1303
1304 /* TODO: GCC bitfields not supported yet */
1305 if (node_field_class_declarator->u.field_class_declarator.bitfield_len !=
1306 NULL) {
1307 _BT_LOGE_NODE(node_field_class_declarator,
1308 "GCC bitfields are not supported as of this version.");
1309 ret = -EPERM;
1310 goto error;
1311 }
1312 }
1313
1314 /* Find the right nested declaration if not provided */
1315 if (!nested_decl) {
1316 struct bt_list_head *pointers =
1317 &node_field_class_declarator->u.field_class_declarator.pointers;
1318
1319 if (node_field_class_declarator && !bt_list_empty(pointers)) {
1320 GQuark qalias;
1321
1322 /*
1323 * If we have a pointer declarator, it HAS to
1324 * be present in the field class aliases (else
1325 * fail).
1326 */
1327 qalias = create_class_alias_identifier(ctx,
1328 cls_specifier_list, node_field_class_declarator);
1329 nested_decl =
1330 ctx_decl_scope_lookup_alias(ctx->current_scope,
1331 g_quark_to_string(qalias), -1, true);
1332 if (!nested_decl) {
1333 _BT_LOGE_NODE(node_field_class_declarator,
1334 "Cannot find class alias: name=\"%s\"",
1335 g_quark_to_string(qalias));
1336 ret = -EINVAL;
1337 goto error;
1338 }
1339
1340 if (nested_decl->type == CTF_FIELD_CLASS_TYPE_INT) {
1341 /* Pointer: force integer's base to 16 */
1342 struct ctf_field_class_int *int_fc =
1343 (void *) nested_decl;
1344
1345 int_fc->disp_base =
1346 BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_HEXADECIMAL;
1347 }
1348 } else {
1349 ret = visit_field_class_specifier_list(ctx,
1350 cls_specifier_list, &nested_decl);
1351 if (ret) {
1352 BT_ASSERT(!nested_decl);
1353 goto error;
1354 }
1355 }
1356 }
1357
1358 BT_ASSERT(nested_decl);
1359
1360 if (!node_field_class_declarator) {
1361 *field_decl = nested_decl;
1362 nested_decl = NULL;
1363 goto end;
1364 }
1365
1366 if (node_field_class_declarator->u.field_class_declarator.type == TYPEDEC_ID) {
1367 if (node_field_class_declarator->u.field_class_declarator.u.id) {
1368 const char *id =
1369 node_field_class_declarator->u.field_class_declarator.u.id;
1370
1371 if (id[0] == '_') {
1372 id++;
1373 }
1374
1375 *field_name = g_quark_from_string(id);
1376 } else {
1377 *field_name = 0;
1378 }
1379
1380 *field_decl = nested_decl;
1381 nested_decl = NULL;
1382 goto end;
1383 } else {
1384 struct ctf_node *first;
1385 struct ctf_field_class *decl = NULL;
1386 struct ctf_field_class *outer_field_decl = NULL;
1387 struct bt_list_head *length =
1388 &node_field_class_declarator->
1389 u.field_class_declarator.u.nested.length;
1390
1391 /* Create array/sequence, pass nested_decl as child */
1392 if (bt_list_empty(length)) {
1393 _BT_LOGE_NODE(node_field_class_declarator,
1394 "Expecting length field reference or value.");
1395 ret = -EINVAL;
1396 goto error;
1397 }
1398
1399 first = _BT_LIST_FIRST_ENTRY(length, struct ctf_node, siblings);
1400 if (first->type != NODE_UNARY_EXPRESSION) {
1401 _BT_LOGE_NODE(first,
1402 "Unexpected node type: node-type=%d",
1403 first->type);
1404 ret = -EINVAL;
1405 goto error;
1406 }
1407
1408 switch (first->u.unary_expression.type) {
1409 case UNARY_UNSIGNED_CONSTANT:
1410 {
1411 struct ctf_field_class_array *array_decl = NULL;
1412
1413 array_decl = ctf_field_class_array_create();
1414 BT_ASSERT(array_decl);
1415 array_decl->length =
1416 first->u.unary_expression.u.unsigned_constant;
1417 array_decl->base.elem_fc = nested_decl;
1418 nested_decl = NULL;
1419 decl = (void *) array_decl;
1420 break;
1421 }
1422 case UNARY_STRING:
1423 {
1424 /* Lookup unsigned integer definition, create seq. */
1425 struct ctf_field_class_sequence *seq_decl = NULL;
1426 char *length_name = concatenate_unary_strings(length);
1427
1428 if (!length_name) {
1429 _BT_LOGE_NODE(node_field_class_declarator,
1430 "Cannot concatenate unary strings.");
1431 ret = -EINVAL;
1432 goto error;
1433 }
1434
1435 if (strncmp(length_name, "env.", 4) == 0) {
1436 /* This is, in fact, an array */
1437 const char *env_entry_name = &length_name[4];
1438 struct ctf_trace_class_env_entry *env_entry =
1439 ctf_trace_class_borrow_env_entry_by_name(
1440 ctx->ctf_tc, env_entry_name);
1441 struct ctf_field_class_array *array_decl;
1442
1443 if (!env_entry) {
1444 _BT_LOGE_NODE(node_field_class_declarator,
1445 "Cannot find environment entry: "
1446 "name=\"%s\"", env_entry_name);
1447 ret = -EINVAL;
1448 goto error;
1449 }
1450
1451 if (env_entry->type != CTF_TRACE_CLASS_ENV_ENTRY_TYPE_INT) {
1452 _BT_LOGE_NODE(node_field_class_declarator,
1453 "Wrong environment entry type "
1454 "(expecting integer): "
1455 "name=\"%s\"", env_entry_name);
1456 ret = -EINVAL;
1457 goto error;
1458 }
1459
1460 if (env_entry->value.i < 0) {
1461 _BT_LOGE_NODE(node_field_class_declarator,
1462 "Invalid, negative array length: "
1463 "env-entry-name=\"%s\", "
1464 "value=%" PRId64,
1465 env_entry_name,
1466 env_entry->value.i);
1467 ret = -EINVAL;
1468 goto error;
1469 }
1470
1471 array_decl = ctf_field_class_array_create();
1472 BT_ASSERT(array_decl);
1473 array_decl->length =
1474 (uint64_t) env_entry->value.i;
1475 array_decl->base.elem_fc = nested_decl;
1476 nested_decl = NULL;
1477 decl = (void *) array_decl;
1478 } else {
1479 char *length_name_no_underscore =
1480 remove_underscores_from_field_ref(
1481 length_name);
1482 if (!length_name_no_underscore) {
1483 /*
1484 * remove_underscores_from_field_ref()
1485 * logs errors
1486 */
1487 ret = -EINVAL;
1488 goto error;
1489 }
1490 seq_decl = ctf_field_class_sequence_create();
1491 BT_ASSERT(seq_decl);
1492 seq_decl->base.elem_fc = nested_decl;
1493 nested_decl = NULL;
1494 g_string_assign(seq_decl->length_ref,
1495 length_name_no_underscore);
1496 free(length_name_no_underscore);
1497 decl = (void *) seq_decl;
1498 }
1499
1500 g_free(length_name);
1501 break;
1502 }
1503 default:
1504 ret = -EINVAL;
1505 goto error;
1506 }
1507
1508 BT_ASSERT(!nested_decl);
1509 BT_ASSERT(decl);
1510 BT_ASSERT(!*field_decl);
1511
1512 /*
1513 * At this point, we found the next nested declaration.
1514 * We currently own this (and lost the ownership of
1515 * nested_decl in the meantime). Pass this next
1516 * nested declaration as the content of the outer
1517 * container, MOVING its ownership.
1518 */
1519 ret = visit_field_class_declarator(ctx, cls_specifier_list,
1520 field_name,
1521 node_field_class_declarator->
1522 u.field_class_declarator.u.nested.field_class_declarator,
1523 &outer_field_decl, decl);
1524 decl = NULL;
1525 if (ret) {
1526 BT_ASSERT(!outer_field_decl);
1527 ret = -EINVAL;
1528 goto error;
1529 }
1530
1531 BT_ASSERT(outer_field_decl);
1532 *field_decl = outer_field_decl;
1533 outer_field_decl = NULL;
1534 }
1535
1536 BT_ASSERT(*field_decl);
1537 goto end;
1538
1539 error:
1540 ctf_field_class_destroy(*field_decl);
1541 *field_decl = NULL;
1542
1543 if (ret >= 0) {
1544 ret = -1;
1545 }
1546
1547 end:
1548 ctf_field_class_destroy(nested_decl);
1549 nested_decl = NULL;
1550 return ret;
1551 }
1552
1553 static
1554 int visit_struct_decl_field(struct ctx *ctx,
1555 struct ctf_field_class_struct *struct_decl,
1556 struct ctf_node *cls_specifier_list,
1557 struct bt_list_head *field_class_declarators)
1558 {
1559 int ret = 0;
1560 struct ctf_node *iter;
1561 struct ctf_field_class *field_decl = NULL;
1562
1563 bt_list_for_each_entry(iter, field_class_declarators, siblings) {
1564 field_decl = NULL;
1565 GQuark qfield_name;
1566 const char *field_name;
1567
1568 ret = visit_field_class_declarator(ctx, cls_specifier_list,
1569 &qfield_name, iter, &field_decl, NULL);
1570 if (ret) {
1571 BT_ASSERT(!field_decl);
1572 _BT_LOGE_NODE(cls_specifier_list,
1573 "Cannot visit field class declarator: ret=%d", ret);
1574 goto error;
1575 }
1576
1577 BT_ASSERT(field_decl);
1578 field_name = g_quark_to_string(qfield_name);
1579
1580 /* Check if field with same name already exists */
1581 if (ctf_field_class_struct_borrow_member_by_name(
1582 struct_decl, field_name)) {
1583 _BT_LOGE_NODE(cls_specifier_list,
1584 "Duplicate field in structure field class: "
1585 "field-name=\"%s\"", field_name);
1586 ret = -EINVAL;
1587 goto error;
1588 }
1589
1590 /* Add field to structure */
1591 ctf_field_class_struct_append_member(struct_decl,
1592 field_name, field_decl);
1593 field_decl = NULL;
1594 }
1595
1596 return 0;
1597
1598 error:
1599 ctf_field_class_destroy(field_decl);
1600 field_decl = NULL;
1601 return ret;
1602 }
1603
1604 static
1605 int visit_variant_decl_field(struct ctx *ctx,
1606 struct ctf_field_class_variant *variant_decl,
1607 struct ctf_node *cls_specifier_list,
1608 struct bt_list_head *field_class_declarators)
1609 {
1610 int ret = 0;
1611 struct ctf_node *iter;
1612 struct ctf_field_class *field_decl = NULL;
1613
1614 bt_list_for_each_entry(iter, field_class_declarators, siblings) {
1615 field_decl = NULL;
1616 GQuark qfield_name;
1617 const char *field_name;
1618
1619 ret = visit_field_class_declarator(ctx, cls_specifier_list,
1620 &qfield_name, iter, &field_decl, NULL);
1621 if (ret) {
1622 BT_ASSERT(!field_decl);
1623 _BT_LOGE_NODE(cls_specifier_list,
1624 "Cannot visit field class declarator: ret=%d", ret);
1625 goto error;
1626 }
1627
1628 BT_ASSERT(field_decl);
1629 field_name = g_quark_to_string(qfield_name);
1630
1631 /* Check if field with same name already exists */
1632 if (ctf_field_class_variant_borrow_option_by_name(
1633 variant_decl, field_name)) {
1634 _BT_LOGE_NODE(cls_specifier_list,
1635 "Duplicate field in variant field class: "
1636 "field-name=\"%s\"", field_name);
1637 ret = -EINVAL;
1638 goto error;
1639 }
1640
1641 /* Add field to structure */
1642 ctf_field_class_variant_append_option(variant_decl,
1643 field_name, field_decl);
1644 field_decl = NULL;
1645 }
1646
1647 return 0;
1648
1649 error:
1650 ctf_field_class_destroy(field_decl);
1651 field_decl = NULL;
1652 return ret;
1653 }
1654
1655 static
1656 int visit_field_class_def(struct ctx *ctx, struct ctf_node *cls_specifier_list,
1657 struct bt_list_head *field_class_declarators)
1658 {
1659 int ret = 0;
1660 GQuark qidentifier;
1661 struct ctf_node *iter;
1662 struct ctf_field_class *class_decl = NULL;
1663
1664 bt_list_for_each_entry(iter, field_class_declarators, siblings) {
1665 ret = visit_field_class_declarator(ctx, cls_specifier_list,
1666 &qidentifier, iter, &class_decl, NULL);
1667 if (ret) {
1668 _BT_LOGE_NODE(iter,
1669 "Cannot visit field class declarator: ret=%d", ret);
1670 ret = -EINVAL;
1671 goto end;
1672 }
1673
1674 /* Do not allow field class def and alias of untagged variants */
1675 if (class_decl->type == CTF_FIELD_CLASS_TYPE_VARIANT) {
1676 struct ctf_field_class_variant *var_fc =
1677 (void *) class_decl;
1678
1679 if (var_fc->tag_path.path->len == 0) {
1680 _BT_LOGE_NODE(iter,
1681 "Type definition of untagged variant field class is not allowed.");
1682 ret = -EPERM;
1683 goto end;
1684 }
1685 }
1686
1687 ret = ctx_decl_scope_register_alias(ctx->current_scope,
1688 g_quark_to_string(qidentifier), class_decl);
1689 if (ret) {
1690 _BT_LOGE_NODE(iter,
1691 "Cannot register field class alias: name=\"%s\"",
1692 g_quark_to_string(qidentifier));
1693 goto end;
1694 }
1695 }
1696
1697 end:
1698 ctf_field_class_destroy(class_decl);
1699 class_decl = NULL;
1700 return ret;
1701 }
1702
1703 static
1704 int visit_field_class_alias(struct ctx *ctx, struct ctf_node *target,
1705 struct ctf_node *alias)
1706 {
1707 int ret = 0;
1708 GQuark qalias;
1709 struct ctf_node *node;
1710 GQuark qdummy_field_name;
1711 struct ctf_field_class *class_decl = NULL;
1712
1713 /* Create target field class */
1714 if (bt_list_empty(&target->u.field_class_alias_target.field_class_declarators)) {
1715 node = NULL;
1716 } else {
1717 node = _BT_LIST_FIRST_ENTRY(
1718 &target->u.field_class_alias_target.field_class_declarators,
1719 struct ctf_node, siblings);
1720 }
1721
1722 ret = visit_field_class_declarator(ctx,
1723 target->u.field_class_alias_target.field_class_specifier_list,
1724 &qdummy_field_name, node, &class_decl, NULL);
1725 if (ret) {
1726 BT_ASSERT(!class_decl);
1727 _BT_LOGE_NODE(node,
1728 "Cannot visit field class declarator: ret=%d", ret);
1729 goto end;
1730 }
1731
1732 /* Do not allow field class def and alias of untagged variants */
1733 if (class_decl->type == CTF_FIELD_CLASS_TYPE_VARIANT) {
1734 struct ctf_field_class_variant *var_fc = (void *) class_decl;
1735
1736 if (var_fc->tag_path.path->len == 0) {
1737 _BT_LOGE_NODE(target,
1738 "Type definition of untagged variant field class is not allowed.");
1739 ret = -EPERM;
1740 goto end;
1741 }
1742 }
1743
1744 /*
1745 * The semantic validator does not check whether the target is
1746 * abstract or not (if it has an identifier). Check it here.
1747 */
1748 if (qdummy_field_name != 0) {
1749 _BT_LOGE_NODE(target,
1750 "Expecting empty identifier: id=\"%s\"",
1751 g_quark_to_string(qdummy_field_name));
1752 ret = -EINVAL;
1753 goto end;
1754 }
1755
1756 /* Create alias identifier */
1757 node = _BT_LIST_FIRST_ENTRY(&alias->u.field_class_alias_name.field_class_declarators,
1758 struct ctf_node, siblings);
1759 qalias = create_class_alias_identifier(ctx,
1760 alias->u.field_class_alias_name.field_class_specifier_list, node);
1761 ret = ctx_decl_scope_register_alias(ctx->current_scope,
1762 g_quark_to_string(qalias), class_decl);
1763 if (ret) {
1764 _BT_LOGE_NODE(node,
1765 "Cannot register class alias: name=\"%s\"",
1766 g_quark_to_string(qalias));
1767 goto end;
1768 }
1769
1770 end:
1771 ctf_field_class_destroy(class_decl);
1772 class_decl = NULL;
1773 return ret;
1774 }
1775
1776 static
1777 int visit_struct_decl_entry(struct ctx *ctx, struct ctf_node *entry_node,
1778 struct ctf_field_class_struct *struct_decl)
1779 {
1780 int ret = 0;
1781
1782 switch (entry_node->type) {
1783 case NODE_TYPEDEF:
1784 ret = visit_field_class_def(ctx,
1785 entry_node->u.field_class_def.field_class_specifier_list,
1786 &entry_node->u.field_class_def.field_class_declarators);
1787 if (ret) {
1788 _BT_LOGE_NODE(entry_node,
1789 "Cannot add field class found in structure field class: ret=%d",
1790 ret);
1791 goto end;
1792 }
1793 break;
1794 case NODE_TYPEALIAS:
1795 ret = visit_field_class_alias(ctx, entry_node->u.field_class_alias.target,
1796 entry_node->u.field_class_alias.alias);
1797 if (ret) {
1798 _BT_LOGE_NODE(entry_node,
1799 "Cannot add field class alias found in structure field class: ret=%d",
1800 ret);
1801 goto end;
1802 }
1803 break;
1804 case NODE_STRUCT_OR_VARIANT_DECLARATION:
1805 /* Field */
1806 ret = visit_struct_decl_field(ctx, struct_decl,
1807 entry_node->u.struct_or_variant_declaration.
1808 field_class_specifier_list,
1809 &entry_node->u.struct_or_variant_declaration.
1810 field_class_declarators);
1811 if (ret) {
1812 goto end;
1813 }
1814 break;
1815 default:
1816 _BT_LOGE_NODE(entry_node,
1817 "Unexpected node type: node-type=%d", entry_node->type);
1818 ret = -EINVAL;
1819 goto end;
1820 }
1821
1822 end:
1823 return ret;
1824 }
1825
1826 static
1827 int visit_variant_decl_entry(struct ctx *ctx, struct ctf_node *entry_node,
1828 struct ctf_field_class_variant *variant_decl)
1829 {
1830 int ret = 0;
1831
1832 switch (entry_node->type) {
1833 case NODE_TYPEDEF:
1834 ret = visit_field_class_def(ctx,
1835 entry_node->u.field_class_def.field_class_specifier_list,
1836 &entry_node->u.field_class_def.field_class_declarators);
1837 if (ret) {
1838 _BT_LOGE_NODE(entry_node,
1839 "Cannot add field class found in variant field class: ret=%d",
1840 ret);
1841 goto end;
1842 }
1843 break;
1844 case NODE_TYPEALIAS:
1845 ret = visit_field_class_alias(ctx, entry_node->u.field_class_alias.target,
1846 entry_node->u.field_class_alias.alias);
1847 if (ret) {
1848 _BT_LOGE_NODE(entry_node,
1849 "Cannot add field class alias found in variant field class: ret=%d",
1850 ret);
1851 goto end;
1852 }
1853 break;
1854 case NODE_STRUCT_OR_VARIANT_DECLARATION:
1855 /* Field */
1856 ret = visit_variant_decl_field(ctx, variant_decl,
1857 entry_node->u.struct_or_variant_declaration.
1858 field_class_specifier_list,
1859 &entry_node->u.struct_or_variant_declaration.
1860 field_class_declarators);
1861 if (ret) {
1862 goto end;
1863 }
1864 break;
1865 default:
1866 _BT_LOGE_NODE(entry_node,
1867 "Unexpected node type: node-type=%d",
1868 entry_node->type);
1869 ret = -EINVAL;
1870 goto end;
1871 }
1872
1873 end:
1874 return ret;
1875 }
1876
1877 static
1878 int visit_struct_decl(struct ctx *ctx, const char *name,
1879 struct bt_list_head *decl_list, int has_body,
1880 struct bt_list_head *min_align,
1881 struct ctf_field_class_struct **struct_decl)
1882 {
1883 int ret = 0;
1884
1885 BT_ASSERT(struct_decl);
1886 *struct_decl = NULL;
1887
1888 /* For named struct (without body), lookup in declaration scope */
1889 if (!has_body) {
1890 if (!name) {
1891 BT_LOGE_STR("Bodyless structure field class: missing name.");
1892 ret = -EPERM;
1893 goto error;
1894 }
1895
1896 *struct_decl = ctx_decl_scope_lookup_struct(ctx->current_scope,
1897 name, -1, true);
1898 if (!*struct_decl) {
1899 BT_LOGE("Cannot find structure field class: name=\"struct %s\"",
1900 name);
1901 ret = -EINVAL;
1902 goto error;
1903 }
1904 } else {
1905 struct ctf_node *entry_node;
1906 uint64_t min_align_value = 0;
1907
1908 if (name) {
1909 if (ctx_decl_scope_lookup_struct(
1910 ctx->current_scope, name, 1, false)) {
1911 BT_LOGE("Structure field class already declared in local scope: "
1912 "name=\"struct %s\"", name);
1913 ret = -EINVAL;
1914 goto error;
1915 }
1916 }
1917
1918 if (!bt_list_empty(min_align)) {
1919 ret = get_unary_unsigned(min_align, &min_align_value);
1920 if (ret) {
1921 BT_LOGE("Unexpected unary expression for structure field class's `align` attribute: "
1922 "ret=%d", ret);
1923 goto error;
1924 }
1925 }
1926
1927 *struct_decl = ctf_field_class_struct_create();
1928 BT_ASSERT(*struct_decl);
1929
1930 if (min_align_value != 0) {
1931 (*struct_decl)->base.alignment = min_align_value;
1932 }
1933
1934 _TRY_PUSH_SCOPE_OR_GOTO_ERROR();
1935
1936 bt_list_for_each_entry(entry_node, decl_list, siblings) {
1937 ret = visit_struct_decl_entry(ctx, entry_node,
1938 *struct_decl);
1939 if (ret) {
1940 _BT_LOGE_NODE(entry_node,
1941 "Cannot visit structure field class entry: "
1942 "ret=%d", ret);
1943 ctx_pop_scope(ctx);
1944 goto error;
1945 }
1946 }
1947
1948 ctx_pop_scope(ctx);
1949
1950 if (name) {
1951 ret = ctx_decl_scope_register_struct(ctx->current_scope,
1952 name, *struct_decl);
1953 if (ret) {
1954 BT_LOGE("Cannot register structure field class in declaration scope: "
1955 "name=\"struct %s\", ret=%d", name, ret);
1956 goto error;
1957 }
1958 }
1959 }
1960
1961 return 0;
1962
1963 error:
1964 ctf_field_class_destroy((void *) *struct_decl);
1965 *struct_decl = NULL;
1966 return ret;
1967 }
1968
1969 static
1970 int visit_variant_decl(struct ctx *ctx, const char *name,
1971 const char *tag, struct bt_list_head *decl_list,
1972 int has_body, struct ctf_field_class_variant **variant_decl)
1973 {
1974 int ret = 0;
1975 struct ctf_field_class_variant *untagged_variant_decl = NULL;
1976
1977 BT_ASSERT(variant_decl);
1978 *variant_decl = NULL;
1979
1980 /* For named variant (without body), lookup in declaration scope */
1981 if (!has_body) {
1982 if (!name) {
1983 BT_LOGE_STR("Bodyless variant field class: missing name.");
1984 ret = -EPERM;
1985 goto error;
1986 }
1987
1988 untagged_variant_decl =
1989 ctx_decl_scope_lookup_variant(ctx->current_scope,
1990 name, -1, true);
1991 if (!untagged_variant_decl) {
1992 BT_LOGE("Cannot find variant field class: name=\"variant %s\"",
1993 name);
1994 ret = -EINVAL;
1995 goto error;
1996 }
1997 } else {
1998 struct ctf_node *entry_node;
1999
2000 if (name) {
2001 if (ctx_decl_scope_lookup_variant(ctx->current_scope,
2002 name, 1, false)) {
2003 BT_LOGE("Variant field class already declared in local scope: "
2004 "name=\"variant %s\"", name);
2005 ret = -EINVAL;
2006 goto error;
2007 }
2008 }
2009
2010 untagged_variant_decl = ctf_field_class_variant_create();
2011 BT_ASSERT(untagged_variant_decl);
2012 _TRY_PUSH_SCOPE_OR_GOTO_ERROR();
2013
2014 bt_list_for_each_entry(entry_node, decl_list, siblings) {
2015 ret = visit_variant_decl_entry(ctx, entry_node,
2016 untagged_variant_decl);
2017 if (ret) {
2018 _BT_LOGE_NODE(entry_node,
2019 "Cannot visit variant field class entry: "
2020 "ret=%d", ret);
2021 ctx_pop_scope(ctx);
2022 goto error;
2023 }
2024 }
2025
2026 ctx_pop_scope(ctx);
2027
2028 if (name) {
2029 ret = ctx_decl_scope_register_variant(
2030 ctx->current_scope, name,
2031 untagged_variant_decl);
2032 if (ret) {
2033 BT_LOGE("Cannot register variant field class in declaration scope: "
2034 "name=\"variant %s\", ret=%d", name, ret);
2035 goto error;
2036 }
2037 }
2038 }
2039
2040 /*
2041 * If tagged, create tagged variant and return; otherwise
2042 * return untagged variant.
2043 */
2044 if (!tag) {
2045 *variant_decl = untagged_variant_decl;
2046 untagged_variant_decl = NULL;
2047 } else {
2048 /*
2049 * At this point, we have a fresh untagged variant; nobody
2050 * else owns it. Set its tag now.
2051 */
2052 char *tag_no_underscore =
2053 remove_underscores_from_field_ref(tag);
2054
2055 if (!tag_no_underscore) {
2056 /* remove_underscores_from_field_ref() logs errors */
2057 goto error;
2058 }
2059
2060 g_string_assign(untagged_variant_decl->tag_ref,
2061 tag_no_underscore);
2062 free(tag_no_underscore);
2063 *variant_decl = untagged_variant_decl;
2064 untagged_variant_decl = NULL;
2065 }
2066
2067 BT_ASSERT(!untagged_variant_decl);
2068 BT_ASSERT(*variant_decl);
2069 return 0;
2070
2071 error:
2072 ctf_field_class_destroy((void *) untagged_variant_decl);
2073 untagged_variant_decl = NULL;
2074 ctf_field_class_destroy((void *) *variant_decl);
2075 *variant_decl = NULL;
2076 return ret;
2077 }
2078
2079 struct uori {
2080 bool is_signed;
2081 union {
2082 uint64_t u;
2083 uint64_t i;
2084 } value;
2085 };
2086
2087 static
2088 int visit_enum_decl_entry(struct ctx *ctx, struct ctf_node *enumerator,
2089 struct ctf_field_class_enum *enum_decl, struct uori *last)
2090 {
2091 int ret = 0;
2092 int nr_vals = 0;
2093 struct ctf_node *iter;
2094 struct uori start = {
2095 .is_signed = false,
2096 .value.u = 0,
2097 };
2098 struct uori end = {
2099 .is_signed = false,
2100 .value.u = 0,
2101 };
2102 const char *label = enumerator->u.enumerator.id;
2103 const char *effective_label = label;
2104 struct bt_list_head *values = &enumerator->u.enumerator.values;
2105
2106 bt_list_for_each_entry(iter, values, siblings) {
2107 struct uori *target;
2108
2109 if (iter->type != NODE_UNARY_EXPRESSION) {
2110 _BT_LOGE_NODE(iter,
2111 "Wrong expression for enumeration field class label: "
2112 "node-type=%d, label=\"%s\"", iter->type,
2113 label);
2114 ret = -EINVAL;
2115 goto error;
2116 }
2117
2118 if (nr_vals == 0) {
2119 target = &start;
2120 } else {
2121 target = &end;
2122 }
2123
2124 switch (iter->u.unary_expression.type) {
2125 case UNARY_SIGNED_CONSTANT:
2126 target->is_signed = true;
2127 target->value.i =
2128 iter->u.unary_expression.u.signed_constant;
2129 break;
2130 case UNARY_UNSIGNED_CONSTANT:
2131 target->is_signed = false;
2132 target->value.u =
2133 iter->u.unary_expression.u.unsigned_constant;
2134 break;
2135 default:
2136 _BT_LOGE_NODE(iter,
2137 "Invalid enumeration field class entry: "
2138 "expecting constant signed or unsigned integer: "
2139 "node-type=%d, label=\"%s\"",
2140 iter->u.unary_expression.type, label);
2141 ret = -EINVAL;
2142 goto error;
2143 }
2144
2145 if (nr_vals > 1) {
2146 _BT_LOGE_NODE(iter,
2147 "Invalid enumeration field class entry: label=\"%s\"",
2148 label);
2149 ret = -EINVAL;
2150 goto error;
2151 }
2152
2153 nr_vals++;
2154 }
2155
2156 if (nr_vals == 0) {
2157 start = *last;
2158 }
2159
2160 if (nr_vals <= 1) {
2161 end = start;
2162 }
2163
2164 if (end.is_signed) {
2165 last->value.i = end.value.i + 1;
2166 } else {
2167 last->value.u = end.value.u + 1;
2168 }
2169
2170 if (label[0] == '_') {
2171 /*
2172 * Strip the first underscore of any enumeration field
2173 * class's label in case this enumeration FC is used as
2174 * a variant FC tag later. The variant FC choice names
2175 * could also start with `_`, in which case the prefix
2176 * is removed, and it the resulting choice name needs to
2177 * match tag labels.
2178 */
2179 effective_label = &label[1];
2180 }
2181
2182 ctf_field_class_enum_append_mapping(enum_decl, effective_label,
2183 start.value.u, end.value.u);
2184 return 0;
2185
2186 error:
2187 return ret;
2188 }
2189
2190 static
2191 int visit_enum_decl(struct ctx *ctx, const char *name,
2192 struct ctf_node *container_cls,
2193 struct bt_list_head *enumerator_list,
2194 int has_body, struct ctf_field_class_enum **enum_decl)
2195 {
2196 int ret = 0;
2197 GQuark qdummy_id;
2198 struct ctf_field_class_int *integer_decl = NULL;
2199
2200 BT_ASSERT(enum_decl);
2201 *enum_decl = NULL;
2202
2203 /* For named enum (without body), lookup in declaration scope */
2204 if (!has_body) {
2205 if (!name) {
2206 BT_LOGE_STR("Bodyless enumeration field class: missing name.");
2207 ret = -EPERM;
2208 goto error;
2209 }
2210
2211 *enum_decl = ctx_decl_scope_lookup_enum(ctx->current_scope,
2212 name, -1, true);
2213 if (!*enum_decl) {
2214 BT_LOGE("Cannot find enumeration field class: "
2215 "name=\"enum %s\"", name);
2216 ret = -EINVAL;
2217 goto error;
2218 }
2219 } else {
2220 struct ctf_node *iter;
2221 struct uori last_value = {
2222 .is_signed = false,
2223 .value.u = 0,
2224 };
2225
2226 if (name) {
2227 if (ctx_decl_scope_lookup_enum(ctx->current_scope,
2228 name, 1, false)) {
2229 BT_LOGE("Enumeration field class already declared in local scope: "
2230 "name=\"enum %s\"", name);
2231 ret = -EINVAL;
2232 goto error;
2233 }
2234 }
2235
2236 if (!container_cls) {
2237 integer_decl = (void *) ctx_decl_scope_lookup_alias(
2238 ctx->current_scope, "int", -1, true);
2239 if (!integer_decl) {
2240 BT_LOGE_STR("Cannot find implicit `int` field class alias for enumeration field class.");
2241 ret = -EINVAL;
2242 goto error;
2243 }
2244 } else {
2245 ret = visit_field_class_declarator(ctx, container_cls,
2246 &qdummy_id, NULL, (void *) &integer_decl,
2247 NULL);
2248 if (ret) {
2249 BT_ASSERT(!integer_decl);
2250 ret = -EINVAL;
2251 goto error;
2252 }
2253 }
2254
2255 BT_ASSERT(integer_decl);
2256
2257 if (integer_decl->base.base.type != CTF_FIELD_CLASS_TYPE_INT) {
2258 BT_LOGE("Container field class for enumeration field class is not an integer field class: "
2259 "fc-type=%d", integer_decl->base.base.type);
2260 ret = -EINVAL;
2261 goto error;
2262 }
2263
2264 *enum_decl = ctf_field_class_enum_create();
2265 BT_ASSERT(*enum_decl);
2266 (*enum_decl)->base.base.base.alignment =
2267 integer_decl->base.base.alignment;
2268 ctf_field_class_int_copy_content((void *) *enum_decl,
2269 (void *) integer_decl);
2270 last_value.is_signed = (*enum_decl)->base.is_signed;
2271
2272 bt_list_for_each_entry(iter, enumerator_list, siblings) {
2273 ret = visit_enum_decl_entry(ctx, iter, *enum_decl,
2274 &last_value);
2275 if (ret) {
2276 _BT_LOGE_NODE(iter,
2277 "Cannot visit enumeration field class entry: "
2278 "ret=%d", ret);
2279 goto error;
2280 }
2281 }
2282
2283 if (name) {
2284 ret = ctx_decl_scope_register_enum(ctx->current_scope,
2285 name, *enum_decl);
2286 if (ret) {
2287 BT_LOGE("Cannot register enumeration field class in declaration scope: "
2288 "ret=%d", ret);
2289 goto error;
2290 }
2291 }
2292 }
2293
2294 goto end;
2295
2296 error:
2297 ctf_field_class_destroy((void *) *enum_decl);
2298 *enum_decl = NULL;
2299
2300 end:
2301 ctf_field_class_destroy((void *) integer_decl);
2302 integer_decl = NULL;
2303 return ret;
2304 }
2305
2306 static
2307 int visit_field_class_specifier(struct ctx *ctx,
2308 struct ctf_node *cls_specifier_list,
2309 struct ctf_field_class **decl)
2310 {
2311 int ret = 0;
2312 GString *str = NULL;
2313
2314 *decl = NULL;
2315 str = g_string_new("");
2316 ret = get_class_specifier_list_name(ctx, cls_specifier_list, str);
2317 if (ret) {
2318 _BT_LOGE_NODE(cls_specifier_list,
2319 "Cannot get field class specifier list's name: ret=%d", ret);
2320 goto error;
2321 }
2322
2323 *decl = ctx_decl_scope_lookup_alias(ctx->current_scope, str->str, -1,
2324 true);
2325 if (!*decl) {
2326 _BT_LOGE_NODE(cls_specifier_list,
2327 "Cannot find field class alias: name=\"%s\"", str->str);
2328 ret = -EINVAL;
2329 goto error;
2330 }
2331
2332 goto end;
2333
2334 error:
2335 ctf_field_class_destroy(*decl);
2336 *decl = NULL;
2337
2338 end:
2339 if (str) {
2340 g_string_free(str, TRUE);
2341 }
2342
2343 return ret;
2344 }
2345
2346 static
2347 int visit_integer_decl(struct ctx *ctx,
2348 struct bt_list_head *expressions,
2349 struct ctf_field_class_int **integer_decl)
2350 {
2351 int set = 0;
2352 int ret = 0;
2353 int signedness = 0;
2354 struct ctf_node *expression;
2355 uint64_t alignment = 0, size = 0;
2356 struct ctf_clock_class *mapped_clock_class = NULL;
2357 enum ctf_encoding encoding = CTF_ENCODING_NONE;
2358 bt_field_class_integer_preferred_display_base base =
2359 BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_DECIMAL;
2360 enum ctf_byte_order byte_order = ctx->ctf_tc->default_byte_order;
2361
2362 *integer_decl = NULL;
2363
2364 bt_list_for_each_entry(expression, expressions, siblings) {
2365 struct ctf_node *left, *right;
2366
2367 left = _BT_LIST_FIRST_ENTRY(&expression->u.ctf_expression.left,
2368 struct ctf_node, siblings);
2369 right = _BT_LIST_FIRST_ENTRY(
2370 &expression->u.ctf_expression.right, struct ctf_node,
2371 siblings);
2372
2373 if (left->u.unary_expression.type != UNARY_STRING) {
2374 _BT_LOGE_NODE(left,
2375 "Unexpected unary expression type: type=%d",
2376 left->u.unary_expression.type);
2377 ret = -EINVAL;
2378 goto error;
2379 }
2380
2381 if (!strcmp(left->u.unary_expression.u.string, "signed")) {
2382 if (_IS_SET(&set, _INTEGER_SIGNED_SET)) {
2383 _BT_LOGE_DUP_ATTR(left, "signed",
2384 "integer field class");
2385 ret = -EPERM;
2386 goto error;
2387 }
2388
2389 signedness = get_boolean(right);
2390 if (signedness < 0) {
2391 _BT_LOGE_NODE(right,
2392 "Invalid boolean value for integer field class's `signed` attribute: "
2393 "ret=%d", ret);
2394 ret = -EINVAL;
2395 goto error;
2396 }
2397
2398 _SET(&set, _INTEGER_SIGNED_SET);
2399 } else if (!strcmp(left->u.unary_expression.u.string,
2400 "byte_order")) {
2401 if (_IS_SET(&set, _INTEGER_BYTE_ORDER_SET)) {
2402 _BT_LOGE_DUP_ATTR(left, "byte_order",
2403 "integer field class");
2404 ret = -EPERM;
2405 goto error;
2406 }
2407
2408 byte_order = get_real_byte_order(ctx, right);
2409 if (byte_order == -1) {
2410 _BT_LOGE_NODE(right,
2411 "Invalid `byte_order` attribute in integer field class: "
2412 "ret=%d", ret);
2413 ret = -EINVAL;
2414 goto error;
2415 }
2416
2417 _SET(&set, _INTEGER_BYTE_ORDER_SET);
2418 } else if (!strcmp(left->u.unary_expression.u.string, "size")) {
2419 if (_IS_SET(&set, _INTEGER_SIZE_SET)) {
2420 _BT_LOGE_DUP_ATTR(left, "size",
2421 "integer field class");
2422 ret = -EPERM;
2423 goto error;
2424 }
2425
2426 if (right->u.unary_expression.type !=
2427 UNARY_UNSIGNED_CONSTANT) {
2428 _BT_LOGE_NODE(right,
2429 "Invalid `size` attribute in integer field class: "
2430 "expecting unsigned constant integer: "
2431 "node-type=%d",
2432 right->u.unary_expression.type);
2433 ret = -EINVAL;
2434 goto error;
2435 }
2436
2437 size = right->u.unary_expression.u.unsigned_constant;
2438 if (size == 0) {
2439 _BT_LOGE_NODE(right,
2440 "Invalid `size` attribute in integer field class: "
2441 "expecting positive constant integer: "
2442 "size=%" PRIu64, size);
2443 ret = -EINVAL;
2444 goto error;
2445 } else if (size > 64) {
2446 _BT_LOGE_NODE(right,
2447 "Invalid `size` attribute in integer field class: "
2448 "integer fields over 64 bits are not supported as of this version: "
2449 "size=%" PRIu64, size);
2450 ret = -EINVAL;
2451 goto error;
2452 }
2453
2454 _SET(&set, _INTEGER_SIZE_SET);
2455 } else if (!strcmp(left->u.unary_expression.u.string,
2456 "align")) {
2457 if (_IS_SET(&set, _INTEGER_ALIGN_SET)) {
2458 _BT_LOGE_DUP_ATTR(left, "align",
2459 "integer field class");
2460 ret = -EPERM;
2461 goto error;
2462 }
2463
2464 if (right->u.unary_expression.type !=
2465 UNARY_UNSIGNED_CONSTANT) {
2466 _BT_LOGE_NODE(right,
2467 "Invalid `align` attribute in integer field class: "
2468 "expecting unsigned constant integer: "
2469 "node-type=%d",
2470 right->u.unary_expression.type);
2471 ret = -EINVAL;
2472 goto error;
2473 }
2474
2475 alignment =
2476 right->u.unary_expression.u.unsigned_constant;
2477 if (!is_align_valid(alignment)) {
2478 _BT_LOGE_NODE(right,
2479 "Invalid `align` attribute in integer field class: "
2480 "expecting power of two: "
2481 "align=%" PRIu64, alignment);
2482 ret = -EINVAL;
2483 goto error;
2484 }
2485
2486 _SET(&set, _INTEGER_ALIGN_SET);
2487 } else if (!strcmp(left->u.unary_expression.u.string, "base")) {
2488 if (_IS_SET(&set, _INTEGER_BASE_SET)) {
2489 _BT_LOGE_DUP_ATTR(left, "base",
2490 "integer field class");
2491 ret = -EPERM;
2492 goto error;
2493 }
2494
2495 switch (right->u.unary_expression.type) {
2496 case UNARY_UNSIGNED_CONSTANT:
2497 {
2498 uint64_t constant = right->u.unary_expression.
2499 u.unsigned_constant;
2500
2501 switch (constant) {
2502 case 2:
2503 base = BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_BINARY;
2504 break;
2505 case 8:
2506 base = BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_OCTAL;
2507 break;
2508 case 10:
2509 base = BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_DECIMAL;
2510 break;
2511 case 16:
2512 base = BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_HEXADECIMAL;
2513 break;
2514 default:
2515 _BT_LOGE_NODE(right,
2516 "Invalid `base` attribute in integer field class: "
2517 "base=%" PRIu64,
2518 right->u.unary_expression.u.unsigned_constant);
2519 ret = -EINVAL;
2520 goto error;
2521 }
2522 break;
2523 }
2524 case UNARY_STRING:
2525 {
2526 char *s_right = concatenate_unary_strings(
2527 &expression->u.ctf_expression.right);
2528 if (!s_right) {
2529 _BT_LOGE_NODE(right,
2530 "Unexpected unary expression for integer field class's `base` attribute.");
2531 ret = -EINVAL;
2532 goto error;
2533 }
2534
2535 if (!strcmp(s_right, "decimal") ||
2536 !strcmp(s_right, "dec") ||
2537 !strcmp(s_right, "d") ||
2538 !strcmp(s_right, "i") ||
2539 !strcmp(s_right, "u")) {
2540 base = BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_DECIMAL;
2541 } else if (!strcmp(s_right, "hexadecimal") ||
2542 !strcmp(s_right, "hex") ||
2543 !strcmp(s_right, "x") ||
2544 !strcmp(s_right, "X") ||
2545 !strcmp(s_right, "p")) {
2546 base = BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_HEXADECIMAL;
2547 } else if (!strcmp(s_right, "octal") ||
2548 !strcmp(s_right, "oct") ||
2549 !strcmp(s_right, "o")) {
2550 base = BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_OCTAL;
2551 } else if (!strcmp(s_right, "binary") ||
2552 !strcmp(s_right, "b")) {
2553 base = BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_BINARY;
2554 } else {
2555 _BT_LOGE_NODE(right,
2556 "Unexpected unary expression for integer field class's `base` attribute: "
2557 "base=\"%s\"", s_right);
2558 g_free(s_right);
2559 ret = -EINVAL;
2560 goto error;
2561 }
2562
2563 g_free(s_right);
2564 break;
2565 }
2566 default:
2567 _BT_LOGE_NODE(right,
2568 "Invalid `base` attribute in integer field class: "
2569 "expecting unsigned constant integer or unary string.");
2570 ret = -EINVAL;
2571 goto error;
2572 }
2573
2574 _SET(&set, _INTEGER_BASE_SET);
2575 } else if (!strcmp(left->u.unary_expression.u.string,
2576 "encoding")) {
2577 char *s_right;
2578
2579 if (_IS_SET(&set, _INTEGER_ENCODING_SET)) {
2580 _BT_LOGE_DUP_ATTR(left, "encoding",
2581 "integer field class");
2582 ret = -EPERM;
2583 goto error;
2584 }
2585
2586 if (right->u.unary_expression.type != UNARY_STRING) {
2587 _BT_LOGE_NODE(right,
2588 "Invalid `encoding` attribute in integer field class: "
2589 "expecting unary string.");
2590 ret = -EINVAL;
2591 goto error;
2592 }
2593
2594 s_right = concatenate_unary_strings(
2595 &expression->u.ctf_expression.right);
2596 if (!s_right) {
2597 _BT_LOGE_NODE(right,
2598 "Unexpected unary expression for integer field class's `encoding` attribute.");
2599 ret = -EINVAL;
2600 goto error;
2601 }
2602
2603 if (!strcmp(s_right, "UTF8") ||
2604 !strcmp(s_right, "utf8") ||
2605 !strcmp(s_right, "utf-8") ||
2606 !strcmp(s_right, "UTF-8") ||
2607 !strcmp(s_right, "ASCII") ||
2608 !strcmp(s_right, "ascii")) {
2609 encoding = CTF_ENCODING_UTF8;
2610 } else if (!strcmp(s_right, "none")) {
2611 encoding = CTF_ENCODING_NONE;
2612 } else {
2613 _BT_LOGE_NODE(right,
2614 "Invalid `encoding` attribute in integer field class: "
2615 "unknown encoding: encoding=\"%s\"",
2616 s_right);
2617 g_free(s_right);
2618 ret = -EINVAL;
2619 goto error;
2620 }
2621
2622 g_free(s_right);
2623 _SET(&set, _INTEGER_ENCODING_SET);
2624 } else if (!strcmp(left->u.unary_expression.u.string, "map")) {
2625 const char *clock_name;
2626
2627 if (_IS_SET(&set, _INTEGER_MAP_SET)) {
2628 _BT_LOGE_DUP_ATTR(left, "map",
2629 "integer field class");
2630 ret = -EPERM;
2631 goto error;
2632 }
2633
2634 if (right->u.unary_expression.type != UNARY_STRING) {
2635 _BT_LOGE_NODE(right,
2636 "Invalid `map` attribute in integer field class: "
2637 "expecting unary string.");
2638 ret = -EINVAL;
2639 goto error;
2640 }
2641
2642 clock_name =
2643 get_map_clock_name_value(
2644 &expression->u.ctf_expression.right);
2645 if (!clock_name) {
2646 char *s_right = concatenate_unary_strings(
2647 &expression->u.ctf_expression.right);
2648
2649 if (!s_right) {
2650 _BT_LOGE_NODE(right,
2651 "Unexpected unary expression for integer field class's `map` attribute.");
2652 ret = -EINVAL;
2653 goto error;
2654 }
2655
2656 _BT_LOGE_NODE(right,
2657 "Invalid `map` attribute in integer field class: "
2658 "cannot find clock class at this point: name=\"%s\"",
2659 s_right);
2660 _SET(&set, _INTEGER_MAP_SET);
2661 g_free(s_right);
2662 continue;
2663 }
2664
2665 mapped_clock_class =
2666 ctf_trace_class_borrow_clock_class_by_name(
2667 ctx->ctf_tc, clock_name);
2668 if (!mapped_clock_class) {
2669 _BT_LOGE_NODE(right,
2670 "Invalid `map` attribute in integer field class: "
2671 "cannot find clock class at this point: name=\"%s\"",
2672 clock_name);
2673 ret = -EINVAL;
2674 goto error;
2675 }
2676
2677 _SET(&set, _INTEGER_MAP_SET);
2678 } else {
2679 _BT_LOGW_NODE(left,
2680 "Unknown attribute in integer field class: "
2681 "attr-name=\"%s\"",
2682 left->u.unary_expression.u.string);
2683 }
2684 }
2685
2686 if (!_IS_SET(&set, _INTEGER_SIZE_SET)) {
2687 BT_LOGE_STR("Missing `size` attribute in integer field class.");
2688 ret = -EPERM;
2689 goto error;
2690 }
2691
2692 if (!_IS_SET(&set, _INTEGER_ALIGN_SET)) {
2693 if (size % CHAR_BIT) {
2694 /* Bit-packed alignment */
2695 alignment = 1;
2696 } else {
2697 /* Byte-packed alignment */
2698 alignment = CHAR_BIT;
2699 }
2700 }
2701
2702 *integer_decl = ctf_field_class_int_create();
2703 BT_ASSERT(*integer_decl);
2704 (*integer_decl)->base.base.alignment = alignment;
2705 (*integer_decl)->base.byte_order = byte_order;
2706 (*integer_decl)->base.size = size;
2707 (*integer_decl)->is_signed = (signedness > 0);
2708 (*integer_decl)->disp_base = base;
2709 (*integer_decl)->encoding = encoding;
2710 (*integer_decl)->mapped_clock_class = mapped_clock_class;
2711 return 0;
2712
2713 error:
2714 ctf_field_class_destroy((void *) *integer_decl);
2715 *integer_decl = NULL;
2716 return ret;
2717 }
2718
2719 static
2720 int visit_floating_point_number_decl(struct ctx *ctx,
2721 struct bt_list_head *expressions,
2722 struct ctf_field_class_float **float_decl)
2723 {
2724 int set = 0;
2725 int ret = 0;
2726 struct ctf_node *expression;
2727 uint64_t alignment = 1, exp_dig = 0, mant_dig = 0;
2728 enum ctf_byte_order byte_order = ctx->ctf_tc->default_byte_order;
2729
2730 *float_decl = NULL;
2731
2732 bt_list_for_each_entry(expression, expressions, siblings) {
2733 struct ctf_node *left, *right;
2734
2735 left = _BT_LIST_FIRST_ENTRY(&expression->u.ctf_expression.left,
2736 struct ctf_node, siblings);
2737 right = _BT_LIST_FIRST_ENTRY(
2738 &expression->u.ctf_expression.right, struct ctf_node,
2739 siblings);
2740
2741 if (left->u.unary_expression.type != UNARY_STRING) {
2742 _BT_LOGE_NODE(left,
2743 "Unexpected unary expression type: type=%d",
2744 left->u.unary_expression.type);
2745 ret = -EINVAL;
2746 goto error;
2747 }
2748
2749 if (!strcmp(left->u.unary_expression.u.string, "byte_order")) {
2750 if (_IS_SET(&set, _FLOAT_BYTE_ORDER_SET)) {
2751 _BT_LOGE_DUP_ATTR(left, "byte_order",
2752 "floating point number field class");
2753 ret = -EPERM;
2754 goto error;
2755 }
2756
2757 byte_order = get_real_byte_order(ctx, right);
2758 if (byte_order == -1) {
2759 _BT_LOGE_NODE(right,
2760 "Invalid `byte_order` attribute in floating point number field class: "
2761 "ret=%d", ret);
2762 ret = -EINVAL;
2763 goto error;
2764 }
2765
2766 _SET(&set, _FLOAT_BYTE_ORDER_SET);
2767 } else if (!strcmp(left->u.unary_expression.u.string,
2768 "exp_dig")) {
2769 if (_IS_SET(&set, _FLOAT_EXP_DIG_SET)) {
2770 _BT_LOGE_DUP_ATTR(left, "exp_dig",
2771 "floating point number field class");
2772 ret = -EPERM;
2773 goto error;
2774 }
2775
2776 if (right->u.unary_expression.type !=
2777 UNARY_UNSIGNED_CONSTANT) {
2778 _BT_LOGE_NODE(right,
2779 "Invalid `exp_dig` attribute in floating point number field class: "
2780 "expecting unsigned constant integer: "
2781 "node-type=%d",
2782 right->u.unary_expression.type);
2783 ret = -EINVAL;
2784 goto error;
2785 }
2786
2787 exp_dig = right->u.unary_expression.u.unsigned_constant;
2788 _SET(&set, _FLOAT_EXP_DIG_SET);
2789 } else if (!strcmp(left->u.unary_expression.u.string,
2790 "mant_dig")) {
2791 if (_IS_SET(&set, _FLOAT_MANT_DIG_SET)) {
2792 _BT_LOGE_DUP_ATTR(left, "mant_dig",
2793 "floating point number field class");
2794 ret = -EPERM;
2795 goto error;
2796 }
2797
2798 if (right->u.unary_expression.type !=
2799 UNARY_UNSIGNED_CONSTANT) {
2800 _BT_LOGE_NODE(right,
2801 "Invalid `mant_dig` attribute in floating point number field class: "
2802 "expecting unsigned constant integer: "
2803 "node-type=%d",
2804 right->u.unary_expression.type);
2805 ret = -EINVAL;
2806 goto error;
2807 }
2808
2809 mant_dig = right->u.unary_expression.u.
2810 unsigned_constant;
2811 _SET(&set, _FLOAT_MANT_DIG_SET);
2812 } else if (!strcmp(left->u.unary_expression.u.string,
2813 "align")) {
2814 if (_IS_SET(&set, _FLOAT_ALIGN_SET)) {
2815 _BT_LOGE_DUP_ATTR(left, "align",
2816 "floating point number field class");
2817 ret = -EPERM;
2818 goto error;
2819 }
2820
2821 if (right->u.unary_expression.type !=
2822 UNARY_UNSIGNED_CONSTANT) {
2823 _BT_LOGE_NODE(right,
2824 "Invalid `align` attribute in floating point number field class: "
2825 "expecting unsigned constant integer: "
2826 "node-type=%d",
2827 right->u.unary_expression.type);
2828 ret = -EINVAL;
2829 goto error;
2830 }
2831
2832 alignment = right->u.unary_expression.u.
2833 unsigned_constant;
2834
2835 if (!is_align_valid(alignment)) {
2836 _BT_LOGE_NODE(right,
2837 "Invalid `align` attribute in floating point number field class: "
2838 "expecting power of two: "
2839 "align=%" PRIu64, alignment);
2840 ret = -EINVAL;
2841 goto error;
2842 }
2843
2844 _SET(&set, _FLOAT_ALIGN_SET);
2845 } else {
2846 _BT_LOGW_NODE(left,
2847 "Unknown attribute in floating point number field class: "
2848 "attr-name=\"%s\"",
2849 left->u.unary_expression.u.string);
2850 }
2851 }
2852
2853 if (!_IS_SET(&set, _FLOAT_MANT_DIG_SET)) {
2854 BT_LOGE_STR("Missing `mant_dig` attribute in floating point number field class.");
2855 ret = -EPERM;
2856 goto error;
2857 }
2858
2859 if (!_IS_SET(&set, _FLOAT_EXP_DIG_SET)) {
2860 BT_LOGE_STR("Missing `exp_dig` attribute in floating point number field class.");
2861 ret = -EPERM;
2862 goto error;
2863 }
2864
2865 if (mant_dig != 24 && mant_dig != 53) {
2866 BT_LOGE_STR("`mant_dig` attribute: expecting 24 or 53.");
2867 ret = -EPERM;
2868 goto error;
2869 }
2870
2871 if (mant_dig == 24 && exp_dig != 8) {
2872 BT_LOGE_STR("`exp_dig` attribute: expecting 8 because `mant_dig` is 24.");
2873 ret = -EPERM;
2874 goto error;
2875 }
2876
2877 if (mant_dig == 53 && exp_dig != 11) {
2878 BT_LOGE_STR("`exp_dig` attribute: expecting 11 because `mant_dig` is 53.");
2879 ret = -EPERM;
2880 goto error;
2881 }
2882
2883 if (!_IS_SET(&set, _INTEGER_ALIGN_SET)) {
2884 if ((mant_dig + exp_dig) % CHAR_BIT) {
2885 /* Bit-packed alignment */
2886 alignment = 1;
2887 } else {
2888 /* Byte-packed alignment */
2889 alignment = CHAR_BIT;
2890 }
2891 }
2892
2893 *float_decl = ctf_field_class_float_create();
2894 BT_ASSERT(*float_decl);
2895 (*float_decl)->base.base.alignment = alignment;
2896 (*float_decl)->base.byte_order = byte_order;
2897 (*float_decl)->base.size = mant_dig + exp_dig;
2898 return 0;
2899
2900 error:
2901 ctf_field_class_destroy((void *) *float_decl);
2902 *float_decl = NULL;
2903 return ret;
2904 }
2905
2906 static
2907 int visit_string_decl(struct ctx *ctx,
2908 struct bt_list_head *expressions,
2909 struct ctf_field_class_string **string_decl)
2910 {
2911 int set = 0;
2912 int ret = 0;
2913 struct ctf_node *expression;
2914 enum ctf_encoding encoding = CTF_ENCODING_UTF8;
2915
2916 *string_decl = NULL;
2917
2918 bt_list_for_each_entry(expression, expressions, siblings) {
2919 struct ctf_node *left, *right;
2920
2921 left = _BT_LIST_FIRST_ENTRY(&expression->u.ctf_expression.left,
2922 struct ctf_node, siblings);
2923 right = _BT_LIST_FIRST_ENTRY(
2924 &expression->u.ctf_expression.right, struct ctf_node,
2925 siblings);
2926
2927 if (left->u.unary_expression.type != UNARY_STRING) {
2928 _BT_LOGE_NODE(left,
2929 "Unexpected unary expression type: type=%d",
2930 left->u.unary_expression.type);
2931 ret = -EINVAL;
2932 goto error;
2933 }
2934
2935 if (!strcmp(left->u.unary_expression.u.string, "encoding")) {
2936 char *s_right;
2937
2938 if (_IS_SET(&set, _STRING_ENCODING_SET)) {
2939 _BT_LOGE_DUP_ATTR(left, "encoding",
2940 "string field class");
2941 ret = -EPERM;
2942 goto error;
2943 }
2944
2945 if (right->u.unary_expression.type != UNARY_STRING) {
2946 _BT_LOGE_NODE(right,
2947 "Invalid `encoding` attribute in string field class: "
2948 "expecting unary string.");
2949 ret = -EINVAL;
2950 goto error;
2951 }
2952
2953 s_right = concatenate_unary_strings(
2954 &expression->u.ctf_expression.right);
2955 if (!s_right) {
2956 _BT_LOGE_NODE(right,
2957 "Unexpected unary expression for string field class's `encoding` attribute.");
2958 ret = -EINVAL;
2959 goto error;
2960 }
2961
2962 if (!strcmp(s_right, "UTF8") ||
2963 !strcmp(s_right, "utf8") ||
2964 !strcmp(s_right, "utf-8") ||
2965 !strcmp(s_right, "UTF-8") ||
2966 !strcmp(s_right, "ASCII") ||
2967 !strcmp(s_right, "ascii")) {
2968 encoding = CTF_ENCODING_UTF8;
2969 } else if (!strcmp(s_right, "none")) {
2970 encoding = CTF_ENCODING_NONE;
2971 } else {
2972 _BT_LOGE_NODE(right,
2973 "Invalid `encoding` attribute in string field class: "
2974 "unknown encoding: encoding=\"%s\"",
2975 s_right);
2976 g_free(s_right);
2977 ret = -EINVAL;
2978 goto error;
2979 }
2980
2981 g_free(s_right);
2982 _SET(&set, _STRING_ENCODING_SET);
2983 } else {
2984 _BT_LOGW_NODE(left,
2985 "Unknown attribute in string field class: "
2986 "attr-name=\"%s\"",
2987 left->u.unary_expression.u.string);
2988 }
2989 }
2990
2991 *string_decl = ctf_field_class_string_create();
2992 BT_ASSERT(*string_decl);
2993 (*string_decl)->encoding = encoding;
2994 return 0;
2995
2996 error:
2997 ctf_field_class_destroy((void *) *string_decl);
2998 *string_decl = NULL;
2999 return ret;
3000 }
3001
3002 static
3003 int visit_field_class_specifier_list(struct ctx *ctx,
3004 struct ctf_node *ts_list, struct ctf_field_class **decl)
3005 {
3006 int ret = 0;
3007 struct ctf_node *first, *node;
3008
3009 *decl = NULL;
3010
3011 if (ts_list->type != NODE_TYPE_SPECIFIER_LIST) {
3012 _BT_LOGE_NODE(ts_list,
3013 "Unexpected node type: node-type=%d", ts_list->type);
3014 ret = -EINVAL;
3015 goto error;
3016 }
3017
3018 first = _BT_LIST_FIRST_ENTRY(&ts_list->u.field_class_specifier_list.head,
3019 struct ctf_node, siblings);
3020 if (first->type != NODE_TYPE_SPECIFIER) {
3021 _BT_LOGE_NODE(first,
3022 "Unexpected node type: node-type=%d", first->type);
3023 ret = -EINVAL;
3024 goto error;
3025 }
3026
3027 node = first->u.field_class_specifier.node;
3028
3029 switch (first->u.field_class_specifier.type) {
3030 case TYPESPEC_INTEGER:
3031 ret = visit_integer_decl(ctx, &node->u.integer.expressions,
3032 (void *) decl);
3033 if (ret) {
3034 BT_ASSERT(!*decl);
3035 goto error;
3036 }
3037 break;
3038 case TYPESPEC_FLOATING_POINT:
3039 ret = visit_floating_point_number_decl(ctx,
3040 &node->u.floating_point.expressions, (void *) decl);
3041 if (ret) {
3042 BT_ASSERT(!*decl);
3043 goto error;
3044 }
3045 break;
3046 case TYPESPEC_STRING:
3047 ret = visit_string_decl(ctx,
3048 &node->u.string.expressions, (void *) decl);
3049 if (ret) {
3050 BT_ASSERT(!*decl);
3051 goto error;
3052 }
3053 break;
3054 case TYPESPEC_STRUCT:
3055 ret = visit_struct_decl(ctx, node->u._struct.name,
3056 &node->u._struct.declaration_list,
3057 node->u._struct.has_body,
3058 &node->u._struct.min_align, (void *) decl);
3059 if (ret) {
3060 BT_ASSERT(!*decl);
3061 goto error;
3062 }
3063 break;
3064 case TYPESPEC_VARIANT:
3065 ret = visit_variant_decl(ctx, node->u.variant.name,
3066 node->u.variant.choice,
3067 &node->u.variant.declaration_list,
3068 node->u.variant.has_body, (void *) decl);
3069 if (ret) {
3070 BT_ASSERT(!*decl);
3071 goto error;
3072 }
3073 break;
3074 case TYPESPEC_ENUM:
3075 ret = visit_enum_decl(ctx, node->u._enum.enum_id,
3076 node->u._enum.container_field_class,
3077 &node->u._enum.enumerator_list,
3078 node->u._enum.has_body, (void *) decl);
3079 if (ret) {
3080 BT_ASSERT(!*decl);
3081 goto error;
3082 }
3083 break;
3084 case TYPESPEC_VOID:
3085 case TYPESPEC_CHAR:
3086 case TYPESPEC_SHORT:
3087 case TYPESPEC_INT:
3088 case TYPESPEC_LONG:
3089 case TYPESPEC_FLOAT:
3090 case TYPESPEC_DOUBLE:
3091 case TYPESPEC_SIGNED:
3092 case TYPESPEC_UNSIGNED:
3093 case TYPESPEC_BOOL:
3094 case TYPESPEC_COMPLEX:
3095 case TYPESPEC_IMAGINARY:
3096 case TYPESPEC_CONST:
3097 case TYPESPEC_ID_TYPE:
3098 ret = visit_field_class_specifier(ctx, ts_list, decl);
3099 if (ret) {
3100 _BT_LOGE_NODE(first,
3101 "Cannot visit field class specifier: ret=%d",
3102 ret);
3103 BT_ASSERT(!*decl);
3104 goto error;
3105 }
3106 break;
3107 default:
3108 _BT_LOGE_NODE(first,
3109 "Unexpected field class specifier type: node-type=%d",
3110 first->u.field_class_specifier.type);
3111 ret = -EINVAL;
3112 goto error;
3113 }
3114
3115 BT_ASSERT(*decl);
3116 return 0;
3117
3118 error:
3119 ctf_field_class_destroy((void *) *decl);
3120 *decl = NULL;
3121 return ret;
3122 }
3123
3124 static
3125 int visit_event_decl_entry(struct ctx *ctx, struct ctf_node *node,
3126 struct ctf_event_class *event_class, uint64_t *stream_id,
3127 int *set)
3128 {
3129 int ret = 0;
3130 char *left = NULL;
3131
3132 switch (node->type) {
3133 case NODE_TYPEDEF:
3134 ret = visit_field_class_def(ctx, node->u.field_class_def.field_class_specifier_list,
3135 &node->u.field_class_def.field_class_declarators);
3136 if (ret) {
3137 _BT_LOGE_NODE(node,
3138 "Cannot add field class found in event class.");
3139 goto error;
3140 }
3141 break;
3142 case NODE_TYPEALIAS:
3143 ret = visit_field_class_alias(ctx, node->u.field_class_alias.target,
3144 node->u.field_class_alias.alias);
3145 if (ret) {
3146 _BT_LOGE_NODE(node,
3147 "Cannot add field class alias found in event class.");
3148 goto error;
3149 }
3150 break;
3151 case NODE_CTF_EXPRESSION:
3152 {
3153 left = concatenate_unary_strings(&node->u.ctf_expression.left);
3154 if (!left) {
3155 _BT_LOGE_NODE(node, "Cannot concatenate unary strings.");
3156 ret = -EINVAL;
3157 goto error;
3158 }
3159
3160 if (!strcmp(left, "name")) {
3161 /* This is already known at this stage */
3162 if (_IS_SET(set, _EVENT_NAME_SET)) {
3163 _BT_LOGE_DUP_ATTR(node, "name", "event class");
3164 ret = -EPERM;
3165 goto error;
3166 }
3167
3168 _SET(set, _EVENT_NAME_SET);
3169 } else if (!strcmp(left, "id")) {
3170 int64_t id = -1;
3171
3172 if (_IS_SET(set, _EVENT_ID_SET)) {
3173 _BT_LOGE_DUP_ATTR(node, "id", "event class");
3174 ret = -EPERM;
3175 goto error;
3176 }
3177
3178 ret = get_unary_unsigned(&node->u.ctf_expression.right,
3179 (uint64_t *) &id);
3180 /* Only read "id" if get_unary_unsigned() succeeded. */
3181 if (ret || (!ret && id < 0)) {
3182 _BT_LOGE_NODE(node,
3183 "Unexpected unary expression for event class's `id` attribute.");
3184 ret = -EINVAL;
3185 goto error;
3186 }
3187
3188 event_class->id = id;
3189 _SET(set, _EVENT_ID_SET);
3190 } else if (!strcmp(left, "stream_id")) {
3191 if (_IS_SET(set, _EVENT_STREAM_ID_SET)) {
3192 _BT_LOGE_DUP_ATTR(node, "stream_id",
3193 "event class");
3194 ret = -EPERM;
3195 goto error;
3196 }
3197
3198 ret = get_unary_unsigned(&node->u.ctf_expression.right,
3199 stream_id);
3200
3201 /*
3202 * Only read "stream_id" if get_unary_unsigned()
3203 * succeeded.
3204 */
3205 if (ret || (!ret && *stream_id < 0)) {
3206 _BT_LOGE_NODE(node,
3207 "Unexpected unary expression for event class's `stream_id` attribute.");
3208 ret = -EINVAL;
3209 goto error;
3210 }
3211
3212 _SET(set, _EVENT_STREAM_ID_SET);
3213 } else if (!strcmp(left, "context")) {
3214 if (_IS_SET(set, _EVENT_CONTEXT_SET)) {
3215 _BT_LOGE_NODE(node,
3216 "Duplicate `context` entry in event class.");
3217 ret = -EPERM;
3218 goto error;
3219 }
3220
3221 ret = visit_field_class_specifier_list(ctx,
3222 _BT_LIST_FIRST_ENTRY(
3223 &node->u.ctf_expression.right,
3224 struct ctf_node, siblings),
3225 &event_class->spec_context_fc);
3226 if (ret) {
3227 _BT_LOGE_NODE(node,
3228 "Cannot create event class's context field class.");
3229 goto error;
3230 }
3231
3232 BT_ASSERT(event_class->spec_context_fc);
3233 _SET(set, _EVENT_CONTEXT_SET);
3234 } else if (!strcmp(left, "fields")) {
3235 if (_IS_SET(set, _EVENT_FIELDS_SET)) {
3236 _BT_LOGE_NODE(node,
3237 "Duplicate `fields` entry in event class.");
3238 ret = -EPERM;
3239 goto error;
3240 }
3241
3242 ret = visit_field_class_specifier_list(ctx,
3243 _BT_LIST_FIRST_ENTRY(
3244 &node->u.ctf_expression.right,
3245 struct ctf_node, siblings),
3246 &event_class->payload_fc);
3247 if (ret) {
3248 _BT_LOGE_NODE(node,
3249 "Cannot create event class's payload field class.");
3250 goto error;
3251 }
3252
3253 BT_ASSERT(event_class->payload_fc);
3254 _SET(set, _EVENT_FIELDS_SET);
3255 } else if (!strcmp(left, "loglevel")) {
3256 uint64_t loglevel_value;
3257 bt_event_class_log_level log_level = -1;
3258
3259 if (_IS_SET(set, _EVENT_LOG_LEVEL_SET)) {
3260 _BT_LOGE_DUP_ATTR(node, "loglevel",
3261 "event class");
3262 ret = -EPERM;
3263 goto error;
3264 }
3265
3266 ret = get_unary_unsigned(&node->u.ctf_expression.right,
3267 &loglevel_value);
3268 if (ret) {
3269 _BT_LOGE_NODE(node,
3270 "Unexpected unary expression for event class's `loglevel` attribute.");
3271 ret = -EINVAL;
3272 goto error;
3273 }
3274
3275 switch (loglevel_value) {
3276 case 0:
3277 log_level = BT_EVENT_CLASS_LOG_LEVEL_EMERGENCY;
3278 break;
3279 case 1:
3280 log_level = BT_EVENT_CLASS_LOG_LEVEL_ALERT;
3281 break;
3282 case 2:
3283 log_level = BT_EVENT_CLASS_LOG_LEVEL_CRITICAL;
3284 break;
3285 case 3:
3286 log_level = BT_EVENT_CLASS_LOG_LEVEL_ERROR;
3287 break;
3288 case 4:
3289 log_level = BT_EVENT_CLASS_LOG_LEVEL_WARNING;
3290 break;
3291 case 5:
3292 log_level = BT_EVENT_CLASS_LOG_LEVEL_NOTICE;
3293 break;
3294 case 6:
3295 log_level = BT_EVENT_CLASS_LOG_LEVEL_INFO;
3296 break;
3297 case 7:
3298 log_level = BT_EVENT_CLASS_LOG_LEVEL_DEBUG_SYSTEM;
3299 break;
3300 case 8:
3301 log_level = BT_EVENT_CLASS_LOG_LEVEL_DEBUG_PROGRAM;
3302 break;
3303 case 9:
3304 log_level = BT_EVENT_CLASS_LOG_LEVEL_DEBUG_PROCESS;
3305 break;
3306 case 10:
3307 log_level = BT_EVENT_CLASS_LOG_LEVEL_DEBUG_MODULE;
3308 break;
3309 case 11:
3310 log_level = BT_EVENT_CLASS_LOG_LEVEL_DEBUG_UNIT;
3311 break;
3312 case 12:
3313 log_level = BT_EVENT_CLASS_LOG_LEVEL_DEBUG_FUNCTION;
3314 break;
3315 case 13:
3316 log_level = BT_EVENT_CLASS_LOG_LEVEL_DEBUG_LINE;
3317 break;
3318 case 14:
3319 log_level = BT_EVENT_CLASS_LOG_LEVEL_DEBUG;
3320 break;
3321 default:
3322 _BT_LOGW_NODE(node, "Not setting event class's log level because its value is unknown: "
3323 "log-level=%" PRIu64, loglevel_value);
3324 }
3325
3326 if (log_level != -1) {
3327 event_class->log_level = log_level;
3328 }
3329
3330 _SET(set, _EVENT_LOG_LEVEL_SET);
3331 } else if (!strcmp(left, "model.emf.uri")) {
3332 char *right;
3333
3334 if (_IS_SET(set, _EVENT_MODEL_EMF_URI_SET)) {
3335 _BT_LOGE_DUP_ATTR(node, "model.emf.uri",
3336 "event class");
3337 ret = -EPERM;
3338 goto error;
3339 }
3340
3341 right = concatenate_unary_strings(
3342 &node->u.ctf_expression.right);
3343 if (!right) {
3344 _BT_LOGE_NODE(node,
3345 "Unexpected unary expression for event class's `model.emf.uri` attribute.");
3346 ret = -EINVAL;
3347 goto error;
3348 }
3349
3350 if (strlen(right) == 0) {
3351 _BT_LOGW_NODE(node,
3352 "Not setting event class's EMF URI because it's empty.");
3353 } else {
3354 g_string_assign(event_class->emf_uri,
3355 right);
3356 }
3357
3358 g_free(right);
3359 _SET(set, _EVENT_MODEL_EMF_URI_SET);
3360 } else {
3361 _BT_LOGW_NODE(node,
3362 "Unknown attribute in event class: "
3363 "attr-name=\"%s\"", left);
3364 }
3365
3366 g_free(left);
3367 left = NULL;
3368 break;
3369 }
3370 default:
3371 ret = -EPERM;
3372 goto error;
3373 }
3374
3375 goto end;
3376
3377 error:
3378 if (left) {
3379 g_free(left);
3380 }
3381
3382 end:
3383 return ret;
3384 }
3385
3386 static
3387 char *get_event_decl_name(struct ctx *ctx, struct ctf_node *node)
3388 {
3389 char *left = NULL;
3390 char *name = NULL;
3391 struct ctf_node *iter;
3392 struct bt_list_head *decl_list = &node->u.event.declaration_list;
3393
3394 bt_list_for_each_entry(iter, decl_list, siblings) {
3395 if (iter->type != NODE_CTF_EXPRESSION) {
3396 continue;
3397 }
3398
3399 left = concatenate_unary_strings(&iter->u.ctf_expression.left);
3400 if (!left) {
3401 _BT_LOGE_NODE(iter,
3402 "Cannot concatenate unary strings.");
3403 goto error;
3404 }
3405
3406 if (!strcmp(left, "name")) {
3407 name = concatenate_unary_strings(
3408 &iter->u.ctf_expression.right);
3409 if (!name) {
3410 _BT_LOGE_NODE(iter,
3411 "Unexpected unary expression for event class's `name` attribute.");
3412 goto error;
3413 }
3414 }
3415
3416 g_free(left);
3417 left = NULL;
3418
3419 if (name) {
3420 break;
3421 }
3422 }
3423
3424 return name;
3425
3426 error:
3427 g_free(left);
3428 return NULL;
3429 }
3430
3431 static
3432 int visit_event_decl(struct ctx *ctx, struct ctf_node *node)
3433 {
3434 int ret = 0;
3435 int set = 0;
3436 struct ctf_node *iter;
3437 uint64_t stream_id = 0;
3438 char *event_name = NULL;
3439 struct ctf_event_class *event_class = NULL;
3440 struct ctf_stream_class *stream_class = NULL;
3441 struct bt_list_head *decl_list = &node->u.event.declaration_list;
3442 bool pop_scope = false;
3443
3444 if (node->visited) {
3445 goto end;
3446 }
3447
3448 node->visited = TRUE;
3449 event_name = get_event_decl_name(ctx, node);
3450 if (!event_name) {
3451 _BT_LOGE_NODE(node,
3452 "Missing `name` attribute in event class.");
3453 ret = -EPERM;
3454 goto error;
3455 }
3456
3457 event_class = ctf_event_class_create();
3458 BT_ASSERT(event_class);
3459 g_string_assign(event_class->name, event_name);
3460 _TRY_PUSH_SCOPE_OR_GOTO_ERROR();
3461 pop_scope = true;
3462
3463 bt_list_for_each_entry(iter, decl_list, siblings) {
3464 ret = visit_event_decl_entry(ctx, iter, event_class,
3465 &stream_id, &set);
3466 if (ret) {
3467 _BT_LOGE_NODE(iter, "Cannot visit event class's entry: "
3468 "ret=%d", ret);
3469 goto error;
3470 }
3471 }
3472
3473 if (!_IS_SET(&set, _EVENT_STREAM_ID_SET)) {
3474 /*
3475 * Allow missing stream_id if there is only a single
3476 * stream class.
3477 */
3478 switch (ctx->ctf_tc->stream_classes->len) {
3479 case 0:
3480 /* Create implicit stream class if there's none */
3481 stream_id = 0;
3482 stream_class = ctf_stream_class_create();
3483 BT_ASSERT(stream_class);
3484 stream_class->id = stream_id;
3485 g_ptr_array_add(ctx->ctf_tc->stream_classes,
3486 stream_class);
3487 break;
3488 case 1:
3489 /* Single stream class: get its ID */
3490 stream_class = ctx->ctf_tc->stream_classes->pdata[0];
3491 stream_id = stream_class->id;
3492 break;
3493 default:
3494 _BT_LOGE_NODE(node,
3495 "Missing `stream_id` attribute in event class.");
3496 ret = -EPERM;
3497 goto error;
3498 }
3499 }
3500
3501 /* We have the stream ID now; get the stream class if found */
3502 if (!stream_class) {
3503 stream_class = ctf_trace_class_borrow_stream_class_by_id(
3504 ctx->ctf_tc, stream_id);
3505 if (!stream_class) {
3506 _BT_LOGE_NODE(node,
3507 "Cannot find stream class at this point: "
3508 "id=%" PRId64, stream_id);
3509 ret = -EINVAL;
3510 goto error;
3511 }
3512 }
3513
3514 BT_ASSERT(stream_class);
3515
3516 if (!_IS_SET(&set, _EVENT_ID_SET)) {
3517 /* Allow only one event without ID per stream */
3518 if (stream_class->event_classes->len != 0) {
3519 _BT_LOGE_NODE(node,
3520 "Missing `id` attribute in event class.");
3521 ret = -EPERM;
3522 goto error;
3523 }
3524
3525 /* Automatic ID */
3526 event_class->id = 0;
3527 }
3528
3529 if (ctf_stream_class_borrow_event_class_by_id(stream_class,
3530 event_class->id)) {
3531 _BT_LOGE_NODE(node,
3532 "Duplicate event class (same ID) in the same stream class: "
3533 "id=%" PRId64, event_class->id);
3534 ret = -EEXIST;
3535 goto error;
3536 }
3537
3538 ctf_stream_class_append_event_class(stream_class, event_class);
3539 event_class = NULL;
3540 goto end;
3541
3542 error:
3543 ctf_event_class_destroy(event_class);
3544 event_class = NULL;
3545
3546 if (ret >= 0) {
3547 ret = -1;
3548 }
3549
3550 end:
3551 if (pop_scope) {
3552 ctx_pop_scope(ctx);
3553 }
3554
3555 if (event_name) {
3556 g_free(event_name);
3557 }
3558
3559 return ret;
3560 }
3561
3562 static
3563 int auto_map_field_to_trace_clock_class(struct ctx *ctx,
3564 struct ctf_field_class *fc)
3565 {
3566 struct ctf_clock_class *clock_class_to_map_to = NULL;
3567 struct ctf_field_class_int *int_fc = (void *) fc;
3568 int ret = 0;
3569 uint64_t clock_class_count;
3570
3571 if (!fc) {
3572 goto end;
3573 }
3574
3575 if (fc->type != CTF_FIELD_CLASS_TYPE_INT &&
3576 fc->type != CTF_FIELD_CLASS_TYPE_ENUM) {
3577 goto end;
3578 }
3579
3580 if (int_fc->mapped_clock_class) {
3581 /* Already mapped */
3582 goto end;
3583 }
3584
3585 clock_class_count = ctx->ctf_tc->clock_classes->len;
3586
3587 switch (clock_class_count) {
3588 case 0:
3589 /*
3590 * No clock class exists in the trace at this point. Create an
3591 * implicit one at 1 GHz, named `default`, and use this clock
3592 * class.
3593 */
3594 clock_class_to_map_to = ctf_clock_class_create();
3595 BT_ASSERT(clock_class_to_map_to);
3596 clock_class_to_map_to->frequency = UINT64_C(1000000000);
3597 g_string_assign(clock_class_to_map_to->name, "default");
3598 BT_ASSERT(ret == 0);
3599 g_ptr_array_add(ctx->ctf_tc->clock_classes,
3600 clock_class_to_map_to);
3601 break;
3602 case 1:
3603 /*
3604 * Only one clock class exists in the trace at this point: use
3605 * this one.
3606 */
3607 clock_class_to_map_to = ctx->ctf_tc->clock_classes->pdata[0];
3608 break;
3609 default:
3610 /*
3611 * Timestamp field not mapped to a clock class and there's more
3612 * than one clock class in the trace: this is an error.
3613 */
3614 BT_LOGE_STR("Timestamp field found with no mapped clock class, "
3615 "but there's more than one clock class in the trace at this point.");
3616 ret = -1;
3617 goto end;
3618 }
3619
3620 BT_ASSERT(clock_class_to_map_to);
3621 int_fc->mapped_clock_class = clock_class_to_map_to;
3622
3623 end:
3624 return ret;
3625 }
3626
3627 static
3628 int auto_map_fields_to_trace_clock_class(struct ctx *ctx,
3629 struct ctf_field_class *root_fc, const char *field_name)
3630 {
3631 int ret = 0;
3632 uint64_t i, count;
3633 struct ctf_field_class_struct *struct_fc = (void *) root_fc;
3634 struct ctf_field_class_variant *var_fc = (void *) root_fc;
3635
3636 if (!root_fc) {
3637 goto end;
3638 }
3639
3640 if (root_fc->type != CTF_FIELD_CLASS_TYPE_STRUCT &&
3641 root_fc->type != CTF_FIELD_CLASS_TYPE_VARIANT) {
3642 goto end;
3643 }
3644
3645 if (root_fc->type == CTF_FIELD_CLASS_TYPE_STRUCT) {
3646 count = struct_fc->members->len;
3647 } else {
3648 count = var_fc->options->len;
3649 }
3650
3651 for (i = 0; i < count; i++) {
3652 struct ctf_named_field_class *named_fc = NULL;
3653
3654 if (root_fc->type == CTF_FIELD_CLASS_TYPE_STRUCT) {
3655 named_fc = ctf_field_class_struct_borrow_member_by_index(
3656 struct_fc, i);
3657 } else if (root_fc->type == CTF_FIELD_CLASS_TYPE_VARIANT) {
3658 named_fc = ctf_field_class_variant_borrow_option_by_index(
3659 var_fc, i);
3660 }
3661
3662 if (strcmp(named_fc->name->str, field_name) == 0) {
3663 ret = auto_map_field_to_trace_clock_class(ctx,
3664 named_fc->fc);
3665 if (ret) {
3666 BT_LOGE("Cannot automatically map field to trace's clock class: "
3667 "field-name=\"%s\"", field_name);
3668 goto end;
3669 }
3670 }
3671
3672 ret = auto_map_fields_to_trace_clock_class(ctx, named_fc->fc,
3673 field_name);
3674 if (ret) {
3675 BT_LOGE("Cannot automatically map structure or variant field class's fields to trace's clock class: "
3676 "field-name=\"%s\", root-field-name=\"%s\"",
3677 field_name, named_fc->name->str);
3678 goto end;
3679 }
3680 }
3681
3682 end:
3683 return ret;
3684 }
3685
3686 static
3687 int visit_stream_decl_entry(struct ctx *ctx, struct ctf_node *node,
3688 struct ctf_stream_class *stream_class, int *set)
3689 {
3690 int ret = 0;
3691 char *left = NULL;
3692
3693 switch (node->type) {
3694 case NODE_TYPEDEF:
3695 ret = visit_field_class_def(ctx, node->u.field_class_def.field_class_specifier_list,
3696 &node->u.field_class_def.field_class_declarators);
3697 if (ret) {
3698 _BT_LOGE_NODE(node,
3699 "Cannot add field class found in stream class.");
3700 goto error;
3701 }
3702 break;
3703 case NODE_TYPEALIAS:
3704 ret = visit_field_class_alias(ctx, node->u.field_class_alias.target,
3705 node->u.field_class_alias.alias);
3706 if (ret) {
3707 _BT_LOGE_NODE(node,
3708 "Cannot add field class alias found in stream class.");
3709 goto error;
3710 }
3711 break;
3712 case NODE_CTF_EXPRESSION:
3713 {
3714 left = concatenate_unary_strings(&node->u.ctf_expression.left);
3715 if (!left) {
3716 _BT_LOGE_NODE(node, "Cannot concatenate unary strings.");
3717 ret = -EINVAL;
3718 goto error;
3719 }
3720
3721 if (!strcmp(left, "id")) {
3722 int64_t id;
3723
3724 if (_IS_SET(set, _STREAM_ID_SET)) {
3725 _BT_LOGE_DUP_ATTR(node, "id",
3726 "stream declaration");
3727 ret = -EPERM;
3728 goto error;
3729 }
3730
3731 ret = get_unary_unsigned(&node->u.ctf_expression.right,
3732 (uint64_t *) &id);
3733
3734 /* Only read "id" if get_unary_unsigned() succeeded. */
3735 if (ret || (!ret && id < 0)) {
3736 _BT_LOGE_NODE(node,
3737 "Unexpected unary expression for stream class's `id` attribute.");
3738 ret = -EINVAL;
3739 goto error;
3740 }
3741
3742 if (ctf_trace_class_borrow_stream_class_by_id(
3743 ctx->ctf_tc, id)) {
3744 _BT_LOGE_NODE(node,
3745 "Duplicate stream class (same ID): id=%" PRId64,
3746 id);
3747 ret = -EEXIST;
3748 goto error;
3749 }
3750
3751 stream_class->id = id;
3752 _SET(set, _STREAM_ID_SET);
3753 } else if (!strcmp(left, "event.header")) {
3754 if (_IS_SET(set, _STREAM_EVENT_HEADER_SET)) {
3755 _BT_LOGE_NODE(node,
3756 "Duplicate `event.header` entry in stream class.");
3757 ret = -EPERM;
3758 goto error;
3759 }
3760
3761 ret = visit_field_class_specifier_list(ctx,
3762 _BT_LIST_FIRST_ENTRY(
3763 &node->u.ctf_expression.right,
3764 struct ctf_node, siblings),
3765 &stream_class->event_header_fc);
3766 if (ret) {
3767 _BT_LOGE_NODE(node,
3768 "Cannot create stream class's event header field class.");
3769 goto error;
3770 }
3771
3772 BT_ASSERT(stream_class->event_header_fc);
3773 ret = auto_map_fields_to_trace_clock_class(ctx,
3774 stream_class->event_header_fc, "timestamp");
3775 if (ret) {
3776 _BT_LOGE_NODE(node,
3777 "Cannot automatically map specific event header field class fields named `timestamp` to trace's clock class.");
3778 goto error;
3779 }
3780
3781 _SET(set, _STREAM_EVENT_HEADER_SET);
3782 } else if (!strcmp(left, "event.context")) {
3783 if (_IS_SET(set, _STREAM_EVENT_CONTEXT_SET)) {
3784 _BT_LOGE_NODE(node,
3785 "Duplicate `event.context` entry in stream class.");
3786 ret = -EPERM;
3787 goto error;
3788 }
3789
3790 ret = visit_field_class_specifier_list(ctx,
3791 _BT_LIST_FIRST_ENTRY(
3792 &node->u.ctf_expression.right,
3793 struct ctf_node, siblings),
3794 &stream_class->event_common_context_fc);
3795 if (ret) {
3796 _BT_LOGE_NODE(node,
3797 "Cannot create stream class's event context field class.");
3798 goto error;
3799 }
3800
3801 BT_ASSERT(stream_class->event_common_context_fc);
3802 _SET(set, _STREAM_EVENT_CONTEXT_SET);
3803 } else if (!strcmp(left, "packet.context")) {
3804 if (_IS_SET(set, _STREAM_PACKET_CONTEXT_SET)) {
3805 _BT_LOGE_NODE(node,
3806 "Duplicate `packet.context` entry in stream class.");
3807 ret = -EPERM;
3808 goto error;
3809 }
3810
3811 ret = visit_field_class_specifier_list(ctx,
3812 _BT_LIST_FIRST_ENTRY(
3813 &node->u.ctf_expression.right,
3814 struct ctf_node, siblings),
3815 &stream_class->packet_context_fc);
3816 if (ret) {
3817 _BT_LOGE_NODE(node,
3818 "Cannot create stream class's packet context field class.");
3819 goto error;
3820 }
3821
3822 BT_ASSERT(stream_class->packet_context_fc);
3823 ret = auto_map_fields_to_trace_clock_class(ctx,
3824 stream_class->packet_context_fc,
3825 "timestamp_begin");
3826 if (ret) {
3827 _BT_LOGE_NODE(node,
3828 "Cannot automatically map specific packet context field class fields named `timestamp_begin` to trace's clock class.");
3829 goto error;
3830 }
3831
3832 ret = auto_map_fields_to_trace_clock_class(ctx,
3833 stream_class->packet_context_fc,
3834 "timestamp_end");
3835 if (ret) {
3836 _BT_LOGE_NODE(node,
3837 "Cannot automatically map specific packet context field class fields named `timestamp_end` to trace's clock class.");
3838 goto error;
3839 }
3840
3841 _SET(set, _STREAM_PACKET_CONTEXT_SET);
3842 } else {
3843 _BT_LOGW_NODE(node,
3844 "Unknown attribute in stream class: "
3845 "attr-name=\"%s\"", left);
3846 }
3847
3848 g_free(left);
3849 left = NULL;
3850 break;
3851 }
3852
3853 default:
3854 ret = -EPERM;
3855 goto error;
3856 }
3857
3858 return 0;
3859
3860 error:
3861 g_free(left);
3862 return ret;
3863 }
3864
3865 static
3866 int visit_stream_decl(struct ctx *ctx, struct ctf_node *node)
3867 {
3868 int set = 0;
3869 int ret = 0;
3870 struct ctf_node *iter;
3871 struct ctf_stream_class *stream_class = NULL;
3872 struct bt_list_head *decl_list = &node->u.stream.declaration_list;
3873
3874 if (node->visited) {
3875 goto end;
3876 }
3877
3878 node->visited = TRUE;
3879 stream_class = ctf_stream_class_create();
3880 BT_ASSERT(stream_class);
3881 _TRY_PUSH_SCOPE_OR_GOTO_ERROR();
3882
3883 bt_list_for_each_entry(iter, decl_list, siblings) {
3884 ret = visit_stream_decl_entry(ctx, iter, stream_class, &set);
3885 if (ret) {
3886 _BT_LOGE_NODE(iter,
3887 "Cannot visit stream class's entry: "
3888 "ret=%d", ret);
3889 ctx_pop_scope(ctx);
3890 goto error;
3891 }
3892 }
3893
3894 ctx_pop_scope(ctx);
3895
3896 if (_IS_SET(&set, _STREAM_ID_SET)) {
3897 /* Check that packet header has `stream_id` field */
3898 struct ctf_named_field_class *named_fc = NULL;
3899
3900 if (!ctx->ctf_tc->packet_header_fc) {
3901 _BT_LOGE_NODE(node,
3902 "Stream class has a `id` attribute, "
3903 "but trace has no packet header field class.");
3904 goto error;
3905 }
3906
3907 named_fc = ctf_field_class_struct_borrow_member_by_name(
3908 (void *) ctx->ctf_tc->packet_header_fc, "stream_id");
3909 if (!named_fc) {
3910 _BT_LOGE_NODE(node,
3911 "Stream class has a `id` attribute, "
3912 "but trace's packet header field class has no `stream_id` field.");
3913 goto error;
3914 }
3915
3916 if (named_fc->fc->type != CTF_FIELD_CLASS_TYPE_INT &&
3917 named_fc->fc->type != CTF_FIELD_CLASS_TYPE_ENUM) {
3918 _BT_LOGE_NODE(node,
3919 "Stream class has a `id` attribute, "
3920 "but trace's packet header field class's `stream_id` field is not an integer field class.");
3921 goto error;
3922 }
3923 } else {
3924 /* Allow only _one_ ID-less stream */
3925 if (ctx->ctf_tc->stream_classes->len != 0) {
3926 _BT_LOGE_NODE(node,
3927 "Missing `id` attribute in stream class as there's more than one stream class in the trace.");
3928 ret = -EPERM;
3929 goto error;
3930 }
3931
3932 /* Automatic ID: 0 */
3933 stream_class->id = 0;
3934 }
3935
3936 /*
3937 * Make sure that this stream class's ID is currently unique in
3938 * the trace.
3939 */
3940 if (ctf_trace_class_borrow_stream_class_by_id(ctx->ctf_tc,
3941 stream_class->id)) {
3942 _BT_LOGE_NODE(node,
3943 "Duplicate stream class (same ID): id=%" PRId64,
3944 stream_class->id);
3945 ret = -EINVAL;
3946 goto error;
3947 }
3948
3949 g_ptr_array_add(ctx->ctf_tc->stream_classes, stream_class);
3950 stream_class = NULL;
3951 goto end;
3952
3953 error:
3954 ctf_stream_class_destroy(stream_class);
3955 stream_class = NULL;
3956
3957 end:
3958 return ret;
3959 }
3960
3961 static
3962 int visit_trace_decl_entry(struct ctx *ctx, struct ctf_node *node, int *set)
3963 {
3964 int ret = 0;
3965 char *left = NULL;
3966 uint64_t val;
3967
3968 switch (node->type) {
3969 case NODE_TYPEDEF:
3970 ret = visit_field_class_def(ctx, node->u.field_class_def.field_class_specifier_list,
3971 &node->u.field_class_def.field_class_declarators);
3972 if (ret) {
3973 _BT_LOGE_NODE(node,
3974 "Cannot add field class found in trace (`trace` block).");
3975 goto error;
3976 }
3977 break;
3978 case NODE_TYPEALIAS:
3979 ret = visit_field_class_alias(ctx, node->u.field_class_alias.target,
3980 node->u.field_class_alias.alias);
3981 if (ret) {
3982 _BT_LOGE_NODE(node,
3983 "Cannot add field class alias found in trace (`trace` block).");
3984 goto error;
3985 }
3986 break;
3987 case NODE_CTF_EXPRESSION:
3988 {
3989 left = concatenate_unary_strings(&node->u.ctf_expression.left);
3990 if (!left) {
3991 _BT_LOGE_NODE(node, "Cannot concatenate unary strings.");
3992 ret = -EINVAL;
3993 goto error;
3994 }
3995
3996 if (!strcmp(left, "major")) {
3997 if (_IS_SET(set, _TRACE_MAJOR_SET)) {
3998 _BT_LOGE_DUP_ATTR(node, "major", "trace");
3999 ret = -EPERM;
4000 goto error;
4001 }
4002
4003 ret = get_unary_unsigned(&node->u.ctf_expression.right,
4004 &val);
4005 if (ret) {
4006 _BT_LOGE_NODE(node,
4007 "Unexpected unary expression for trace's `major` attribute.");
4008 ret = -EINVAL;
4009 goto error;
4010 }
4011
4012 if (val != 1) {
4013 _BT_LOGE_NODE(node,
4014 "Invalid trace's `minor` attribute: expecting 1.");
4015 goto error;
4016 }
4017
4018 ctx->ctf_tc->major = val;
4019 _SET(set, _TRACE_MAJOR_SET);
4020 } else if (!strcmp(left, "minor")) {
4021 if (_IS_SET(set, _TRACE_MINOR_SET)) {
4022 _BT_LOGE_DUP_ATTR(node, "minor", "trace");
4023 ret = -EPERM;
4024 goto error;
4025 }
4026
4027 ret = get_unary_unsigned(&node->u.ctf_expression.right,
4028 &val);
4029 if (ret) {
4030 _BT_LOGE_NODE(node,
4031 "Unexpected unary expression for trace's `minor` attribute.");
4032 ret = -EINVAL;
4033 goto error;
4034 }
4035
4036 if (val != 8) {
4037 _BT_LOGE_NODE(node,
4038 "Invalid trace's `minor` attribute: expecting 8.");
4039 goto error;
4040 }
4041
4042 ctx->ctf_tc->minor = val;
4043 _SET(set, _TRACE_MINOR_SET);
4044 } else if (!strcmp(left, "uuid")) {
4045 if (_IS_SET(set, _TRACE_UUID_SET)) {
4046 _BT_LOGE_DUP_ATTR(node, "uuid", "trace");
4047 ret = -EPERM;
4048 goto error;
4049 }
4050
4051 ret = get_unary_uuid(&node->u.ctf_expression.right,
4052 ctx->ctf_tc->uuid);
4053 if (ret) {
4054 _BT_LOGE_NODE(node,
4055 "Invalid trace's `uuid` attribute.");
4056 goto error;
4057 }
4058
4059 ctx->ctf_tc->is_uuid_set = true;
4060 _SET(set, _TRACE_UUID_SET);
4061 } else if (!strcmp(left, "byte_order")) {
4062 /* Default byte order is already known at this stage */
4063 if (_IS_SET(set, _TRACE_BYTE_ORDER_SET)) {
4064 _BT_LOGE_DUP_ATTR(node, "byte_order",
4065 "trace");
4066 ret = -EPERM;
4067 goto error;
4068 }
4069
4070 BT_ASSERT(ctx->ctf_tc->default_byte_order != -1);
4071 _SET(set, _TRACE_BYTE_ORDER_SET);
4072 } else if (!strcmp(left, "packet.header")) {
4073 if (_IS_SET(set, _TRACE_PACKET_HEADER_SET)) {
4074 _BT_LOGE_NODE(node,
4075 "Duplicate `packet.header` entry in trace.");
4076 ret = -EPERM;
4077 goto error;
4078 }
4079
4080 ret = visit_field_class_specifier_list(ctx,
4081 _BT_LIST_FIRST_ENTRY(
4082 &node->u.ctf_expression.right,
4083 struct ctf_node, siblings),
4084 &ctx->ctf_tc->packet_header_fc);
4085 if (ret) {
4086 _BT_LOGE_NODE(node,
4087 "Cannot create trace's packet header field class.");
4088 goto error;
4089 }
4090
4091 BT_ASSERT(ctx->ctf_tc->packet_header_fc);
4092 _SET(set, _TRACE_PACKET_HEADER_SET);
4093 } else {
4094 _BT_LOGW_NODE(node,
4095 "Unknown attribute in stream class: "
4096 "attr-name=\"%s\"", left);
4097 }
4098
4099 g_free(left);
4100 left = NULL;
4101 break;
4102 }
4103 default:
4104 _BT_LOGE_NODE(node, "Unknown expression in trace.");
4105 ret = -EINVAL;
4106 goto error;
4107 }
4108
4109 return 0;
4110
4111 error:
4112 g_free(left);
4113 return ret;
4114 }
4115
4116 static
4117 int visit_trace_decl(struct ctx *ctx, struct ctf_node *node)
4118 {
4119 int ret = 0;
4120 int set = 0;
4121 struct ctf_node *iter;
4122 struct bt_list_head *decl_list = &node->u.trace.declaration_list;
4123
4124 if (node->visited) {
4125 goto end;
4126 }
4127
4128 node->visited = TRUE;
4129
4130 if (ctx->is_trace_visited) {
4131 _BT_LOGE_NODE(node, "Duplicate trace (`trace` block).");
4132 ret = -EEXIST;
4133 goto error;
4134 }
4135
4136 _TRY_PUSH_SCOPE_OR_GOTO_ERROR();
4137
4138 bt_list_for_each_entry(iter, decl_list, siblings) {
4139 ret = visit_trace_decl_entry(ctx, iter, &set);
4140 if (ret) {
4141 _BT_LOGE_NODE(iter, "Cannot visit trace's entry (`trace` block): "
4142 "ret=%d", ret);
4143 ctx_pop_scope(ctx);
4144 goto error;
4145 }
4146 }
4147
4148 ctx_pop_scope(ctx);
4149
4150 if (!_IS_SET(&set, _TRACE_MAJOR_SET)) {
4151 _BT_LOGE_NODE(node,
4152 "Missing `major` attribute in trace (`trace` block).");
4153 ret = -EPERM;
4154 goto error;
4155 }
4156
4157 if (!_IS_SET(&set, _TRACE_MINOR_SET)) {
4158 _BT_LOGE_NODE(node,
4159 "Missing `minor` attribute in trace (`trace` block).");
4160 ret = -EPERM;
4161 goto error;
4162 }
4163
4164 if (!_IS_SET(&set, _TRACE_BYTE_ORDER_SET)) {
4165 _BT_LOGE_NODE(node,
4166 "Missing `byte_order` attribute in trace (`trace` block).");
4167 ret = -EPERM;
4168 goto error;
4169 }
4170
4171 ctx->is_trace_visited = true;
4172
4173 end:
4174 return 0;
4175
4176 error:
4177 return ret;
4178 }
4179
4180 static
4181 int visit_env(struct ctx *ctx, struct ctf_node *node)
4182 {
4183 int ret = 0;
4184 char *left = NULL;
4185 struct ctf_node *entry_node;
4186 struct bt_list_head *decl_list = &node->u.env.declaration_list;
4187
4188 if (node->visited) {
4189 goto end;
4190 }
4191
4192 node->visited = TRUE;
4193
4194 bt_list_for_each_entry(entry_node, decl_list, siblings) {
4195 struct bt_list_head *right_head =
4196 &entry_node->u.ctf_expression.right;
4197
4198 if (entry_node->type != NODE_CTF_EXPRESSION) {
4199 _BT_LOGE_NODE(entry_node,
4200 "Wrong expression in environment entry: "
4201 "node-type=%d", entry_node->type);
4202 ret = -EPERM;
4203 goto error;
4204 }
4205
4206 left = concatenate_unary_strings(
4207 &entry_node->u.ctf_expression.left);
4208 if (!left) {
4209 _BT_LOGE_NODE(entry_node,
4210 "Cannot get environment entry's name.");
4211 ret = -EINVAL;
4212 goto error;
4213 }
4214
4215 if (is_unary_string(right_head)) {
4216 char *right = concatenate_unary_strings(right_head);
4217
4218 if (!right) {
4219 _BT_LOGE_NODE(entry_node,
4220 "Unexpected unary expression for environment entry's value: "
4221 "name=\"%s\"", left);
4222 ret = -EINVAL;
4223 goto error;
4224 }
4225
4226 if (strcmp(left, "tracer_name") == 0) {
4227 if (strncmp(right, "lttng", 5) == 0) {
4228 BT_LOGI("Detected LTTng trace from `%s` environment value: "
4229 "tracer-name=\"%s\"",
4230 left, right);
4231 ctx->is_lttng = true;
4232 }
4233 }
4234
4235 ctf_trace_class_append_env_entry(ctx->ctf_tc,
4236 left, CTF_TRACE_CLASS_ENV_ENTRY_TYPE_STR,
4237 right, 0);
4238 g_free(right);
4239 } else if (is_unary_unsigned(right_head) ||
4240 is_unary_signed(right_head)) {
4241 int64_t v;
4242
4243 if (is_unary_unsigned(right_head)) {
4244 ret = get_unary_unsigned(right_head,
4245 (uint64_t *) &v);
4246 } else {
4247 ret = get_unary_signed(right_head, &v);
4248 }
4249 if (ret) {
4250 _BT_LOGE_NODE(entry_node,
4251 "Unexpected unary expression for environment entry's value: "
4252 "name=\"%s\"", left);
4253 ret = -EINVAL;
4254 goto error;
4255 }
4256
4257 ctf_trace_class_append_env_entry(ctx->ctf_tc,
4258 left, CTF_TRACE_CLASS_ENV_ENTRY_TYPE_INT,
4259 NULL, v);
4260 } else {
4261 _BT_LOGW_NODE(entry_node,
4262 "Environment entry has unknown type: "
4263 "name=\"%s\"", left);
4264 }
4265
4266 g_free(left);
4267 left = NULL;
4268 }
4269
4270 end:
4271 return 0;
4272
4273 error:
4274 g_free(left);
4275 return ret;
4276 }
4277
4278 static
4279 int set_trace_byte_order(struct ctx *ctx, struct ctf_node *trace_node)
4280 {
4281 int ret = 0;
4282 int set = 0;
4283 char *left = NULL;
4284 struct ctf_node *node;
4285 struct bt_list_head *decl_list = &trace_node->u.trace.declaration_list;
4286
4287 bt_list_for_each_entry(node, decl_list, siblings) {
4288 if (node->type == NODE_CTF_EXPRESSION) {
4289 struct ctf_node *right_node;
4290
4291 left = concatenate_unary_strings(
4292 &node->u.ctf_expression.left);
4293 if (!left) {
4294 _BT_LOGE_NODE(node,
4295 "Cannot concatenate unary strings.");
4296 ret = -EINVAL;
4297 goto error;
4298 }
4299
4300 if (!strcmp(left, "byte_order")) {
4301 enum ctf_byte_order bo;
4302
4303 if (_IS_SET(&set, _TRACE_BYTE_ORDER_SET)) {
4304 _BT_LOGE_DUP_ATTR(node, "byte_order",
4305 "trace");
4306 ret = -EPERM;
4307 goto error;
4308 }
4309
4310 _SET(&set, _TRACE_BYTE_ORDER_SET);
4311 right_node = _BT_LIST_FIRST_ENTRY(
4312 &node->u.ctf_expression.right,
4313 struct ctf_node, siblings);
4314 bo = byte_order_from_unary_expr(right_node);
4315 if (bo == -1) {
4316 _BT_LOGE_NODE(node,
4317 "Invalid `byte_order` attribute in trace (`trace` block): "
4318 "expecting `le`, `be`, or `network`.");
4319 ret = -EINVAL;
4320 goto error;
4321 } else if (bo == CTF_BYTE_ORDER_DEFAULT) {
4322 _BT_LOGE_NODE(node,
4323 "Invalid `byte_order` attribute in trace (`trace` block): "
4324 "cannot be set to `native` here.");
4325 ret = -EPERM;
4326 goto error;
4327 }
4328
4329 ctx->ctf_tc->default_byte_order = bo;
4330 }
4331
4332 g_free(left);
4333 left = NULL;
4334 }
4335 }
4336
4337 if (!_IS_SET(&set, _TRACE_BYTE_ORDER_SET)) {
4338 _BT_LOGE_NODE(trace_node,
4339 "Missing `byte_order` attribute in trace (`trace` block).");
4340 ret = -EINVAL;
4341 goto error;
4342 }
4343
4344 return 0;
4345
4346 error:
4347 g_free(left);
4348 return ret;
4349 }
4350
4351 static
4352 int visit_clock_decl_entry(struct ctx *ctx, struct ctf_node *entry_node,
4353 struct ctf_clock_class *clock, int *set, int64_t *offset_seconds,
4354 uint64_t *offset_cycles)
4355 {
4356 int ret = 0;
4357 char *left = NULL;
4358
4359 if (entry_node->type != NODE_CTF_EXPRESSION) {
4360 _BT_LOGE_NODE(entry_node,
4361 "Unexpected node type: node-type=%d",
4362 entry_node->type);
4363 ret = -EPERM;
4364 goto error;
4365 }
4366
4367 left = concatenate_unary_strings(&entry_node->u.ctf_expression.left);
4368 if (!left) {
4369 _BT_LOGE_NODE(entry_node, "Cannot concatenate unary strings.");
4370 ret = -EINVAL;
4371 goto error;
4372 }
4373
4374 if (!strcmp(left, "name")) {
4375 char *right;
4376
4377 if (_IS_SET(set, _CLOCK_NAME_SET)) {
4378 _BT_LOGE_DUP_ATTR(entry_node, "name", "clock class");
4379 ret = -EPERM;
4380 goto error;
4381 }
4382
4383 right = concatenate_unary_strings(
4384 &entry_node->u.ctf_expression.right);
4385 if (!right) {
4386 _BT_LOGE_NODE(entry_node,
4387 "Unexpected unary expression for clock class's `name` attribute.");
4388 ret = -EINVAL;
4389 goto error;
4390 }
4391
4392 g_string_assign(clock->name, right);
4393 g_free(right);
4394 _SET(set, _CLOCK_NAME_SET);
4395 } else if (!strcmp(left, "uuid")) {
4396 uint8_t uuid[BABELTRACE_UUID_LEN];
4397
4398 if (_IS_SET(set, _CLOCK_UUID_SET)) {
4399 _BT_LOGE_DUP_ATTR(entry_node, "uuid", "clock class");
4400 ret = -EPERM;
4401 goto error;
4402 }
4403
4404 ret = get_unary_uuid(&entry_node->u.ctf_expression.right, uuid);
4405 if (ret) {
4406 _BT_LOGE_NODE(entry_node,
4407 "Invalid clock class's `uuid` attribute.");
4408 goto error;
4409 }
4410
4411 clock->has_uuid = true;
4412 memcpy(&clock->uuid[0], uuid, 16);
4413 _SET(set, _CLOCK_UUID_SET);
4414 } else if (!strcmp(left, "description")) {
4415 char *right;
4416
4417 if (_IS_SET(set, _CLOCK_DESCRIPTION_SET)) {
4418 _BT_LOGE_DUP_ATTR(entry_node, "description",
4419 "clock class");
4420 ret = -EPERM;
4421 goto error;
4422 }
4423
4424 right = concatenate_unary_strings(
4425 &entry_node->u.ctf_expression.right);
4426 if (!right) {
4427 _BT_LOGE_NODE(entry_node,
4428 "Unexpected unary expression for clock class's `description` attribute.");
4429 ret = -EINVAL;
4430 goto error;
4431 }
4432
4433 g_string_assign(clock->description, right);
4434 g_free(right);
4435 _SET(set, _CLOCK_DESCRIPTION_SET);
4436 } else if (!strcmp(left, "freq")) {
4437 uint64_t freq = UINT64_C(-1);
4438
4439 if (_IS_SET(set, _CLOCK_FREQ_SET)) {
4440 _BT_LOGE_DUP_ATTR(entry_node, "freq", "clock class");
4441 ret = -EPERM;
4442 goto error;
4443 }
4444
4445 ret = get_unary_unsigned(
4446 &entry_node->u.ctf_expression.right, &freq);
4447 if (ret) {
4448 _BT_LOGE_NODE(entry_node,
4449 "Unexpected unary expression for clock class's `freq` attribute.");
4450 ret = -EINVAL;
4451 goto error;
4452 }
4453
4454 if (freq == UINT64_C(-1) || freq == 0) {
4455 _BT_LOGE_NODE(entry_node,
4456 "Invalid clock class frequency: freq=%" PRIu64,
4457 freq);
4458 ret = -EINVAL;
4459 goto error;
4460 }
4461
4462 clock->frequency = freq;
4463 _SET(set, _CLOCK_FREQ_SET);
4464 } else if (!strcmp(left, "precision")) {
4465 uint64_t precision;
4466
4467 if (_IS_SET(set, _CLOCK_PRECISION_SET)) {
4468 _BT_LOGE_DUP_ATTR(entry_node, "precision",
4469 "clock class");
4470 ret = -EPERM;
4471 goto error;
4472 }
4473
4474 ret = get_unary_unsigned(
4475 &entry_node->u.ctf_expression.right, &precision);
4476 if (ret) {
4477 _BT_LOGE_NODE(entry_node,
4478 "Unexpected unary expression for clock class's `precision` attribute.");
4479 ret = -EINVAL;
4480 goto error;
4481 }
4482
4483 clock->precision = precision;
4484 _SET(set, _CLOCK_PRECISION_SET);
4485 } else if (!strcmp(left, "offset_s")) {
4486 if (_IS_SET(set, _CLOCK_OFFSET_S_SET)) {
4487 _BT_LOGE_DUP_ATTR(entry_node, "offset_s",
4488 "clock class");
4489 ret = -EPERM;
4490 goto error;
4491 }
4492
4493 ret = get_unary_signed(
4494 &entry_node->u.ctf_expression.right, offset_seconds);
4495 if (ret) {
4496 _BT_LOGE_NODE(entry_node,
4497 "Unexpected unary expression for clock class's `offset_s` attribute.");
4498 ret = -EINVAL;
4499 goto error;
4500 }
4501
4502 _SET(set, _CLOCK_OFFSET_S_SET);
4503 } else if (!strcmp(left, "offset")) {
4504 if (_IS_SET(set, _CLOCK_OFFSET_SET)) {
4505 _BT_LOGE_DUP_ATTR(entry_node, "offset", "clock class");
4506 ret = -EPERM;
4507 goto error;
4508 }
4509
4510 ret = get_unary_unsigned(
4511 &entry_node->u.ctf_expression.right, offset_cycles);
4512 if (ret) {
4513 _BT_LOGE_NODE(entry_node,
4514 "Unexpected unary expression for clock class's `offset` attribute.");
4515 ret = -EINVAL;
4516 goto error;
4517 }
4518
4519 _SET(set, _CLOCK_OFFSET_SET);
4520 } else if (!strcmp(left, "absolute")) {
4521 struct ctf_node *right;
4522
4523 if (_IS_SET(set, _CLOCK_ABSOLUTE_SET)) {
4524 _BT_LOGE_DUP_ATTR(entry_node, "absolute",
4525 "clock class");
4526 ret = -EPERM;
4527 goto error;
4528 }
4529
4530 right = _BT_LIST_FIRST_ENTRY(
4531 &entry_node->u.ctf_expression.right,
4532 struct ctf_node, siblings);
4533 ret = get_boolean(right);
4534 if (ret < 0) {
4535 _BT_LOGE_NODE(entry_node,
4536 "Unexpected unary expression for clock class's `absolute` attribute.");
4537 ret = -EINVAL;
4538 goto error;
4539 }
4540
4541 clock->is_absolute = ret;
4542 _SET(set, _CLOCK_ABSOLUTE_SET);
4543 } else {
4544 _BT_LOGW_NODE(entry_node,
4545 "Unknown attribute in clock class: attr-name=\"%s\"",
4546 left);
4547 }
4548
4549 g_free(left);
4550 left = NULL;
4551 return 0;
4552
4553 error:
4554 g_free(left);
4555 return ret;
4556 }
4557
4558 static inline
4559 uint64_t cycles_from_ns(uint64_t frequency, uint64_t ns)
4560 {
4561 uint64_t cycles;
4562
4563 /* 1GHz */
4564 if (frequency == UINT64_C(1000000000)) {
4565 cycles = ns;
4566 } else {
4567 cycles = (uint64_t) (((double) ns * (double) frequency) / 1e9);
4568 }
4569
4570 return cycles;
4571 }
4572
4573 static
4574 void calibrate_clock_class_offsets(int64_t *offset_seconds,
4575 uint64_t *offset_cycles, uint64_t freq)
4576 {
4577 if (*offset_cycles >= freq) {
4578 const uint64_t s_in_offset_cycles = *offset_cycles / freq;
4579
4580 *offset_seconds += (int64_t) s_in_offset_cycles;
4581 *offset_cycles -= (s_in_offset_cycles * freq);
4582 }
4583 }
4584
4585 static
4586 void apply_clock_class_offset(struct ctx *ctx,
4587 struct ctf_clock_class *clock)
4588 {
4589 uint64_t freq;
4590 int64_t offset_s_to_apply = ctx->decoder_config.clock_class_offset_s;
4591 uint64_t offset_ns_to_apply;
4592 int64_t cur_offset_s;
4593 uint64_t cur_offset_cycles;
4594
4595 if (ctx->decoder_config.clock_class_offset_s == 0 &&
4596 ctx->decoder_config.clock_class_offset_ns == 0) {
4597 goto end;
4598 }
4599
4600 /* Transfer nanoseconds to seconds as much as possible */
4601 if (ctx->decoder_config.clock_class_offset_ns < 0) {
4602 const int64_t abs_ns = -ctx->decoder_config.clock_class_offset_ns;
4603 const int64_t abs_extra_s = abs_ns / INT64_C(1000000000) + 1;
4604 const int64_t extra_s = -abs_extra_s;
4605 const int64_t offset_ns = ctx->decoder_config.clock_class_offset_ns -
4606 (extra_s * INT64_C(1000000000));
4607
4608 BT_ASSERT(offset_ns > 0);
4609 offset_ns_to_apply = (uint64_t) offset_ns;
4610 offset_s_to_apply += extra_s;
4611 } else {
4612 const int64_t extra_s = ctx->decoder_config.clock_class_offset_ns /
4613 INT64_C(1000000000);
4614 const int64_t offset_ns = ctx->decoder_config.clock_class_offset_ns -
4615 (extra_s * INT64_C(1000000000));
4616
4617 BT_ASSERT(offset_ns >= 0);
4618 offset_ns_to_apply = (uint64_t) offset_ns;
4619 offset_s_to_apply += extra_s;
4620 }
4621
4622 freq = clock->frequency;
4623 cur_offset_s = clock->offset_seconds;
4624 cur_offset_cycles = clock->offset_cycles;
4625
4626 /* Apply offsets */
4627 cur_offset_s += offset_s_to_apply;
4628 cur_offset_cycles += cycles_from_ns(freq, offset_ns_to_apply);
4629
4630 /*
4631 * Recalibrate offsets because the part in cycles can be greater
4632 * than the frequency at this point.
4633 */
4634 calibrate_clock_class_offsets(&cur_offset_s, &cur_offset_cycles, freq);
4635
4636 /* Set final offsets */
4637 clock->offset_seconds = cur_offset_s;
4638 clock->offset_cycles = cur_offset_cycles;
4639
4640 end:
4641 return;
4642 }
4643
4644 static
4645 int visit_clock_decl(struct ctx *ctx, struct ctf_node *clock_node)
4646 {
4647 int ret = 0;
4648 int set = 0;
4649 struct ctf_clock_class *clock;
4650 struct ctf_node *entry_node;
4651 struct bt_list_head *decl_list = &clock_node->u.clock.declaration_list;
4652 const char *clock_class_name;
4653 int64_t offset_seconds = 0;
4654 uint64_t offset_cycles = 0;
4655 uint64_t freq;
4656
4657 if (clock_node->visited) {
4658 return 0;
4659 }
4660
4661 clock_node->visited = TRUE;
4662
4663 /* CTF 1.8's default frequency for a clock class is 1 GHz */
4664 clock = ctf_clock_class_create();
4665 if (!clock) {
4666 _BT_LOGE_NODE(clock_node,
4667 "Cannot create default clock class.");
4668 ret = -ENOMEM;
4669 goto end;
4670 }
4671
4672 bt_list_for_each_entry(entry_node, decl_list, siblings) {
4673 ret = visit_clock_decl_entry(ctx, entry_node, clock, &set,
4674 &offset_seconds, &offset_cycles);
4675 if (ret) {
4676 _BT_LOGE_NODE(entry_node,
4677 "Cannot visit clock class's entry: ret=%d",
4678 ret);
4679 goto end;
4680 }
4681 }
4682
4683 if (!_IS_SET(&set, _CLOCK_NAME_SET)) {
4684 _BT_LOGE_NODE(clock_node,
4685 "Missing `name` attribute in clock class.");
4686 ret = -EPERM;
4687 goto end;
4688 }
4689
4690 clock_class_name = clock->name->str;
4691 BT_ASSERT(clock_class_name);
4692 if (ctx->is_lttng && strcmp(clock_class_name, "monotonic") == 0) {
4693 /*
4694 * Old versions of LTTng forgot to set its clock class
4695 * as absolute, even if it is. This is important because
4696 * it's a condition to be able to sort messages
4697 * from different sources.
4698 */
4699 clock->is_absolute = true;
4700 }
4701
4702 /*
4703 * Adjust offsets so that the part in cycles is less than the
4704 * frequency (move to the part in seconds).
4705 */
4706 freq = clock->frequency;
4707 calibrate_clock_class_offsets(&offset_seconds, &offset_cycles, freq);
4708 BT_ASSERT(offset_cycles < clock->frequency);
4709 clock->offset_seconds = offset_seconds;
4710 clock->offset_cycles = offset_cycles;
4711 apply_clock_class_offset(ctx, clock);
4712 g_ptr_array_add(ctx->ctf_tc->clock_classes, clock);
4713 clock = NULL;
4714
4715 end:
4716 if (clock) {
4717 ctf_clock_class_destroy(clock);
4718 }
4719
4720 return ret;
4721 }
4722
4723 static
4724 int visit_root_decl(struct ctx *ctx, struct ctf_node *root_decl_node)
4725 {
4726 int ret = 0;
4727
4728 if (root_decl_node->visited) {
4729 goto end;
4730 }
4731
4732 root_decl_node->visited = TRUE;
4733
4734 switch (root_decl_node->type) {
4735 case NODE_TYPEDEF:
4736 ret = visit_field_class_def(ctx,
4737 root_decl_node->u.field_class_def.field_class_specifier_list,
4738 &root_decl_node->u.field_class_def.field_class_declarators);
4739 if (ret) {
4740 _BT_LOGE_NODE(root_decl_node,
4741 "Cannot add field class found in root scope.");
4742 goto end;
4743 }
4744 break;
4745 case NODE_TYPEALIAS:
4746 ret = visit_field_class_alias(ctx, root_decl_node->u.field_class_alias.target,
4747 root_decl_node->u.field_class_alias.alias);
4748 if (ret) {
4749 _BT_LOGE_NODE(root_decl_node,
4750 "Cannot add field class alias found in root scope.");
4751 goto end;
4752 }
4753 break;
4754 case NODE_TYPE_SPECIFIER_LIST:
4755 {
4756 struct ctf_field_class *decl = NULL;
4757
4758 /*
4759 * Just add the field class specifier to the root
4760 * declaration scope. Put local reference.
4761 */
4762 ret = visit_field_class_specifier_list(ctx, root_decl_node, &decl);
4763 if (ret) {
4764 _BT_LOGE_NODE(root_decl_node,
4765 "Cannot visit root scope's field class: "
4766 "ret=%d", ret);
4767 BT_ASSERT(!decl);
4768 goto end;
4769 }
4770
4771 ctf_field_class_destroy(decl);
4772 decl = NULL;
4773 break;
4774 }
4775 default:
4776 _BT_LOGE_NODE(root_decl_node,
4777 "Unexpected node type: node-type=%d",
4778 root_decl_node->type);
4779 ret = -EPERM;
4780 goto end;
4781 }
4782
4783 end:
4784 return ret;
4785 }
4786
4787 BT_HIDDEN
4788 struct ctf_visitor_generate_ir *ctf_visitor_generate_ir_create(
4789 bt_self_component_source *self_comp,
4790 const struct ctf_metadata_decoder_config *decoder_config)
4791 {
4792 struct ctx *ctx = NULL;
4793
4794 /* Create visitor's context */
4795 ctx = ctx_create(self_comp, decoder_config);
4796 if (!ctx) {
4797 BT_LOGE_STR("Cannot create visitor's context.");
4798 goto error;
4799 }
4800
4801 goto end;
4802
4803 error:
4804 ctx_destroy(ctx);
4805 ctx = NULL;
4806
4807 end:
4808 return (void *) ctx;
4809 }
4810
4811 BT_HIDDEN
4812 void ctf_visitor_generate_ir_destroy(struct ctf_visitor_generate_ir *visitor)
4813 {
4814 ctx_destroy((void *) visitor);
4815 }
4816
4817 BT_HIDDEN
4818 bt_trace_class *ctf_visitor_generate_ir_get_ir_trace_class(
4819 struct ctf_visitor_generate_ir *visitor)
4820 {
4821 struct ctx *ctx = (void *) visitor;
4822
4823 BT_ASSERT(ctx);
4824
4825 if (ctx->trace_class) {
4826 bt_trace_class_get_ref(ctx->trace_class);
4827 }
4828
4829 return ctx->trace_class;
4830 }
4831
4832 BT_HIDDEN
4833 struct ctf_trace_class *ctf_visitor_generate_ir_borrow_ctf_trace_class(
4834 struct ctf_visitor_generate_ir *visitor)
4835 {
4836 struct ctx *ctx = (void *) visitor;
4837
4838 BT_ASSERT(ctx);
4839 BT_ASSERT(ctx->ctf_tc);
4840 return ctx->ctf_tc;
4841 }
4842
4843 BT_HIDDEN
4844 int ctf_visitor_generate_ir_visit_node(struct ctf_visitor_generate_ir *visitor,
4845 struct ctf_node *node)
4846 {
4847 int ret = 0;
4848 struct ctx *ctx = (void *) visitor;
4849
4850 BT_LOGI_STR("Visiting metadata's AST to generate CTF IR objects.");
4851
4852 switch (node->type) {
4853 case NODE_ROOT:
4854 {
4855 struct ctf_node *iter;
4856 bool got_trace_decl = false;
4857
4858 /*
4859 * The first thing we need is the native byte order of
4860 * the trace block, because early class aliases can have
4861 * a `byte_order` attribute set to `native`. If we don't
4862 * have the native byte order yet, and we don't have any
4863 * trace block yet, then fail with EINCOMPLETE.
4864 */
4865 if (ctx->ctf_tc->default_byte_order == -1) {
4866 bt_list_for_each_entry(iter, &node->u.root.trace, siblings) {
4867 if (got_trace_decl) {
4868 _BT_LOGE_NODE(node,
4869 "Duplicate trace (`trace` block).");
4870 ret = -1;
4871 goto end;
4872 }
4873
4874 ret = set_trace_byte_order(ctx, iter);
4875 if (ret) {
4876 _BT_LOGE_NODE(node,
4877 "Cannot set trace's native byte order: "
4878 "ret=%d", ret);
4879 goto end;
4880 }
4881
4882 got_trace_decl = true;
4883 }
4884
4885 if (!got_trace_decl) {
4886 BT_LOGD_STR("Incomplete AST: need trace (`trace` block).");
4887 ret = -EINCOMPLETE;
4888 goto end;
4889 }
4890 }
4891
4892 BT_ASSERT(ctx->ctf_tc->default_byte_order == CTF_BYTE_ORDER_LITTLE ||
4893 ctx->ctf_tc->default_byte_order == CTF_BYTE_ORDER_BIG);
4894 BT_ASSERT(ctx->current_scope &&
4895 ctx->current_scope->parent_scope == NULL);
4896
4897 /* Environment */
4898 bt_list_for_each_entry(iter, &node->u.root.env, siblings) {
4899 ret = visit_env(ctx, iter);
4900 if (ret) {
4901 _BT_LOGE_NODE(iter,
4902 "Cannot visit trace's environment (`env` block) entry: "
4903 "ret=%d", ret);
4904 goto end;
4905 }
4906 }
4907
4908 BT_ASSERT(ctx->current_scope &&
4909 ctx->current_scope->parent_scope == NULL);
4910
4911 /*
4912 * Visit clock blocks.
4913 */
4914 bt_list_for_each_entry(iter, &node->u.root.clock, siblings) {
4915 ret = visit_clock_decl(ctx, iter);
4916 if (ret) {
4917 _BT_LOGE_NODE(iter,
4918 "Cannot visit clock class: ret=%d",
4919 ret);
4920 goto end;
4921 }
4922 }
4923
4924 BT_ASSERT(ctx->current_scope &&
4925 ctx->current_scope->parent_scope == NULL);
4926
4927 /*
4928 * Visit root declarations next, as they can be used by any
4929 * following entity.
4930 */
4931 bt_list_for_each_entry(iter, &node->u.root.declaration_list,
4932 siblings) {
4933 ret = visit_root_decl(ctx, iter);
4934 if (ret) {
4935 _BT_LOGE_NODE(iter,
4936 "Cannot visit root entry: ret=%d",
4937 ret);
4938 goto end;
4939 }
4940 }
4941
4942 BT_ASSERT(ctx->current_scope &&
4943 ctx->current_scope->parent_scope == NULL);
4944
4945 /* Callsite blocks are not supported */
4946 bt_list_for_each_entry(iter, &node->u.root.callsite, siblings) {
4947 _BT_LOGW_NODE(iter,
4948 "\"callsite\" blocks are not supported as of this version.");
4949 }
4950
4951 BT_ASSERT(ctx->current_scope &&
4952 ctx->current_scope->parent_scope == NULL);
4953
4954 /* Trace */
4955 bt_list_for_each_entry(iter, &node->u.root.trace, siblings) {
4956 ret = visit_trace_decl(ctx, iter);
4957 if (ret) {
4958 _BT_LOGE_NODE(iter,
4959 "Cannot visit trace (`trace` block): "
4960 "ret=%d", ret);
4961 goto end;
4962 }
4963 }
4964
4965 BT_ASSERT(ctx->current_scope &&
4966 ctx->current_scope->parent_scope == NULL);
4967
4968 /* Streams */
4969 bt_list_for_each_entry(iter, &node->u.root.stream, siblings) {
4970 ret = visit_stream_decl(ctx, iter);
4971 if (ret) {
4972 _BT_LOGE_NODE(iter,
4973 "Cannot visit stream class: ret=%d",
4974 ret);
4975 goto end;
4976 }
4977 }
4978
4979 BT_ASSERT(ctx->current_scope &&
4980 ctx->current_scope->parent_scope == NULL);
4981
4982 /* Events */
4983 bt_list_for_each_entry(iter, &node->u.root.event, siblings) {
4984 ret = visit_event_decl(ctx, iter);
4985 if (ret) {
4986 _BT_LOGE_NODE(iter,
4987 "Cannot visit event class: ret=%d",
4988 ret);
4989 goto end;
4990 }
4991 }
4992
4993 BT_ASSERT(ctx->current_scope &&
4994 ctx->current_scope->parent_scope == NULL);
4995 break;
4996 }
4997 default:
4998 _BT_LOGE_NODE(node,
4999 "Unexpected node type: node-type=%d",
5000 node->type);
5001 ret = -EINVAL;
5002 goto end;
5003 }
5004
5005 /* Update default clock classes */
5006 ret = ctf_trace_class_update_default_clock_classes(ctx->ctf_tc);
5007 if (ret) {
5008 ret = -EINVAL;
5009 goto end;
5010 }
5011
5012 /* Update trace class meanings */
5013 ret = ctf_trace_class_update_meanings(ctx->ctf_tc);
5014 if (ret) {
5015 ret = -EINVAL;
5016 goto end;
5017 }
5018
5019 /* Update text arrays and sequences */
5020 ret = ctf_trace_class_update_text_array_sequence(ctx->ctf_tc);
5021 if (ret) {
5022 ret = -EINVAL;
5023 goto end;
5024 }
5025
5026 /* Resolve sequence lengths and variant tags */
5027 ret = ctf_trace_class_resolve_field_classes(ctx->ctf_tc);
5028 if (ret) {
5029 ret = -EINVAL;
5030 goto end;
5031 }
5032
5033 if (ctx->trace_class) {
5034 /*
5035 * Update "in IR" for field classes.
5036 *
5037 * If we have no IR trace class, then we'll have no way
5038 * to create IR fields anyway, so we leave all the
5039 * `in_ir` members false.
5040 */
5041 ret = ctf_trace_class_update_in_ir(ctx->ctf_tc);
5042 if (ret) {
5043 ret = -EINVAL;
5044 goto end;
5045 }
5046 }
5047
5048 /* Update saved value indexes */
5049 ret = ctf_trace_class_update_value_storing_indexes(ctx->ctf_tc);
5050 if (ret) {
5051 ret = -EINVAL;
5052 goto end;
5053 }
5054
5055 /* Validate what we have so far */
5056 ret = ctf_trace_class_validate(ctx->ctf_tc);
5057 if (ret) {
5058 ret = -EINVAL;
5059 goto end;
5060 }
5061
5062 /*
5063 * If there are fields which are not related to the CTF format
5064 * itself in the packet header and in event header field
5065 * classes, warn about it because they are never translated.
5066 */
5067 ctf_trace_class_warn_meaningless_header_fields(ctx->ctf_tc);
5068
5069 if (ctx->trace_class) {
5070 /* Copy new CTF metadata -> new IR metadata */
5071 ret = ctf_trace_class_translate(ctx->trace_class, ctx->ctf_tc);
5072 if (ret) {
5073 ret = -EINVAL;
5074 goto end;
5075 }
5076 }
5077
5078 end:
5079 return ret;
5080 }
This page took 0.157684 seconds and 4 git commands to generate.