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