ctf: Fix one -Wnull-dereference warning
[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 } else {
3497 abort();
3498 }
3499
3500 if (strcmp(named_fc->name->str, field_name) == 0) {
3501 ret = auto_map_field_to_trace_clock_class(ctx,
3502 named_fc->fc);
3503 if (ret) {
3504 BT_COMP_LOGE("Cannot automatically map field to trace's clock class: "
3505 "field-name=\"%s\"", field_name);
3506 goto end;
3507 }
3508 }
3509
3510 ret = auto_map_fields_to_trace_clock_class(ctx, named_fc->fc,
3511 field_name);
3512 if (ret) {
3513 BT_COMP_LOGE("Cannot automatically map structure or variant field class's fields to trace's clock class: "
3514 "field-name=\"%s\", root-field-name=\"%s\"",
3515 field_name, named_fc->name->str);
3516 goto end;
3517 }
3518 }
3519
3520 end:
3521 return ret;
3522 }
3523
3524 static
3525 int visit_stream_decl_entry(struct ctx *ctx, struct ctf_node *node,
3526 struct ctf_stream_class *stream_class, int *set)
3527 {
3528 int ret = 0;
3529 char *left = NULL;
3530
3531 switch (node->type) {
3532 case NODE_TYPEDEF:
3533 ret = visit_field_class_def(ctx, node->u.field_class_def.field_class_specifier_list,
3534 &node->u.field_class_def.field_class_declarators);
3535 if (ret) {
3536 _BT_COMP_LOGE_NODE(node,
3537 "Cannot add field class found in stream class.");
3538 goto error;
3539 }
3540 break;
3541 case NODE_TYPEALIAS:
3542 ret = visit_field_class_alias(ctx, node->u.field_class_alias.target,
3543 node->u.field_class_alias.alias);
3544 if (ret) {
3545 _BT_COMP_LOGE_NODE(node,
3546 "Cannot add field class alias found in stream class.");
3547 goto error;
3548 }
3549 break;
3550 case NODE_CTF_EXPRESSION:
3551 {
3552 left = ctf_ast_concatenate_unary_strings(&node->u.ctf_expression.left);
3553 if (!left) {
3554 _BT_COMP_LOGE_NODE(node, "Cannot concatenate unary strings.");
3555 ret = -EINVAL;
3556 goto error;
3557 }
3558
3559 if (strcmp(left, "id") == 0) {
3560 int64_t id;
3561
3562 if (_IS_SET(set, _STREAM_ID_SET)) {
3563 _BT_COMP_LOGE_DUP_ATTR(node, "id",
3564 "stream declaration");
3565 ret = -EPERM;
3566 goto error;
3567 }
3568
3569 ret = get_unary_unsigned(ctx,
3570 &node->u.ctf_expression.right,
3571 (uint64_t *) &id);
3572
3573 /* Only read "id" if get_unary_unsigned() succeeded. */
3574 if (ret || (!ret && id < 0)) {
3575 _BT_COMP_LOGE_NODE(node,
3576 "Unexpected unary expression for stream class's `id` attribute.");
3577 ret = -EINVAL;
3578 goto error;
3579 }
3580
3581 if (ctf_trace_class_borrow_stream_class_by_id(
3582 ctx->ctf_tc, id)) {
3583 _BT_COMP_LOGE_NODE(node,
3584 "Duplicate stream class (same ID): id=%" PRId64,
3585 id);
3586 ret = -EEXIST;
3587 goto error;
3588 }
3589
3590 stream_class->id = id;
3591 _SET(set, _STREAM_ID_SET);
3592 } else if (strcmp(left, "event.header") == 0) {
3593 if (_IS_SET(set, _STREAM_EVENT_HEADER_SET)) {
3594 _BT_COMP_LOGE_NODE(node,
3595 "Duplicate `event.header` entry in stream class.");
3596 ret = -EPERM;
3597 goto error;
3598 }
3599
3600 ret = visit_field_class_specifier_list(ctx,
3601 _BT_LIST_FIRST_ENTRY(
3602 &node->u.ctf_expression.right,
3603 struct ctf_node, siblings),
3604 &stream_class->event_header_fc);
3605 if (ret) {
3606 _BT_COMP_LOGE_NODE(node,
3607 "Cannot create stream class's event header field class.");
3608 goto error;
3609 }
3610
3611 BT_ASSERT(stream_class->event_header_fc);
3612 ret = auto_map_fields_to_trace_clock_class(ctx,
3613 stream_class->event_header_fc, "timestamp");
3614 if (ret) {
3615 _BT_COMP_LOGE_NODE(node,
3616 "Cannot automatically map specific event header field class fields named `timestamp` to trace's clock class.");
3617 goto error;
3618 }
3619
3620 _SET(set, _STREAM_EVENT_HEADER_SET);
3621 } else if (strcmp(left, "event.context") == 0) {
3622 if (_IS_SET(set, _STREAM_EVENT_CONTEXT_SET)) {
3623 _BT_COMP_LOGE_NODE(node,
3624 "Duplicate `event.context` entry in stream class.");
3625 ret = -EPERM;
3626 goto error;
3627 }
3628
3629 ret = visit_field_class_specifier_list(ctx,
3630 _BT_LIST_FIRST_ENTRY(
3631 &node->u.ctf_expression.right,
3632 struct ctf_node, siblings),
3633 &stream_class->event_common_context_fc);
3634 if (ret) {
3635 _BT_COMP_LOGE_NODE(node,
3636 "Cannot create stream class's event context field class.");
3637 goto error;
3638 }
3639
3640 BT_ASSERT(stream_class->event_common_context_fc);
3641 _SET(set, _STREAM_EVENT_CONTEXT_SET);
3642 } else if (strcmp(left, "packet.context") == 0) {
3643 if (_IS_SET(set, _STREAM_PACKET_CONTEXT_SET)) {
3644 _BT_COMP_LOGE_NODE(node,
3645 "Duplicate `packet.context` entry in stream class.");
3646 ret = -EPERM;
3647 goto error;
3648 }
3649
3650 ret = visit_field_class_specifier_list(ctx,
3651 _BT_LIST_FIRST_ENTRY(
3652 &node->u.ctf_expression.right,
3653 struct ctf_node, siblings),
3654 &stream_class->packet_context_fc);
3655 if (ret) {
3656 _BT_COMP_LOGE_NODE(node,
3657 "Cannot create stream class's packet context field class.");
3658 goto error;
3659 }
3660
3661 BT_ASSERT(stream_class->packet_context_fc);
3662 ret = auto_map_fields_to_trace_clock_class(ctx,
3663 stream_class->packet_context_fc,
3664 "timestamp_begin");
3665 if (ret) {
3666 _BT_COMP_LOGE_NODE(node,
3667 "Cannot automatically map specific packet context field class fields named `timestamp_begin` to trace's clock class.");
3668 goto error;
3669 }
3670
3671 ret = auto_map_fields_to_trace_clock_class(ctx,
3672 stream_class->packet_context_fc,
3673 "timestamp_end");
3674 if (ret) {
3675 _BT_COMP_LOGE_NODE(node,
3676 "Cannot automatically map specific packet context field class fields named `timestamp_end` to trace's clock class.");
3677 goto error;
3678 }
3679
3680 _SET(set, _STREAM_PACKET_CONTEXT_SET);
3681 } else {
3682 _BT_COMP_LOGW_NODE(node,
3683 "Unknown attribute in stream class: "
3684 "attr-name=\"%s\"", left);
3685 }
3686
3687 g_free(left);
3688 left = NULL;
3689 break;
3690 }
3691
3692 default:
3693 ret = -EPERM;
3694 goto error;
3695 }
3696
3697 return 0;
3698
3699 error:
3700 g_free(left);
3701 return ret;
3702 }
3703
3704 static
3705 int visit_stream_decl(struct ctx *ctx, struct ctf_node *node)
3706 {
3707 int set = 0;
3708 int ret = 0;
3709 struct ctf_node *iter;
3710 struct ctf_stream_class *stream_class = NULL;
3711 struct bt_list_head *decl_list = &node->u.stream.declaration_list;
3712
3713 if (node->visited) {
3714 goto end;
3715 }
3716
3717 node->visited = TRUE;
3718 stream_class = ctf_stream_class_create();
3719 BT_ASSERT(stream_class);
3720 _TRY_PUSH_SCOPE_OR_GOTO_ERROR();
3721
3722 bt_list_for_each_entry(iter, decl_list, siblings) {
3723 ret = visit_stream_decl_entry(ctx, iter, stream_class, &set);
3724 if (ret) {
3725 _BT_COMP_LOGE_NODE(iter,
3726 "Cannot visit stream class's entry: "
3727 "ret=%d", ret);
3728 ctx_pop_scope(ctx);
3729 goto error;
3730 }
3731 }
3732
3733 ctx_pop_scope(ctx);
3734
3735 if (_IS_SET(&set, _STREAM_ID_SET)) {
3736 /* Check that packet header has `stream_id` field */
3737 struct ctf_named_field_class *named_fc = NULL;
3738
3739 if (!ctx->ctf_tc->packet_header_fc) {
3740 _BT_COMP_LOGE_NODE(node,
3741 "Stream class has a `id` attribute, "
3742 "but trace has no packet header field class.");
3743 goto error;
3744 }
3745
3746 named_fc = ctf_field_class_struct_borrow_member_by_name(
3747 (void *) ctx->ctf_tc->packet_header_fc, "stream_id");
3748 if (!named_fc) {
3749 _BT_COMP_LOGE_NODE(node,
3750 "Stream class has a `id` attribute, "
3751 "but trace's packet header field class has no `stream_id` field.");
3752 goto error;
3753 }
3754
3755 if (named_fc->fc->type != CTF_FIELD_CLASS_TYPE_INT &&
3756 named_fc->fc->type != CTF_FIELD_CLASS_TYPE_ENUM) {
3757 _BT_COMP_LOGE_NODE(node,
3758 "Stream class has a `id` attribute, "
3759 "but trace's packet header field class's `stream_id` field is not an integer field class.");
3760 goto error;
3761 }
3762 } else {
3763 /* Allow only _one_ ID-less stream */
3764 if (ctx->ctf_tc->stream_classes->len != 0) {
3765 _BT_COMP_LOGE_NODE(node,
3766 "Missing `id` attribute in stream class as there's more than one stream class in the trace.");
3767 ret = -EPERM;
3768 goto error;
3769 }
3770
3771 /* Automatic ID: 0 */
3772 stream_class->id = 0;
3773 }
3774
3775 /*
3776 * Make sure that this stream class's ID is currently unique in
3777 * the trace.
3778 */
3779 if (ctf_trace_class_borrow_stream_class_by_id(ctx->ctf_tc,
3780 stream_class->id)) {
3781 _BT_COMP_LOGE_NODE(node,
3782 "Duplicate stream class (same ID): id=%" PRId64,
3783 stream_class->id);
3784 ret = -EINVAL;
3785 goto error;
3786 }
3787
3788 g_ptr_array_add(ctx->ctf_tc->stream_classes, stream_class);
3789 stream_class = NULL;
3790 goto end;
3791
3792 error:
3793 ctf_stream_class_destroy(stream_class);
3794 stream_class = NULL;
3795
3796 end:
3797 return ret;
3798 }
3799
3800 static
3801 int visit_trace_decl_entry(struct ctx *ctx, struct ctf_node *node, int *set)
3802 {
3803 int ret = 0;
3804 char *left = NULL;
3805 uint64_t val;
3806
3807 switch (node->type) {
3808 case NODE_TYPEDEF:
3809 ret = visit_field_class_def(ctx, node->u.field_class_def.field_class_specifier_list,
3810 &node->u.field_class_def.field_class_declarators);
3811 if (ret) {
3812 _BT_COMP_LOGE_NODE(node,
3813 "Cannot add field class found in trace (`trace` block).");
3814 goto error;
3815 }
3816 break;
3817 case NODE_TYPEALIAS:
3818 ret = visit_field_class_alias(ctx, node->u.field_class_alias.target,
3819 node->u.field_class_alias.alias);
3820 if (ret) {
3821 _BT_COMP_LOGE_NODE(node,
3822 "Cannot add field class alias found in trace (`trace` block).");
3823 goto error;
3824 }
3825 break;
3826 case NODE_CTF_EXPRESSION:
3827 {
3828 left = ctf_ast_concatenate_unary_strings(&node->u.ctf_expression.left);
3829 if (!left) {
3830 _BT_COMP_LOGE_NODE(node, "Cannot concatenate unary strings.");
3831 ret = -EINVAL;
3832 goto error;
3833 }
3834
3835 if (strcmp(left, "major") == 0) {
3836 if (_IS_SET(set, _TRACE_MAJOR_SET)) {
3837 _BT_COMP_LOGE_DUP_ATTR(node, "major", "trace");
3838 ret = -EPERM;
3839 goto error;
3840 }
3841
3842 ret = get_unary_unsigned(ctx,
3843 &node->u.ctf_expression.right, &val);
3844 if (ret) {
3845 _BT_COMP_LOGE_NODE(node,
3846 "Unexpected unary expression for trace's `major` attribute.");
3847 ret = -EINVAL;
3848 goto error;
3849 }
3850
3851 if (val != 1) {
3852 _BT_COMP_LOGE_NODE(node,
3853 "Invalid trace's `minor` attribute: expecting 1.");
3854 goto error;
3855 }
3856
3857 ctx->ctf_tc->major = val;
3858 _SET(set, _TRACE_MAJOR_SET);
3859 } else if (strcmp(left, "minor") == 0) {
3860 if (_IS_SET(set, _TRACE_MINOR_SET)) {
3861 _BT_COMP_LOGE_DUP_ATTR(node, "minor", "trace");
3862 ret = -EPERM;
3863 goto error;
3864 }
3865
3866 ret = get_unary_unsigned(ctx,
3867 &node->u.ctf_expression.right, &val);
3868 if (ret) {
3869 _BT_COMP_LOGE_NODE(node,
3870 "Unexpected unary expression for trace's `minor` attribute.");
3871 ret = -EINVAL;
3872 goto error;
3873 }
3874
3875 if (val != 8) {
3876 _BT_COMP_LOGE_NODE(node,
3877 "Invalid trace's `minor` attribute: expecting 8.");
3878 goto error;
3879 }
3880
3881 ctx->ctf_tc->minor = val;
3882 _SET(set, _TRACE_MINOR_SET);
3883 } else if (strcmp(left, "uuid") == 0) {
3884 if (_IS_SET(set, _TRACE_UUID_SET)) {
3885 _BT_COMP_LOGE_DUP_ATTR(node, "uuid", "trace");
3886 ret = -EPERM;
3887 goto error;
3888 }
3889
3890 ret = get_unary_uuid(ctx,
3891 &node->u.ctf_expression.right,
3892 ctx->ctf_tc->uuid);
3893 if (ret) {
3894 _BT_COMP_LOGE_NODE(node,
3895 "Invalid trace's `uuid` attribute.");
3896 goto error;
3897 }
3898
3899 ctx->ctf_tc->is_uuid_set = true;
3900 _SET(set, _TRACE_UUID_SET);
3901 } else if (strcmp(left, "byte_order") == 0) {
3902 /* Default byte order is already known at this stage */
3903 if (_IS_SET(set, _TRACE_BYTE_ORDER_SET)) {
3904 _BT_COMP_LOGE_DUP_ATTR(node, "byte_order",
3905 "trace");
3906 ret = -EPERM;
3907 goto error;
3908 }
3909
3910 BT_ASSERT(ctx->ctf_tc->default_byte_order != CTF_BYTE_ORDER_UNKNOWN);
3911 _SET(set, _TRACE_BYTE_ORDER_SET);
3912 } else if (strcmp(left, "packet.header") == 0) {
3913 if (_IS_SET(set, _TRACE_PACKET_HEADER_SET)) {
3914 _BT_COMP_LOGE_NODE(node,
3915 "Duplicate `packet.header` entry in trace.");
3916 ret = -EPERM;
3917 goto error;
3918 }
3919
3920 ret = visit_field_class_specifier_list(ctx,
3921 _BT_LIST_FIRST_ENTRY(
3922 &node->u.ctf_expression.right,
3923 struct ctf_node, siblings),
3924 &ctx->ctf_tc->packet_header_fc);
3925 if (ret) {
3926 _BT_COMP_LOGE_NODE(node,
3927 "Cannot create trace's packet header field class.");
3928 goto error;
3929 }
3930
3931 BT_ASSERT(ctx->ctf_tc->packet_header_fc);
3932 _SET(set, _TRACE_PACKET_HEADER_SET);
3933 } else {
3934 _BT_COMP_LOGW_NODE(node,
3935 "Unknown attribute in stream class: "
3936 "attr-name=\"%s\"", left);
3937 }
3938
3939 g_free(left);
3940 left = NULL;
3941 break;
3942 }
3943 default:
3944 _BT_COMP_LOGE_NODE(node, "Unknown expression in trace.");
3945 ret = -EINVAL;
3946 goto error;
3947 }
3948
3949 return 0;
3950
3951 error:
3952 g_free(left);
3953 return ret;
3954 }
3955
3956 static
3957 int visit_trace_decl(struct ctx *ctx, struct ctf_node *node)
3958 {
3959 int ret = 0;
3960 int set = 0;
3961 struct ctf_node *iter;
3962 struct bt_list_head *decl_list = &node->u.trace.declaration_list;
3963
3964 if (node->visited) {
3965 goto end;
3966 }
3967
3968 node->visited = TRUE;
3969
3970 if (ctx->is_trace_visited) {
3971 _BT_COMP_LOGE_NODE(node, "Duplicate trace (`trace` block).");
3972 ret = -EEXIST;
3973 goto error;
3974 }
3975
3976 _TRY_PUSH_SCOPE_OR_GOTO_ERROR();
3977
3978 bt_list_for_each_entry(iter, decl_list, siblings) {
3979 ret = visit_trace_decl_entry(ctx, iter, &set);
3980 if (ret) {
3981 _BT_COMP_LOGE_NODE(iter, "Cannot visit trace's entry (`trace` block): "
3982 "ret=%d", ret);
3983 ctx_pop_scope(ctx);
3984 goto error;
3985 }
3986 }
3987
3988 ctx_pop_scope(ctx);
3989
3990 if (!_IS_SET(&set, _TRACE_MAJOR_SET)) {
3991 _BT_COMP_LOGE_NODE(node,
3992 "Missing `major` attribute in trace (`trace` block).");
3993 ret = -EPERM;
3994 goto error;
3995 }
3996
3997 if (!_IS_SET(&set, _TRACE_MINOR_SET)) {
3998 _BT_COMP_LOGE_NODE(node,
3999 "Missing `minor` attribute in trace (`trace` block).");
4000 ret = -EPERM;
4001 goto error;
4002 }
4003
4004 if (!_IS_SET(&set, _TRACE_BYTE_ORDER_SET)) {
4005 _BT_COMP_LOGE_NODE(node,
4006 "Missing `byte_order` attribute in trace (`trace` block).");
4007 ret = -EPERM;
4008 goto error;
4009 }
4010
4011 ctx->is_trace_visited = true;
4012
4013 end:
4014 return 0;
4015
4016 error:
4017 return ret;
4018 }
4019
4020 static
4021 int visit_env(struct ctx *ctx, struct ctf_node *node)
4022 {
4023 int ret = 0;
4024 char *left = NULL;
4025 struct ctf_node *entry_node;
4026 struct bt_list_head *decl_list = &node->u.env.declaration_list;
4027
4028 if (node->visited) {
4029 goto end;
4030 }
4031
4032 node->visited = TRUE;
4033
4034 bt_list_for_each_entry(entry_node, decl_list, siblings) {
4035 struct bt_list_head *right_head =
4036 &entry_node->u.ctf_expression.right;
4037
4038 if (entry_node->type != NODE_CTF_EXPRESSION) {
4039 _BT_COMP_LOGE_NODE(entry_node,
4040 "Wrong expression in environment entry: "
4041 "node-type=%d", entry_node->type);
4042 ret = -EPERM;
4043 goto error;
4044 }
4045
4046 left = ctf_ast_concatenate_unary_strings(
4047 &entry_node->u.ctf_expression.left);
4048 if (!left) {
4049 _BT_COMP_LOGE_NODE(entry_node,
4050 "Cannot get environment entry's name.");
4051 ret = -EINVAL;
4052 goto error;
4053 }
4054
4055 if (is_unary_string(right_head)) {
4056 char *right = ctf_ast_concatenate_unary_strings(right_head);
4057
4058 if (!right) {
4059 _BT_COMP_LOGE_NODE(entry_node,
4060 "Unexpected unary expression for environment entry's value: "
4061 "name=\"%s\"", left);
4062 ret = -EINVAL;
4063 goto error;
4064 }
4065
4066 if (strcmp(left, "tracer_name") == 0) {
4067 if (strncmp(right, "lttng", 5) == 0) {
4068 BT_COMP_LOGI("Detected LTTng trace from `%s` environment value: "
4069 "tracer-name=\"%s\"",
4070 left, right);
4071 ctx->is_lttng = true;
4072 }
4073 }
4074
4075 ctf_trace_class_append_env_entry(ctx->ctf_tc,
4076 left, CTF_TRACE_CLASS_ENV_ENTRY_TYPE_STR,
4077 right, 0);
4078 g_free(right);
4079 } else if (is_unary_unsigned(right_head) ||
4080 is_unary_signed(right_head)) {
4081 int64_t v;
4082
4083 if (is_unary_unsigned(right_head)) {
4084 ret = get_unary_unsigned(ctx, right_head,
4085 (uint64_t *) &v);
4086 } else {
4087 ret = get_unary_signed(right_head, &v);
4088 }
4089 if (ret) {
4090 _BT_COMP_LOGE_NODE(entry_node,
4091 "Unexpected unary expression for environment entry's value: "
4092 "name=\"%s\"", left);
4093 ret = -EINVAL;
4094 goto error;
4095 }
4096
4097 ctf_trace_class_append_env_entry(ctx->ctf_tc,
4098 left, CTF_TRACE_CLASS_ENV_ENTRY_TYPE_INT,
4099 NULL, v);
4100 } else {
4101 _BT_COMP_LOGW_NODE(entry_node,
4102 "Environment entry has unknown type: "
4103 "name=\"%s\"", left);
4104 }
4105
4106 g_free(left);
4107 left = NULL;
4108 }
4109
4110 end:
4111 return 0;
4112
4113 error:
4114 g_free(left);
4115 return ret;
4116 }
4117
4118 static
4119 int set_trace_byte_order(struct ctx *ctx, struct ctf_node *trace_node)
4120 {
4121 int ret = 0;
4122 int set = 0;
4123 char *left = NULL;
4124 struct ctf_node *node;
4125 struct bt_list_head *decl_list = &trace_node->u.trace.declaration_list;
4126
4127 bt_list_for_each_entry(node, decl_list, siblings) {
4128 if (node->type == NODE_CTF_EXPRESSION) {
4129 struct ctf_node *right_node;
4130
4131 left = ctf_ast_concatenate_unary_strings(
4132 &node->u.ctf_expression.left);
4133 if (!left) {
4134 _BT_COMP_LOGE_NODE(node,
4135 "Cannot concatenate unary strings.");
4136 ret = -EINVAL;
4137 goto error;
4138 }
4139
4140 if (strcmp(left, "byte_order") == 0) {
4141 enum ctf_byte_order bo;
4142
4143 if (_IS_SET(&set, _TRACE_BYTE_ORDER_SET)) {
4144 _BT_COMP_LOGE_DUP_ATTR(node, "byte_order",
4145 "trace");
4146 ret = -EPERM;
4147 goto error;
4148 }
4149
4150 _SET(&set, _TRACE_BYTE_ORDER_SET);
4151 right_node = _BT_LIST_FIRST_ENTRY(
4152 &node->u.ctf_expression.right,
4153 struct ctf_node, siblings);
4154 bo = byte_order_from_unary_expr(ctx,
4155 right_node);
4156 if (bo == CTF_BYTE_ORDER_UNKNOWN) {
4157 _BT_COMP_LOGE_NODE(node,
4158 "Invalid `byte_order` attribute in trace (`trace` block): "
4159 "expecting `le`, `be`, or `network`.");
4160 ret = -EINVAL;
4161 goto error;
4162 } else if (bo == CTF_BYTE_ORDER_DEFAULT) {
4163 _BT_COMP_LOGE_NODE(node,
4164 "Invalid `byte_order` attribute in trace (`trace` block): "
4165 "cannot be set to `native` here.");
4166 ret = -EPERM;
4167 goto error;
4168 }
4169
4170 ctx->ctf_tc->default_byte_order = bo;
4171 }
4172
4173 g_free(left);
4174 left = NULL;
4175 }
4176 }
4177
4178 if (!_IS_SET(&set, _TRACE_BYTE_ORDER_SET)) {
4179 _BT_COMP_LOGE_NODE(trace_node,
4180 "Missing `byte_order` attribute in trace (`trace` block).");
4181 ret = -EINVAL;
4182 goto error;
4183 }
4184
4185 return 0;
4186
4187 error:
4188 g_free(left);
4189 return ret;
4190 }
4191
4192 static
4193 int visit_clock_decl_entry(struct ctx *ctx, struct ctf_node *entry_node,
4194 struct ctf_clock_class *clock, int *set, int64_t *offset_seconds,
4195 uint64_t *offset_cycles)
4196 {
4197 int ret = 0;
4198 char *left = NULL;
4199
4200 if (entry_node->type != NODE_CTF_EXPRESSION) {
4201 _BT_COMP_LOGE_NODE(entry_node,
4202 "Unexpected node type: node-type=%d",
4203 entry_node->type);
4204 ret = -EPERM;
4205 goto error;
4206 }
4207
4208 left = ctf_ast_concatenate_unary_strings(&entry_node->u.ctf_expression.left);
4209 if (!left) {
4210 _BT_COMP_LOGE_NODE(entry_node, "Cannot concatenate unary strings.");
4211 ret = -EINVAL;
4212 goto error;
4213 }
4214
4215 if (strcmp(left, "name") == 0) {
4216 char *right;
4217
4218 if (_IS_SET(set, _CLOCK_NAME_SET)) {
4219 _BT_COMP_LOGE_DUP_ATTR(entry_node, "name", "clock class");
4220 ret = -EPERM;
4221 goto error;
4222 }
4223
4224 right = ctf_ast_concatenate_unary_strings(
4225 &entry_node->u.ctf_expression.right);
4226 if (!right) {
4227 _BT_COMP_LOGE_NODE(entry_node,
4228 "Unexpected unary expression for clock class's `name` attribute.");
4229 ret = -EINVAL;
4230 goto error;
4231 }
4232
4233 g_string_assign(clock->name, right);
4234 g_free(right);
4235 _SET(set, _CLOCK_NAME_SET);
4236 } else if (strcmp(left, "uuid") == 0) {
4237 bt_uuid_t uuid;
4238
4239 if (_IS_SET(set, _CLOCK_UUID_SET)) {
4240 _BT_COMP_LOGE_DUP_ATTR(entry_node, "uuid", "clock class");
4241 ret = -EPERM;
4242 goto error;
4243 }
4244
4245 ret = get_unary_uuid(ctx, &entry_node->u.ctf_expression.right,
4246 uuid);
4247 if (ret) {
4248 _BT_COMP_LOGE_NODE(entry_node,
4249 "Invalid clock class's `uuid` attribute.");
4250 goto error;
4251 }
4252
4253 clock->has_uuid = true;
4254 bt_uuid_copy(clock->uuid, uuid);
4255 _SET(set, _CLOCK_UUID_SET);
4256 } else if (strcmp(left, "description") == 0) {
4257 char *right;
4258
4259 if (_IS_SET(set, _CLOCK_DESCRIPTION_SET)) {
4260 _BT_COMP_LOGE_DUP_ATTR(entry_node, "description",
4261 "clock class");
4262 ret = -EPERM;
4263 goto error;
4264 }
4265
4266 right = ctf_ast_concatenate_unary_strings(
4267 &entry_node->u.ctf_expression.right);
4268 if (!right) {
4269 _BT_COMP_LOGE_NODE(entry_node,
4270 "Unexpected unary expression for clock class's `description` attribute.");
4271 ret = -EINVAL;
4272 goto error;
4273 }
4274
4275 g_string_assign(clock->description, right);
4276 g_free(right);
4277 _SET(set, _CLOCK_DESCRIPTION_SET);
4278 } else if (strcmp(left, "freq") == 0) {
4279 uint64_t freq = UINT64_C(-1);
4280
4281 if (_IS_SET(set, _CLOCK_FREQ_SET)) {
4282 _BT_COMP_LOGE_DUP_ATTR(entry_node, "freq", "clock class");
4283 ret = -EPERM;
4284 goto error;
4285 }
4286
4287 ret = get_unary_unsigned(ctx,
4288 &entry_node->u.ctf_expression.right, &freq);
4289 if (ret) {
4290 _BT_COMP_LOGE_NODE(entry_node,
4291 "Unexpected unary expression for clock class's `freq` attribute.");
4292 ret = -EINVAL;
4293 goto error;
4294 }
4295
4296 if (freq == UINT64_C(-1) || freq == 0) {
4297 _BT_COMP_LOGE_NODE(entry_node,
4298 "Invalid clock class frequency: freq=%" PRIu64,
4299 freq);
4300 ret = -EINVAL;
4301 goto error;
4302 }
4303
4304 clock->frequency = freq;
4305 _SET(set, _CLOCK_FREQ_SET);
4306 } else if (strcmp(left, "precision") == 0) {
4307 uint64_t precision;
4308
4309 if (_IS_SET(set, _CLOCK_PRECISION_SET)) {
4310 _BT_COMP_LOGE_DUP_ATTR(entry_node, "precision",
4311 "clock class");
4312 ret = -EPERM;
4313 goto error;
4314 }
4315
4316 ret = get_unary_unsigned(ctx,
4317 &entry_node->u.ctf_expression.right, &precision);
4318 if (ret) {
4319 _BT_COMP_LOGE_NODE(entry_node,
4320 "Unexpected unary expression for clock class's `precision` attribute.");
4321 ret = -EINVAL;
4322 goto error;
4323 }
4324
4325 clock->precision = precision;
4326 _SET(set, _CLOCK_PRECISION_SET);
4327 } else if (strcmp(left, "offset_s") == 0) {
4328 if (_IS_SET(set, _CLOCK_OFFSET_S_SET)) {
4329 _BT_COMP_LOGE_DUP_ATTR(entry_node, "offset_s",
4330 "clock class");
4331 ret = -EPERM;
4332 goto error;
4333 }
4334
4335 ret = get_unary_signed(
4336 &entry_node->u.ctf_expression.right, offset_seconds);
4337 if (ret) {
4338 _BT_COMP_LOGE_NODE(entry_node,
4339 "Unexpected unary expression for clock class's `offset_s` attribute.");
4340 ret = -EINVAL;
4341 goto error;
4342 }
4343
4344 _SET(set, _CLOCK_OFFSET_S_SET);
4345 } else if (strcmp(left, "offset") == 0) {
4346 if (_IS_SET(set, _CLOCK_OFFSET_SET)) {
4347 _BT_COMP_LOGE_DUP_ATTR(entry_node, "offset", "clock class");
4348 ret = -EPERM;
4349 goto error;
4350 }
4351
4352 ret = get_unary_unsigned(ctx,
4353 &entry_node->u.ctf_expression.right, offset_cycles);
4354 if (ret) {
4355 _BT_COMP_LOGE_NODE(entry_node,
4356 "Unexpected unary expression for clock class's `offset` attribute.");
4357 ret = -EINVAL;
4358 goto error;
4359 }
4360
4361 _SET(set, _CLOCK_OFFSET_SET);
4362 } else if (strcmp(left, "absolute") == 0) {
4363 struct ctf_node *right;
4364
4365 if (_IS_SET(set, _CLOCK_ABSOLUTE_SET)) {
4366 _BT_COMP_LOGE_DUP_ATTR(entry_node, "absolute",
4367 "clock class");
4368 ret = -EPERM;
4369 goto error;
4370 }
4371
4372 right = _BT_LIST_FIRST_ENTRY(
4373 &entry_node->u.ctf_expression.right,
4374 struct ctf_node, siblings);
4375 ret = get_boolean(ctx, right);
4376 if (ret < 0) {
4377 _BT_COMP_LOGE_NODE(entry_node,
4378 "Unexpected unary expression for clock class's `absolute` attribute.");
4379 ret = -EINVAL;
4380 goto error;
4381 }
4382
4383 clock->is_absolute = ret;
4384 _SET(set, _CLOCK_ABSOLUTE_SET);
4385 } else {
4386 _BT_COMP_LOGW_NODE(entry_node,
4387 "Unknown attribute in clock class: attr-name=\"%s\"",
4388 left);
4389 }
4390
4391 g_free(left);
4392 left = NULL;
4393 return 0;
4394
4395 error:
4396 g_free(left);
4397 return ret;
4398 }
4399
4400 static inline
4401 uint64_t cycles_from_ns(uint64_t frequency, uint64_t ns)
4402 {
4403 uint64_t cycles;
4404
4405 /* 1GHz */
4406 if (frequency == UINT64_C(1000000000)) {
4407 cycles = ns;
4408 } else {
4409 cycles = (uint64_t) (((double) ns * (double) frequency) / 1e9);
4410 }
4411
4412 return cycles;
4413 }
4414
4415 static
4416 void calibrate_clock_class_offsets(int64_t *offset_seconds,
4417 uint64_t *offset_cycles, uint64_t freq)
4418 {
4419 if (*offset_cycles >= freq) {
4420 const uint64_t s_in_offset_cycles = *offset_cycles / freq;
4421
4422 *offset_seconds += (int64_t) s_in_offset_cycles;
4423 *offset_cycles -= (s_in_offset_cycles * freq);
4424 }
4425 }
4426
4427 static
4428 void apply_clock_class_is_absolute(struct ctx *ctx,
4429 struct ctf_clock_class *clock)
4430 {
4431 if (ctx->decoder_config.force_clock_class_origin_unix_epoch) {
4432 clock->is_absolute = true;
4433 }
4434
4435 return;
4436 }
4437
4438 static
4439 void apply_clock_class_offset(struct ctx *ctx,
4440 struct ctf_clock_class *clock)
4441 {
4442 uint64_t freq;
4443 int64_t offset_s_to_apply = ctx->decoder_config.clock_class_offset_s;
4444 uint64_t offset_ns_to_apply;
4445 int64_t cur_offset_s;
4446 uint64_t cur_offset_cycles;
4447
4448 if (ctx->decoder_config.clock_class_offset_s == 0 &&
4449 ctx->decoder_config.clock_class_offset_ns == 0) {
4450 goto end;
4451 }
4452
4453 /* Transfer nanoseconds to seconds as much as possible */
4454 if (ctx->decoder_config.clock_class_offset_ns < 0) {
4455 const int64_t abs_ns = -ctx->decoder_config.clock_class_offset_ns;
4456 const int64_t abs_extra_s = abs_ns / INT64_C(1000000000) + 1;
4457 const int64_t extra_s = -abs_extra_s;
4458 const int64_t offset_ns = ctx->decoder_config.clock_class_offset_ns -
4459 (extra_s * INT64_C(1000000000));
4460
4461 BT_ASSERT(offset_ns > 0);
4462 offset_ns_to_apply = (uint64_t) offset_ns;
4463 offset_s_to_apply += extra_s;
4464 } else {
4465 const int64_t extra_s = ctx->decoder_config.clock_class_offset_ns /
4466 INT64_C(1000000000);
4467 const int64_t offset_ns = ctx->decoder_config.clock_class_offset_ns -
4468 (extra_s * INT64_C(1000000000));
4469
4470 BT_ASSERT(offset_ns >= 0);
4471 offset_ns_to_apply = (uint64_t) offset_ns;
4472 offset_s_to_apply += extra_s;
4473 }
4474
4475 freq = clock->frequency;
4476 cur_offset_s = clock->offset_seconds;
4477 cur_offset_cycles = clock->offset_cycles;
4478
4479 /* Apply offsets */
4480 cur_offset_s += offset_s_to_apply;
4481 cur_offset_cycles += cycles_from_ns(freq, offset_ns_to_apply);
4482
4483 /*
4484 * Recalibrate offsets because the part in cycles can be greater
4485 * than the frequency at this point.
4486 */
4487 calibrate_clock_class_offsets(&cur_offset_s, &cur_offset_cycles, freq);
4488
4489 /* Set final offsets */
4490 clock->offset_seconds = cur_offset_s;
4491 clock->offset_cycles = cur_offset_cycles;
4492
4493 end:
4494 return;
4495 }
4496
4497 static
4498 int visit_clock_decl(struct ctx *ctx, struct ctf_node *clock_node)
4499 {
4500 int ret = 0;
4501 int set = 0;
4502 struct ctf_clock_class *clock;
4503 struct ctf_node *entry_node;
4504 struct bt_list_head *decl_list = &clock_node->u.clock.declaration_list;
4505 const char *clock_class_name;
4506 int64_t offset_seconds = 0;
4507 uint64_t offset_cycles = 0;
4508 uint64_t freq;
4509
4510 if (clock_node->visited) {
4511 return 0;
4512 }
4513
4514 clock_node->visited = TRUE;
4515
4516 /* CTF 1.8's default frequency for a clock class is 1 GHz */
4517 clock = ctf_clock_class_create();
4518 if (!clock) {
4519 _BT_COMP_LOGE_NODE(clock_node,
4520 "Cannot create default clock class.");
4521 ret = -ENOMEM;
4522 goto end;
4523 }
4524
4525 bt_list_for_each_entry(entry_node, decl_list, siblings) {
4526 ret = visit_clock_decl_entry(ctx, entry_node, clock, &set,
4527 &offset_seconds, &offset_cycles);
4528 if (ret) {
4529 _BT_COMP_LOGE_NODE(entry_node,
4530 "Cannot visit clock class's entry: ret=%d",
4531 ret);
4532 goto end;
4533 }
4534 }
4535
4536 if (!_IS_SET(&set, _CLOCK_NAME_SET)) {
4537 _BT_COMP_LOGE_NODE(clock_node,
4538 "Missing `name` attribute in clock class.");
4539 ret = -EPERM;
4540 goto end;
4541 }
4542
4543 clock_class_name = clock->name->str;
4544 BT_ASSERT(clock_class_name);
4545 if (ctx->is_lttng && strcmp(clock_class_name, "monotonic") == 0) {
4546 /*
4547 * Old versions of LTTng forgot to set its clock class
4548 * as absolute, even if it is. This is important because
4549 * it's a condition to be able to sort messages
4550 * from different sources.
4551 */
4552 clock->is_absolute = true;
4553 }
4554
4555 /*
4556 * Adjust offsets so that the part in cycles is less than the
4557 * frequency (move to the part in seconds).
4558 */
4559 freq = clock->frequency;
4560 calibrate_clock_class_offsets(&offset_seconds, &offset_cycles, freq);
4561 BT_ASSERT(offset_cycles < clock->frequency);
4562 clock->offset_seconds = offset_seconds;
4563 clock->offset_cycles = offset_cycles;
4564 apply_clock_class_offset(ctx, clock);
4565 apply_clock_class_is_absolute(ctx, clock);
4566 g_ptr_array_add(ctx->ctf_tc->clock_classes, clock);
4567 clock = NULL;
4568
4569 end:
4570 if (clock) {
4571 ctf_clock_class_destroy(clock);
4572 }
4573
4574 return ret;
4575 }
4576
4577 static
4578 int visit_root_decl(struct ctx *ctx, struct ctf_node *root_decl_node)
4579 {
4580 int ret = 0;
4581
4582 if (root_decl_node->visited) {
4583 goto end;
4584 }
4585
4586 root_decl_node->visited = TRUE;
4587
4588 switch (root_decl_node->type) {
4589 case NODE_TYPEDEF:
4590 ret = visit_field_class_def(ctx,
4591 root_decl_node->u.field_class_def.field_class_specifier_list,
4592 &root_decl_node->u.field_class_def.field_class_declarators);
4593 if (ret) {
4594 _BT_COMP_LOGE_NODE(root_decl_node,
4595 "Cannot add field class found in root scope.");
4596 goto end;
4597 }
4598 break;
4599 case NODE_TYPEALIAS:
4600 ret = visit_field_class_alias(ctx, root_decl_node->u.field_class_alias.target,
4601 root_decl_node->u.field_class_alias.alias);
4602 if (ret) {
4603 _BT_COMP_LOGE_NODE(root_decl_node,
4604 "Cannot add field class alias found in root scope.");
4605 goto end;
4606 }
4607 break;
4608 case NODE_TYPE_SPECIFIER_LIST:
4609 {
4610 struct ctf_field_class *decl = NULL;
4611
4612 /*
4613 * Just add the field class specifier to the root
4614 * declaration scope. Put local reference.
4615 */
4616 ret = visit_field_class_specifier_list(ctx, root_decl_node, &decl);
4617 if (ret) {
4618 _BT_COMP_LOGE_NODE(root_decl_node,
4619 "Cannot visit root scope's field class: "
4620 "ret=%d", ret);
4621 BT_ASSERT(!decl);
4622 goto end;
4623 }
4624
4625 ctf_field_class_destroy(decl);
4626 decl = NULL;
4627 break;
4628 }
4629 default:
4630 _BT_COMP_LOGE_NODE(root_decl_node,
4631 "Unexpected node type: node-type=%d",
4632 root_decl_node->type);
4633 ret = -EPERM;
4634 goto end;
4635 }
4636
4637 end:
4638 return ret;
4639 }
4640
4641 BT_HIDDEN
4642 struct ctf_visitor_generate_ir *ctf_visitor_generate_ir_create(
4643 const struct ctf_metadata_decoder_config *decoder_config)
4644 {
4645 struct ctx *ctx = NULL;
4646
4647 /* Create visitor's context */
4648 ctx = ctx_create(decoder_config);
4649 if (!ctx) {
4650 BT_COMP_LOG_CUR_LVL(BT_LOG_ERROR, decoder_config->log_level,
4651 decoder_config->self_comp,
4652 "Cannot create visitor's context.");
4653 goto error;
4654 }
4655
4656 goto end;
4657
4658 error:
4659 ctx_destroy(ctx);
4660 ctx = NULL;
4661
4662 end:
4663 return (void *) ctx;
4664 }
4665
4666 BT_HIDDEN
4667 void ctf_visitor_generate_ir_destroy(struct ctf_visitor_generate_ir *visitor)
4668 {
4669 ctx_destroy((void *) visitor);
4670 }
4671
4672 BT_HIDDEN
4673 bt_trace_class *ctf_visitor_generate_ir_get_ir_trace_class(
4674 struct ctf_visitor_generate_ir *visitor)
4675 {
4676 struct ctx *ctx = (void *) visitor;
4677
4678 BT_ASSERT_DBG(ctx);
4679
4680 if (ctx->trace_class) {
4681 bt_trace_class_get_ref(ctx->trace_class);
4682 }
4683
4684 return ctx->trace_class;
4685 }
4686
4687 BT_HIDDEN
4688 struct ctf_trace_class *ctf_visitor_generate_ir_borrow_ctf_trace_class(
4689 struct ctf_visitor_generate_ir *visitor)
4690 {
4691 struct ctx *ctx = (void *) visitor;
4692
4693 BT_ASSERT_DBG(ctx);
4694 BT_ASSERT_DBG(ctx->ctf_tc);
4695 return ctx->ctf_tc;
4696 }
4697
4698 BT_HIDDEN
4699 int ctf_visitor_generate_ir_visit_node(struct ctf_visitor_generate_ir *visitor,
4700 struct ctf_node *node)
4701 {
4702 int ret = 0;
4703 struct ctx *ctx = (void *) visitor;
4704
4705 BT_COMP_LOGI_STR("Visiting metadata's AST to generate CTF IR objects.");
4706
4707 switch (node->type) {
4708 case NODE_ROOT:
4709 {
4710 struct ctf_node *iter;
4711 bool got_trace_decl = false;
4712
4713 /*
4714 * The first thing we need is the native byte order of
4715 * the trace block, because early class aliases can have
4716 * a `byte_order` attribute set to `native`. If we don't
4717 * have the native byte order yet, and we don't have any
4718 * trace block yet, then fail with EINCOMPLETE.
4719 */
4720 if (ctx->ctf_tc->default_byte_order == CTF_BYTE_ORDER_UNKNOWN) {
4721 bt_list_for_each_entry(iter, &node->u.root.trace, siblings) {
4722 if (got_trace_decl) {
4723 _BT_COMP_LOGE_NODE(node,
4724 "Duplicate trace (`trace` block).");
4725 ret = -1;
4726 goto end;
4727 }
4728
4729 ret = set_trace_byte_order(ctx, iter);
4730 if (ret) {
4731 _BT_COMP_LOGE_NODE(node,
4732 "Cannot set trace's native byte order: "
4733 "ret=%d", ret);
4734 goto end;
4735 }
4736
4737 got_trace_decl = true;
4738 }
4739
4740 if (!got_trace_decl) {
4741 BT_COMP_LOGD_STR("Incomplete AST: need trace (`trace` block).");
4742 ret = -EINCOMPLETE;
4743 goto end;
4744 }
4745 }
4746
4747 BT_ASSERT(ctx->ctf_tc->default_byte_order == CTF_BYTE_ORDER_LITTLE ||
4748 ctx->ctf_tc->default_byte_order == CTF_BYTE_ORDER_BIG);
4749 BT_ASSERT(ctx->current_scope &&
4750 !ctx->current_scope->parent_scope);
4751
4752 /* Environment */
4753 bt_list_for_each_entry(iter, &node->u.root.env, siblings) {
4754 ret = visit_env(ctx, iter);
4755 if (ret) {
4756 _BT_COMP_LOGE_NODE(iter,
4757 "Cannot visit trace's environment (`env` block) entry: "
4758 "ret=%d", ret);
4759 goto end;
4760 }
4761 }
4762
4763 BT_ASSERT(ctx->current_scope &&
4764 !ctx->current_scope->parent_scope);
4765
4766 /*
4767 * Visit clock blocks.
4768 */
4769 bt_list_for_each_entry(iter, &node->u.root.clock, siblings) {
4770 ret = visit_clock_decl(ctx, iter);
4771 if (ret) {
4772 _BT_COMP_LOGE_NODE(iter,
4773 "Cannot visit clock class: ret=%d",
4774 ret);
4775 goto end;
4776 }
4777 }
4778
4779 BT_ASSERT(ctx->current_scope &&
4780 !ctx->current_scope->parent_scope);
4781
4782 /*
4783 * Visit root declarations next, as they can be used by any
4784 * following entity.
4785 */
4786 bt_list_for_each_entry(iter, &node->u.root.declaration_list,
4787 siblings) {
4788 ret = visit_root_decl(ctx, iter);
4789 if (ret) {
4790 _BT_COMP_LOGE_NODE(iter,
4791 "Cannot visit root entry: ret=%d",
4792 ret);
4793 goto end;
4794 }
4795 }
4796
4797 BT_ASSERT(ctx->current_scope &&
4798 !ctx->current_scope->parent_scope);
4799
4800 /* Callsite blocks are not supported */
4801 bt_list_for_each_entry(iter, &node->u.root.callsite, siblings) {
4802 _BT_COMP_LOGW_NODE(iter,
4803 "\"callsite\" blocks are not supported as of this version.");
4804 }
4805
4806 BT_ASSERT(ctx->current_scope &&
4807 !ctx->current_scope->parent_scope);
4808
4809 /* Trace */
4810 bt_list_for_each_entry(iter, &node->u.root.trace, siblings) {
4811 ret = visit_trace_decl(ctx, iter);
4812 if (ret) {
4813 _BT_COMP_LOGE_NODE(iter,
4814 "Cannot visit trace (`trace` block): "
4815 "ret=%d", ret);
4816 goto end;
4817 }
4818 }
4819
4820 BT_ASSERT(ctx->current_scope &&
4821 !ctx->current_scope->parent_scope);
4822
4823 /* Streams */
4824 bt_list_for_each_entry(iter, &node->u.root.stream, siblings) {
4825 ret = visit_stream_decl(ctx, iter);
4826 if (ret) {
4827 _BT_COMP_LOGE_NODE(iter,
4828 "Cannot visit stream class: ret=%d",
4829 ret);
4830 goto end;
4831 }
4832 }
4833
4834 BT_ASSERT(ctx->current_scope &&
4835 !ctx->current_scope->parent_scope);
4836
4837 /* Events */
4838 bt_list_for_each_entry(iter, &node->u.root.event, siblings) {
4839 ret = visit_event_decl(ctx, iter);
4840 if (ret) {
4841 _BT_COMP_LOGE_NODE(iter,
4842 "Cannot visit event class: ret=%d",
4843 ret);
4844 goto end;
4845 }
4846 }
4847
4848 BT_ASSERT(ctx->current_scope &&
4849 !ctx->current_scope->parent_scope);
4850 break;
4851 }
4852 default:
4853 _BT_COMP_LOGE_NODE(node,
4854 "Unexpected node type: node-type=%d",
4855 node->type);
4856 ret = -EINVAL;
4857 goto end;
4858 }
4859
4860 /* Update default clock classes */
4861 ret = ctf_trace_class_update_default_clock_classes(ctx->ctf_tc,
4862 &ctx->log_cfg);
4863 if (ret) {
4864 ret = -EINVAL;
4865 goto end;
4866 }
4867
4868 /* Update trace class meanings */
4869 ret = ctf_trace_class_update_meanings(ctx->ctf_tc);
4870 if (ret) {
4871 ret = -EINVAL;
4872 goto end;
4873 }
4874
4875 /* Update stream class configuration */
4876 ret = ctf_trace_class_update_stream_class_config(ctx->ctf_tc);
4877 if (ret) {
4878 ret = -EINVAL;
4879 goto end;
4880 }
4881
4882 /* Update text arrays and sequences */
4883 ret = ctf_trace_class_update_text_array_sequence(ctx->ctf_tc);
4884 if (ret) {
4885 ret = -EINVAL;
4886 goto end;
4887 }
4888
4889 /* Resolve sequence lengths and variant tags */
4890 ret = ctf_trace_class_resolve_field_classes(ctx->ctf_tc, &ctx->log_cfg);
4891 if (ret) {
4892 ret = -EINVAL;
4893 goto end;
4894 }
4895
4896 if (ctx->trace_class) {
4897 /*
4898 * Update "in IR" for field classes.
4899 *
4900 * If we have no IR trace class, then we'll have no way
4901 * to create IR fields anyway, so we leave all the
4902 * `in_ir` members false.
4903 */
4904 ret = ctf_trace_class_update_in_ir(ctx->ctf_tc);
4905 if (ret) {
4906 ret = -EINVAL;
4907 goto end;
4908 }
4909 }
4910
4911 /* Update saved value indexes */
4912 ret = ctf_trace_class_update_value_storing_indexes(ctx->ctf_tc);
4913 if (ret) {
4914 ret = -EINVAL;
4915 goto end;
4916 }
4917
4918 /* Validate what we have so far */
4919 ret = ctf_trace_class_validate(ctx->ctf_tc, &ctx->log_cfg);
4920 if (ret) {
4921 ret = -EINVAL;
4922 goto end;
4923 }
4924
4925 /*
4926 * If there are fields which are not related to the CTF format
4927 * itself in the packet header and in event header field
4928 * classes, warn about it because they are never translated.
4929 */
4930 ctf_trace_class_warn_meaningless_header_fields(ctx->ctf_tc,
4931 &ctx->log_cfg);
4932
4933 if (ctx->trace_class) {
4934 /* Copy new CTF metadata -> new IR metadata */
4935 ret = ctf_trace_class_translate(ctx->log_cfg.self_comp,
4936 ctx->trace_class, ctx->ctf_tc);
4937 if (ret) {
4938 ret = -EINVAL;
4939 goto end;
4940 }
4941 }
4942
4943 end:
4944 return ret;
4945 }
This page took 0.231168 seconds and 5 git commands to generate.