Cleanup: fix cppcheck warning
[babeltrace.git] / formats / ctf / metadata / ctf-visitor-generate-io-struct.c
1 /*
2 * ctf-visitor-generate-io-struct.c
3 *
4 * Common Trace Format Metadata Visitor (generate I/O structures).
5 *
6 * Copyright 2010 - Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
7 *
8 * Permission is hereby granted, free of charge, to any person obtaining a copy
9 * of this software and associated documentation files (the "Software"), to deal
10 * in the Software without restriction, including without limitation the rights
11 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12 * copies of the Software, and to permit persons to whom the Software is
13 * furnished to do so, subject to the following conditions:
14 *
15 * The above copyright notice and this permission notice shall be included in
16 * all copies or substantial portions of the Software.
17 */
18
19 #include <stdio.h>
20 #include <unistd.h>
21 #include <string.h>
22 #include <stdlib.h>
23 #include <assert.h>
24 #include <glib.h>
25 #include <inttypes.h>
26 #include <errno.h>
27 #include <babeltrace/babeltrace-internal.h>
28 #include <babeltrace/list.h>
29 #include <babeltrace/types.h>
30 #include <babeltrace/ctf/metadata.h>
31 #include <babeltrace/uuid.h>
32 #include <babeltrace/endian.h>
33 #include <babeltrace/ctf/events-internal.h>
34 #include "ctf-scanner.h"
35 #include "ctf-parser.h"
36 #include "ctf-ast.h"
37
38 #define fprintf_dbg(fd, fmt, args...) fprintf(fd, "%s: " fmt, __func__, ## args)
39
40 #define _bt_list_first_entry(ptr, type, member) \
41 bt_list_entry((ptr)->next, type, member)
42
43 struct last_enum_value {
44 union {
45 int64_t s;
46 uint64_t u;
47 } u;
48 };
49
50 int opt_clock_force_correlate;
51
52 static
53 struct declaration *ctf_type_specifier_list_visit(FILE *fd,
54 int depth, struct ctf_node *type_specifier_list,
55 struct declaration_scope *declaration_scope,
56 struct ctf_trace *trace);
57
58 static
59 int ctf_stream_visit(FILE *fd, int depth, struct ctf_node *node,
60 struct declaration_scope *parent_declaration_scope, struct ctf_trace *trace);
61
62 static
63 int is_unary_string(struct bt_list_head *head)
64 {
65 struct ctf_node *node;
66
67 bt_list_for_each_entry(node, head, siblings) {
68 if (node->type != NODE_UNARY_EXPRESSION)
69 return 0;
70 if (node->u.unary_expression.type != UNARY_STRING)
71 return 0;
72 }
73 return 1;
74 }
75
76 /*
77 * String returned must be freed by the caller using g_free.
78 */
79 static
80 char *concatenate_unary_strings(struct bt_list_head *head)
81 {
82 struct ctf_node *node;
83 GString *str;
84 int i = 0;
85
86 str = g_string_new("");
87 bt_list_for_each_entry(node, head, siblings) {
88 char *src_string;
89
90 assert(node->type == NODE_UNARY_EXPRESSION);
91 assert(node->u.unary_expression.type == UNARY_STRING);
92 assert((node->u.unary_expression.link == UNARY_LINK_UNKNOWN)
93 ^ (i != 0));
94 switch (node->u.unary_expression.link) {
95 case UNARY_DOTLINK:
96 g_string_append(str, ".");
97 break;
98 case UNARY_ARROWLINK:
99 g_string_append(str, "->");
100 break;
101 case UNARY_DOTDOTDOT:
102 g_string_append(str, "...");
103 break;
104 default:
105 break;
106 }
107 src_string = node->u.unary_expression.u.string;
108 g_string_append(str, src_string);
109 i++;
110 }
111 return g_string_free(str, FALSE);
112 }
113
114 static
115 GQuark get_map_clock_name_value(struct bt_list_head *head)
116 {
117 struct ctf_node *node;
118 const char *name = NULL;
119 int i = 0;
120
121 bt_list_for_each_entry(node, head, siblings) {
122 char *src_string;
123
124 assert(node->type == NODE_UNARY_EXPRESSION);
125 assert(node->u.unary_expression.type == UNARY_STRING);
126 assert((node->u.unary_expression.link == UNARY_LINK_UNKNOWN)
127 ^ (i != 0));
128 /* needs to be chained with . */
129 switch (node->u.unary_expression.link) {
130 case UNARY_DOTLINK:
131 break;
132 case UNARY_ARROWLINK:
133 case UNARY_DOTDOTDOT:
134 return 0;
135 default:
136 break;
137 }
138 src_string = node->u.unary_expression.u.string;
139 switch (i) {
140 case 0: if (strcmp("clock", src_string) != 0) {
141 return 0;
142 }
143 break;
144 case 1: name = src_string;
145 break;
146 case 2: if (strcmp("value", src_string) != 0) {
147 return 0;
148 }
149 break;
150 default:
151 return 0; /* extra identifier, unknown */
152 }
153 i++;
154 }
155 return g_quark_from_string(name);
156 }
157
158 static
159 int is_unary_unsigned(struct bt_list_head *head)
160 {
161 struct ctf_node *node;
162
163 bt_list_for_each_entry(node, head, siblings) {
164 if (node->type != NODE_UNARY_EXPRESSION)
165 return 0;
166 if (node->u.unary_expression.type != UNARY_UNSIGNED_CONSTANT)
167 return 0;
168 }
169 return 1;
170 }
171
172 static
173 int get_unary_unsigned(struct bt_list_head *head, uint64_t *value)
174 {
175 struct ctf_node *node;
176 int i = 0;
177
178 bt_list_for_each_entry(node, head, siblings) {
179 assert(node->type == NODE_UNARY_EXPRESSION);
180 assert(node->u.unary_expression.type == UNARY_UNSIGNED_CONSTANT);
181 assert(node->u.unary_expression.link == UNARY_LINK_UNKNOWN);
182 assert(i == 0);
183 *value = node->u.unary_expression.u.unsigned_constant;
184 i++;
185 }
186 return 0;
187 }
188
189 static
190 int is_unary_signed(struct bt_list_head *head)
191 {
192 struct ctf_node *node;
193
194 bt_list_for_each_entry(node, head, siblings) {
195 if (node->type != NODE_UNARY_EXPRESSION)
196 return 0;
197 if (node->u.unary_expression.type != UNARY_SIGNED_CONSTANT)
198 return 0;
199 }
200 return 1;
201 }
202
203 static
204 int get_unary_signed(struct bt_list_head *head, int64_t *value)
205 {
206 struct ctf_node *node;
207 int i = 0;
208
209 bt_list_for_each_entry(node, head, siblings) {
210 assert(node->type == NODE_UNARY_EXPRESSION);
211 assert(node->u.unary_expression.type == UNARY_UNSIGNED_CONSTANT
212 || node->u.unary_expression.type == UNARY_SIGNED_CONSTANT);
213 assert(node->u.unary_expression.link == UNARY_LINK_UNKNOWN);
214 assert(i == 0);
215 switch (node->u.unary_expression.type) {
216 case UNARY_UNSIGNED_CONSTANT:
217 *value = (int64_t) node->u.unary_expression.u.unsigned_constant;
218 break;
219 case UNARY_SIGNED_CONSTANT:
220 *value = node->u.unary_expression.u.signed_constant;
221 break;
222 default:
223 assert(0);
224 }
225 i++;
226 }
227 return 0;
228 }
229
230 static
231 int get_unary_uuid(struct bt_list_head *head, unsigned char *uuid)
232 {
233 struct ctf_node *node;
234 int i = 0;
235 int ret = -1;
236
237 bt_list_for_each_entry(node, head, siblings) {
238 const char *src_string;
239
240 assert(node->type == NODE_UNARY_EXPRESSION);
241 assert(node->u.unary_expression.type == UNARY_STRING);
242 assert(node->u.unary_expression.link == UNARY_LINK_UNKNOWN);
243 assert(i == 0);
244 src_string = node->u.unary_expression.u.string;
245 ret = babeltrace_uuid_parse(src_string, uuid);
246 }
247 return ret;
248 }
249
250 static
251 struct ctf_stream_declaration *trace_stream_lookup(struct ctf_trace *trace, uint64_t stream_id)
252 {
253 if (trace->streams->len <= stream_id)
254 return NULL;
255 return g_ptr_array_index(trace->streams, stream_id);
256 }
257
258 static
259 struct ctf_clock *trace_clock_lookup(struct ctf_trace *trace, GQuark clock_name)
260 {
261 return g_hash_table_lookup(trace->clocks, (gpointer) (unsigned long) clock_name);
262 }
263
264 static
265 int visit_type_specifier(FILE *fd, struct ctf_node *type_specifier, GString *str)
266 {
267 assert(type_specifier->type == NODE_TYPE_SPECIFIER);
268
269 switch (type_specifier->u.type_specifier.type) {
270 case TYPESPEC_VOID:
271 g_string_append(str, "void");
272 break;
273 case TYPESPEC_CHAR:
274 g_string_append(str, "char");
275 break;
276 case TYPESPEC_SHORT:
277 g_string_append(str, "short");
278 break;
279 case TYPESPEC_INT:
280 g_string_append(str, "int");
281 break;
282 case TYPESPEC_LONG:
283 g_string_append(str, "long");
284 break;
285 case TYPESPEC_FLOAT:
286 g_string_append(str, "float");
287 break;
288 case TYPESPEC_DOUBLE:
289 g_string_append(str, "double");
290 break;
291 case TYPESPEC_SIGNED:
292 g_string_append(str, "signed");
293 break;
294 case TYPESPEC_UNSIGNED:
295 g_string_append(str, "unsigned");
296 break;
297 case TYPESPEC_BOOL:
298 g_string_append(str, "bool");
299 break;
300 case TYPESPEC_COMPLEX:
301 g_string_append(str, "_Complex");
302 break;
303 case TYPESPEC_IMAGINARY:
304 g_string_append(str, "_Imaginary");
305 break;
306 case TYPESPEC_CONST:
307 g_string_append(str, "const");
308 break;
309 case TYPESPEC_ID_TYPE:
310 if (type_specifier->u.type_specifier.id_type)
311 g_string_append(str, type_specifier->u.type_specifier.id_type);
312 break;
313 case TYPESPEC_STRUCT:
314 {
315 struct ctf_node *node = type_specifier->u.type_specifier.node;
316
317 if (!node->u._struct.name) {
318 fprintf(fd, "[error] %s: unexpected empty variant name\n", __func__);
319 return -EINVAL;
320 }
321 g_string_append(str, "struct ");
322 g_string_append(str, node->u._struct.name);
323 break;
324 }
325 case TYPESPEC_VARIANT:
326 {
327 struct ctf_node *node = type_specifier->u.type_specifier.node;
328
329 if (!node->u.variant.name) {
330 fprintf(fd, "[error] %s: unexpected empty variant name\n", __func__);
331 return -EINVAL;
332 }
333 g_string_append(str, "variant ");
334 g_string_append(str, node->u.variant.name);
335 break;
336 }
337 case TYPESPEC_ENUM:
338 {
339 struct ctf_node *node = type_specifier->u.type_specifier.node;
340
341 if (!node->u._enum.enum_id) {
342 fprintf(fd, "[error] %s: unexpected empty enum ID\n", __func__);
343 return -EINVAL;
344 }
345 g_string_append(str, "enum ");
346 g_string_append(str, node->u._enum.enum_id);
347 break;
348 }
349 case TYPESPEC_FLOATING_POINT:
350 case TYPESPEC_INTEGER:
351 case TYPESPEC_STRING:
352 default:
353 fprintf(fd, "[error] %s: unknown specifier\n", __func__);
354 return -EINVAL;
355 }
356 return 0;
357 }
358
359 static
360 int visit_type_specifier_list(FILE *fd, struct ctf_node *type_specifier_list, GString *str)
361 {
362 struct ctf_node *iter;
363 int alias_item_nr = 0;
364 int ret;
365
366 bt_list_for_each_entry(iter, &type_specifier_list->u.type_specifier_list.head, siblings) {
367 if (alias_item_nr != 0)
368 g_string_append(str, " ");
369 alias_item_nr++;
370 ret = visit_type_specifier(fd, iter, str);
371 if (ret)
372 return ret;
373 }
374 return 0;
375 }
376
377 static
378 GQuark create_typealias_identifier(FILE *fd, int depth,
379 struct ctf_node *type_specifier_list,
380 struct ctf_node *node_type_declarator)
381 {
382 struct ctf_node *iter;
383 GString *str;
384 char *str_c;
385 GQuark alias_q;
386 int ret;
387
388 str = g_string_new("");
389 ret = visit_type_specifier_list(fd, type_specifier_list, str);
390 if (ret) {
391 g_string_free(str, TRUE);
392 return 0;
393 }
394 bt_list_for_each_entry(iter, &node_type_declarator->u.type_declarator.pointers, siblings) {
395 g_string_append(str, " *");
396 if (iter->u.pointer.const_qualifier)
397 g_string_append(str, " const");
398 }
399 str_c = g_string_free(str, FALSE);
400 alias_q = g_quark_from_string(str_c);
401 g_free(str_c);
402 return alias_q;
403 }
404
405 static
406 struct declaration *ctf_type_declarator_visit(FILE *fd, int depth,
407 struct ctf_node *type_specifier_list,
408 GQuark *field_name,
409 struct ctf_node *node_type_declarator,
410 struct declaration_scope *declaration_scope,
411 struct declaration *nested_declaration,
412 struct ctf_trace *trace)
413 {
414 /*
415 * Visit type declarator by first taking care of sequence/array
416 * (recursively). Then, when we get to the identifier, take care
417 * of pointers.
418 */
419
420 if (node_type_declarator) {
421 assert(node_type_declarator->u.type_declarator.type != TYPEDEC_UNKNOWN);
422
423 /* TODO: gcc bitfields not supported yet. */
424 if (node_type_declarator->u.type_declarator.bitfield_len != NULL) {
425 fprintf(fd, "[error] %s: gcc bitfields are not supported yet.\n", __func__);
426 return NULL;
427 }
428 }
429
430 if (!nested_declaration) {
431 if (node_type_declarator && !bt_list_empty(&node_type_declarator->u.type_declarator.pointers)) {
432 GQuark alias_q;
433
434 /*
435 * If we have a pointer declarator, it _has_ to be present in
436 * the typealiases (else fail).
437 */
438 alias_q = create_typealias_identifier(fd, depth,
439 type_specifier_list, node_type_declarator);
440 nested_declaration = lookup_declaration(alias_q, declaration_scope);
441 if (!nested_declaration) {
442 fprintf(fd, "[error] %s: cannot find typealias \"%s\".\n", __func__, g_quark_to_string(alias_q));
443 return NULL;
444 }
445 if (nested_declaration->id == CTF_TYPE_INTEGER) {
446 struct declaration_integer *integer_declaration =
447 container_of(nested_declaration, struct declaration_integer, p);
448 /* For base to 16 for pointers (expected pretty-print) */
449 if (!integer_declaration->base) {
450 /*
451 * We need to do a copy of the
452 * integer declaration to modify it. There could be other references to
453 * it.
454 */
455 integer_declaration = integer_declaration_new(integer_declaration->len,
456 integer_declaration->byte_order, integer_declaration->signedness,
457 integer_declaration->p.alignment, 16, integer_declaration->encoding,
458 integer_declaration->clock);
459 nested_declaration = &integer_declaration->p;
460 }
461 }
462 } else {
463 nested_declaration = ctf_type_specifier_list_visit(fd, depth,
464 type_specifier_list, declaration_scope, trace);
465 }
466 }
467
468 if (!node_type_declarator)
469 return nested_declaration;
470
471 if (node_type_declarator->u.type_declarator.type == TYPEDEC_ID) {
472 if (node_type_declarator->u.type_declarator.u.id)
473 *field_name = g_quark_from_string(node_type_declarator->u.type_declarator.u.id);
474 else
475 *field_name = 0;
476 return nested_declaration;
477 } else {
478 struct declaration *declaration;
479 struct ctf_node *first;
480
481 /* TYPEDEC_NESTED */
482
483 if (!nested_declaration) {
484 fprintf(fd, "[error] %s: nested type is unknown.\n", __func__);
485 return NULL;
486 }
487
488 /* create array/sequence, pass nested_declaration as child. */
489 if (bt_list_empty(&node_type_declarator->u.type_declarator.u.nested.length)) {
490 fprintf(fd, "[error] %s: expecting length field reference or value.\n", __func__);
491 return NULL;
492 }
493 first = _bt_list_first_entry(&node_type_declarator->u.type_declarator.u.nested.length,
494 struct ctf_node, siblings);
495 assert(first->type == NODE_UNARY_EXPRESSION);
496
497 switch (first->u.unary_expression.type) {
498 case UNARY_UNSIGNED_CONSTANT:
499 {
500 struct declaration_array *array_declaration;
501 size_t len;
502
503 len = first->u.unary_expression.u.unsigned_constant;
504 array_declaration = array_declaration_new(len, nested_declaration,
505 declaration_scope);
506
507 if (!array_declaration) {
508 fprintf(fd, "[error] %s: cannot create array declaration.\n", __func__);
509 return NULL;
510 }
511 declaration_unref(nested_declaration);
512 declaration = &array_declaration->p;
513 break;
514 }
515 case UNARY_STRING:
516 {
517 /* Lookup unsigned integer definition, create sequence */
518 char *length_name = concatenate_unary_strings(&node_type_declarator->u.type_declarator.u.nested.length);
519 struct declaration_sequence *sequence_declaration;
520
521 sequence_declaration = sequence_declaration_new(length_name, nested_declaration, declaration_scope);
522 if (!sequence_declaration) {
523 fprintf(fd, "[error] %s: cannot create sequence declaration.\n", __func__);
524 g_free(length_name);
525 return NULL;
526 }
527 declaration_unref(nested_declaration);
528 declaration = &sequence_declaration->p;
529 g_free(length_name);
530 break;
531 }
532 default:
533 assert(0);
534 }
535
536 /* Pass it as content of outer container */
537 declaration = ctf_type_declarator_visit(fd, depth,
538 type_specifier_list, field_name,
539 node_type_declarator->u.type_declarator.u.nested.type_declarator,
540 declaration_scope, declaration, trace);
541 return declaration;
542 }
543 }
544
545 static
546 int ctf_struct_type_declarators_visit(FILE *fd, int depth,
547 struct declaration_struct *struct_declaration,
548 struct ctf_node *type_specifier_list,
549 struct bt_list_head *type_declarators,
550 struct declaration_scope *declaration_scope,
551 struct ctf_trace *trace)
552 {
553 struct ctf_node *iter;
554 GQuark field_name;
555
556 bt_list_for_each_entry(iter, type_declarators, siblings) {
557 struct declaration *field_declaration;
558
559 field_declaration = ctf_type_declarator_visit(fd, depth,
560 type_specifier_list,
561 &field_name, iter,
562 struct_declaration->scope,
563 NULL, trace);
564 if (!field_declaration) {
565 fprintf(fd, "[error] %s: unable to find struct field declaration type\n", __func__);
566 return -EINVAL;
567 }
568
569 /* Check if field with same name already exists */
570 if (struct_declaration_lookup_field_index(struct_declaration, field_name) >= 0) {
571 fprintf(fd, "[error] %s: duplicate field %s in struct\n", __func__, g_quark_to_string(field_name));
572 return -EINVAL;
573 }
574
575 struct_declaration_add_field(struct_declaration,
576 g_quark_to_string(field_name),
577 field_declaration);
578 declaration_unref(field_declaration);
579 }
580 return 0;
581 }
582
583 static
584 int ctf_variant_type_declarators_visit(FILE *fd, int depth,
585 struct declaration_untagged_variant *untagged_variant_declaration,
586 struct ctf_node *type_specifier_list,
587 struct bt_list_head *type_declarators,
588 struct declaration_scope *declaration_scope,
589 struct ctf_trace *trace)
590 {
591 struct ctf_node *iter;
592 GQuark field_name;
593
594 bt_list_for_each_entry(iter, type_declarators, siblings) {
595 struct declaration *field_declaration;
596
597 field_declaration = ctf_type_declarator_visit(fd, depth,
598 type_specifier_list,
599 &field_name, iter,
600 untagged_variant_declaration->scope,
601 NULL, trace);
602 if (!field_declaration) {
603 fprintf(fd, "[error] %s: unable to find variant field declaration type\n", __func__);
604 return -EINVAL;
605 }
606
607 if (untagged_variant_declaration_get_field_from_tag(untagged_variant_declaration, field_name) != NULL) {
608 fprintf(fd, "[error] %s: duplicate field %s in variant\n", __func__, g_quark_to_string(field_name));
609 return -EINVAL;
610 }
611
612 untagged_variant_declaration_add_field(untagged_variant_declaration,
613 g_quark_to_string(field_name),
614 field_declaration);
615 declaration_unref(field_declaration);
616 }
617 return 0;
618 }
619
620 static
621 int ctf_typedef_visit(FILE *fd, int depth, struct declaration_scope *scope,
622 struct ctf_node *type_specifier_list,
623 struct bt_list_head *type_declarators,
624 struct ctf_trace *trace)
625 {
626 struct ctf_node *iter;
627 GQuark identifier;
628
629 bt_list_for_each_entry(iter, type_declarators, siblings) {
630 struct declaration *type_declaration;
631 int ret;
632
633 type_declaration = ctf_type_declarator_visit(fd, depth,
634 type_specifier_list,
635 &identifier, iter,
636 scope, NULL, trace);
637 if (!type_declaration) {
638 fprintf(fd, "[error] %s: problem creating type declaration\n", __func__);
639 return -EINVAL;
640 }
641 /*
642 * Don't allow typedef and typealias of untagged
643 * variants.
644 */
645 if (type_declaration->id == CTF_TYPE_UNTAGGED_VARIANT) {
646 fprintf(fd, "[error] %s: typedef of untagged variant is not permitted.\n", __func__);
647 declaration_unref(type_declaration);
648 return -EPERM;
649 }
650 ret = register_declaration(identifier, type_declaration, scope);
651 if (ret) {
652 type_declaration->declaration_free(type_declaration);
653 return ret;
654 }
655 declaration_unref(type_declaration);
656 }
657 return 0;
658 }
659
660 static
661 int ctf_typealias_visit(FILE *fd, int depth, struct declaration_scope *scope,
662 struct ctf_node *target, struct ctf_node *alias,
663 struct ctf_trace *trace)
664 {
665 struct declaration *type_declaration;
666 struct ctf_node *node;
667 GQuark dummy_id;
668 GQuark alias_q;
669 int err;
670
671 /* See ctf_visitor_type_declarator() in the semantic validator. */
672
673 /*
674 * Create target type declaration.
675 */
676
677 if (bt_list_empty(&target->u.typealias_target.type_declarators))
678 node = NULL;
679 else
680 node = _bt_list_first_entry(&target->u.typealias_target.type_declarators,
681 struct ctf_node, siblings);
682 type_declaration = ctf_type_declarator_visit(fd, depth,
683 target->u.typealias_target.type_specifier_list,
684 &dummy_id, node,
685 scope, NULL, trace);
686 if (!type_declaration) {
687 fprintf(fd, "[error] %s: problem creating type declaration\n", __func__);
688 err = -EINVAL;
689 goto error;
690 }
691 /*
692 * Don't allow typedef and typealias of untagged
693 * variants.
694 */
695 if (type_declaration->id == CTF_TYPE_UNTAGGED_VARIANT) {
696 fprintf(fd, "[error] %s: typedef of untagged variant is not permitted.\n", __func__);
697 declaration_unref(type_declaration);
698 return -EPERM;
699 }
700 /*
701 * The semantic validator does not check whether the target is
702 * abstract or not (if it has an identifier). Check it here.
703 */
704 if (dummy_id != 0) {
705 fprintf(fd, "[error] %s: expecting empty identifier\n", __func__);
706 err = -EINVAL;
707 goto error;
708 }
709 /*
710 * Create alias identifier.
711 */
712
713 node = _bt_list_first_entry(&alias->u.typealias_alias.type_declarators,
714 struct ctf_node, siblings);
715 alias_q = create_typealias_identifier(fd, depth,
716 alias->u.typealias_alias.type_specifier_list, node);
717 err = register_declaration(alias_q, type_declaration, scope);
718 if (err)
719 goto error;
720 declaration_unref(type_declaration);
721 return 0;
722
723 error:
724 if (type_declaration) {
725 type_declaration->declaration_free(type_declaration);
726 }
727 return err;
728 }
729
730 static
731 int ctf_struct_declaration_list_visit(FILE *fd, int depth,
732 struct ctf_node *iter, struct declaration_struct *struct_declaration,
733 struct ctf_trace *trace)
734 {
735 int ret;
736
737 switch (iter->type) {
738 case NODE_TYPEDEF:
739 /* For each declarator, declare type and add type to struct declaration scope */
740 ret = ctf_typedef_visit(fd, depth,
741 struct_declaration->scope,
742 iter->u._typedef.type_specifier_list,
743 &iter->u._typedef.type_declarators, trace);
744 if (ret)
745 return ret;
746 break;
747 case NODE_TYPEALIAS:
748 /* Declare type with declarator and add type to struct declaration scope */
749 ret = ctf_typealias_visit(fd, depth,
750 struct_declaration->scope,
751 iter->u.typealias.target,
752 iter->u.typealias.alias, trace);
753 if (ret)
754 return ret;
755 break;
756 case NODE_STRUCT_OR_VARIANT_DECLARATION:
757 /* Add field to structure declaration */
758 ret = ctf_struct_type_declarators_visit(fd, depth,
759 struct_declaration,
760 iter->u.struct_or_variant_declaration.type_specifier_list,
761 &iter->u.struct_or_variant_declaration.type_declarators,
762 struct_declaration->scope, trace);
763 if (ret)
764 return ret;
765 break;
766 default:
767 fprintf(fd, "[error] %s: unexpected node type %d\n", __func__, (int) iter->type);
768 assert(0);
769 }
770 return 0;
771 }
772
773 static
774 int ctf_variant_declaration_list_visit(FILE *fd, int depth,
775 struct ctf_node *iter,
776 struct declaration_untagged_variant *untagged_variant_declaration,
777 struct ctf_trace *trace)
778 {
779 int ret;
780
781 switch (iter->type) {
782 case NODE_TYPEDEF:
783 /* For each declarator, declare type and add type to variant declaration scope */
784 ret = ctf_typedef_visit(fd, depth,
785 untagged_variant_declaration->scope,
786 iter->u._typedef.type_specifier_list,
787 &iter->u._typedef.type_declarators, trace);
788 if (ret)
789 return ret;
790 break;
791 case NODE_TYPEALIAS:
792 /* Declare type with declarator and add type to variant declaration scope */
793 ret = ctf_typealias_visit(fd, depth,
794 untagged_variant_declaration->scope,
795 iter->u.typealias.target,
796 iter->u.typealias.alias, trace);
797 if (ret)
798 return ret;
799 break;
800 case NODE_STRUCT_OR_VARIANT_DECLARATION:
801 /* Add field to structure declaration */
802 ret = ctf_variant_type_declarators_visit(fd, depth,
803 untagged_variant_declaration,
804 iter->u.struct_or_variant_declaration.type_specifier_list,
805 &iter->u.struct_or_variant_declaration.type_declarators,
806 untagged_variant_declaration->scope, trace);
807 if (ret)
808 return ret;
809 break;
810 default:
811 fprintf(fd, "[error] %s: unexpected node type %d\n", __func__, (int) iter->type);
812 assert(0);
813 }
814 return 0;
815 }
816
817 static
818 struct declaration *ctf_declaration_struct_visit(FILE *fd,
819 int depth, const char *name, struct bt_list_head *declaration_list,
820 int has_body, struct bt_list_head *min_align,
821 struct declaration_scope *declaration_scope,
822 struct ctf_trace *trace)
823 {
824 struct declaration_struct *struct_declaration;
825 struct ctf_node *iter;
826
827 /*
828 * For named struct (without body), lookup in
829 * declaration scope. Don't take reference on struct
830 * declaration: ref is only taken upon definition.
831 */
832 if (!has_body) {
833 assert(name);
834 struct_declaration =
835 lookup_struct_declaration(g_quark_from_string(name),
836 declaration_scope);
837 declaration_ref(&struct_declaration->p);
838 return &struct_declaration->p;
839 } else {
840 uint64_t min_align_value = 0;
841
842 /* For unnamed struct, create type */
843 /* For named struct (with body), create type and add to declaration scope */
844 if (name) {
845 if (lookup_struct_declaration(g_quark_from_string(name),
846 declaration_scope)) {
847
848 fprintf(fd, "[error] %s: struct %s already declared in scope\n", __func__, name);
849 return NULL;
850 }
851 }
852 if (!bt_list_empty(min_align)) {
853 int ret;
854
855 ret = get_unary_unsigned(min_align, &min_align_value);
856 if (ret) {
857 fprintf(fd, "[error] %s: unexpected unary expression for structure \"align\" attribute\n", __func__);
858 ret = -EINVAL;
859 goto error;
860 }
861 }
862 struct_declaration = struct_declaration_new(declaration_scope,
863 min_align_value);
864 bt_list_for_each_entry(iter, declaration_list, siblings) {
865 int ret;
866
867 ret = ctf_struct_declaration_list_visit(fd, depth + 1, iter,
868 struct_declaration, trace);
869 if (ret)
870 goto error_free_declaration;
871 }
872 if (name) {
873 int ret;
874
875 ret = register_struct_declaration(g_quark_from_string(name),
876 struct_declaration,
877 declaration_scope);
878 assert(!ret);
879 }
880 return &struct_declaration->p;
881 }
882 error_free_declaration:
883 struct_declaration->p.declaration_free(&struct_declaration->p);
884 error:
885 return NULL;
886 }
887
888 static
889 struct declaration *ctf_declaration_variant_visit(FILE *fd,
890 int depth, const char *name, const char *choice,
891 struct bt_list_head *declaration_list,
892 int has_body, struct declaration_scope *declaration_scope,
893 struct ctf_trace *trace)
894 {
895 struct declaration_untagged_variant *untagged_variant_declaration;
896 struct declaration_variant *variant_declaration;
897 struct ctf_node *iter;
898
899 /*
900 * For named variant (without body), lookup in
901 * declaration scope. Don't take reference on variant
902 * declaration: ref is only taken upon definition.
903 */
904 if (!has_body) {
905 assert(name);
906 untagged_variant_declaration =
907 lookup_variant_declaration(g_quark_from_string(name),
908 declaration_scope);
909 declaration_ref(&untagged_variant_declaration->p);
910 } else {
911 /* For unnamed variant, create type */
912 /* For named variant (with body), create type and add to declaration scope */
913 if (name) {
914 if (lookup_variant_declaration(g_quark_from_string(name),
915 declaration_scope)) {
916
917 fprintf(fd, "[error] %s: variant %s already declared in scope\n", __func__, name);
918 return NULL;
919 }
920 }
921 untagged_variant_declaration = untagged_variant_declaration_new(declaration_scope);
922 bt_list_for_each_entry(iter, declaration_list, siblings) {
923 int ret;
924
925 ret = ctf_variant_declaration_list_visit(fd, depth + 1, iter,
926 untagged_variant_declaration, trace);
927 if (ret)
928 goto error;
929 }
930 if (name) {
931 int ret;
932
933 ret = register_variant_declaration(g_quark_from_string(name),
934 untagged_variant_declaration,
935 declaration_scope);
936 assert(!ret);
937 }
938 }
939 /*
940 * if tagged, create tagged variant and return. else return
941 * untagged variant.
942 */
943 if (!choice) {
944 return &untagged_variant_declaration->p;
945 } else {
946 variant_declaration = variant_declaration_new(untagged_variant_declaration, choice);
947 if (!variant_declaration)
948 goto error;
949 declaration_unref(&untagged_variant_declaration->p);
950 return &variant_declaration->p;
951 }
952 error:
953 untagged_variant_declaration->p.declaration_free(&untagged_variant_declaration->p);
954 return NULL;
955 }
956
957 static
958 int ctf_enumerator_list_visit(FILE *fd, int depth,
959 struct ctf_node *enumerator,
960 struct declaration_enum *enum_declaration,
961 struct last_enum_value *last)
962 {
963 GQuark q;
964 struct ctf_node *iter;
965
966 q = g_quark_from_string(enumerator->u.enumerator.id);
967 if (enum_declaration->integer_declaration->signedness) {
968 int64_t start, end;
969 int nr_vals = 0;
970
971 bt_list_for_each_entry(iter, &enumerator->u.enumerator.values, siblings) {
972 int64_t *target;
973
974 assert(iter->type == NODE_UNARY_EXPRESSION);
975 if (nr_vals == 0)
976 target = &start;
977 else
978 target = &end;
979
980 switch (iter->u.unary_expression.type) {
981 case UNARY_SIGNED_CONSTANT:
982 *target = iter->u.unary_expression.u.signed_constant;
983 break;
984 case UNARY_UNSIGNED_CONSTANT:
985 *target = iter->u.unary_expression.u.unsigned_constant;
986 break;
987 default:
988 fprintf(fd, "[error] %s: invalid enumerator\n", __func__);
989 return -EINVAL;
990 }
991 if (nr_vals > 1) {
992 fprintf(fd, "[error] %s: invalid enumerator\n", __func__);
993 return -EINVAL;
994 }
995 nr_vals++;
996 }
997 if (nr_vals == 0)
998 start = last->u.s;
999 if (nr_vals <= 1)
1000 end = start;
1001 last->u.s = end + 1;
1002 enum_signed_insert(enum_declaration, start, end, q);
1003 } else {
1004 uint64_t start, end;
1005 int nr_vals = 0;
1006
1007 bt_list_for_each_entry(iter, &enumerator->u.enumerator.values, siblings) {
1008 uint64_t *target;
1009
1010 assert(iter->type == NODE_UNARY_EXPRESSION);
1011 if (nr_vals == 0)
1012 target = &start;
1013 else
1014 target = &end;
1015
1016 switch (iter->u.unary_expression.type) {
1017 case UNARY_UNSIGNED_CONSTANT:
1018 *target = iter->u.unary_expression.u.unsigned_constant;
1019 break;
1020 case UNARY_SIGNED_CONSTANT:
1021 /*
1022 * We don't accept signed constants for enums with unsigned
1023 * container type.
1024 */
1025 fprintf(fd, "[error] %s: invalid enumerator (signed constant encountered, but enum container type is unsigned)\n", __func__);
1026 return -EINVAL;
1027 default:
1028 fprintf(fd, "[error] %s: invalid enumerator\n", __func__);
1029 return -EINVAL;
1030 }
1031 if (nr_vals > 1) {
1032 fprintf(fd, "[error] %s: invalid enumerator\n", __func__);
1033 return -EINVAL;
1034 }
1035 nr_vals++;
1036 }
1037 if (nr_vals == 0)
1038 start = last->u.u;
1039 if (nr_vals <= 1)
1040 end = start;
1041 last->u.u = end + 1;
1042 enum_unsigned_insert(enum_declaration, start, end, q);
1043 }
1044 return 0;
1045 }
1046
1047 static
1048 struct declaration *ctf_declaration_enum_visit(FILE *fd, int depth,
1049 const char *name,
1050 struct ctf_node *container_type,
1051 struct bt_list_head *enumerator_list,
1052 int has_body,
1053 struct declaration_scope *declaration_scope,
1054 struct ctf_trace *trace)
1055 {
1056 struct declaration *declaration;
1057 struct declaration_enum *enum_declaration;
1058 struct declaration_integer *integer_declaration;
1059 struct last_enum_value last_value;
1060 struct ctf_node *iter;
1061 GQuark dummy_id;
1062
1063 /*
1064 * For named enum (without body), lookup in
1065 * declaration scope. Don't take reference on enum
1066 * declaration: ref is only taken upon definition.
1067 */
1068 if (!has_body) {
1069 assert(name);
1070 enum_declaration =
1071 lookup_enum_declaration(g_quark_from_string(name),
1072 declaration_scope);
1073 declaration_ref(&enum_declaration->p);
1074 return &enum_declaration->p;
1075 } else {
1076 /* For unnamed enum, create type */
1077 /* For named enum (with body), create type and add to declaration scope */
1078 if (name) {
1079 if (lookup_enum_declaration(g_quark_from_string(name),
1080 declaration_scope)) {
1081
1082 fprintf(fd, "[error] %s: enum %s already declared in scope\n", __func__, name);
1083 return NULL;
1084 }
1085 }
1086 if (!container_type) {
1087 declaration = lookup_declaration(g_quark_from_static_string("int"),
1088 declaration_scope);
1089 if (!declaration) {
1090 fprintf(fd, "[error] %s: \"int\" type declaration missing for enumeration\n", __func__);
1091 return NULL;
1092 }
1093 } else {
1094 declaration = ctf_type_declarator_visit(fd, depth,
1095 container_type,
1096 &dummy_id, NULL,
1097 declaration_scope,
1098 NULL, trace);
1099 }
1100 if (!declaration) {
1101 fprintf(fd, "[error] %s: unable to create container type for enumeration\n", __func__);
1102 return NULL;
1103 }
1104 if (declaration->id != CTF_TYPE_INTEGER) {
1105 fprintf(fd, "[error] %s: container type for enumeration is not integer\n", __func__);
1106 return NULL;
1107 }
1108 integer_declaration = container_of(declaration, struct declaration_integer, p);
1109 enum_declaration = enum_declaration_new(integer_declaration);
1110 declaration_unref(&integer_declaration->p); /* leave ref to enum */
1111 if (enum_declaration->integer_declaration->signedness) {
1112 last_value.u.s = 0;
1113 } else {
1114 last_value.u.u = 0;
1115 }
1116 bt_list_for_each_entry(iter, enumerator_list, siblings) {
1117 int ret;
1118
1119 ret = ctf_enumerator_list_visit(fd, depth + 1, iter, enum_declaration,
1120 &last_value);
1121 if (ret)
1122 goto error;
1123 }
1124 if (name) {
1125 int ret;
1126
1127 ret = register_enum_declaration(g_quark_from_string(name),
1128 enum_declaration,
1129 declaration_scope);
1130 assert(!ret);
1131 declaration_unref(&enum_declaration->p);
1132 }
1133 return &enum_declaration->p;
1134 }
1135 error:
1136 enum_declaration->p.declaration_free(&enum_declaration->p);
1137 return NULL;
1138 }
1139
1140 static
1141 struct declaration *ctf_declaration_type_specifier_visit(FILE *fd, int depth,
1142 struct ctf_node *type_specifier_list,
1143 struct declaration_scope *declaration_scope)
1144 {
1145 GString *str;
1146 struct declaration *declaration;
1147 char *str_c;
1148 int ret;
1149 GQuark id_q;
1150
1151 str = g_string_new("");
1152 ret = visit_type_specifier_list(fd, type_specifier_list, str);
1153 if (ret)
1154 return NULL;
1155 str_c = g_string_free(str, FALSE);
1156 id_q = g_quark_from_string(str_c);
1157 g_free(str_c);
1158 declaration = lookup_declaration(id_q, declaration_scope);
1159 declaration_ref(declaration);
1160 return declaration;
1161 }
1162
1163 /*
1164 * Returns 0/1 boolean, or < 0 on error.
1165 */
1166 static
1167 int get_boolean(FILE *fd, int depth, struct ctf_node *unary_expression)
1168 {
1169 if (unary_expression->type != NODE_UNARY_EXPRESSION) {
1170 fprintf(fd, "[error] %s: expecting unary expression\n",
1171 __func__);
1172 return -EINVAL;
1173 }
1174 switch (unary_expression->u.unary_expression.type) {
1175 case UNARY_UNSIGNED_CONSTANT:
1176 if (unary_expression->u.unary_expression.u.unsigned_constant == 0)
1177 return 0;
1178 else
1179 return 1;
1180 case UNARY_SIGNED_CONSTANT:
1181 if (unary_expression->u.unary_expression.u.signed_constant == 0)
1182 return 0;
1183 else
1184 return 1;
1185 case UNARY_STRING:
1186 if (!strcmp(unary_expression->u.unary_expression.u.string, "true"))
1187 return 1;
1188 else if (!strcmp(unary_expression->u.unary_expression.u.string, "TRUE"))
1189 return 1;
1190 else if (!strcmp(unary_expression->u.unary_expression.u.string, "false"))
1191 return 0;
1192 else if (!strcmp(unary_expression->u.unary_expression.u.string, "FALSE"))
1193 return 0;
1194 else {
1195 fprintf(fd, "[error] %s: unexpected string \"%s\"\n",
1196 __func__, unary_expression->u.unary_expression.u.string);
1197 return -EINVAL;
1198 }
1199 break;
1200 default:
1201 fprintf(fd, "[error] %s: unexpected unary expression type\n",
1202 __func__);
1203 return -EINVAL;
1204 }
1205
1206 }
1207
1208 static
1209 int get_trace_byte_order(FILE *fd, int depth, struct ctf_node *unary_expression)
1210 {
1211 int byte_order;
1212
1213 if (unary_expression->u.unary_expression.type != UNARY_STRING) {
1214 fprintf(fd, "[error] %s: byte_order: expecting string\n",
1215 __func__);
1216 return -EINVAL;
1217 }
1218 if (!strcmp(unary_expression->u.unary_expression.u.string, "be"))
1219 byte_order = BIG_ENDIAN;
1220 else if (!strcmp(unary_expression->u.unary_expression.u.string, "le"))
1221 byte_order = LITTLE_ENDIAN;
1222 else {
1223 fprintf(fd, "[error] %s: unexpected string \"%s\". Should be \"native\", \"network\", \"be\" or \"le\".\n",
1224 __func__, unary_expression->u.unary_expression.u.string);
1225 return -EINVAL;
1226 }
1227 return byte_order;
1228 }
1229
1230 static
1231 int get_byte_order(FILE *fd, int depth, struct ctf_node *unary_expression,
1232 struct ctf_trace *trace)
1233 {
1234 int byte_order;
1235
1236 if (unary_expression->u.unary_expression.type != UNARY_STRING) {
1237 fprintf(fd, "[error] %s: byte_order: expecting string\n",
1238 __func__);
1239 return -EINVAL;
1240 }
1241 if (!strcmp(unary_expression->u.unary_expression.u.string, "native"))
1242 byte_order = trace->byte_order;
1243 else if (!strcmp(unary_expression->u.unary_expression.u.string, "network"))
1244 byte_order = BIG_ENDIAN;
1245 else if (!strcmp(unary_expression->u.unary_expression.u.string, "be"))
1246 byte_order = BIG_ENDIAN;
1247 else if (!strcmp(unary_expression->u.unary_expression.u.string, "le"))
1248 byte_order = LITTLE_ENDIAN;
1249 else {
1250 fprintf(fd, "[error] %s: unexpected string \"%s\". Should be \"native\", \"network\", \"be\" or \"le\".\n",
1251 __func__, unary_expression->u.unary_expression.u.string);
1252 return -EINVAL;
1253 }
1254 return byte_order;
1255 }
1256
1257 static
1258 struct declaration *ctf_declaration_integer_visit(FILE *fd, int depth,
1259 struct bt_list_head *expressions,
1260 struct ctf_trace *trace)
1261 {
1262 struct ctf_node *expression;
1263 uint64_t alignment = 1, size = 0;
1264 int byte_order = trace->byte_order;
1265 int signedness = 0;
1266 int has_alignment = 0, has_size = 0;
1267 int base = 0;
1268 enum ctf_string_encoding encoding = CTF_STRING_NONE;
1269 struct ctf_clock *clock = NULL;
1270 struct declaration_integer *integer_declaration;
1271
1272 bt_list_for_each_entry(expression, expressions, siblings) {
1273 struct ctf_node *left, *right;
1274
1275 left = _bt_list_first_entry(&expression->u.ctf_expression.left, struct ctf_node, siblings);
1276 right = _bt_list_first_entry(&expression->u.ctf_expression.right, struct ctf_node, siblings);
1277 assert(left->u.unary_expression.type == UNARY_STRING);
1278 if (!strcmp(left->u.unary_expression.u.string, "signed")) {
1279 signedness = get_boolean(fd, depth, right);
1280 if (signedness < 0)
1281 return NULL;
1282 } else if (!strcmp(left->u.unary_expression.u.string, "byte_order")) {
1283 byte_order = get_byte_order(fd, depth, right, trace);
1284 if (byte_order < 0)
1285 return NULL;
1286 } else if (!strcmp(left->u.unary_expression.u.string, "size")) {
1287 if (right->u.unary_expression.type != UNARY_UNSIGNED_CONSTANT) {
1288 fprintf(fd, "[error] %s: size: expecting unsigned constant\n",
1289 __func__);
1290 return NULL;
1291 }
1292 size = right->u.unary_expression.u.unsigned_constant;
1293 has_size = 1;
1294 } else if (!strcmp(left->u.unary_expression.u.string, "align")) {
1295 if (right->u.unary_expression.type != UNARY_UNSIGNED_CONSTANT) {
1296 fprintf(fd, "[error] %s: align: expecting unsigned constant\n",
1297 __func__);
1298 return NULL;
1299 }
1300 alignment = right->u.unary_expression.u.unsigned_constant;
1301 /* Make sure alignment is a power of two */
1302 if (alignment == 0 || (alignment & (alignment - 1)) != 0) {
1303 fprintf(fd, "[error] %s: align: expecting power of two\n",
1304 __func__);
1305 return NULL;
1306 }
1307 has_alignment = 1;
1308 } else if (!strcmp(left->u.unary_expression.u.string, "base")) {
1309 switch (right->u.unary_expression.type) {
1310 case UNARY_UNSIGNED_CONSTANT:
1311 switch (right->u.unary_expression.u.unsigned_constant) {
1312 case 2:
1313 case 8:
1314 case 10:
1315 case 16:
1316 base = right->u.unary_expression.u.unsigned_constant;
1317 break;
1318 default:
1319 fprintf(fd, "[error] %s: base not supported (%" PRIu64 ")\n",
1320 __func__, right->u.unary_expression.u.unsigned_constant);
1321 return NULL;
1322 }
1323 break;
1324 case UNARY_STRING:
1325 {
1326 char *s_right = concatenate_unary_strings(&expression->u.ctf_expression.right);
1327 if (!s_right) {
1328 fprintf(fd, "[error] %s: unexpected unary expression for integer base\n", __func__);
1329 g_free(s_right);
1330 return NULL;
1331 }
1332 if (!strcmp(s_right, "decimal") || !strcmp(s_right, "dec") || !strcmp(s_right, "d")
1333 || !strcmp(s_right, "i") || !strcmp(s_right, "u")) {
1334 base = 10;
1335 } else if (!strcmp(s_right, "hexadecimal") || !strcmp(s_right, "hex")
1336 || !strcmp(s_right, "x") || !strcmp(s_right, "X")
1337 || !strcmp(s_right, "p")) {
1338 base = 16;
1339 } else if (!strcmp(s_right, "octal") || !strcmp(s_right, "oct")
1340 || !strcmp(s_right, "o")) {
1341 base = 8;
1342 } else if (!strcmp(s_right, "binary") || !strcmp(s_right, "b")) {
1343 base = 2;
1344 } else {
1345 fprintf(fd, "[error] %s: unexpected expression for integer base (%s)\n", __func__, s_right);
1346 g_free(s_right);
1347 return NULL;
1348 }
1349
1350 g_free(s_right);
1351 break;
1352 }
1353 default:
1354 fprintf(fd, "[error] %s: base: expecting unsigned constant or unary string\n",
1355 __func__);
1356 return NULL;
1357 }
1358 } else if (!strcmp(left->u.unary_expression.u.string, "encoding")) {
1359 char *s_right;
1360
1361 if (right->u.unary_expression.type != UNARY_STRING) {
1362 fprintf(fd, "[error] %s: encoding: expecting unary string\n",
1363 __func__);
1364 return NULL;
1365 }
1366 s_right = concatenate_unary_strings(&expression->u.ctf_expression.right);
1367 if (!s_right) {
1368 fprintf(fd, "[error] %s: unexpected unary expression for integer base\n", __func__);
1369 g_free(s_right);
1370 return NULL;
1371 }
1372 if (!strcmp(s_right, "UTF8")
1373 || !strcmp(s_right, "utf8")
1374 || !strcmp(s_right, "utf-8")
1375 || !strcmp(s_right, "UTF-8"))
1376 encoding = CTF_STRING_UTF8;
1377 else if (!strcmp(s_right, "ASCII")
1378 || !strcmp(s_right, "ascii"))
1379 encoding = CTF_STRING_ASCII;
1380 else if (!strcmp(s_right, "none"))
1381 encoding = CTF_STRING_NONE;
1382 else {
1383 fprintf(fd, "[error] %s: unknown string encoding \"%s\"\n", __func__, s_right);
1384 g_free(s_right);
1385 return NULL;
1386 }
1387 g_free(s_right);
1388 } else if (!strcmp(left->u.unary_expression.u.string, "map")) {
1389 GQuark clock_name;
1390
1391 if (right->u.unary_expression.type != UNARY_STRING) {
1392 fprintf(fd, "[error] %s: map: expecting identifier\n",
1393 __func__);
1394 return NULL;
1395 }
1396 /* currently only support clock.name.value */
1397 clock_name = get_map_clock_name_value(&expression->u.ctf_expression.right);
1398 if (!clock_name) {
1399 char *s_right;
1400
1401 s_right = concatenate_unary_strings(&expression->u.ctf_expression.right);
1402 if (!s_right) {
1403 fprintf(fd, "[error] %s: unexpected unary expression for integer map\n", __func__);
1404 g_free(s_right);
1405 return NULL;
1406 }
1407 fprintf(fd, "[warning] %s: unknown map %s in integer declaration\n", __func__,
1408 s_right);
1409 g_free(s_right);
1410 continue;
1411 }
1412 clock = trace_clock_lookup(trace, clock_name);
1413 if (!clock) {
1414 fprintf(fd, "[error] %s: map: unable to find clock %s declaration\n",
1415 __func__, g_quark_to_string(clock_name));
1416 return NULL;
1417 }
1418 } else {
1419 fprintf(fd, "[warning] %s: unknown attribute name %s\n",
1420 __func__, left->u.unary_expression.u.string);
1421 /* Fall-through after warning */
1422 }
1423 }
1424 if (!has_size) {
1425 fprintf(fd, "[error] %s: missing size attribute\n", __func__);
1426 return NULL;
1427 }
1428 if (!has_alignment) {
1429 if (size % CHAR_BIT) {
1430 /* bit-packed alignment */
1431 alignment = 1;
1432 } else {
1433 /* byte-packed alignment */
1434 alignment = CHAR_BIT;
1435 }
1436 }
1437 integer_declaration = integer_declaration_new(size,
1438 byte_order, signedness, alignment,
1439 base, encoding, clock);
1440 return &integer_declaration->p;
1441 }
1442
1443 static
1444 struct declaration *ctf_declaration_floating_point_visit(FILE *fd, int depth,
1445 struct bt_list_head *expressions,
1446 struct ctf_trace *trace)
1447 {
1448 struct ctf_node *expression;
1449 uint64_t alignment = 1, exp_dig = 0, mant_dig = 0,
1450 byte_order = trace->byte_order;
1451 int has_alignment = 0, has_exp_dig = 0, has_mant_dig = 0;
1452 struct declaration_float *float_declaration;
1453
1454 bt_list_for_each_entry(expression, expressions, siblings) {
1455 struct ctf_node *left, *right;
1456
1457 left = _bt_list_first_entry(&expression->u.ctf_expression.left, struct ctf_node, siblings);
1458 right = _bt_list_first_entry(&expression->u.ctf_expression.right, struct ctf_node, siblings);
1459 assert(left->u.unary_expression.type == UNARY_STRING);
1460 if (!strcmp(left->u.unary_expression.u.string, "byte_order")) {
1461 byte_order = get_byte_order(fd, depth, right, trace);
1462 if (byte_order < 0)
1463 return NULL;
1464 } else if (!strcmp(left->u.unary_expression.u.string, "exp_dig")) {
1465 if (right->u.unary_expression.type != UNARY_UNSIGNED_CONSTANT) {
1466 fprintf(fd, "[error] %s: exp_dig: expecting unsigned constant\n",
1467 __func__);
1468 return NULL;
1469 }
1470 exp_dig = right->u.unary_expression.u.unsigned_constant;
1471 has_exp_dig = 1;
1472 } else if (!strcmp(left->u.unary_expression.u.string, "mant_dig")) {
1473 if (right->u.unary_expression.type != UNARY_UNSIGNED_CONSTANT) {
1474 fprintf(fd, "[error] %s: mant_dig: expecting unsigned constant\n",
1475 __func__);
1476 return NULL;
1477 }
1478 mant_dig = right->u.unary_expression.u.unsigned_constant;
1479 has_mant_dig = 1;
1480 } else if (!strcmp(left->u.unary_expression.u.string, "align")) {
1481 if (right->u.unary_expression.type != UNARY_UNSIGNED_CONSTANT) {
1482 fprintf(fd, "[error] %s: align: expecting unsigned constant\n",
1483 __func__);
1484 return NULL;
1485 }
1486 alignment = right->u.unary_expression.u.unsigned_constant;
1487 /* Make sure alignment is a power of two */
1488 if (alignment == 0 || (alignment & (alignment - 1)) != 0) {
1489 fprintf(fd, "[error] %s: align: expecting power of two\n",
1490 __func__);
1491 return NULL;
1492 }
1493 has_alignment = 1;
1494 } else {
1495 fprintf(fd, "[warning] %s: unknown attribute name %s\n",
1496 __func__, left->u.unary_expression.u.string);
1497 /* Fall-through after warning */
1498 }
1499 }
1500 if (!has_mant_dig) {
1501 fprintf(fd, "[error] %s: missing mant_dig attribute\n", __func__);
1502 return NULL;
1503 }
1504 if (!has_exp_dig) {
1505 fprintf(fd, "[error] %s: missing exp_dig attribute\n", __func__);
1506 return NULL;
1507 }
1508 if (!has_alignment) {
1509 if ((mant_dig + exp_dig) % CHAR_BIT) {
1510 /* bit-packed alignment */
1511 alignment = 1;
1512 } else {
1513 /* byte-packed alignment */
1514 alignment = CHAR_BIT;
1515 }
1516 }
1517 float_declaration = float_declaration_new(mant_dig, exp_dig,
1518 byte_order, alignment);
1519 return &float_declaration->p;
1520 }
1521
1522 static
1523 struct declaration *ctf_declaration_string_visit(FILE *fd, int depth,
1524 struct bt_list_head *expressions,
1525 struct ctf_trace *trace)
1526 {
1527 struct ctf_node *expression;
1528 const char *encoding_c = NULL;
1529 enum ctf_string_encoding encoding = CTF_STRING_UTF8;
1530 struct declaration_string *string_declaration;
1531
1532 bt_list_for_each_entry(expression, expressions, siblings) {
1533 struct ctf_node *left, *right;
1534
1535 left = _bt_list_first_entry(&expression->u.ctf_expression.left, struct ctf_node, siblings);
1536 right = _bt_list_first_entry(&expression->u.ctf_expression.right, struct ctf_node, siblings);
1537 assert(left->u.unary_expression.type == UNARY_STRING);
1538 if (!strcmp(left->u.unary_expression.u.string, "encoding")) {
1539 if (right->u.unary_expression.type != UNARY_STRING) {
1540 fprintf(fd, "[error] %s: encoding: expecting string\n",
1541 __func__);
1542 return NULL;
1543 }
1544 encoding_c = right->u.unary_expression.u.string;
1545 } else {
1546 fprintf(fd, "[warning] %s: unknown attribute name %s\n",
1547 __func__, left->u.unary_expression.u.string);
1548 /* Fall-through after warning */
1549 }
1550 }
1551 if (encoding_c && !strcmp(encoding_c, "ASCII"))
1552 encoding = CTF_STRING_ASCII;
1553 string_declaration = string_declaration_new(encoding);
1554 return &string_declaration->p;
1555 }
1556
1557
1558 static
1559 struct declaration *ctf_type_specifier_list_visit(FILE *fd,
1560 int depth, struct ctf_node *type_specifier_list,
1561 struct declaration_scope *declaration_scope,
1562 struct ctf_trace *trace)
1563 {
1564 struct ctf_node *first;
1565 struct ctf_node *node;
1566
1567 assert(type_specifier_list->type == NODE_TYPE_SPECIFIER_LIST);
1568
1569 first = _bt_list_first_entry(&type_specifier_list->u.type_specifier_list.head, struct ctf_node, siblings);
1570
1571 assert(first->type == NODE_TYPE_SPECIFIER);
1572
1573 node = first->u.type_specifier.node;
1574
1575 switch (first->u.type_specifier.type) {
1576 case TYPESPEC_FLOATING_POINT:
1577 return ctf_declaration_floating_point_visit(fd, depth,
1578 &node->u.floating_point.expressions, trace);
1579 case TYPESPEC_INTEGER:
1580 return ctf_declaration_integer_visit(fd, depth,
1581 &node->u.integer.expressions, trace);
1582 case TYPESPEC_STRING:
1583 return ctf_declaration_string_visit(fd, depth,
1584 &node->u.string.expressions, trace);
1585 case TYPESPEC_STRUCT:
1586 return ctf_declaration_struct_visit(fd, depth,
1587 node->u._struct.name,
1588 &node->u._struct.declaration_list,
1589 node->u._struct.has_body,
1590 &node->u._struct.min_align,
1591 declaration_scope,
1592 trace);
1593 case TYPESPEC_VARIANT:
1594 return ctf_declaration_variant_visit(fd, depth,
1595 node->u.variant.name,
1596 node->u.variant.choice,
1597 &node->u.variant.declaration_list,
1598 node->u.variant.has_body,
1599 declaration_scope,
1600 trace);
1601 case TYPESPEC_ENUM:
1602 return ctf_declaration_enum_visit(fd, depth,
1603 node->u._enum.enum_id,
1604 node->u._enum.container_type,
1605 &node->u._enum.enumerator_list,
1606 node->u._enum.has_body,
1607 declaration_scope,
1608 trace);
1609
1610 case TYPESPEC_VOID:
1611 case TYPESPEC_CHAR:
1612 case TYPESPEC_SHORT:
1613 case TYPESPEC_INT:
1614 case TYPESPEC_LONG:
1615 case TYPESPEC_FLOAT:
1616 case TYPESPEC_DOUBLE:
1617 case TYPESPEC_SIGNED:
1618 case TYPESPEC_UNSIGNED:
1619 case TYPESPEC_BOOL:
1620 case TYPESPEC_COMPLEX:
1621 case TYPESPEC_IMAGINARY:
1622 case TYPESPEC_CONST:
1623 case TYPESPEC_ID_TYPE:
1624 return ctf_declaration_type_specifier_visit(fd, depth,
1625 type_specifier_list, declaration_scope);
1626 default:
1627 fprintf(fd, "[error] %s: unexpected node type %d\n", __func__, (int) first->u.type_specifier.type);
1628 return NULL;
1629 }
1630 }
1631
1632 static
1633 int ctf_event_declaration_visit(FILE *fd, int depth, struct ctf_node *node, struct ctf_event_declaration *event, struct ctf_trace *trace)
1634 {
1635 int ret = 0;
1636
1637 switch (node->type) {
1638 case NODE_TYPEDEF:
1639 ret = ctf_typedef_visit(fd, depth + 1,
1640 event->declaration_scope,
1641 node->u._typedef.type_specifier_list,
1642 &node->u._typedef.type_declarators,
1643 trace);
1644 if (ret)
1645 return ret;
1646 break;
1647 case NODE_TYPEALIAS:
1648 ret = ctf_typealias_visit(fd, depth + 1,
1649 event->declaration_scope,
1650 node->u.typealias.target, node->u.typealias.alias,
1651 trace);
1652 if (ret)
1653 return ret;
1654 break;
1655 case NODE_CTF_EXPRESSION:
1656 {
1657 char *left;
1658
1659 left = concatenate_unary_strings(&node->u.ctf_expression.left);
1660 if (!strcmp(left, "name")) {
1661 char *right;
1662
1663 if (CTF_EVENT_FIELD_IS_SET(event, name)) {
1664 fprintf(fd, "[error] %s: name already declared in event declaration\n", __func__);
1665 ret = -EPERM;
1666 goto error;
1667 }
1668 right = concatenate_unary_strings(&node->u.ctf_expression.right);
1669 if (!right) {
1670 fprintf(fd, "[error] %s: unexpected unary expression for event name\n", __func__);
1671 ret = -EINVAL;
1672 goto error;
1673 }
1674 event->name = g_quark_from_string(right);
1675 g_free(right);
1676 CTF_EVENT_SET_FIELD(event, name);
1677 } else if (!strcmp(left, "id")) {
1678 if (CTF_EVENT_FIELD_IS_SET(event, id)) {
1679 fprintf(fd, "[error] %s: id already declared in event declaration\n", __func__);
1680 ret = -EPERM;
1681 goto error;
1682 }
1683 ret = get_unary_unsigned(&node->u.ctf_expression.right, &event->id);
1684 if (ret) {
1685 fprintf(fd, "[error] %s: unexpected unary expression for event id\n", __func__);
1686 ret = -EINVAL;
1687 goto error;
1688 }
1689 CTF_EVENT_SET_FIELD(event, id);
1690 } else if (!strcmp(left, "stream_id")) {
1691 if (CTF_EVENT_FIELD_IS_SET(event, stream_id)) {
1692 fprintf(fd, "[error] %s: stream_id already declared in event declaration\n", __func__);
1693 ret = -EPERM;
1694 goto error;
1695 }
1696 ret = get_unary_unsigned(&node->u.ctf_expression.right, &event->stream_id);
1697 if (ret) {
1698 fprintf(fd, "[error] %s: unexpected unary expression for event stream_id\n", __func__);
1699 ret = -EINVAL;
1700 goto error;
1701 }
1702 event->stream = trace_stream_lookup(trace, event->stream_id);
1703 if (!event->stream) {
1704 fprintf(fd, "[error] %s: stream id %" PRIu64 " cannot be found\n", __func__, event->stream_id);
1705 ret = -EINVAL;
1706 goto error;
1707 }
1708 CTF_EVENT_SET_FIELD(event, stream_id);
1709 } else if (!strcmp(left, "context")) {
1710 struct declaration *declaration;
1711
1712 if (event->context_decl) {
1713 fprintf(fd, "[error] %s: context already declared in event declaration\n", __func__);
1714 ret = -EINVAL;
1715 goto error;
1716 }
1717 declaration = ctf_type_specifier_list_visit(fd, depth,
1718 _bt_list_first_entry(&node->u.ctf_expression.right,
1719 struct ctf_node, siblings),
1720 event->declaration_scope, trace);
1721 if (!declaration) {
1722 ret = -EPERM;
1723 goto error;
1724 }
1725 if (declaration->id != CTF_TYPE_STRUCT) {
1726 ret = -EPERM;
1727 goto error;
1728 }
1729 event->context_decl = container_of(declaration, struct declaration_struct, p);
1730 } else if (!strcmp(left, "fields")) {
1731 struct declaration *declaration;
1732
1733 if (event->fields_decl) {
1734 fprintf(fd, "[error] %s: fields already declared in event declaration\n", __func__);
1735 ret = -EINVAL;
1736 goto error;
1737 }
1738 declaration = ctf_type_specifier_list_visit(fd, depth,
1739 _bt_list_first_entry(&node->u.ctf_expression.right,
1740 struct ctf_node, siblings),
1741 event->declaration_scope, trace);
1742 if (!declaration) {
1743 ret = -EPERM;
1744 goto error;
1745 }
1746 if (declaration->id != CTF_TYPE_STRUCT) {
1747 ret = -EPERM;
1748 goto error;
1749 }
1750 event->fields_decl = container_of(declaration, struct declaration_struct, p);
1751 } else if (!strcmp(left, "loglevel")) {
1752 int64_t loglevel = -1;
1753
1754 if (CTF_EVENT_FIELD_IS_SET(event, loglevel)) {
1755 fprintf(fd, "[error] %s: loglevel already declared in event declaration\n", __func__);
1756 ret = -EPERM;
1757 goto error;
1758 }
1759 ret = get_unary_signed(&node->u.ctf_expression.right, &loglevel);
1760 if (ret) {
1761 fprintf(fd, "[error] %s: unexpected unary expression for event loglevel\n", __func__);
1762 ret = -EINVAL;
1763 goto error;
1764 }
1765 event->loglevel = (int) loglevel;
1766 CTF_EVENT_SET_FIELD(event, loglevel);
1767 } else if (!strcmp(left, "model.emf.uri")) {
1768 char *right;
1769
1770 if (CTF_EVENT_FIELD_IS_SET(event, model_emf_uri)) {
1771 fprintf(fd, "[error] %s: model.emf.uri already declared in event declaration\n", __func__);
1772 ret = -EPERM;
1773 goto error;
1774 }
1775 right = concatenate_unary_strings(&node->u.ctf_expression.right);
1776 if (!right) {
1777 fprintf(fd, "[error] %s: unexpected unary expression for event model.emf.uri\n", __func__);
1778 ret = -EINVAL;
1779 goto error;
1780 }
1781 event->model_emf_uri = g_quark_from_string(right);
1782 g_free(right);
1783 CTF_EVENT_SET_FIELD(event, model_emf_uri);
1784 } else {
1785 fprintf(fd, "[warning] %s: attribute \"%s\" is unknown in event declaration.\n", __func__, left);
1786 /* Fall-through after warning */
1787 }
1788 error:
1789 g_free(left);
1790 break;
1791 }
1792 default:
1793 return -EPERM;
1794 /* TODO: declaration specifier should be added. */
1795 }
1796
1797 return ret;
1798 }
1799
1800 static
1801 int ctf_event_visit(FILE *fd, int depth, struct ctf_node *node,
1802 struct declaration_scope *parent_declaration_scope, struct ctf_trace *trace)
1803 {
1804 int ret = 0;
1805 struct ctf_node *iter;
1806 struct ctf_event_declaration *event;
1807 struct bt_ctf_event_decl *event_decl;
1808
1809 event_decl = g_new0(struct bt_ctf_event_decl, 1);
1810 event = &event_decl->parent;
1811 event->declaration_scope = new_declaration_scope(parent_declaration_scope);
1812 event->loglevel = -1;
1813 bt_list_for_each_entry(iter, &node->u.event.declaration_list, siblings) {
1814 ret = ctf_event_declaration_visit(fd, depth + 1, iter, event, trace);
1815 if (ret)
1816 goto error;
1817 }
1818 if (!CTF_EVENT_FIELD_IS_SET(event, name)) {
1819 ret = -EPERM;
1820 fprintf(fd, "[error] %s: missing name field in event declaration\n", __func__);
1821 goto error;
1822 }
1823 if (!CTF_EVENT_FIELD_IS_SET(event, stream_id)) {
1824 /* Allow missing stream_id if there is only a single stream */
1825 switch (trace->streams->len) {
1826 case 0: /* Create stream if there was none. */
1827 ret = ctf_stream_visit(fd, depth, NULL, trace->root_declaration_scope, trace);
1828 if (ret)
1829 goto error;
1830 /* Fall-through */
1831 case 1:
1832 event->stream_id = 0;
1833 event->stream = trace_stream_lookup(trace, event->stream_id);
1834 break;
1835 default:
1836 ret = -EPERM;
1837 fprintf(fd, "[error] %s: missing stream_id field in event declaration\n", __func__);
1838 goto error;
1839 }
1840 }
1841 /* Allow only one event without id per stream */
1842 if (!CTF_EVENT_FIELD_IS_SET(event, id)
1843 && event->stream->events_by_id->len != 0) {
1844 ret = -EPERM;
1845 fprintf(fd, "[error] %s: missing id field in event declaration\n", __func__);
1846 goto error;
1847 }
1848 if (event->stream->events_by_id->len <= event->id)
1849 g_ptr_array_set_size(event->stream->events_by_id, event->id + 1);
1850 g_ptr_array_index(event->stream->events_by_id, event->id) = event;
1851 g_hash_table_insert(event->stream->event_quark_to_id,
1852 (gpointer) (unsigned long) event->name,
1853 &event->id);
1854 g_ptr_array_add(trace->event_declarations, event_decl);
1855 return 0;
1856
1857 error:
1858 if (event->fields_decl)
1859 declaration_unref(&event->fields_decl->p);
1860 if (event->context_decl)
1861 declaration_unref(&event->context_decl->p);
1862 free_declaration_scope(event->declaration_scope);
1863 g_free(event_decl);
1864 return ret;
1865 }
1866
1867
1868 static
1869 int ctf_stream_declaration_visit(FILE *fd, int depth, struct ctf_node *node, struct ctf_stream_declaration *stream, struct ctf_trace *trace)
1870 {
1871 int ret = 0;
1872
1873 switch (node->type) {
1874 case NODE_TYPEDEF:
1875 ret = ctf_typedef_visit(fd, depth + 1,
1876 stream->declaration_scope,
1877 node->u._typedef.type_specifier_list,
1878 &node->u._typedef.type_declarators,
1879 trace);
1880 if (ret)
1881 return ret;
1882 break;
1883 case NODE_TYPEALIAS:
1884 ret = ctf_typealias_visit(fd, depth + 1,
1885 stream->declaration_scope,
1886 node->u.typealias.target, node->u.typealias.alias,
1887 trace);
1888 if (ret)
1889 return ret;
1890 break;
1891 case NODE_CTF_EXPRESSION:
1892 {
1893 char *left;
1894
1895 left = concatenate_unary_strings(&node->u.ctf_expression.left);
1896 if (!strcmp(left, "id")) {
1897 if (CTF_STREAM_FIELD_IS_SET(stream, stream_id)) {
1898 fprintf(fd, "[error] %s: id already declared in stream declaration\n", __func__);
1899 ret = -EPERM;
1900 goto error;
1901 }
1902 ret = get_unary_unsigned(&node->u.ctf_expression.right, &stream->stream_id);
1903 if (ret) {
1904 fprintf(fd, "[error] %s: unexpected unary expression for stream id\n", __func__);
1905 ret = -EINVAL;
1906 goto error;
1907 }
1908 CTF_STREAM_SET_FIELD(stream, stream_id);
1909 } else if (!strcmp(left, "event.header")) {
1910 struct declaration *declaration;
1911
1912 if (stream->event_header_decl) {
1913 fprintf(fd, "[error] %s: event.header already declared in stream declaration\n", __func__);
1914 ret = -EINVAL;
1915 goto error;
1916 }
1917 declaration = ctf_type_specifier_list_visit(fd, depth,
1918 _bt_list_first_entry(&node->u.ctf_expression.right,
1919 struct ctf_node, siblings),
1920 stream->declaration_scope, trace);
1921 if (!declaration) {
1922 ret = -EPERM;
1923 goto error;
1924 }
1925 if (declaration->id != CTF_TYPE_STRUCT) {
1926 ret = -EPERM;
1927 goto error;
1928 }
1929 stream->event_header_decl = container_of(declaration, struct declaration_struct, p);
1930 } else if (!strcmp(left, "event.context")) {
1931 struct declaration *declaration;
1932
1933 if (stream->event_context_decl) {
1934 fprintf(fd, "[error] %s: event.context already declared in stream declaration\n", __func__);
1935 ret = -EINVAL;
1936 goto error;
1937 }
1938 declaration = ctf_type_specifier_list_visit(fd, depth,
1939 _bt_list_first_entry(&node->u.ctf_expression.right,
1940 struct ctf_node, siblings),
1941 stream->declaration_scope, trace);
1942 if (!declaration) {
1943 ret = -EPERM;
1944 goto error;
1945 }
1946 if (declaration->id != CTF_TYPE_STRUCT) {
1947 ret = -EPERM;
1948 goto error;
1949 }
1950 stream->event_context_decl = container_of(declaration, struct declaration_struct, p);
1951 } else if (!strcmp(left, "packet.context")) {
1952 struct declaration *declaration;
1953
1954 if (stream->packet_context_decl) {
1955 fprintf(fd, "[error] %s: packet.context already declared in stream declaration\n", __func__);
1956 ret = -EINVAL;
1957 goto error;
1958 }
1959 declaration = ctf_type_specifier_list_visit(fd, depth,
1960 _bt_list_first_entry(&node->u.ctf_expression.right,
1961 struct ctf_node, siblings),
1962 stream->declaration_scope, trace);
1963 if (!declaration) {
1964 ret = -EPERM;
1965 goto error;
1966 }
1967 if (declaration->id != CTF_TYPE_STRUCT) {
1968 ret = -EPERM;
1969 goto error;
1970 }
1971 stream->packet_context_decl = container_of(declaration, struct declaration_struct, p);
1972 } else {
1973 fprintf(fd, "[warning] %s: attribute \"%s\" is unknown in stream declaration.\n", __func__, left);
1974 /* Fall-through after warning */
1975 }
1976
1977 error:
1978 g_free(left);
1979 break;
1980 }
1981 default:
1982 return -EPERM;
1983 /* TODO: declaration specifier should be added. */
1984 }
1985
1986 return ret;
1987 }
1988
1989 static
1990 int ctf_stream_visit(FILE *fd, int depth, struct ctf_node *node,
1991 struct declaration_scope *parent_declaration_scope, struct ctf_trace *trace)
1992 {
1993 int ret = 0;
1994 struct ctf_node *iter;
1995 struct ctf_stream_declaration *stream;
1996
1997 stream = g_new0(struct ctf_stream_declaration, 1);
1998 stream->declaration_scope = new_declaration_scope(parent_declaration_scope);
1999 stream->events_by_id = g_ptr_array_new();
2000 stream->event_quark_to_id = g_hash_table_new(g_direct_hash, g_direct_equal);
2001 stream->streams = g_ptr_array_new();
2002 if (node) {
2003 bt_list_for_each_entry(iter, &node->u.stream.declaration_list, siblings) {
2004 ret = ctf_stream_declaration_visit(fd, depth + 1, iter, stream, trace);
2005 if (ret)
2006 goto error;
2007 }
2008 }
2009 if (CTF_STREAM_FIELD_IS_SET(stream, stream_id)) {
2010 /* check that packet header has stream_id field. */
2011 if (!trace->packet_header_decl
2012 || struct_declaration_lookup_field_index(trace->packet_header_decl, g_quark_from_static_string("stream_id")) < 0) {
2013 ret = -EPERM;
2014 fprintf(fd, "[error] %s: missing stream_id field in packet header declaration, but stream_id attribute is declared for stream.\n", __func__);
2015 goto error;
2016 }
2017 } else {
2018 /* Allow only one id-less stream */
2019 if (trace->streams->len != 0) {
2020 ret = -EPERM;
2021 fprintf(fd, "[error] %s: missing id field in stream declaration\n", __func__);
2022 goto error;
2023 }
2024 stream->stream_id = 0;
2025 }
2026 if (trace->streams->len <= stream->stream_id)
2027 g_ptr_array_set_size(trace->streams, stream->stream_id + 1);
2028 g_ptr_array_index(trace->streams, stream->stream_id) = stream;
2029 stream->trace = trace;
2030
2031 return 0;
2032
2033 error:
2034 if (stream->event_header_decl)
2035 declaration_unref(&stream->event_header_decl->p);
2036 if (stream->event_context_decl)
2037 declaration_unref(&stream->event_context_decl->p);
2038 if (stream->packet_context_decl)
2039 declaration_unref(&stream->packet_context_decl->p);
2040 g_ptr_array_free(stream->streams, TRUE);
2041 g_ptr_array_free(stream->events_by_id, TRUE);
2042 g_hash_table_destroy(stream->event_quark_to_id);
2043 free_declaration_scope(stream->declaration_scope);
2044 g_free(stream);
2045 return ret;
2046 }
2047
2048 static
2049 int ctf_trace_declaration_visit(FILE *fd, int depth, struct ctf_node *node, struct ctf_trace *trace)
2050 {
2051 int ret = 0;
2052
2053 switch (node->type) {
2054 case NODE_TYPEDEF:
2055 ret = ctf_typedef_visit(fd, depth + 1,
2056 trace->declaration_scope,
2057 node->u._typedef.type_specifier_list,
2058 &node->u._typedef.type_declarators,
2059 trace);
2060 if (ret)
2061 return ret;
2062 break;
2063 case NODE_TYPEALIAS:
2064 ret = ctf_typealias_visit(fd, depth + 1,
2065 trace->declaration_scope,
2066 node->u.typealias.target, node->u.typealias.alias,
2067 trace);
2068 if (ret)
2069 return ret;
2070 break;
2071 case NODE_CTF_EXPRESSION:
2072 {
2073 char *left;
2074
2075 left = concatenate_unary_strings(&node->u.ctf_expression.left);
2076 if (!strcmp(left, "major")) {
2077 if (CTF_TRACE_FIELD_IS_SET(trace, major)) {
2078 fprintf(fd, "[error] %s: major already declared in trace declaration\n", __func__);
2079 ret = -EPERM;
2080 goto error;
2081 }
2082 ret = get_unary_unsigned(&node->u.ctf_expression.right, &trace->major);
2083 if (ret) {
2084 fprintf(fd, "[error] %s: unexpected unary expression for trace major number\n", __func__);
2085 ret = -EINVAL;
2086 goto error;
2087 }
2088 CTF_TRACE_SET_FIELD(trace, major);
2089 } else if (!strcmp(left, "minor")) {
2090 if (CTF_TRACE_FIELD_IS_SET(trace, minor)) {
2091 fprintf(fd, "[error] %s: minor already declared in trace declaration\n", __func__);
2092 ret = -EPERM;
2093 goto error;
2094 }
2095 ret = get_unary_unsigned(&node->u.ctf_expression.right, &trace->minor);
2096 if (ret) {
2097 fprintf(fd, "[error] %s: unexpected unary expression for trace minor number\n", __func__);
2098 ret = -EINVAL;
2099 goto error;
2100 }
2101 CTF_TRACE_SET_FIELD(trace, minor);
2102 } else if (!strcmp(left, "uuid")) {
2103 unsigned char uuid[BABELTRACE_UUID_LEN];
2104
2105 ret = get_unary_uuid(&node->u.ctf_expression.right, uuid);
2106 if (ret) {
2107 fprintf(fd, "[error] %s: unexpected unary expression for trace uuid\n", __func__);
2108 ret = -EINVAL;
2109 goto error;
2110 }
2111 if (CTF_TRACE_FIELD_IS_SET(trace, uuid)
2112 && babeltrace_uuid_compare(uuid, trace->uuid)) {
2113 fprintf(fd, "[error] %s: uuid mismatch\n", __func__);
2114 ret = -EPERM;
2115 goto error;
2116 } else {
2117 memcpy(trace->uuid, uuid, sizeof(uuid));
2118 }
2119 CTF_TRACE_SET_FIELD(trace, uuid);
2120 } else if (!strcmp(left, "byte_order")) {
2121 struct ctf_node *right;
2122 int byte_order;
2123
2124 right = _bt_list_first_entry(&node->u.ctf_expression.right, struct ctf_node, siblings);
2125 byte_order = get_trace_byte_order(fd, depth, right);
2126 if (byte_order < 0)
2127 return -EINVAL;
2128
2129 if (CTF_TRACE_FIELD_IS_SET(trace, byte_order)
2130 && byte_order != trace->byte_order) {
2131 fprintf(fd, "[error] %s: endianness mismatch\n", __func__);
2132 ret = -EPERM;
2133 goto error;
2134 } else {
2135 if (byte_order != trace->byte_order) {
2136 trace->byte_order = byte_order;
2137 /*
2138 * We need to restart
2139 * construction of the
2140 * intermediate representation.
2141 */
2142 trace->field_mask = 0;
2143 CTF_TRACE_SET_FIELD(trace, byte_order);
2144 ret = -EINTR;
2145 goto error;
2146 }
2147 }
2148 CTF_TRACE_SET_FIELD(trace, byte_order);
2149 } else if (!strcmp(left, "packet.header")) {
2150 struct declaration *declaration;
2151
2152 if (trace->packet_header_decl) {
2153 fprintf(fd, "[error] %s: packet.header already declared in trace declaration\n", __func__);
2154 ret = -EINVAL;
2155 goto error;
2156 }
2157 declaration = ctf_type_specifier_list_visit(fd, depth,
2158 _bt_list_first_entry(&node->u.ctf_expression.right,
2159 struct ctf_node, siblings),
2160 trace->declaration_scope, trace);
2161 if (!declaration) {
2162 ret = -EPERM;
2163 goto error;
2164 }
2165 if (declaration->id != CTF_TYPE_STRUCT) {
2166 ret = -EPERM;
2167 goto error;
2168 }
2169 trace->packet_header_decl = container_of(declaration, struct declaration_struct, p);
2170 } else {
2171 fprintf(fd, "[warning] %s: attribute \"%s\" is unknown in trace declaration.\n", __func__, left);
2172 }
2173
2174 error:
2175 g_free(left);
2176 break;
2177 }
2178 default:
2179 return -EPERM;
2180 /* TODO: declaration specifier should be added. */
2181 }
2182
2183 return ret;
2184 }
2185
2186 static
2187 int ctf_trace_visit(FILE *fd, int depth, struct ctf_node *node, struct ctf_trace *trace)
2188 {
2189 int ret = 0;
2190 struct ctf_node *iter;
2191
2192 if (trace->declaration_scope)
2193 return -EEXIST;
2194 trace->declaration_scope = new_declaration_scope(trace->root_declaration_scope);
2195 trace->streams = g_ptr_array_new();
2196 trace->event_declarations = g_ptr_array_new();
2197 bt_list_for_each_entry(iter, &node->u.trace.declaration_list, siblings) {
2198 ret = ctf_trace_declaration_visit(fd, depth + 1, iter, trace);
2199 if (ret)
2200 goto error;
2201 }
2202 if (!CTF_TRACE_FIELD_IS_SET(trace, major)) {
2203 ret = -EPERM;
2204 fprintf(fd, "[error] %s: missing major field in trace declaration\n", __func__);
2205 goto error;
2206 }
2207 if (!CTF_TRACE_FIELD_IS_SET(trace, minor)) {
2208 ret = -EPERM;
2209 fprintf(fd, "[error] %s: missing minor field in trace declaration\n", __func__);
2210 goto error;
2211 }
2212 if (!CTF_TRACE_FIELD_IS_SET(trace, byte_order)) {
2213 ret = -EPERM;
2214 fprintf(fd, "[error] %s: missing byte_order field in trace declaration\n", __func__);
2215 goto error;
2216 }
2217
2218 if (!CTF_TRACE_FIELD_IS_SET(trace, byte_order)) {
2219 /* check that the packet header contains a "magic" field */
2220 if (!trace->packet_header_decl
2221 || struct_declaration_lookup_field_index(trace->packet_header_decl, g_quark_from_static_string("magic")) < 0) {
2222 ret = -EPERM;
2223 fprintf(fd, "[error] %s: missing both byte_order and packet header magic number in trace declaration\n", __func__);
2224 goto error;
2225 }
2226 }
2227 return 0;
2228
2229 error:
2230 if (trace->packet_header_decl) {
2231 declaration_unref(&trace->packet_header_decl->p);
2232 trace->packet_header_decl = NULL;
2233 }
2234 g_ptr_array_free(trace->streams, TRUE);
2235 g_ptr_array_free(trace->event_declarations, TRUE);
2236 free_declaration_scope(trace->declaration_scope);
2237 trace->declaration_scope = NULL;
2238 return ret;
2239 }
2240
2241 static
2242 int ctf_clock_declaration_visit(FILE *fd, int depth, struct ctf_node *node,
2243 struct ctf_clock *clock, struct ctf_trace *trace)
2244 {
2245 int ret = 0;
2246
2247 switch (node->type) {
2248 case NODE_CTF_EXPRESSION:
2249 {
2250 char *left;
2251
2252 left = concatenate_unary_strings(&node->u.ctf_expression.left);
2253 if (!strcmp(left, "name")) {
2254 char *right;
2255
2256 if (CTF_CLOCK_FIELD_IS_SET(clock, name)) {
2257 fprintf(fd, "[error] %s: name already declared in clock declaration\n", __func__);
2258 ret = -EPERM;
2259 goto error;
2260 }
2261 right = concatenate_unary_strings(&node->u.ctf_expression.right);
2262 if (!right) {
2263 fprintf(fd, "[error] %s: unexpected unary expression for clock name\n", __func__);
2264 ret = -EINVAL;
2265 goto error;
2266 }
2267 clock->name = g_quark_from_string(right);
2268 g_free(right);
2269 CTF_CLOCK_SET_FIELD(clock, name);
2270 } else if (!strcmp(left, "uuid")) {
2271 char *right;
2272
2273 if (clock->uuid) {
2274 fprintf(fd, "[error] %s: uuid already declared in clock declaration\n", __func__);
2275 ret = -EPERM;
2276 goto error;
2277 }
2278 right = concatenate_unary_strings(&node->u.ctf_expression.right);
2279 if (!right) {
2280 fprintf(fd, "[error] %s: unexpected unary expression for clock uuid\n", __func__);
2281 ret = -EINVAL;
2282 goto error;
2283 }
2284 clock->uuid = g_quark_from_string(right);
2285 g_free(right);
2286 } else if (!strcmp(left, "description")) {
2287 char *right;
2288
2289 if (clock->description) {
2290 fprintf(fd, "[warning] %s: duplicated clock description\n", __func__);
2291 goto error; /* ret is 0, so not an actual error, just warn. */
2292 }
2293 right = concatenate_unary_strings(&node->u.ctf_expression.right);
2294 if (!right) {
2295 fprintf(fd, "[warning] %s: unexpected unary expression for clock description\n", __func__);
2296 goto error; /* ret is 0, so not an actual error, just warn. */
2297 }
2298 clock->description = right;
2299 } else if (!strcmp(left, "freq")) {
2300 if (CTF_CLOCK_FIELD_IS_SET(clock, freq)) {
2301 fprintf(fd, "[error] %s: freq already declared in clock declaration\n", __func__);
2302 ret = -EPERM;
2303 goto error;
2304 }
2305 ret = get_unary_unsigned(&node->u.ctf_expression.right, &clock->freq);
2306 if (ret) {
2307 fprintf(fd, "[error] %s: unexpected unary expression for clock freq\n", __func__);
2308 ret = -EINVAL;
2309 goto error;
2310 }
2311 CTF_CLOCK_SET_FIELD(clock, freq);
2312 } else if (!strcmp(left, "precision")) {
2313 if (clock->precision) {
2314 fprintf(fd, "[error] %s: precision already declared in clock declaration\n", __func__);
2315 ret = -EPERM;
2316 goto error;
2317 }
2318 ret = get_unary_unsigned(&node->u.ctf_expression.right, &clock->precision);
2319 if (ret) {
2320 fprintf(fd, "[error] %s: unexpected unary expression for clock precision\n", __func__);
2321 ret = -EINVAL;
2322 goto error;
2323 }
2324 } else if (!strcmp(left, "offset_s")) {
2325 if (clock->offset_s) {
2326 fprintf(fd, "[error] %s: offset_s already declared in clock declaration\n", __func__);
2327 ret = -EPERM;
2328 goto error;
2329 }
2330 ret = get_unary_unsigned(&node->u.ctf_expression.right, &clock->offset_s);
2331 if (ret) {
2332 fprintf(fd, "[error] %s: unexpected unary expression for clock offset_s\n", __func__);
2333 ret = -EINVAL;
2334 goto error;
2335 }
2336 } else if (!strcmp(left, "offset")) {
2337 if (clock->offset) {
2338 fprintf(fd, "[error] %s: offset already declared in clock declaration\n", __func__);
2339 ret = -EPERM;
2340 goto error;
2341 }
2342 ret = get_unary_unsigned(&node->u.ctf_expression.right, &clock->offset);
2343 if (ret) {
2344 fprintf(fd, "[error] %s: unexpected unary expression for clock offset\n", __func__);
2345 ret = -EINVAL;
2346 goto error;
2347 }
2348 } else if (!strcmp(left, "absolute")) {
2349 struct ctf_node *right;
2350
2351 right = _bt_list_first_entry(&node->u.ctf_expression.right, struct ctf_node, siblings);
2352 ret = get_boolean(fd, depth, right);
2353 if (ret < 0) {
2354 fprintf(fd, "[error] %s: unexpected \"absolute\" right member\n", __func__);
2355 ret = -EINVAL;
2356 goto error;
2357 }
2358 clock->absolute = ret;
2359 } else {
2360 fprintf(fd, "[warning] %s: attribute \"%s\" is unknown in clock declaration.\n", __func__, left);
2361 }
2362
2363 error:
2364 g_free(left);
2365 break;
2366 }
2367 default:
2368 return -EPERM;
2369 /* TODO: declaration specifier should be added. */
2370 }
2371
2372 return ret;
2373 }
2374
2375 static
2376 int ctf_clock_visit(FILE *fd, int depth, struct ctf_node *node, struct ctf_trace *trace)
2377 {
2378 int ret = 0;
2379 struct ctf_node *iter;
2380 struct ctf_clock *clock;
2381
2382 clock = g_new0(struct ctf_clock, 1);
2383 /* Default clock frequency is set to 1000000000 */
2384 clock->freq = 1000000000ULL;
2385 bt_list_for_each_entry(iter, &node->u.clock.declaration_list, siblings) {
2386 ret = ctf_clock_declaration_visit(fd, depth + 1, iter, clock, trace);
2387 if (ret)
2388 goto error;
2389 }
2390 if (opt_clock_force_correlate) {
2391 /*
2392 * User requested to forcibly correlate the clock
2393 * sources, even if we have no correlatation
2394 * information.
2395 */
2396 if (!clock->absolute) {
2397 fprintf(fd, "[warning] Forcibly correlating trace clock sources (--clock-force-correlate).\n");
2398 }
2399 clock->absolute = 1;
2400 }
2401 if (!CTF_CLOCK_FIELD_IS_SET(clock, name)) {
2402 ret = -EPERM;
2403 fprintf(fd, "[error] %s: missing name field in clock declaration\n", __func__);
2404 goto error;
2405 }
2406 if (g_hash_table_size(trace->clocks) > 0) {
2407 fprintf(fd, "[error] Only CTF traces with a single clock description are supported by this babeltrace version.\n");
2408 ret = -EINVAL;
2409 goto error;
2410 }
2411 trace->single_clock = clock;
2412 g_hash_table_insert(trace->clocks, (gpointer) (unsigned long) clock->name, clock);
2413 return 0;
2414
2415 error:
2416 g_free(clock->description);
2417 g_free(clock);
2418 return ret;
2419 }
2420
2421 static
2422 void ctf_clock_default(FILE *fd, int depth, struct ctf_trace *trace)
2423 {
2424 struct ctf_clock *clock;
2425
2426 clock = g_new0(struct ctf_clock, 1);
2427 clock->name = g_quark_from_string("monotonic");
2428 clock->uuid = 0;
2429 clock->description = g_strdup("Default clock");
2430 /* Default clock frequency is set to 1000000000 */
2431 clock->freq = 1000000000ULL;
2432 if (opt_clock_force_correlate) {
2433 /*
2434 * User requested to forcibly correlate the clock
2435 * sources, even if we have no correlatation
2436 * information.
2437 */
2438 if (!clock->absolute) {
2439 fprintf(fd, "[warning] Forcibly correlating trace clock sources (--clock-force-correlate).\n");
2440 }
2441 clock->absolute = 1;
2442 } else {
2443 clock->absolute = 0; /* Not an absolute reference across traces */
2444 }
2445
2446 trace->single_clock = clock;
2447 g_hash_table_insert(trace->clocks, (gpointer) (unsigned long) clock->name, clock);
2448 }
2449
2450 static
2451 void clock_free(gpointer data)
2452 {
2453 struct ctf_clock *clock = data;
2454
2455 g_free(clock->description);
2456 g_free(clock);
2457 }
2458
2459 static
2460 int ctf_callsite_declaration_visit(FILE *fd, int depth, struct ctf_node *node,
2461 struct ctf_callsite *callsite, struct ctf_trace *trace)
2462 {
2463 int ret = 0;
2464
2465 switch (node->type) {
2466 case NODE_CTF_EXPRESSION:
2467 {
2468 char *left;
2469
2470 left = concatenate_unary_strings(&node->u.ctf_expression.left);
2471 if (!strcmp(left, "name")) {
2472 char *right;
2473
2474 if (CTF_CALLSITE_FIELD_IS_SET(callsite, name)) {
2475 fprintf(fd, "[error] %s: name already declared in callsite declaration\n", __func__);
2476 ret = -EPERM;
2477 goto error;
2478 }
2479 right = concatenate_unary_strings(&node->u.ctf_expression.right);
2480 if (!right) {
2481 fprintf(fd, "[error] %s: unexpected unary expression for callsite name\n", __func__);
2482 ret = -EINVAL;
2483 goto error;
2484 }
2485 callsite->name = g_quark_from_string(right);
2486 g_free(right);
2487 CTF_CALLSITE_SET_FIELD(callsite, name);
2488 } else if (!strcmp(left, "func")) {
2489 char *right;
2490
2491 if (CTF_CALLSITE_FIELD_IS_SET(callsite, func)) {
2492 fprintf(fd, "[error] %s: func already declared in callsite declaration\n", __func__);
2493 ret = -EPERM;
2494 goto error;
2495 }
2496 right = concatenate_unary_strings(&node->u.ctf_expression.right);
2497 if (!right) {
2498 fprintf(fd, "[error] %s: unexpected unary expression for callsite func\n", __func__);
2499 ret = -EINVAL;
2500 goto error;
2501 }
2502 callsite->func = right;
2503 CTF_CALLSITE_SET_FIELD(callsite, func);
2504 } else if (!strcmp(left, "file")) {
2505 char *right;
2506
2507 if (CTF_CALLSITE_FIELD_IS_SET(callsite, file)) {
2508 fprintf(fd, "[error] %s: file already declared in callsite declaration\n", __func__);
2509 ret = -EPERM;
2510 goto error;
2511 }
2512 right = concatenate_unary_strings(&node->u.ctf_expression.right);
2513 if (!right) {
2514 fprintf(fd, "[error] %s: unexpected unary expression for callsite file\n", __func__);
2515 ret = -EINVAL;
2516 goto error;
2517 }
2518 callsite->file = right;
2519 CTF_CALLSITE_SET_FIELD(callsite, file);
2520 } else if (!strcmp(left, "line")) {
2521 if (CTF_CALLSITE_FIELD_IS_SET(callsite, line)) {
2522 fprintf(fd, "[error] %s: line already declared in callsite declaration\n", __func__);
2523 ret = -EPERM;
2524 goto error;
2525 }
2526 ret = get_unary_unsigned(&node->u.ctf_expression.right, &callsite->line);
2527 if (ret) {
2528 fprintf(fd, "[error] %s: unexpected unary expression for callsite line\n", __func__);
2529 ret = -EINVAL;
2530 goto error;
2531 }
2532 CTF_CALLSITE_SET_FIELD(callsite, line);
2533 } else if (!strcmp(left, "ip")) {
2534 if (CTF_CALLSITE_FIELD_IS_SET(callsite, ip)) {
2535 fprintf(fd, "[error] %s: ip already declared in callsite declaration\n", __func__);
2536 ret = -EPERM;
2537 goto error;
2538 }
2539 ret = get_unary_unsigned(&node->u.ctf_expression.right, &callsite->ip);
2540 if (ret) {
2541 fprintf(fd, "[error] %s: unexpected unary expression for callsite ip\n", __func__);
2542 ret = -EINVAL;
2543 goto error;
2544 }
2545 CTF_CALLSITE_SET_FIELD(callsite, ip);
2546 } else {
2547 fprintf(fd, "[warning] %s: attribute \"%s\" is unknown in callsite declaration.\n", __func__, left);
2548 }
2549
2550 error:
2551 g_free(left);
2552 break;
2553 }
2554 default:
2555 return -EPERM;
2556 /* TODO: declaration specifier should be added. */
2557 }
2558
2559 return ret;
2560 }
2561
2562 static
2563 int ctf_callsite_visit(FILE *fd, int depth, struct ctf_node *node, struct ctf_trace *trace)
2564 {
2565 int ret = 0;
2566 struct ctf_node *iter;
2567 struct ctf_callsite *callsite;
2568 struct ctf_callsite_dups *cs_dups;
2569
2570 callsite = g_new0(struct ctf_callsite, 1);
2571 bt_list_for_each_entry(iter, &node->u.callsite.declaration_list, siblings) {
2572 ret = ctf_callsite_declaration_visit(fd, depth + 1, iter, callsite, trace);
2573 if (ret)
2574 goto error;
2575 }
2576 if (!CTF_CALLSITE_FIELD_IS_SET(callsite, name)) {
2577 ret = -EPERM;
2578 fprintf(fd, "[error] %s: missing name field in callsite declaration\n", __func__);
2579 goto error;
2580 }
2581 if (!CTF_CALLSITE_FIELD_IS_SET(callsite, func)) {
2582 ret = -EPERM;
2583 fprintf(fd, "[error] %s: missing func field in callsite declaration\n", __func__);
2584 goto error;
2585 }
2586 if (!CTF_CALLSITE_FIELD_IS_SET(callsite, file)) {
2587 ret = -EPERM;
2588 fprintf(fd, "[error] %s: missing file field in callsite declaration\n", __func__);
2589 goto error;
2590 }
2591 if (!CTF_CALLSITE_FIELD_IS_SET(callsite, line)) {
2592 ret = -EPERM;
2593 fprintf(fd, "[error] %s: missing line field in callsite declaration\n", __func__);
2594 goto error;
2595 }
2596
2597 cs_dups = g_hash_table_lookup(trace->callsites,
2598 (gpointer) (unsigned long) callsite->name);
2599 if (!cs_dups) {
2600 cs_dups = g_new0(struct ctf_callsite_dups, 1);
2601 BT_INIT_LIST_HEAD(&cs_dups->head);
2602 g_hash_table_insert(trace->callsites,
2603 (gpointer) (unsigned long) callsite->name, cs_dups);
2604 }
2605 bt_list_add_tail(&callsite->node, &cs_dups->head);
2606 return 0;
2607
2608 error:
2609 g_free(callsite->func);
2610 g_free(callsite->file);
2611 g_free(callsite);
2612 return ret;
2613 }
2614
2615 static
2616 void callsite_free(gpointer data)
2617 {
2618 struct ctf_callsite_dups *cs_dups = data;
2619 struct ctf_callsite *callsite, *cs_n;
2620
2621 bt_list_for_each_entry_safe(callsite, cs_n, &cs_dups->head, node) {
2622 g_free(callsite->func);
2623 g_free(callsite->file);
2624 g_free(callsite);
2625 }
2626 g_free(cs_dups);
2627 }
2628
2629 static
2630 int ctf_env_declaration_visit(FILE *fd, int depth, struct ctf_node *node,
2631 struct ctf_trace *trace)
2632 {
2633 int ret = 0;
2634 struct ctf_tracer_env *env = &trace->env;
2635
2636 switch (node->type) {
2637 case NODE_CTF_EXPRESSION:
2638 {
2639 char *left;
2640
2641 left = concatenate_unary_strings(&node->u.ctf_expression.left);
2642 if (!strcmp(left, "vpid")) {
2643 uint64_t v;
2644
2645 if (env->vpid != -1) {
2646 fprintf(fd, "[error] %s: vpid already declared in env declaration\n", __func__);
2647 goto error; /* ret is 0, so not an actual error, just warn. */
2648 }
2649 ret = get_unary_unsigned(&node->u.ctf_expression.right, &v);
2650 if (ret) {
2651 fprintf(fd, "[error] %s: unexpected unary expression for env vpid\n", __func__);
2652 goto error; /* ret is 0, so not an actual error, just warn. */
2653 }
2654 env->vpid = (int) v;
2655 printf_verbose("env.vpid = %d\n", env->vpid);
2656 } else if (!strcmp(left, "procname")) {
2657 char *right;
2658
2659 if (env->procname[0]) {
2660 fprintf(fd, "[warning] %s: duplicated env procname\n", __func__);
2661 goto error; /* ret is 0, so not an actual error, just warn. */
2662 }
2663 right = concatenate_unary_strings(&node->u.ctf_expression.right);
2664 if (!right) {
2665 fprintf(fd, "[warning] %s: unexpected unary expression for env procname\n", __func__);
2666 goto error; /* ret is 0, so not an actual error, just warn. */
2667 }
2668 strncpy(env->procname, right, TRACER_ENV_LEN);
2669 env->procname[TRACER_ENV_LEN - 1] = '\0';
2670 printf_verbose("env.procname = \"%s\"\n", env->procname);
2671 g_free(right);
2672 } else if (!strcmp(left, "hostname")) {
2673 char *right;
2674
2675 if (env->hostname[0]) {
2676 fprintf(fd, "[warning] %s: duplicated env hostname\n", __func__);
2677 goto error; /* ret is 0, so not an actual error, just warn. */
2678 }
2679 right = concatenate_unary_strings(&node->u.ctf_expression.right);
2680 if (!right) {
2681 fprintf(fd, "[warning] %s: unexpected unary expression for env hostname\n", __func__);
2682 goto error; /* ret is 0, so not an actual error, just warn. */
2683 }
2684 strncpy(env->hostname, right, TRACER_ENV_LEN);
2685 env->hostname[TRACER_ENV_LEN - 1] = '\0';
2686 printf_verbose("env.hostname = \"%s\"\n", env->hostname);
2687 g_free(right);
2688 } else if (!strcmp(left, "domain")) {
2689 char *right;
2690
2691 if (env->domain[0]) {
2692 fprintf(fd, "[warning] %s: duplicated env domain\n", __func__);
2693 goto error; /* ret is 0, so not an actual error, just warn. */
2694 }
2695 right = concatenate_unary_strings(&node->u.ctf_expression.right);
2696 if (!right) {
2697 fprintf(fd, "[warning] %s: unexpected unary expression for env domain\n", __func__);
2698 goto error; /* ret is 0, so not an actual error, just warn. */
2699 }
2700 strncpy(env->domain, right, TRACER_ENV_LEN);
2701 env->domain[TRACER_ENV_LEN - 1] = '\0';
2702 printf_verbose("env.domain = \"%s\"\n", env->domain);
2703 g_free(right);
2704 } else if (!strcmp(left, "sysname")) {
2705 char *right;
2706
2707 if (env->sysname[0]) {
2708 fprintf(fd, "[warning] %s: duplicated env sysname\n", __func__);
2709 goto error; /* ret is 0, so not an actual error, just warn. */
2710 }
2711 right = concatenate_unary_strings(&node->u.ctf_expression.right);
2712 if (!right) {
2713 fprintf(fd, "[warning] %s: unexpected unary expression for env sysname\n", __func__);
2714 goto error; /* ret is 0, so not an actual error, just warn. */
2715 }
2716 strncpy(env->sysname, right, TRACER_ENV_LEN);
2717 env->sysname[TRACER_ENV_LEN - 1] = '\0';
2718 printf_verbose("env.sysname = \"%s\"\n", env->sysname);
2719 g_free(right);
2720 } else if (!strcmp(left, "kernel_release")) {
2721 char *right;
2722
2723 if (env->release[0]) {
2724 fprintf(fd, "[warning] %s: duplicated env release\n", __func__);
2725 goto error; /* ret is 0, so not an actual error, just warn. */
2726 }
2727 right = concatenate_unary_strings(&node->u.ctf_expression.right);
2728 if (!right) {
2729 fprintf(fd, "[warning] %s: unexpected unary expression for env release\n", __func__);
2730 goto error; /* ret is 0, so not an actual error, just warn. */
2731 }
2732 strncpy(env->release, right, TRACER_ENV_LEN);
2733 env->release[TRACER_ENV_LEN - 1] = '\0';
2734 printf_verbose("env.release = \"%s\"\n", env->release);
2735 g_free(right);
2736 } else if (!strcmp(left, "kernel_version")) {
2737 char *right;
2738
2739 if (env->version[0]) {
2740 fprintf(fd, "[warning] %s: duplicated env version\n", __func__);
2741 goto error; /* ret is 0, so not an actual error, just warn. */
2742 }
2743 right = concatenate_unary_strings(&node->u.ctf_expression.right);
2744 if (!right) {
2745 fprintf(fd, "[warning] %s: unexpected unary expression for env version\n", __func__);
2746 goto error; /* ret is 0, so not an actual error, just warn. */
2747 }
2748 strncpy(env->version, right, TRACER_ENV_LEN);
2749 env->version[TRACER_ENV_LEN - 1] = '\0';
2750 printf_verbose("env.version = \"%s\"\n", env->version);
2751 g_free(right);
2752 } else {
2753 if (is_unary_string(&node->u.ctf_expression.right)) {
2754 char *right;
2755
2756 right = concatenate_unary_strings(&node->u.ctf_expression.right);
2757 printf_verbose("env.%s = \"%s\"\n", left, right);
2758 g_free(right);
2759 } else if (is_unary_unsigned(&node->u.ctf_expression.right)) {
2760 uint64_t v;
2761 int ret;
2762
2763 ret = get_unary_unsigned(&node->u.ctf_expression.right, &v);
2764 assert(ret == 0);
2765 printf_verbose("env.%s = %" PRIu64 "\n", left, v);
2766 } else if (is_unary_signed(&node->u.ctf_expression.right)) {
2767 int64_t v;
2768 int ret;
2769
2770 ret = get_unary_signed(&node->u.ctf_expression.right, &v);
2771 assert(ret == 0);
2772 printf_verbose("env.%s = %" PRId64 "\n", left, v);
2773 } else {
2774 printf_verbose("%s: attribute \"%s\" has unknown type.\n", __func__, left);
2775 }
2776 }
2777
2778 error:
2779 g_free(left);
2780 break;
2781 }
2782 default:
2783 return -EPERM;
2784 }
2785
2786 return ret;
2787 }
2788
2789 static
2790 int ctf_env_visit(FILE *fd, int depth, struct ctf_node *node, struct ctf_trace *trace)
2791 {
2792 int ret = 0;
2793 struct ctf_node *iter;
2794
2795 trace->env.vpid = -1;
2796 trace->env.procname[0] = '\0';
2797 trace->env.hostname[0] = '\0';
2798 trace->env.domain[0] = '\0';
2799 trace->env.sysname[0] = '\0';
2800 trace->env.release[0] = '\0';
2801 trace->env.version[0] = '\0';
2802 bt_list_for_each_entry(iter, &node->u.env.declaration_list, siblings) {
2803 ret = ctf_env_declaration_visit(fd, depth + 1, iter, trace);
2804 if (ret)
2805 goto error;
2806 }
2807 error:
2808 return 0;
2809 }
2810
2811 static
2812 int ctf_root_declaration_visit(FILE *fd, int depth, struct ctf_node *node, struct ctf_trace *trace)
2813 {
2814 int ret = 0;
2815
2816 switch (node->type) {
2817 case NODE_TYPEDEF:
2818 ret = ctf_typedef_visit(fd, depth + 1,
2819 trace->root_declaration_scope,
2820 node->u._typedef.type_specifier_list,
2821 &node->u._typedef.type_declarators,
2822 trace);
2823 if (ret)
2824 return ret;
2825 break;
2826 case NODE_TYPEALIAS:
2827 ret = ctf_typealias_visit(fd, depth + 1,
2828 trace->root_declaration_scope,
2829 node->u.typealias.target, node->u.typealias.alias,
2830 trace);
2831 if (ret)
2832 return ret;
2833 break;
2834 case NODE_TYPE_SPECIFIER_LIST:
2835 {
2836 struct declaration *declaration;
2837
2838 /*
2839 * Just add the type specifier to the root scope
2840 * declaration scope. Release local reference.
2841 */
2842 declaration = ctf_type_specifier_list_visit(fd, depth + 1,
2843 node, trace->root_declaration_scope, trace);
2844 if (!declaration)
2845 return -ENOMEM;
2846 declaration_unref(declaration);
2847 break;
2848 }
2849 default:
2850 return -EPERM;
2851 }
2852
2853 return 0;
2854 }
2855
2856 int ctf_visitor_construct_metadata(FILE *fd, int depth, struct ctf_node *node,
2857 struct ctf_trace *trace, int byte_order)
2858 {
2859 int ret = 0;
2860 struct ctf_node *iter;
2861 int env_clock_done = 0;
2862
2863 printf_verbose("CTF visitor: metadata construction... ");
2864 trace->byte_order = byte_order;
2865 trace->clocks = g_hash_table_new_full(g_direct_hash, g_direct_equal,
2866 NULL, clock_free);
2867 trace->callsites = g_hash_table_new_full(g_direct_hash, g_direct_equal,
2868 NULL, callsite_free);
2869
2870 retry:
2871 trace->root_declaration_scope = new_declaration_scope(NULL);
2872
2873 switch (node->type) {
2874 case NODE_ROOT:
2875 if (!env_clock_done) {
2876 /*
2877 * declarations need to query clock hash table,
2878 * so clock need to be treated first.
2879 */
2880 if (bt_list_empty(&node->u.root.clock)) {
2881 ctf_clock_default(fd, depth + 1, trace);
2882 } else {
2883 bt_list_for_each_entry(iter, &node->u.root.clock, siblings) {
2884 ret = ctf_clock_visit(fd, depth + 1, iter,
2885 trace);
2886 if (ret) {
2887 fprintf(fd, "[error] %s: clock declaration error\n", __func__);
2888 goto error;
2889 }
2890 }
2891 }
2892 env_clock_done = 1;
2893 }
2894 bt_list_for_each_entry(iter, &node->u.root.declaration_list,
2895 siblings) {
2896 ret = ctf_root_declaration_visit(fd, depth + 1, iter, trace);
2897 if (ret) {
2898 fprintf(fd, "[error] %s: root declaration error\n", __func__);
2899 goto error;
2900 }
2901 }
2902 bt_list_for_each_entry(iter, &node->u.root.trace, siblings) {
2903 ret = ctf_trace_visit(fd, depth + 1, iter, trace);
2904 if (ret == -EINTR) {
2905 free_declaration_scope(trace->root_declaration_scope);
2906 /*
2907 * Need to restart creation of type
2908 * definitions, aliases and
2909 * trace header declarations.
2910 */
2911 goto retry;
2912 }
2913 if (ret) {
2914 fprintf(fd, "[error] %s: trace declaration error\n", __func__);
2915 goto error;
2916 }
2917 }
2918 bt_list_for_each_entry(iter, &node->u.root.callsite, siblings) {
2919 ret = ctf_callsite_visit(fd, depth + 1, iter,
2920 trace);
2921 if (ret) {
2922 fprintf(fd, "[error] %s: callsite declaration error\n", __func__);
2923 goto error;
2924 }
2925 }
2926 if (!trace->streams) {
2927 fprintf(fd, "[error] %s: missing trace declaration\n", __func__);
2928 ret = -EINVAL;
2929 goto error;
2930 }
2931 bt_list_for_each_entry(iter, &node->u.root.env, siblings) {
2932 ret = ctf_env_visit(fd, depth + 1, iter, trace);
2933 if (ret) {
2934 fprintf(fd, "[error] %s: env declaration error\n", __func__);
2935 goto error;
2936 }
2937 }
2938 bt_list_for_each_entry(iter, &node->u.root.stream, siblings) {
2939 ret = ctf_stream_visit(fd, depth + 1, iter,
2940 trace->root_declaration_scope, trace);
2941 if (ret) {
2942 fprintf(fd, "[error] %s: stream declaration error\n", __func__);
2943 goto error;
2944 }
2945 }
2946 bt_list_for_each_entry(iter, &node->u.root.event, siblings) {
2947 ret = ctf_event_visit(fd, depth + 1, iter,
2948 trace->root_declaration_scope, trace);
2949 if (ret) {
2950 fprintf(fd, "[error] %s: event declaration error\n", __func__);
2951 goto error;
2952 }
2953 }
2954 break;
2955 case NODE_UNKNOWN:
2956 default:
2957 fprintf(fd, "[error] %s: unknown node type %d\n", __func__,
2958 (int) node->type);
2959 ret = -EINVAL;
2960 goto error;
2961 }
2962 printf_verbose("done.\n");
2963 return ret;
2964
2965 error:
2966 free_declaration_scope(trace->root_declaration_scope);
2967 g_hash_table_destroy(trace->callsites);
2968 g_hash_table_destroy(trace->clocks);
2969 return ret;
2970 }
2971
2972 int ctf_destroy_metadata(struct ctf_trace *trace)
2973 {
2974 int i;
2975 struct ctf_file_stream *metadata_stream;
2976
2977 if (trace->streams) {
2978 for (i = 0; i < trace->streams->len; i++) {
2979 struct ctf_stream_declaration *stream;
2980 int j;
2981
2982 stream = g_ptr_array_index(trace->streams, i);
2983 if (!stream)
2984 continue;
2985 for (j = 0; j < stream->streams->len; j++) {
2986 struct ctf_stream_definition *stream_def;
2987 int k;
2988
2989 stream_def = g_ptr_array_index(stream->streams, j);
2990 if (!stream_def)
2991 continue;
2992 for (k = 0; k < stream_def->events_by_id->len; k++) {
2993 struct ctf_event_definition *event;
2994
2995 event = g_ptr_array_index(stream_def->events_by_id, k);
2996 if (!event)
2997 continue;
2998 if (&event->event_fields->p)
2999 definition_unref(&event->event_fields->p);
3000 if (&event->event_context->p)
3001 definition_unref(&event->event_context->p);
3002 g_free(event);
3003 }
3004 if (&stream_def->trace_packet_header->p)
3005 definition_unref(&stream_def->trace_packet_header->p);
3006 if (&stream_def->stream_event_header->p)
3007 definition_unref(&stream_def->stream_event_header->p);
3008 if (&stream_def->stream_packet_context->p)
3009 definition_unref(&stream_def->stream_packet_context->p);
3010 if (&stream_def->stream_event_context->p)
3011 definition_unref(&stream_def->stream_event_context->p);
3012 g_ptr_array_free(stream_def->events_by_id, TRUE);
3013 g_free(stream_def);
3014 }
3015 if (stream->event_header_decl)
3016 declaration_unref(&stream->event_header_decl->p);
3017 if (stream->event_context_decl)
3018 declaration_unref(&stream->event_context_decl->p);
3019 if (stream->packet_context_decl)
3020 declaration_unref(&stream->packet_context_decl->p);
3021 g_ptr_array_free(stream->streams, TRUE);
3022 g_ptr_array_free(stream->events_by_id, TRUE);
3023 g_hash_table_destroy(stream->event_quark_to_id);
3024 free_declaration_scope(stream->declaration_scope);
3025 g_free(stream);
3026 }
3027 g_ptr_array_free(trace->streams, TRUE);
3028 }
3029
3030 if (trace->event_declarations) {
3031 for (i = 0; i < trace->event_declarations->len; i++) {
3032 struct bt_ctf_event_decl *event_decl;
3033 struct ctf_event_declaration *event;
3034
3035 event_decl = g_ptr_array_index(trace->event_declarations, i);
3036 if (event_decl->context_decl)
3037 g_ptr_array_free(event_decl->context_decl, TRUE);
3038 if (event_decl->fields_decl)
3039 g_ptr_array_free(event_decl->fields_decl, TRUE);
3040 if (event_decl->packet_header_decl)
3041 g_ptr_array_free(event_decl->packet_header_decl, TRUE);
3042 if (event_decl->event_context_decl)
3043 g_ptr_array_free(event_decl->event_context_decl, TRUE);
3044 if (event_decl->event_header_decl)
3045 g_ptr_array_free(event_decl->event_header_decl, TRUE);
3046 if (event_decl->packet_context_decl)
3047 g_ptr_array_free(event_decl->packet_context_decl, TRUE);
3048
3049 event = &event_decl->parent;
3050 if (event->fields_decl)
3051 declaration_unref(&event->fields_decl->p);
3052 if (event->context_decl)
3053 declaration_unref(&event->context_decl->p);
3054 free_declaration_scope(event->declaration_scope);
3055
3056 g_free(event);
3057 }
3058 g_ptr_array_free(trace->event_declarations, TRUE);
3059 }
3060 if (trace->packet_header_decl)
3061 declaration_unref(&trace->packet_header_decl->p);
3062
3063 free_declaration_scope(trace->root_declaration_scope);
3064 free_declaration_scope(trace->declaration_scope);
3065
3066 g_hash_table_destroy(trace->callsites);
3067 g_hash_table_destroy(trace->clocks);
3068
3069 metadata_stream = container_of(trace->metadata, struct ctf_file_stream, parent);
3070 g_free(metadata_stream);
3071
3072 return 0;
3073 }
This page took 0.155638 seconds and 4 git commands to generate.