Fix: free all the metadata-related memory
[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 int ret;
827
828 /*
829 * For named struct (without body), lookup in
830 * declaration scope. Don't take reference on struct
831 * declaration: ref is only taken upon definition.
832 */
833 if (!has_body) {
834 assert(name);
835 struct_declaration =
836 lookup_struct_declaration(g_quark_from_string(name),
837 declaration_scope);
838 declaration_ref(&struct_declaration->p);
839 return &struct_declaration->p;
840 } else {
841 uint64_t min_align_value = 0;
842
843 /* For unnamed struct, create type */
844 /* For named struct (with body), create type and add to declaration scope */
845 if (name) {
846 if (lookup_struct_declaration(g_quark_from_string(name),
847 declaration_scope)) {
848
849 fprintf(fd, "[error] %s: struct %s already declared in scope\n", __func__, name);
850 return NULL;
851 }
852 }
853 if (!bt_list_empty(min_align)) {
854 ret = get_unary_unsigned(min_align, &min_align_value);
855 if (ret) {
856 fprintf(fd, "[error] %s: unexpected unary expression for structure \"align\" attribute\n", __func__);
857 ret = -EINVAL;
858 goto error;
859 }
860 }
861 struct_declaration = struct_declaration_new(declaration_scope,
862 min_align_value);
863 bt_list_for_each_entry(iter, declaration_list, siblings) {
864 ret = ctf_struct_declaration_list_visit(fd, depth + 1, iter,
865 struct_declaration, trace);
866 if (ret)
867 goto error_free_declaration;
868 }
869 if (name) {
870 ret = register_struct_declaration(g_quark_from_string(name),
871 struct_declaration,
872 declaration_scope);
873 assert(!ret);
874 }
875 return &struct_declaration->p;
876 }
877 error_free_declaration:
878 struct_declaration->p.declaration_free(&struct_declaration->p);
879 error:
880 return NULL;
881 }
882
883 static
884 struct declaration *ctf_declaration_variant_visit(FILE *fd,
885 int depth, const char *name, const char *choice,
886 struct bt_list_head *declaration_list,
887 int has_body, struct declaration_scope *declaration_scope,
888 struct ctf_trace *trace)
889 {
890 struct declaration_untagged_variant *untagged_variant_declaration;
891 struct declaration_variant *variant_declaration;
892 struct ctf_node *iter;
893 int ret;
894
895 /*
896 * For named variant (without body), lookup in
897 * declaration scope. Don't take reference on variant
898 * declaration: ref is only taken upon definition.
899 */
900 if (!has_body) {
901 assert(name);
902 untagged_variant_declaration =
903 lookup_variant_declaration(g_quark_from_string(name),
904 declaration_scope);
905 declaration_ref(&untagged_variant_declaration->p);
906 } else {
907 /* For unnamed variant, create type */
908 /* For named variant (with body), create type and add to declaration scope */
909 if (name) {
910 if (lookup_variant_declaration(g_quark_from_string(name),
911 declaration_scope)) {
912
913 fprintf(fd, "[error] %s: variant %s already declared in scope\n", __func__, name);
914 return NULL;
915 }
916 }
917 untagged_variant_declaration = untagged_variant_declaration_new(declaration_scope);
918 bt_list_for_each_entry(iter, declaration_list, siblings) {
919 ret = ctf_variant_declaration_list_visit(fd, depth + 1, iter,
920 untagged_variant_declaration, trace);
921 if (ret)
922 goto error;
923 }
924 if (name) {
925 ret = register_variant_declaration(g_quark_from_string(name),
926 untagged_variant_declaration,
927 declaration_scope);
928 assert(!ret);
929 }
930 }
931 /*
932 * if tagged, create tagged variant and return. else return
933 * untagged variant.
934 */
935 if (!choice) {
936 return &untagged_variant_declaration->p;
937 } else {
938 variant_declaration = variant_declaration_new(untagged_variant_declaration, choice);
939 if (!variant_declaration)
940 goto error;
941 declaration_unref(&untagged_variant_declaration->p);
942 return &variant_declaration->p;
943 }
944 error:
945 untagged_variant_declaration->p.declaration_free(&untagged_variant_declaration->p);
946 return NULL;
947 }
948
949 static
950 int ctf_enumerator_list_visit(FILE *fd, int depth,
951 struct ctf_node *enumerator,
952 struct declaration_enum *enum_declaration,
953 struct last_enum_value *last)
954 {
955 GQuark q;
956 struct ctf_node *iter;
957
958 q = g_quark_from_string(enumerator->u.enumerator.id);
959 if (enum_declaration->integer_declaration->signedness) {
960 int64_t start, end;
961 int nr_vals = 0;
962
963 bt_list_for_each_entry(iter, &enumerator->u.enumerator.values, siblings) {
964 int64_t *target;
965
966 assert(iter->type == NODE_UNARY_EXPRESSION);
967 if (nr_vals == 0)
968 target = &start;
969 else
970 target = &end;
971
972 switch (iter->u.unary_expression.type) {
973 case UNARY_SIGNED_CONSTANT:
974 *target = iter->u.unary_expression.u.signed_constant;
975 break;
976 case UNARY_UNSIGNED_CONSTANT:
977 *target = iter->u.unary_expression.u.unsigned_constant;
978 break;
979 default:
980 fprintf(fd, "[error] %s: invalid enumerator\n", __func__);
981 return -EINVAL;
982 }
983 if (nr_vals > 1) {
984 fprintf(fd, "[error] %s: invalid enumerator\n", __func__);
985 return -EINVAL;
986 }
987 nr_vals++;
988 }
989 if (nr_vals == 0)
990 start = last->u.s;
991 if (nr_vals <= 1)
992 end = start;
993 last->u.s = end + 1;
994 enum_signed_insert(enum_declaration, start, end, q);
995 } else {
996 uint64_t start, end;
997 int nr_vals = 0;
998
999 bt_list_for_each_entry(iter, &enumerator->u.enumerator.values, siblings) {
1000 uint64_t *target;
1001
1002 assert(iter->type == NODE_UNARY_EXPRESSION);
1003 if (nr_vals == 0)
1004 target = &start;
1005 else
1006 target = &end;
1007
1008 switch (iter->u.unary_expression.type) {
1009 case UNARY_UNSIGNED_CONSTANT:
1010 *target = iter->u.unary_expression.u.unsigned_constant;
1011 break;
1012 case UNARY_SIGNED_CONSTANT:
1013 /*
1014 * We don't accept signed constants for enums with unsigned
1015 * container type.
1016 */
1017 fprintf(fd, "[error] %s: invalid enumerator (signed constant encountered, but enum container type is unsigned)\n", __func__);
1018 return -EINVAL;
1019 default:
1020 fprintf(fd, "[error] %s: invalid enumerator\n", __func__);
1021 return -EINVAL;
1022 }
1023 if (nr_vals > 1) {
1024 fprintf(fd, "[error] %s: invalid enumerator\n", __func__);
1025 return -EINVAL;
1026 }
1027 nr_vals++;
1028 }
1029 if (nr_vals == 0)
1030 start = last->u.u;
1031 if (nr_vals <= 1)
1032 end = start;
1033 last->u.u = end + 1;
1034 enum_unsigned_insert(enum_declaration, start, end, q);
1035 }
1036 return 0;
1037 }
1038
1039 static
1040 struct declaration *ctf_declaration_enum_visit(FILE *fd, int depth,
1041 const char *name,
1042 struct ctf_node *container_type,
1043 struct bt_list_head *enumerator_list,
1044 int has_body,
1045 struct declaration_scope *declaration_scope,
1046 struct ctf_trace *trace)
1047 {
1048 struct declaration *declaration;
1049 struct declaration_enum *enum_declaration;
1050 struct declaration_integer *integer_declaration;
1051 struct last_enum_value last_value;
1052 struct ctf_node *iter;
1053 GQuark dummy_id;
1054 int ret;
1055
1056 /*
1057 * For named enum (without body), lookup in
1058 * declaration scope. Don't take reference on enum
1059 * declaration: ref is only taken upon definition.
1060 */
1061 if (!has_body) {
1062 assert(name);
1063 enum_declaration =
1064 lookup_enum_declaration(g_quark_from_string(name),
1065 declaration_scope);
1066 declaration_ref(&enum_declaration->p);
1067 return &enum_declaration->p;
1068 } else {
1069 /* For unnamed enum, create type */
1070 /* For named enum (with body), create type and add to declaration scope */
1071 if (name) {
1072 if (lookup_enum_declaration(g_quark_from_string(name),
1073 declaration_scope)) {
1074
1075 fprintf(fd, "[error] %s: enum %s already declared in scope\n", __func__, name);
1076 return NULL;
1077 }
1078 }
1079 if (!container_type) {
1080 declaration = lookup_declaration(g_quark_from_static_string("int"),
1081 declaration_scope);
1082 if (!declaration) {
1083 fprintf(fd, "[error] %s: \"int\" type declaration missing for enumeration\n", __func__);
1084 return NULL;
1085 }
1086 } else {
1087 declaration = ctf_type_declarator_visit(fd, depth,
1088 container_type,
1089 &dummy_id, NULL,
1090 declaration_scope,
1091 NULL, trace);
1092 }
1093 if (!declaration) {
1094 fprintf(fd, "[error] %s: unable to create container type for enumeration\n", __func__);
1095 return NULL;
1096 }
1097 if (declaration->id != CTF_TYPE_INTEGER) {
1098 fprintf(fd, "[error] %s: container type for enumeration is not integer\n", __func__);
1099 return NULL;
1100 }
1101 integer_declaration = container_of(declaration, struct declaration_integer, p);
1102 enum_declaration = enum_declaration_new(integer_declaration);
1103 declaration_unref(&integer_declaration->p); /* leave ref to enum */
1104 if (enum_declaration->integer_declaration->signedness) {
1105 last_value.u.s = 0;
1106 } else {
1107 last_value.u.u = 0;
1108 }
1109 bt_list_for_each_entry(iter, enumerator_list, siblings) {
1110 ret = ctf_enumerator_list_visit(fd, depth + 1, iter, enum_declaration,
1111 &last_value);
1112 if (ret)
1113 goto error;
1114 }
1115 if (name) {
1116 ret = register_enum_declaration(g_quark_from_string(name),
1117 enum_declaration,
1118 declaration_scope);
1119 assert(!ret);
1120 declaration_unref(&enum_declaration->p);
1121 }
1122 return &enum_declaration->p;
1123 }
1124 error:
1125 enum_declaration->p.declaration_free(&enum_declaration->p);
1126 return NULL;
1127 }
1128
1129 static
1130 struct declaration *ctf_declaration_type_specifier_visit(FILE *fd, int depth,
1131 struct ctf_node *type_specifier_list,
1132 struct declaration_scope *declaration_scope)
1133 {
1134 GString *str;
1135 struct declaration *declaration;
1136 char *str_c;
1137 int ret;
1138 GQuark id_q;
1139
1140 str = g_string_new("");
1141 ret = visit_type_specifier_list(fd, type_specifier_list, str);
1142 if (ret)
1143 return NULL;
1144 str_c = g_string_free(str, FALSE);
1145 id_q = g_quark_from_string(str_c);
1146 g_free(str_c);
1147 declaration = lookup_declaration(id_q, declaration_scope);
1148 declaration_ref(declaration);
1149 return declaration;
1150 }
1151
1152 /*
1153 * Returns 0/1 boolean, or < 0 on error.
1154 */
1155 static
1156 int get_boolean(FILE *fd, int depth, struct ctf_node *unary_expression)
1157 {
1158 if (unary_expression->type != NODE_UNARY_EXPRESSION) {
1159 fprintf(fd, "[error] %s: expecting unary expression\n",
1160 __func__);
1161 return -EINVAL;
1162 }
1163 switch (unary_expression->u.unary_expression.type) {
1164 case UNARY_UNSIGNED_CONSTANT:
1165 if (unary_expression->u.unary_expression.u.unsigned_constant == 0)
1166 return 0;
1167 else
1168 return 1;
1169 case UNARY_SIGNED_CONSTANT:
1170 if (unary_expression->u.unary_expression.u.signed_constant == 0)
1171 return 0;
1172 else
1173 return 1;
1174 case UNARY_STRING:
1175 if (!strcmp(unary_expression->u.unary_expression.u.string, "true"))
1176 return 1;
1177 else if (!strcmp(unary_expression->u.unary_expression.u.string, "TRUE"))
1178 return 1;
1179 else if (!strcmp(unary_expression->u.unary_expression.u.string, "false"))
1180 return 0;
1181 else if (!strcmp(unary_expression->u.unary_expression.u.string, "FALSE"))
1182 return 0;
1183 else {
1184 fprintf(fd, "[error] %s: unexpected string \"%s\"\n",
1185 __func__, unary_expression->u.unary_expression.u.string);
1186 return -EINVAL;
1187 }
1188 break;
1189 default:
1190 fprintf(fd, "[error] %s: unexpected unary expression type\n",
1191 __func__);
1192 return -EINVAL;
1193 }
1194
1195 }
1196
1197 static
1198 int get_trace_byte_order(FILE *fd, int depth, struct ctf_node *unary_expression)
1199 {
1200 int byte_order;
1201
1202 if (unary_expression->u.unary_expression.type != UNARY_STRING) {
1203 fprintf(fd, "[error] %s: byte_order: expecting string\n",
1204 __func__);
1205 return -EINVAL;
1206 }
1207 if (!strcmp(unary_expression->u.unary_expression.u.string, "be"))
1208 byte_order = BIG_ENDIAN;
1209 else if (!strcmp(unary_expression->u.unary_expression.u.string, "le"))
1210 byte_order = LITTLE_ENDIAN;
1211 else {
1212 fprintf(fd, "[error] %s: unexpected string \"%s\". Should be \"native\", \"network\", \"be\" or \"le\".\n",
1213 __func__, unary_expression->u.unary_expression.u.string);
1214 return -EINVAL;
1215 }
1216 return byte_order;
1217 }
1218
1219 static
1220 int get_byte_order(FILE *fd, int depth, struct ctf_node *unary_expression,
1221 struct ctf_trace *trace)
1222 {
1223 int byte_order;
1224
1225 if (unary_expression->u.unary_expression.type != UNARY_STRING) {
1226 fprintf(fd, "[error] %s: byte_order: expecting string\n",
1227 __func__);
1228 return -EINVAL;
1229 }
1230 if (!strcmp(unary_expression->u.unary_expression.u.string, "native"))
1231 byte_order = trace->byte_order;
1232 else if (!strcmp(unary_expression->u.unary_expression.u.string, "network"))
1233 byte_order = BIG_ENDIAN;
1234 else if (!strcmp(unary_expression->u.unary_expression.u.string, "be"))
1235 byte_order = BIG_ENDIAN;
1236 else if (!strcmp(unary_expression->u.unary_expression.u.string, "le"))
1237 byte_order = LITTLE_ENDIAN;
1238 else {
1239 fprintf(fd, "[error] %s: unexpected string \"%s\". Should be \"native\", \"network\", \"be\" or \"le\".\n",
1240 __func__, unary_expression->u.unary_expression.u.string);
1241 return -EINVAL;
1242 }
1243 return byte_order;
1244 }
1245
1246 static
1247 struct declaration *ctf_declaration_integer_visit(FILE *fd, int depth,
1248 struct bt_list_head *expressions,
1249 struct ctf_trace *trace)
1250 {
1251 struct ctf_node *expression;
1252 uint64_t alignment = 1, size = 0;
1253 int byte_order = trace->byte_order;
1254 int signedness = 0;
1255 int has_alignment = 0, has_size = 0;
1256 int base = 0;
1257 enum ctf_string_encoding encoding = CTF_STRING_NONE;
1258 struct ctf_clock *clock = NULL;
1259 struct declaration_integer *integer_declaration;
1260
1261 bt_list_for_each_entry(expression, expressions, siblings) {
1262 struct ctf_node *left, *right;
1263
1264 left = _bt_list_first_entry(&expression->u.ctf_expression.left, struct ctf_node, siblings);
1265 right = _bt_list_first_entry(&expression->u.ctf_expression.right, struct ctf_node, siblings);
1266 assert(left->u.unary_expression.type == UNARY_STRING);
1267 if (!strcmp(left->u.unary_expression.u.string, "signed")) {
1268 signedness = get_boolean(fd, depth, right);
1269 if (signedness < 0)
1270 return NULL;
1271 } else if (!strcmp(left->u.unary_expression.u.string, "byte_order")) {
1272 byte_order = get_byte_order(fd, depth, right, trace);
1273 if (byte_order < 0)
1274 return NULL;
1275 } else if (!strcmp(left->u.unary_expression.u.string, "size")) {
1276 if (right->u.unary_expression.type != UNARY_UNSIGNED_CONSTANT) {
1277 fprintf(fd, "[error] %s: size: expecting unsigned constant\n",
1278 __func__);
1279 return NULL;
1280 }
1281 size = right->u.unary_expression.u.unsigned_constant;
1282 has_size = 1;
1283 } else if (!strcmp(left->u.unary_expression.u.string, "align")) {
1284 if (right->u.unary_expression.type != UNARY_UNSIGNED_CONSTANT) {
1285 fprintf(fd, "[error] %s: align: expecting unsigned constant\n",
1286 __func__);
1287 return NULL;
1288 }
1289 alignment = right->u.unary_expression.u.unsigned_constant;
1290 /* Make sure alignment is a power of two */
1291 if (alignment == 0 || (alignment & (alignment - 1)) != 0) {
1292 fprintf(fd, "[error] %s: align: expecting power of two\n",
1293 __func__);
1294 return NULL;
1295 }
1296 has_alignment = 1;
1297 } else if (!strcmp(left->u.unary_expression.u.string, "base")) {
1298 switch (right->u.unary_expression.type) {
1299 case UNARY_UNSIGNED_CONSTANT:
1300 switch (right->u.unary_expression.u.unsigned_constant) {
1301 case 2:
1302 case 8:
1303 case 10:
1304 case 16:
1305 base = right->u.unary_expression.u.unsigned_constant;
1306 break;
1307 default:
1308 fprintf(fd, "[error] %s: base not supported (%" PRIu64 ")\n",
1309 __func__, right->u.unary_expression.u.unsigned_constant);
1310 return NULL;
1311 }
1312 break;
1313 case UNARY_STRING:
1314 {
1315 char *s_right = concatenate_unary_strings(&expression->u.ctf_expression.right);
1316 if (!s_right) {
1317 fprintf(fd, "[error] %s: unexpected unary expression for integer base\n", __func__);
1318 g_free(s_right);
1319 return NULL;
1320 }
1321 if (!strcmp(s_right, "decimal") || !strcmp(s_right, "dec") || !strcmp(s_right, "d")
1322 || !strcmp(s_right, "i") || !strcmp(s_right, "u")) {
1323 base = 10;
1324 } else if (!strcmp(s_right, "hexadecimal") || !strcmp(s_right, "hex")
1325 || !strcmp(s_right, "x") || !strcmp(s_right, "X")
1326 || !strcmp(s_right, "p")) {
1327 base = 16;
1328 } else if (!strcmp(s_right, "octal") || !strcmp(s_right, "oct")
1329 || !strcmp(s_right, "o")) {
1330 base = 8;
1331 } else if (!strcmp(s_right, "binary") || !strcmp(s_right, "b")) {
1332 base = 2;
1333 } else {
1334 fprintf(fd, "[error] %s: unexpected expression for integer base (%s)\n", __func__, s_right);
1335 g_free(s_right);
1336 return NULL;
1337 }
1338
1339 g_free(s_right);
1340 break;
1341 }
1342 default:
1343 fprintf(fd, "[error] %s: base: expecting unsigned constant or unary string\n",
1344 __func__);
1345 return NULL;
1346 }
1347 } else if (!strcmp(left->u.unary_expression.u.string, "encoding")) {
1348 char *s_right;
1349
1350 if (right->u.unary_expression.type != UNARY_STRING) {
1351 fprintf(fd, "[error] %s: encoding: expecting unary string\n",
1352 __func__);
1353 return NULL;
1354 }
1355 s_right = concatenate_unary_strings(&expression->u.ctf_expression.right);
1356 if (!s_right) {
1357 fprintf(fd, "[error] %s: unexpected unary expression for integer base\n", __func__);
1358 g_free(s_right);
1359 return NULL;
1360 }
1361 if (!strcmp(s_right, "UTF8")
1362 || !strcmp(s_right, "utf8")
1363 || !strcmp(s_right, "utf-8")
1364 || !strcmp(s_right, "UTF-8"))
1365 encoding = CTF_STRING_UTF8;
1366 else if (!strcmp(s_right, "ASCII")
1367 || !strcmp(s_right, "ascii"))
1368 encoding = CTF_STRING_ASCII;
1369 else if (!strcmp(s_right, "none"))
1370 encoding = CTF_STRING_NONE;
1371 else {
1372 fprintf(fd, "[error] %s: unknown string encoding \"%s\"\n", __func__, s_right);
1373 g_free(s_right);
1374 return NULL;
1375 }
1376 g_free(s_right);
1377 } else if (!strcmp(left->u.unary_expression.u.string, "map")) {
1378 GQuark clock_name;
1379
1380 if (right->u.unary_expression.type != UNARY_STRING) {
1381 fprintf(fd, "[error] %s: map: expecting identifier\n",
1382 __func__);
1383 return NULL;
1384 }
1385 /* currently only support clock.name.value */
1386 clock_name = get_map_clock_name_value(&expression->u.ctf_expression.right);
1387 if (!clock_name) {
1388 char *s_right;
1389
1390 s_right = concatenate_unary_strings(&expression->u.ctf_expression.right);
1391 if (!s_right) {
1392 fprintf(fd, "[error] %s: unexpected unary expression for integer map\n", __func__);
1393 g_free(s_right);
1394 return NULL;
1395 }
1396 fprintf(fd, "[warning] %s: unknown map %s in integer declaration\n", __func__,
1397 s_right);
1398 g_free(s_right);
1399 continue;
1400 }
1401 clock = trace_clock_lookup(trace, clock_name);
1402 if (!clock) {
1403 fprintf(fd, "[error] %s: map: unable to find clock %s declaration\n",
1404 __func__, g_quark_to_string(clock_name));
1405 return NULL;
1406 }
1407 } else {
1408 fprintf(fd, "[warning] %s: unknown attribute name %s\n",
1409 __func__, left->u.unary_expression.u.string);
1410 /* Fall-through after warning */
1411 }
1412 }
1413 if (!has_size) {
1414 fprintf(fd, "[error] %s: missing size attribute\n", __func__);
1415 return NULL;
1416 }
1417 if (!has_alignment) {
1418 if (size % CHAR_BIT) {
1419 /* bit-packed alignment */
1420 alignment = 1;
1421 } else {
1422 /* byte-packed alignment */
1423 alignment = CHAR_BIT;
1424 }
1425 }
1426 integer_declaration = integer_declaration_new(size,
1427 byte_order, signedness, alignment,
1428 base, encoding, clock);
1429 return &integer_declaration->p;
1430 }
1431
1432 static
1433 struct declaration *ctf_declaration_floating_point_visit(FILE *fd, int depth,
1434 struct bt_list_head *expressions,
1435 struct ctf_trace *trace)
1436 {
1437 struct ctf_node *expression;
1438 uint64_t alignment = 1, exp_dig = 0, mant_dig = 0,
1439 byte_order = trace->byte_order;
1440 int has_alignment = 0, has_exp_dig = 0, has_mant_dig = 0;
1441 struct declaration_float *float_declaration;
1442
1443 bt_list_for_each_entry(expression, expressions, siblings) {
1444 struct ctf_node *left, *right;
1445
1446 left = _bt_list_first_entry(&expression->u.ctf_expression.left, struct ctf_node, siblings);
1447 right = _bt_list_first_entry(&expression->u.ctf_expression.right, struct ctf_node, siblings);
1448 assert(left->u.unary_expression.type == UNARY_STRING);
1449 if (!strcmp(left->u.unary_expression.u.string, "byte_order")) {
1450 byte_order = get_byte_order(fd, depth, right, trace);
1451 if (byte_order < 0)
1452 return NULL;
1453 } else if (!strcmp(left->u.unary_expression.u.string, "exp_dig")) {
1454 if (right->u.unary_expression.type != UNARY_UNSIGNED_CONSTANT) {
1455 fprintf(fd, "[error] %s: exp_dig: expecting unsigned constant\n",
1456 __func__);
1457 return NULL;
1458 }
1459 exp_dig = right->u.unary_expression.u.unsigned_constant;
1460 has_exp_dig = 1;
1461 } else if (!strcmp(left->u.unary_expression.u.string, "mant_dig")) {
1462 if (right->u.unary_expression.type != UNARY_UNSIGNED_CONSTANT) {
1463 fprintf(fd, "[error] %s: mant_dig: expecting unsigned constant\n",
1464 __func__);
1465 return NULL;
1466 }
1467 mant_dig = right->u.unary_expression.u.unsigned_constant;
1468 has_mant_dig = 1;
1469 } else if (!strcmp(left->u.unary_expression.u.string, "align")) {
1470 if (right->u.unary_expression.type != UNARY_UNSIGNED_CONSTANT) {
1471 fprintf(fd, "[error] %s: align: expecting unsigned constant\n",
1472 __func__);
1473 return NULL;
1474 }
1475 alignment = right->u.unary_expression.u.unsigned_constant;
1476 /* Make sure alignment is a power of two */
1477 if (alignment == 0 || (alignment & (alignment - 1)) != 0) {
1478 fprintf(fd, "[error] %s: align: expecting power of two\n",
1479 __func__);
1480 return NULL;
1481 }
1482 has_alignment = 1;
1483 } else {
1484 fprintf(fd, "[warning] %s: unknown attribute name %s\n",
1485 __func__, left->u.unary_expression.u.string);
1486 /* Fall-through after warning */
1487 }
1488 }
1489 if (!has_mant_dig) {
1490 fprintf(fd, "[error] %s: missing mant_dig attribute\n", __func__);
1491 return NULL;
1492 }
1493 if (!has_exp_dig) {
1494 fprintf(fd, "[error] %s: missing exp_dig attribute\n", __func__);
1495 return NULL;
1496 }
1497 if (!has_alignment) {
1498 if ((mant_dig + exp_dig) % CHAR_BIT) {
1499 /* bit-packed alignment */
1500 alignment = 1;
1501 } else {
1502 /* byte-packed alignment */
1503 alignment = CHAR_BIT;
1504 }
1505 }
1506 float_declaration = float_declaration_new(mant_dig, exp_dig,
1507 byte_order, alignment);
1508 return &float_declaration->p;
1509 }
1510
1511 static
1512 struct declaration *ctf_declaration_string_visit(FILE *fd, int depth,
1513 struct bt_list_head *expressions,
1514 struct ctf_trace *trace)
1515 {
1516 struct ctf_node *expression;
1517 const char *encoding_c = NULL;
1518 enum ctf_string_encoding encoding = CTF_STRING_UTF8;
1519 struct declaration_string *string_declaration;
1520
1521 bt_list_for_each_entry(expression, expressions, siblings) {
1522 struct ctf_node *left, *right;
1523
1524 left = _bt_list_first_entry(&expression->u.ctf_expression.left, struct ctf_node, siblings);
1525 right = _bt_list_first_entry(&expression->u.ctf_expression.right, struct ctf_node, siblings);
1526 assert(left->u.unary_expression.type == UNARY_STRING);
1527 if (!strcmp(left->u.unary_expression.u.string, "encoding")) {
1528 if (right->u.unary_expression.type != UNARY_STRING) {
1529 fprintf(fd, "[error] %s: encoding: expecting string\n",
1530 __func__);
1531 return NULL;
1532 }
1533 encoding_c = right->u.unary_expression.u.string;
1534 } else {
1535 fprintf(fd, "[warning] %s: unknown attribute name %s\n",
1536 __func__, left->u.unary_expression.u.string);
1537 /* Fall-through after warning */
1538 }
1539 }
1540 if (encoding_c && !strcmp(encoding_c, "ASCII"))
1541 encoding = CTF_STRING_ASCII;
1542 string_declaration = string_declaration_new(encoding);
1543 return &string_declaration->p;
1544 }
1545
1546
1547 static
1548 struct declaration *ctf_type_specifier_list_visit(FILE *fd,
1549 int depth, struct ctf_node *type_specifier_list,
1550 struct declaration_scope *declaration_scope,
1551 struct ctf_trace *trace)
1552 {
1553 struct ctf_node *first;
1554 struct ctf_node *node;
1555
1556 assert(type_specifier_list->type == NODE_TYPE_SPECIFIER_LIST);
1557
1558 first = _bt_list_first_entry(&type_specifier_list->u.type_specifier_list.head, struct ctf_node, siblings);
1559
1560 assert(first->type == NODE_TYPE_SPECIFIER);
1561
1562 node = first->u.type_specifier.node;
1563
1564 switch (first->u.type_specifier.type) {
1565 case TYPESPEC_FLOATING_POINT:
1566 return ctf_declaration_floating_point_visit(fd, depth,
1567 &node->u.floating_point.expressions, trace);
1568 case TYPESPEC_INTEGER:
1569 return ctf_declaration_integer_visit(fd, depth,
1570 &node->u.integer.expressions, trace);
1571 case TYPESPEC_STRING:
1572 return ctf_declaration_string_visit(fd, depth,
1573 &node->u.string.expressions, trace);
1574 case TYPESPEC_STRUCT:
1575 return ctf_declaration_struct_visit(fd, depth,
1576 node->u._struct.name,
1577 &node->u._struct.declaration_list,
1578 node->u._struct.has_body,
1579 &node->u._struct.min_align,
1580 declaration_scope,
1581 trace);
1582 case TYPESPEC_VARIANT:
1583 return ctf_declaration_variant_visit(fd, depth,
1584 node->u.variant.name,
1585 node->u.variant.choice,
1586 &node->u.variant.declaration_list,
1587 node->u.variant.has_body,
1588 declaration_scope,
1589 trace);
1590 case TYPESPEC_ENUM:
1591 return ctf_declaration_enum_visit(fd, depth,
1592 node->u._enum.enum_id,
1593 node->u._enum.container_type,
1594 &node->u._enum.enumerator_list,
1595 node->u._enum.has_body,
1596 declaration_scope,
1597 trace);
1598
1599 case TYPESPEC_VOID:
1600 case TYPESPEC_CHAR:
1601 case TYPESPEC_SHORT:
1602 case TYPESPEC_INT:
1603 case TYPESPEC_LONG:
1604 case TYPESPEC_FLOAT:
1605 case TYPESPEC_DOUBLE:
1606 case TYPESPEC_SIGNED:
1607 case TYPESPEC_UNSIGNED:
1608 case TYPESPEC_BOOL:
1609 case TYPESPEC_COMPLEX:
1610 case TYPESPEC_IMAGINARY:
1611 case TYPESPEC_CONST:
1612 case TYPESPEC_ID_TYPE:
1613 return ctf_declaration_type_specifier_visit(fd, depth,
1614 type_specifier_list, declaration_scope);
1615 default:
1616 fprintf(fd, "[error] %s: unexpected node type %d\n", __func__, (int) first->u.type_specifier.type);
1617 return NULL;
1618 }
1619 }
1620
1621 static
1622 int ctf_event_declaration_visit(FILE *fd, int depth, struct ctf_node *node, struct ctf_event_declaration *event, struct ctf_trace *trace)
1623 {
1624 int ret = 0;
1625
1626 switch (node->type) {
1627 case NODE_TYPEDEF:
1628 ret = ctf_typedef_visit(fd, depth + 1,
1629 event->declaration_scope,
1630 node->u._typedef.type_specifier_list,
1631 &node->u._typedef.type_declarators,
1632 trace);
1633 if (ret)
1634 return ret;
1635 break;
1636 case NODE_TYPEALIAS:
1637 ret = ctf_typealias_visit(fd, depth + 1,
1638 event->declaration_scope,
1639 node->u.typealias.target, node->u.typealias.alias,
1640 trace);
1641 if (ret)
1642 return ret;
1643 break;
1644 case NODE_CTF_EXPRESSION:
1645 {
1646 char *left;
1647
1648 left = concatenate_unary_strings(&node->u.ctf_expression.left);
1649 if (!strcmp(left, "name")) {
1650 char *right;
1651
1652 if (CTF_EVENT_FIELD_IS_SET(event, name)) {
1653 fprintf(fd, "[error] %s: name already declared in event declaration\n", __func__);
1654 ret = -EPERM;
1655 goto error;
1656 }
1657 right = concatenate_unary_strings(&node->u.ctf_expression.right);
1658 if (!right) {
1659 fprintf(fd, "[error] %s: unexpected unary expression for event name\n", __func__);
1660 ret = -EINVAL;
1661 goto error;
1662 }
1663 event->name = g_quark_from_string(right);
1664 g_free(right);
1665 CTF_EVENT_SET_FIELD(event, name);
1666 } else if (!strcmp(left, "id")) {
1667 if (CTF_EVENT_FIELD_IS_SET(event, id)) {
1668 fprintf(fd, "[error] %s: id already declared in event declaration\n", __func__);
1669 ret = -EPERM;
1670 goto error;
1671 }
1672 ret = get_unary_unsigned(&node->u.ctf_expression.right, &event->id);
1673 if (ret) {
1674 fprintf(fd, "[error] %s: unexpected unary expression for event id\n", __func__);
1675 ret = -EINVAL;
1676 goto error;
1677 }
1678 CTF_EVENT_SET_FIELD(event, id);
1679 } else if (!strcmp(left, "stream_id")) {
1680 if (CTF_EVENT_FIELD_IS_SET(event, stream_id)) {
1681 fprintf(fd, "[error] %s: stream_id already declared in event declaration\n", __func__);
1682 ret = -EPERM;
1683 goto error;
1684 }
1685 ret = get_unary_unsigned(&node->u.ctf_expression.right, &event->stream_id);
1686 if (ret) {
1687 fprintf(fd, "[error] %s: unexpected unary expression for event stream_id\n", __func__);
1688 ret = -EINVAL;
1689 goto error;
1690 }
1691 event->stream = trace_stream_lookup(trace, event->stream_id);
1692 if (!event->stream) {
1693 fprintf(fd, "[error] %s: stream id %" PRIu64 " cannot be found\n", __func__, event->stream_id);
1694 ret = -EINVAL;
1695 goto error;
1696 }
1697 CTF_EVENT_SET_FIELD(event, stream_id);
1698 } else if (!strcmp(left, "context")) {
1699 struct declaration *declaration;
1700
1701 if (event->context_decl) {
1702 fprintf(fd, "[error] %s: context already declared in event declaration\n", __func__);
1703 ret = -EINVAL;
1704 goto error;
1705 }
1706 declaration = ctf_type_specifier_list_visit(fd, depth,
1707 _bt_list_first_entry(&node->u.ctf_expression.right,
1708 struct ctf_node, siblings),
1709 event->declaration_scope, trace);
1710 if (!declaration) {
1711 ret = -EPERM;
1712 goto error;
1713 }
1714 if (declaration->id != CTF_TYPE_STRUCT) {
1715 ret = -EPERM;
1716 goto error;
1717 }
1718 event->context_decl = container_of(declaration, struct declaration_struct, p);
1719 } else if (!strcmp(left, "fields")) {
1720 struct declaration *declaration;
1721
1722 if (event->fields_decl) {
1723 fprintf(fd, "[error] %s: fields already declared in event declaration\n", __func__);
1724 ret = -EINVAL;
1725 goto error;
1726 }
1727 declaration = ctf_type_specifier_list_visit(fd, depth,
1728 _bt_list_first_entry(&node->u.ctf_expression.right,
1729 struct ctf_node, siblings),
1730 event->declaration_scope, trace);
1731 if (!declaration) {
1732 ret = -EPERM;
1733 goto error;
1734 }
1735 if (declaration->id != CTF_TYPE_STRUCT) {
1736 ret = -EPERM;
1737 goto error;
1738 }
1739 event->fields_decl = container_of(declaration, struct declaration_struct, p);
1740 } else if (!strcmp(left, "loglevel")) {
1741 int64_t loglevel = -1;
1742
1743 if (CTF_EVENT_FIELD_IS_SET(event, loglevel)) {
1744 fprintf(fd, "[error] %s: loglevel already declared in event declaration\n", __func__);
1745 ret = -EPERM;
1746 goto error;
1747 }
1748 ret = get_unary_signed(&node->u.ctf_expression.right, &loglevel);
1749 if (ret) {
1750 fprintf(fd, "[error] %s: unexpected unary expression for event loglevel\n", __func__);
1751 ret = -EINVAL;
1752 goto error;
1753 }
1754 event->loglevel = (int) loglevel;
1755 CTF_EVENT_SET_FIELD(event, loglevel);
1756 } else if (!strcmp(left, "model.emf.uri")) {
1757 char *right;
1758
1759 if (CTF_EVENT_FIELD_IS_SET(event, model_emf_uri)) {
1760 fprintf(fd, "[error] %s: model.emf.uri already declared in event declaration\n", __func__);
1761 ret = -EPERM;
1762 goto error;
1763 }
1764 right = concatenate_unary_strings(&node->u.ctf_expression.right);
1765 if (!right) {
1766 fprintf(fd, "[error] %s: unexpected unary expression for event model.emf.uri\n", __func__);
1767 ret = -EINVAL;
1768 goto error;
1769 }
1770 event->model_emf_uri = g_quark_from_string(right);
1771 g_free(right);
1772 CTF_EVENT_SET_FIELD(event, model_emf_uri);
1773 } else {
1774 fprintf(fd, "[warning] %s: attribute \"%s\" is unknown in event declaration.\n", __func__, left);
1775 /* Fall-through after warning */
1776 }
1777 error:
1778 g_free(left);
1779 break;
1780 }
1781 default:
1782 return -EPERM;
1783 /* TODO: declaration specifier should be added. */
1784 }
1785
1786 return ret;
1787 }
1788
1789 static
1790 int ctf_event_visit(FILE *fd, int depth, struct ctf_node *node,
1791 struct declaration_scope *parent_declaration_scope, struct ctf_trace *trace)
1792 {
1793 int ret = 0;
1794 struct ctf_node *iter;
1795 struct ctf_event_declaration *event;
1796 struct bt_ctf_event_decl *event_decl;
1797
1798 event_decl = g_new0(struct bt_ctf_event_decl, 1);
1799 event = &event_decl->parent;
1800 event->declaration_scope = new_declaration_scope(parent_declaration_scope);
1801 event->loglevel = -1;
1802 bt_list_for_each_entry(iter, &node->u.event.declaration_list, siblings) {
1803 ret = ctf_event_declaration_visit(fd, depth + 1, iter, event, trace);
1804 if (ret)
1805 goto error;
1806 }
1807 if (!CTF_EVENT_FIELD_IS_SET(event, name)) {
1808 ret = -EPERM;
1809 fprintf(fd, "[error] %s: missing name field in event declaration\n", __func__);
1810 goto error;
1811 }
1812 if (!CTF_EVENT_FIELD_IS_SET(event, stream_id)) {
1813 /* Allow missing stream_id if there is only a single stream */
1814 switch (trace->streams->len) {
1815 case 0: /* Create stream if there was none. */
1816 ret = ctf_stream_visit(fd, depth, NULL, trace->root_declaration_scope, trace);
1817 if (ret)
1818 goto error;
1819 /* Fall-through */
1820 case 1:
1821 event->stream_id = 0;
1822 event->stream = trace_stream_lookup(trace, event->stream_id);
1823 break;
1824 default:
1825 ret = -EPERM;
1826 fprintf(fd, "[error] %s: missing stream_id field in event declaration\n", __func__);
1827 goto error;
1828 }
1829 }
1830 /* Allow only one event without id per stream */
1831 if (!CTF_EVENT_FIELD_IS_SET(event, id)
1832 && event->stream->events_by_id->len != 0) {
1833 ret = -EPERM;
1834 fprintf(fd, "[error] %s: missing id field in event declaration\n", __func__);
1835 goto error;
1836 }
1837 if (event->stream->events_by_id->len <= event->id)
1838 g_ptr_array_set_size(event->stream->events_by_id, event->id + 1);
1839 g_ptr_array_index(event->stream->events_by_id, event->id) = event;
1840 g_hash_table_insert(event->stream->event_quark_to_id,
1841 (gpointer) (unsigned long) event->name,
1842 &event->id);
1843 g_ptr_array_add(trace->event_declarations, event_decl);
1844 return 0;
1845
1846 error:
1847 if (event->fields_decl)
1848 declaration_unref(&event->fields_decl->p);
1849 if (event->context_decl)
1850 declaration_unref(&event->context_decl->p);
1851 free_declaration_scope(event->declaration_scope);
1852 g_free(event_decl);
1853 return ret;
1854 }
1855
1856
1857 static
1858 int ctf_stream_declaration_visit(FILE *fd, int depth, struct ctf_node *node, struct ctf_stream_declaration *stream, struct ctf_trace *trace)
1859 {
1860 int ret = 0;
1861
1862 switch (node->type) {
1863 case NODE_TYPEDEF:
1864 ret = ctf_typedef_visit(fd, depth + 1,
1865 stream->declaration_scope,
1866 node->u._typedef.type_specifier_list,
1867 &node->u._typedef.type_declarators,
1868 trace);
1869 if (ret)
1870 return ret;
1871 break;
1872 case NODE_TYPEALIAS:
1873 ret = ctf_typealias_visit(fd, depth + 1,
1874 stream->declaration_scope,
1875 node->u.typealias.target, node->u.typealias.alias,
1876 trace);
1877 if (ret)
1878 return ret;
1879 break;
1880 case NODE_CTF_EXPRESSION:
1881 {
1882 char *left;
1883
1884 left = concatenate_unary_strings(&node->u.ctf_expression.left);
1885 if (!strcmp(left, "id")) {
1886 if (CTF_STREAM_FIELD_IS_SET(stream, stream_id)) {
1887 fprintf(fd, "[error] %s: id already declared in stream declaration\n", __func__);
1888 ret = -EPERM;
1889 goto error;
1890 }
1891 ret = get_unary_unsigned(&node->u.ctf_expression.right, &stream->stream_id);
1892 if (ret) {
1893 fprintf(fd, "[error] %s: unexpected unary expression for stream id\n", __func__);
1894 ret = -EINVAL;
1895 goto error;
1896 }
1897 CTF_STREAM_SET_FIELD(stream, stream_id);
1898 } else if (!strcmp(left, "event.header")) {
1899 struct declaration *declaration;
1900
1901 if (stream->event_header_decl) {
1902 fprintf(fd, "[error] %s: event.header already declared in stream declaration\n", __func__);
1903 ret = -EINVAL;
1904 goto error;
1905 }
1906 declaration = ctf_type_specifier_list_visit(fd, depth,
1907 _bt_list_first_entry(&node->u.ctf_expression.right,
1908 struct ctf_node, siblings),
1909 stream->declaration_scope, trace);
1910 if (!declaration) {
1911 ret = -EPERM;
1912 goto error;
1913 }
1914 if (declaration->id != CTF_TYPE_STRUCT) {
1915 ret = -EPERM;
1916 goto error;
1917 }
1918 stream->event_header_decl = container_of(declaration, struct declaration_struct, p);
1919 } else if (!strcmp(left, "event.context")) {
1920 struct declaration *declaration;
1921
1922 if (stream->event_context_decl) {
1923 fprintf(fd, "[error] %s: event.context already declared in stream declaration\n", __func__);
1924 ret = -EINVAL;
1925 goto error;
1926 }
1927 declaration = ctf_type_specifier_list_visit(fd, depth,
1928 _bt_list_first_entry(&node->u.ctf_expression.right,
1929 struct ctf_node, siblings),
1930 stream->declaration_scope, trace);
1931 if (!declaration) {
1932 ret = -EPERM;
1933 goto error;
1934 }
1935 if (declaration->id != CTF_TYPE_STRUCT) {
1936 ret = -EPERM;
1937 goto error;
1938 }
1939 stream->event_context_decl = container_of(declaration, struct declaration_struct, p);
1940 } else if (!strcmp(left, "packet.context")) {
1941 struct declaration *declaration;
1942
1943 if (stream->packet_context_decl) {
1944 fprintf(fd, "[error] %s: packet.context already declared in stream declaration\n", __func__);
1945 ret = -EINVAL;
1946 goto error;
1947 }
1948 declaration = ctf_type_specifier_list_visit(fd, depth,
1949 _bt_list_first_entry(&node->u.ctf_expression.right,
1950 struct ctf_node, siblings),
1951 stream->declaration_scope, trace);
1952 if (!declaration) {
1953 ret = -EPERM;
1954 goto error;
1955 }
1956 if (declaration->id != CTF_TYPE_STRUCT) {
1957 ret = -EPERM;
1958 goto error;
1959 }
1960 stream->packet_context_decl = container_of(declaration, struct declaration_struct, p);
1961 } else {
1962 fprintf(fd, "[warning] %s: attribute \"%s\" is unknown in stream declaration.\n", __func__, left);
1963 /* Fall-through after warning */
1964 }
1965
1966 error:
1967 g_free(left);
1968 break;
1969 }
1970 default:
1971 return -EPERM;
1972 /* TODO: declaration specifier should be added. */
1973 }
1974
1975 return ret;
1976 }
1977
1978 static
1979 int ctf_stream_visit(FILE *fd, int depth, struct ctf_node *node,
1980 struct declaration_scope *parent_declaration_scope, struct ctf_trace *trace)
1981 {
1982 int ret = 0;
1983 struct ctf_node *iter;
1984 struct ctf_stream_declaration *stream;
1985
1986 stream = g_new0(struct ctf_stream_declaration, 1);
1987 stream->declaration_scope = new_declaration_scope(parent_declaration_scope);
1988 stream->events_by_id = g_ptr_array_new();
1989 stream->event_quark_to_id = g_hash_table_new(g_direct_hash, g_direct_equal);
1990 stream->streams = g_ptr_array_new();
1991 if (node) {
1992 bt_list_for_each_entry(iter, &node->u.stream.declaration_list, siblings) {
1993 ret = ctf_stream_declaration_visit(fd, depth + 1, iter, stream, trace);
1994 if (ret)
1995 goto error;
1996 }
1997 }
1998 if (CTF_STREAM_FIELD_IS_SET(stream, stream_id)) {
1999 /* check that packet header has stream_id field. */
2000 if (!trace->packet_header_decl
2001 || struct_declaration_lookup_field_index(trace->packet_header_decl, g_quark_from_static_string("stream_id")) < 0) {
2002 ret = -EPERM;
2003 fprintf(fd, "[error] %s: missing stream_id field in packet header declaration, but stream_id attribute is declared for stream.\n", __func__);
2004 goto error;
2005 }
2006 } else {
2007 /* Allow only one id-less stream */
2008 if (trace->streams->len != 0) {
2009 ret = -EPERM;
2010 fprintf(fd, "[error] %s: missing id field in stream declaration\n", __func__);
2011 goto error;
2012 }
2013 stream->stream_id = 0;
2014 }
2015 if (trace->streams->len <= stream->stream_id)
2016 g_ptr_array_set_size(trace->streams, stream->stream_id + 1);
2017 g_ptr_array_index(trace->streams, stream->stream_id) = stream;
2018 stream->trace = trace;
2019
2020 return 0;
2021
2022 error:
2023 if (stream->event_header_decl)
2024 declaration_unref(&stream->event_header_decl->p);
2025 if (stream->event_context_decl)
2026 declaration_unref(&stream->event_context_decl->p);
2027 if (stream->packet_context_decl)
2028 declaration_unref(&stream->packet_context_decl->p);
2029 g_ptr_array_free(stream->streams, TRUE);
2030 g_ptr_array_free(stream->events_by_id, TRUE);
2031 g_hash_table_destroy(stream->event_quark_to_id);
2032 free_declaration_scope(stream->declaration_scope);
2033 g_free(stream);
2034 return ret;
2035 }
2036
2037 static
2038 int ctf_trace_declaration_visit(FILE *fd, int depth, struct ctf_node *node, struct ctf_trace *trace)
2039 {
2040 int ret = 0;
2041
2042 switch (node->type) {
2043 case NODE_TYPEDEF:
2044 ret = ctf_typedef_visit(fd, depth + 1,
2045 trace->declaration_scope,
2046 node->u._typedef.type_specifier_list,
2047 &node->u._typedef.type_declarators,
2048 trace);
2049 if (ret)
2050 return ret;
2051 break;
2052 case NODE_TYPEALIAS:
2053 ret = ctf_typealias_visit(fd, depth + 1,
2054 trace->declaration_scope,
2055 node->u.typealias.target, node->u.typealias.alias,
2056 trace);
2057 if (ret)
2058 return ret;
2059 break;
2060 case NODE_CTF_EXPRESSION:
2061 {
2062 char *left;
2063
2064 left = concatenate_unary_strings(&node->u.ctf_expression.left);
2065 if (!strcmp(left, "major")) {
2066 if (CTF_TRACE_FIELD_IS_SET(trace, major)) {
2067 fprintf(fd, "[error] %s: major already declared in trace declaration\n", __func__);
2068 ret = -EPERM;
2069 goto error;
2070 }
2071 ret = get_unary_unsigned(&node->u.ctf_expression.right, &trace->major);
2072 if (ret) {
2073 fprintf(fd, "[error] %s: unexpected unary expression for trace major number\n", __func__);
2074 ret = -EINVAL;
2075 goto error;
2076 }
2077 CTF_TRACE_SET_FIELD(trace, major);
2078 } else if (!strcmp(left, "minor")) {
2079 if (CTF_TRACE_FIELD_IS_SET(trace, minor)) {
2080 fprintf(fd, "[error] %s: minor already declared in trace declaration\n", __func__);
2081 ret = -EPERM;
2082 goto error;
2083 }
2084 ret = get_unary_unsigned(&node->u.ctf_expression.right, &trace->minor);
2085 if (ret) {
2086 fprintf(fd, "[error] %s: unexpected unary expression for trace minor number\n", __func__);
2087 ret = -EINVAL;
2088 goto error;
2089 }
2090 CTF_TRACE_SET_FIELD(trace, minor);
2091 } else if (!strcmp(left, "uuid")) {
2092 unsigned char uuid[BABELTRACE_UUID_LEN];
2093
2094 ret = get_unary_uuid(&node->u.ctf_expression.right, uuid);
2095 if (ret) {
2096 fprintf(fd, "[error] %s: unexpected unary expression for trace uuid\n", __func__);
2097 ret = -EINVAL;
2098 goto error;
2099 }
2100 if (CTF_TRACE_FIELD_IS_SET(trace, uuid)
2101 && babeltrace_uuid_compare(uuid, trace->uuid)) {
2102 fprintf(fd, "[error] %s: uuid mismatch\n", __func__);
2103 ret = -EPERM;
2104 goto error;
2105 } else {
2106 memcpy(trace->uuid, uuid, sizeof(uuid));
2107 }
2108 CTF_TRACE_SET_FIELD(trace, uuid);
2109 } else if (!strcmp(left, "byte_order")) {
2110 struct ctf_node *right;
2111 int byte_order;
2112
2113 right = _bt_list_first_entry(&node->u.ctf_expression.right, struct ctf_node, siblings);
2114 byte_order = get_trace_byte_order(fd, depth, right);
2115 if (byte_order < 0)
2116 return -EINVAL;
2117
2118 if (CTF_TRACE_FIELD_IS_SET(trace, byte_order)
2119 && byte_order != trace->byte_order) {
2120 fprintf(fd, "[error] %s: endianness mismatch\n", __func__);
2121 ret = -EPERM;
2122 goto error;
2123 } else {
2124 if (byte_order != trace->byte_order) {
2125 trace->byte_order = byte_order;
2126 /*
2127 * We need to restart
2128 * construction of the
2129 * intermediate representation.
2130 */
2131 trace->field_mask = 0;
2132 CTF_TRACE_SET_FIELD(trace, byte_order);
2133 ret = -EINTR;
2134 goto error;
2135 }
2136 }
2137 CTF_TRACE_SET_FIELD(trace, byte_order);
2138 } else if (!strcmp(left, "packet.header")) {
2139 struct declaration *declaration;
2140
2141 if (trace->packet_header_decl) {
2142 fprintf(fd, "[error] %s: packet.header already declared in trace declaration\n", __func__);
2143 ret = -EINVAL;
2144 goto error;
2145 }
2146 declaration = ctf_type_specifier_list_visit(fd, depth,
2147 _bt_list_first_entry(&node->u.ctf_expression.right,
2148 struct ctf_node, siblings),
2149 trace->declaration_scope, trace);
2150 if (!declaration) {
2151 ret = -EPERM;
2152 goto error;
2153 }
2154 if (declaration->id != CTF_TYPE_STRUCT) {
2155 ret = -EPERM;
2156 goto error;
2157 }
2158 trace->packet_header_decl = container_of(declaration, struct declaration_struct, p);
2159 } else {
2160 fprintf(fd, "[warning] %s: attribute \"%s\" is unknown in trace declaration.\n", __func__, left);
2161 }
2162
2163 error:
2164 g_free(left);
2165 break;
2166 }
2167 default:
2168 return -EPERM;
2169 /* TODO: declaration specifier should be added. */
2170 }
2171
2172 return ret;
2173 }
2174
2175 static
2176 int ctf_trace_visit(FILE *fd, int depth, struct ctf_node *node, struct ctf_trace *trace)
2177 {
2178 int ret = 0;
2179 struct ctf_node *iter;
2180
2181 if (trace->declaration_scope)
2182 return -EEXIST;
2183 trace->declaration_scope = new_declaration_scope(trace->root_declaration_scope);
2184 trace->streams = g_ptr_array_new();
2185 trace->event_declarations = g_ptr_array_new();
2186 bt_list_for_each_entry(iter, &node->u.trace.declaration_list, siblings) {
2187 ret = ctf_trace_declaration_visit(fd, depth + 1, iter, trace);
2188 if (ret)
2189 goto error;
2190 }
2191 if (!CTF_TRACE_FIELD_IS_SET(trace, major)) {
2192 ret = -EPERM;
2193 fprintf(fd, "[error] %s: missing major field in trace declaration\n", __func__);
2194 goto error;
2195 }
2196 if (!CTF_TRACE_FIELD_IS_SET(trace, minor)) {
2197 ret = -EPERM;
2198 fprintf(fd, "[error] %s: missing minor field in trace declaration\n", __func__);
2199 goto error;
2200 }
2201 if (!CTF_TRACE_FIELD_IS_SET(trace, byte_order)) {
2202 ret = -EPERM;
2203 fprintf(fd, "[error] %s: missing byte_order field in trace declaration\n", __func__);
2204 goto error;
2205 }
2206
2207 if (!CTF_TRACE_FIELD_IS_SET(trace, byte_order)) {
2208 /* check that the packet header contains a "magic" field */
2209 if (!trace->packet_header_decl
2210 || struct_declaration_lookup_field_index(trace->packet_header_decl, g_quark_from_static_string("magic")) < 0) {
2211 ret = -EPERM;
2212 fprintf(fd, "[error] %s: missing both byte_order and packet header magic number in trace declaration\n", __func__);
2213 goto error;
2214 }
2215 }
2216 return 0;
2217
2218 error:
2219 if (trace->packet_header_decl) {
2220 declaration_unref(&trace->packet_header_decl->p);
2221 trace->packet_header_decl = NULL;
2222 }
2223 g_ptr_array_free(trace->streams, TRUE);
2224 g_ptr_array_free(trace->event_declarations, TRUE);
2225 free_declaration_scope(trace->declaration_scope);
2226 trace->declaration_scope = NULL;
2227 return ret;
2228 }
2229
2230 static
2231 int ctf_clock_declaration_visit(FILE *fd, int depth, struct ctf_node *node,
2232 struct ctf_clock *clock, struct ctf_trace *trace)
2233 {
2234 int ret = 0;
2235
2236 switch (node->type) {
2237 case NODE_CTF_EXPRESSION:
2238 {
2239 char *left;
2240
2241 left = concatenate_unary_strings(&node->u.ctf_expression.left);
2242 if (!strcmp(left, "name")) {
2243 char *right;
2244
2245 if (CTF_CLOCK_FIELD_IS_SET(clock, name)) {
2246 fprintf(fd, "[error] %s: name already declared in clock declaration\n", __func__);
2247 ret = -EPERM;
2248 goto error;
2249 }
2250 right = concatenate_unary_strings(&node->u.ctf_expression.right);
2251 if (!right) {
2252 fprintf(fd, "[error] %s: unexpected unary expression for clock name\n", __func__);
2253 ret = -EINVAL;
2254 goto error;
2255 }
2256 clock->name = g_quark_from_string(right);
2257 g_free(right);
2258 CTF_CLOCK_SET_FIELD(clock, name);
2259 } else if (!strcmp(left, "uuid")) {
2260 char *right;
2261
2262 if (clock->uuid) {
2263 fprintf(fd, "[error] %s: uuid already declared in clock declaration\n", __func__);
2264 ret = -EPERM;
2265 goto error;
2266 }
2267 right = concatenate_unary_strings(&node->u.ctf_expression.right);
2268 if (!right) {
2269 fprintf(fd, "[error] %s: unexpected unary expression for clock uuid\n", __func__);
2270 ret = -EINVAL;
2271 goto error;
2272 }
2273 clock->uuid = g_quark_from_string(right);
2274 g_free(right);
2275 } else if (!strcmp(left, "description")) {
2276 char *right;
2277
2278 if (clock->description) {
2279 fprintf(fd, "[warning] %s: duplicated clock description\n", __func__);
2280 goto error; /* ret is 0, so not an actual error, just warn. */
2281 }
2282 right = concatenate_unary_strings(&node->u.ctf_expression.right);
2283 if (!right) {
2284 fprintf(fd, "[warning] %s: unexpected unary expression for clock description\n", __func__);
2285 goto error; /* ret is 0, so not an actual error, just warn. */
2286 }
2287 clock->description = right;
2288 } else if (!strcmp(left, "freq")) {
2289 if (CTF_CLOCK_FIELD_IS_SET(clock, freq)) {
2290 fprintf(fd, "[error] %s: freq already declared in clock declaration\n", __func__);
2291 ret = -EPERM;
2292 goto error;
2293 }
2294 ret = get_unary_unsigned(&node->u.ctf_expression.right, &clock->freq);
2295 if (ret) {
2296 fprintf(fd, "[error] %s: unexpected unary expression for clock freq\n", __func__);
2297 ret = -EINVAL;
2298 goto error;
2299 }
2300 CTF_CLOCK_SET_FIELD(clock, freq);
2301 } else if (!strcmp(left, "precision")) {
2302 if (clock->precision) {
2303 fprintf(fd, "[error] %s: precision already declared in clock declaration\n", __func__);
2304 ret = -EPERM;
2305 goto error;
2306 }
2307 ret = get_unary_unsigned(&node->u.ctf_expression.right, &clock->precision);
2308 if (ret) {
2309 fprintf(fd, "[error] %s: unexpected unary expression for clock precision\n", __func__);
2310 ret = -EINVAL;
2311 goto error;
2312 }
2313 } else if (!strcmp(left, "offset_s")) {
2314 if (clock->offset_s) {
2315 fprintf(fd, "[error] %s: offset_s already declared in clock declaration\n", __func__);
2316 ret = -EPERM;
2317 goto error;
2318 }
2319 ret = get_unary_unsigned(&node->u.ctf_expression.right, &clock->offset_s);
2320 if (ret) {
2321 fprintf(fd, "[error] %s: unexpected unary expression for clock offset_s\n", __func__);
2322 ret = -EINVAL;
2323 goto error;
2324 }
2325 } else if (!strcmp(left, "offset")) {
2326 if (clock->offset) {
2327 fprintf(fd, "[error] %s: offset already declared in clock declaration\n", __func__);
2328 ret = -EPERM;
2329 goto error;
2330 }
2331 ret = get_unary_unsigned(&node->u.ctf_expression.right, &clock->offset);
2332 if (ret) {
2333 fprintf(fd, "[error] %s: unexpected unary expression for clock offset\n", __func__);
2334 ret = -EINVAL;
2335 goto error;
2336 }
2337 } else if (!strcmp(left, "absolute")) {
2338 struct ctf_node *right;
2339
2340 right = _bt_list_first_entry(&node->u.ctf_expression.right, struct ctf_node, siblings);
2341 ret = get_boolean(fd, depth, right);
2342 if (ret < 0) {
2343 fprintf(fd, "[error] %s: unexpected \"absolute\" right member\n", __func__);
2344 ret = -EINVAL;
2345 goto error;
2346 }
2347 clock->absolute = ret;
2348 } else {
2349 fprintf(fd, "[warning] %s: attribute \"%s\" is unknown in clock declaration.\n", __func__, left);
2350 }
2351
2352 error:
2353 g_free(left);
2354 break;
2355 }
2356 default:
2357 return -EPERM;
2358 /* TODO: declaration specifier should be added. */
2359 }
2360
2361 return ret;
2362 }
2363
2364 static
2365 int ctf_clock_visit(FILE *fd, int depth, struct ctf_node *node, struct ctf_trace *trace)
2366 {
2367 int ret = 0;
2368 struct ctf_node *iter;
2369 struct ctf_clock *clock;
2370
2371 clock = g_new0(struct ctf_clock, 1);
2372 /* Default clock frequency is set to 1000000000 */
2373 clock->freq = 1000000000ULL;
2374 bt_list_for_each_entry(iter, &node->u.clock.declaration_list, siblings) {
2375 ret = ctf_clock_declaration_visit(fd, depth + 1, iter, clock, trace);
2376 if (ret)
2377 goto error;
2378 }
2379 if (opt_clock_force_correlate) {
2380 /*
2381 * User requested to forcibly correlate the clock
2382 * sources, even if we have no correlatation
2383 * information.
2384 */
2385 if (!clock->absolute) {
2386 fprintf(fd, "[warning] Forcibly correlating trace clock sources (--clock-force-correlate).\n");
2387 }
2388 clock->absolute = 1;
2389 }
2390 if (!CTF_CLOCK_FIELD_IS_SET(clock, name)) {
2391 ret = -EPERM;
2392 fprintf(fd, "[error] %s: missing name field in clock declaration\n", __func__);
2393 goto error;
2394 }
2395 if (g_hash_table_size(trace->clocks) > 0) {
2396 fprintf(fd, "[error] Only CTF traces with a single clock description are supported by this babeltrace version.\n");
2397 ret = -EINVAL;
2398 goto error;
2399 }
2400 trace->single_clock = clock;
2401 g_hash_table_insert(trace->clocks, (gpointer) (unsigned long) clock->name, clock);
2402 return 0;
2403
2404 error:
2405 g_free(clock->description);
2406 g_free(clock);
2407 return ret;
2408 }
2409
2410 static
2411 void ctf_clock_default(FILE *fd, int depth, struct ctf_trace *trace)
2412 {
2413 struct ctf_clock *clock;
2414
2415 clock = g_new0(struct ctf_clock, 1);
2416 clock->name = g_quark_from_string("monotonic");
2417 clock->uuid = 0;
2418 clock->description = g_strdup("Default clock");
2419 /* Default clock frequency is set to 1000000000 */
2420 clock->freq = 1000000000ULL;
2421 if (opt_clock_force_correlate) {
2422 /*
2423 * User requested to forcibly correlate the clock
2424 * sources, even if we have no correlatation
2425 * information.
2426 */
2427 if (!clock->absolute) {
2428 fprintf(fd, "[warning] Forcibly correlating trace clock sources (--clock-force-correlate).\n");
2429 }
2430 clock->absolute = 1;
2431 } else {
2432 clock->absolute = 0; /* Not an absolute reference across traces */
2433 }
2434
2435 trace->single_clock = clock;
2436 g_hash_table_insert(trace->clocks, (gpointer) (unsigned long) clock->name, clock);
2437 }
2438
2439 static
2440 void clock_free(gpointer data)
2441 {
2442 struct ctf_clock *clock = data;
2443
2444 g_free(clock->description);
2445 g_free(clock);
2446 }
2447
2448 static
2449 int ctf_callsite_declaration_visit(FILE *fd, int depth, struct ctf_node *node,
2450 struct ctf_callsite *callsite, struct ctf_trace *trace)
2451 {
2452 int ret = 0;
2453
2454 switch (node->type) {
2455 case NODE_CTF_EXPRESSION:
2456 {
2457 char *left;
2458
2459 left = concatenate_unary_strings(&node->u.ctf_expression.left);
2460 if (!strcmp(left, "name")) {
2461 char *right;
2462
2463 if (CTF_CALLSITE_FIELD_IS_SET(callsite, name)) {
2464 fprintf(fd, "[error] %s: name already declared in callsite declaration\n", __func__);
2465 ret = -EPERM;
2466 goto error;
2467 }
2468 right = concatenate_unary_strings(&node->u.ctf_expression.right);
2469 if (!right) {
2470 fprintf(fd, "[error] %s: unexpected unary expression for callsite name\n", __func__);
2471 ret = -EINVAL;
2472 goto error;
2473 }
2474 callsite->name = g_quark_from_string(right);
2475 g_free(right);
2476 CTF_CALLSITE_SET_FIELD(callsite, name);
2477 } else if (!strcmp(left, "func")) {
2478 char *right;
2479
2480 if (CTF_CALLSITE_FIELD_IS_SET(callsite, func)) {
2481 fprintf(fd, "[error] %s: func already declared in callsite declaration\n", __func__);
2482 ret = -EPERM;
2483 goto error;
2484 }
2485 right = concatenate_unary_strings(&node->u.ctf_expression.right);
2486 if (!right) {
2487 fprintf(fd, "[error] %s: unexpected unary expression for callsite func\n", __func__);
2488 ret = -EINVAL;
2489 goto error;
2490 }
2491 callsite->func = right;
2492 CTF_CALLSITE_SET_FIELD(callsite, func);
2493 } else if (!strcmp(left, "file")) {
2494 char *right;
2495
2496 if (CTF_CALLSITE_FIELD_IS_SET(callsite, file)) {
2497 fprintf(fd, "[error] %s: file already declared in callsite declaration\n", __func__);
2498 ret = -EPERM;
2499 goto error;
2500 }
2501 right = concatenate_unary_strings(&node->u.ctf_expression.right);
2502 if (!right) {
2503 fprintf(fd, "[error] %s: unexpected unary expression for callsite file\n", __func__);
2504 ret = -EINVAL;
2505 goto error;
2506 }
2507 callsite->file = right;
2508 CTF_CALLSITE_SET_FIELD(callsite, file);
2509 } else if (!strcmp(left, "line")) {
2510 if (CTF_CALLSITE_FIELD_IS_SET(callsite, line)) {
2511 fprintf(fd, "[error] %s: line already declared in callsite declaration\n", __func__);
2512 ret = -EPERM;
2513 goto error;
2514 }
2515 ret = get_unary_unsigned(&node->u.ctf_expression.right, &callsite->line);
2516 if (ret) {
2517 fprintf(fd, "[error] %s: unexpected unary expression for callsite line\n", __func__);
2518 ret = -EINVAL;
2519 goto error;
2520 }
2521 CTF_CALLSITE_SET_FIELD(callsite, line);
2522 } else if (!strcmp(left, "ip")) {
2523 if (CTF_CALLSITE_FIELD_IS_SET(callsite, ip)) {
2524 fprintf(fd, "[error] %s: ip already declared in callsite declaration\n", __func__);
2525 ret = -EPERM;
2526 goto error;
2527 }
2528 ret = get_unary_unsigned(&node->u.ctf_expression.right, &callsite->ip);
2529 if (ret) {
2530 fprintf(fd, "[error] %s: unexpected unary expression for callsite ip\n", __func__);
2531 ret = -EINVAL;
2532 goto error;
2533 }
2534 CTF_CALLSITE_SET_FIELD(callsite, ip);
2535 } else {
2536 fprintf(fd, "[warning] %s: attribute \"%s\" is unknown in callsite declaration.\n", __func__, left);
2537 }
2538
2539 error:
2540 g_free(left);
2541 break;
2542 }
2543 default:
2544 return -EPERM;
2545 /* TODO: declaration specifier should be added. */
2546 }
2547
2548 return ret;
2549 }
2550
2551 static
2552 int ctf_callsite_visit(FILE *fd, int depth, struct ctf_node *node, struct ctf_trace *trace)
2553 {
2554 int ret = 0;
2555 struct ctf_node *iter;
2556 struct ctf_callsite *callsite;
2557 struct ctf_callsite_dups *cs_dups;
2558
2559 callsite = g_new0(struct ctf_callsite, 1);
2560 bt_list_for_each_entry(iter, &node->u.callsite.declaration_list, siblings) {
2561 ret = ctf_callsite_declaration_visit(fd, depth + 1, iter, callsite, trace);
2562 if (ret)
2563 goto error;
2564 }
2565 if (!CTF_CALLSITE_FIELD_IS_SET(callsite, name)) {
2566 ret = -EPERM;
2567 fprintf(fd, "[error] %s: missing name field in callsite declaration\n", __func__);
2568 goto error;
2569 }
2570 if (!CTF_CALLSITE_FIELD_IS_SET(callsite, func)) {
2571 ret = -EPERM;
2572 fprintf(fd, "[error] %s: missing func field in callsite declaration\n", __func__);
2573 goto error;
2574 }
2575 if (!CTF_CALLSITE_FIELD_IS_SET(callsite, file)) {
2576 ret = -EPERM;
2577 fprintf(fd, "[error] %s: missing file field in callsite declaration\n", __func__);
2578 goto error;
2579 }
2580 if (!CTF_CALLSITE_FIELD_IS_SET(callsite, line)) {
2581 ret = -EPERM;
2582 fprintf(fd, "[error] %s: missing line field in callsite declaration\n", __func__);
2583 goto error;
2584 }
2585
2586 cs_dups = g_hash_table_lookup(trace->callsites,
2587 (gpointer) (unsigned long) callsite->name);
2588 if (!cs_dups) {
2589 cs_dups = g_new0(struct ctf_callsite_dups, 1);
2590 BT_INIT_LIST_HEAD(&cs_dups->head);
2591 g_hash_table_insert(trace->callsites,
2592 (gpointer) (unsigned long) callsite->name, cs_dups);
2593 }
2594 bt_list_add_tail(&callsite->node, &cs_dups->head);
2595 return 0;
2596
2597 error:
2598 g_free(callsite->func);
2599 g_free(callsite->file);
2600 g_free(callsite);
2601 return ret;
2602 }
2603
2604 static
2605 void callsite_free(gpointer data)
2606 {
2607 struct ctf_callsite_dups *cs_dups = data;
2608 struct ctf_callsite *callsite, *cs_n;
2609
2610 bt_list_for_each_entry_safe(callsite, cs_n, &cs_dups->head, node) {
2611 g_free(callsite->func);
2612 g_free(callsite->file);
2613 g_free(callsite);
2614 }
2615 }
2616
2617 static
2618 int ctf_env_declaration_visit(FILE *fd, int depth, struct ctf_node *node,
2619 struct ctf_trace *trace)
2620 {
2621 int ret = 0;
2622 struct ctf_tracer_env *env = &trace->env;
2623
2624 switch (node->type) {
2625 case NODE_CTF_EXPRESSION:
2626 {
2627 char *left;
2628
2629 left = concatenate_unary_strings(&node->u.ctf_expression.left);
2630 if (!strcmp(left, "vpid")) {
2631 uint64_t v;
2632
2633 if (env->vpid != -1) {
2634 fprintf(fd, "[error] %s: vpid already declared in env declaration\n", __func__);
2635 goto error; /* ret is 0, so not an actual error, just warn. */
2636 }
2637 ret = get_unary_unsigned(&node->u.ctf_expression.right, &v);
2638 if (ret) {
2639 fprintf(fd, "[error] %s: unexpected unary expression for env vpid\n", __func__);
2640 goto error; /* ret is 0, so not an actual error, just warn. */
2641 }
2642 env->vpid = (int) v;
2643 printf_verbose("env.vpid = %d\n", env->vpid);
2644 } else if (!strcmp(left, "procname")) {
2645 char *right;
2646
2647 if (env->procname[0]) {
2648 fprintf(fd, "[warning] %s: duplicated env procname\n", __func__);
2649 goto error; /* ret is 0, so not an actual error, just warn. */
2650 }
2651 right = concatenate_unary_strings(&node->u.ctf_expression.right);
2652 if (!right) {
2653 fprintf(fd, "[warning] %s: unexpected unary expression for env procname\n", __func__);
2654 goto error; /* ret is 0, so not an actual error, just warn. */
2655 }
2656 strncpy(env->procname, right, TRACER_ENV_LEN);
2657 env->procname[TRACER_ENV_LEN - 1] = '\0';
2658 printf_verbose("env.procname = \"%s\"\n", env->procname);
2659 g_free(right);
2660 } else if (!strcmp(left, "hostname")) {
2661 char *right;
2662
2663 if (env->hostname[0]) {
2664 fprintf(fd, "[warning] %s: duplicated env hostname\n", __func__);
2665 goto error; /* ret is 0, so not an actual error, just warn. */
2666 }
2667 right = concatenate_unary_strings(&node->u.ctf_expression.right);
2668 if (!right) {
2669 fprintf(fd, "[warning] %s: unexpected unary expression for env hostname\n", __func__);
2670 goto error; /* ret is 0, so not an actual error, just warn. */
2671 }
2672 strncpy(env->hostname, right, TRACER_ENV_LEN);
2673 env->hostname[TRACER_ENV_LEN - 1] = '\0';
2674 printf_verbose("env.hostname = \"%s\"\n", env->hostname);
2675 g_free(right);
2676 } else if (!strcmp(left, "domain")) {
2677 char *right;
2678
2679 if (env->domain[0]) {
2680 fprintf(fd, "[warning] %s: duplicated env domain\n", __func__);
2681 goto error; /* ret is 0, so not an actual error, just warn. */
2682 }
2683 right = concatenate_unary_strings(&node->u.ctf_expression.right);
2684 if (!right) {
2685 fprintf(fd, "[warning] %s: unexpected unary expression for env domain\n", __func__);
2686 goto error; /* ret is 0, so not an actual error, just warn. */
2687 }
2688 strncpy(env->domain, right, TRACER_ENV_LEN);
2689 env->domain[TRACER_ENV_LEN - 1] = '\0';
2690 printf_verbose("env.domain = \"%s\"\n", env->domain);
2691 g_free(right);
2692 } else if (!strcmp(left, "sysname")) {
2693 char *right;
2694
2695 if (env->sysname[0]) {
2696 fprintf(fd, "[warning] %s: duplicated env sysname\n", __func__);
2697 goto error; /* ret is 0, so not an actual error, just warn. */
2698 }
2699 right = concatenate_unary_strings(&node->u.ctf_expression.right);
2700 if (!right) {
2701 fprintf(fd, "[warning] %s: unexpected unary expression for env sysname\n", __func__);
2702 goto error; /* ret is 0, so not an actual error, just warn. */
2703 }
2704 strncpy(env->sysname, right, TRACER_ENV_LEN);
2705 env->sysname[TRACER_ENV_LEN - 1] = '\0';
2706 printf_verbose("env.sysname = \"%s\"\n", env->sysname);
2707 g_free(right);
2708 } else if (!strcmp(left, "kernel_release")) {
2709 char *right;
2710
2711 if (env->release[0]) {
2712 fprintf(fd, "[warning] %s: duplicated env release\n", __func__);
2713 goto error; /* ret is 0, so not an actual error, just warn. */
2714 }
2715 right = concatenate_unary_strings(&node->u.ctf_expression.right);
2716 if (!right) {
2717 fprintf(fd, "[warning] %s: unexpected unary expression for env release\n", __func__);
2718 goto error; /* ret is 0, so not an actual error, just warn. */
2719 }
2720 strncpy(env->release, right, TRACER_ENV_LEN);
2721 env->release[TRACER_ENV_LEN - 1] = '\0';
2722 printf_verbose("env.release = \"%s\"\n", env->release);
2723 g_free(right);
2724 } else if (!strcmp(left, "kernel_version")) {
2725 char *right;
2726
2727 if (env->version[0]) {
2728 fprintf(fd, "[warning] %s: duplicated env version\n", __func__);
2729 goto error; /* ret is 0, so not an actual error, just warn. */
2730 }
2731 right = concatenate_unary_strings(&node->u.ctf_expression.right);
2732 if (!right) {
2733 fprintf(fd, "[warning] %s: unexpected unary expression for env version\n", __func__);
2734 goto error; /* ret is 0, so not an actual error, just warn. */
2735 }
2736 strncpy(env->version, right, TRACER_ENV_LEN);
2737 env->version[TRACER_ENV_LEN - 1] = '\0';
2738 printf_verbose("env.version = \"%s\"\n", env->version);
2739 g_free(right);
2740 } else {
2741 if (is_unary_string(&node->u.ctf_expression.right)) {
2742 char *right;
2743
2744 right = concatenate_unary_strings(&node->u.ctf_expression.right);
2745 printf_verbose("env.%s = \"%s\"\n", left, right);
2746 g_free(right);
2747 } else if (is_unary_unsigned(&node->u.ctf_expression.right)) {
2748 uint64_t v;
2749 int ret;
2750
2751 ret = get_unary_unsigned(&node->u.ctf_expression.right, &v);
2752 assert(ret == 0);
2753 printf_verbose("env.%s = %" PRIu64 "\n", left, v);
2754 } else if (is_unary_signed(&node->u.ctf_expression.right)) {
2755 int64_t v;
2756 int ret;
2757
2758 ret = get_unary_signed(&node->u.ctf_expression.right, &v);
2759 assert(ret == 0);
2760 printf_verbose("env.%s = %" PRId64 "\n", left, v);
2761 } else {
2762 printf_verbose("%s: attribute \"%s\" has unknown type.\n", __func__, left);
2763 }
2764 }
2765
2766 error:
2767 g_free(left);
2768 break;
2769 }
2770 default:
2771 return -EPERM;
2772 }
2773
2774 return ret;
2775 }
2776
2777 static
2778 int ctf_env_visit(FILE *fd, int depth, struct ctf_node *node, struct ctf_trace *trace)
2779 {
2780 int ret = 0;
2781 struct ctf_node *iter;
2782
2783 trace->env.vpid = -1;
2784 trace->env.procname[0] = '\0';
2785 trace->env.hostname[0] = '\0';
2786 trace->env.domain[0] = '\0';
2787 trace->env.sysname[0] = '\0';
2788 trace->env.release[0] = '\0';
2789 trace->env.version[0] = '\0';
2790 bt_list_for_each_entry(iter, &node->u.env.declaration_list, siblings) {
2791 ret = ctf_env_declaration_visit(fd, depth + 1, iter, trace);
2792 if (ret)
2793 goto error;
2794 }
2795 error:
2796 return 0;
2797 }
2798
2799 static
2800 int ctf_root_declaration_visit(FILE *fd, int depth, struct ctf_node *node, struct ctf_trace *trace)
2801 {
2802 int ret = 0;
2803
2804 switch (node->type) {
2805 case NODE_TYPEDEF:
2806 ret = ctf_typedef_visit(fd, depth + 1,
2807 trace->root_declaration_scope,
2808 node->u._typedef.type_specifier_list,
2809 &node->u._typedef.type_declarators,
2810 trace);
2811 if (ret)
2812 return ret;
2813 break;
2814 case NODE_TYPEALIAS:
2815 ret = ctf_typealias_visit(fd, depth + 1,
2816 trace->root_declaration_scope,
2817 node->u.typealias.target, node->u.typealias.alias,
2818 trace);
2819 if (ret)
2820 return ret;
2821 break;
2822 case NODE_TYPE_SPECIFIER_LIST:
2823 {
2824 struct declaration *declaration;
2825
2826 /*
2827 * Just add the type specifier to the root scope
2828 * declaration scope. Release local reference.
2829 */
2830 declaration = ctf_type_specifier_list_visit(fd, depth + 1,
2831 node, trace->root_declaration_scope, trace);
2832 if (!declaration)
2833 return -ENOMEM;
2834 declaration_unref(declaration);
2835 break;
2836 }
2837 default:
2838 return -EPERM;
2839 }
2840
2841 return 0;
2842 }
2843
2844 int ctf_visitor_construct_metadata(FILE *fd, int depth, struct ctf_node *node,
2845 struct ctf_trace *trace, int byte_order)
2846 {
2847 int ret = 0;
2848 struct ctf_node *iter;
2849 int env_clock_done = 0;
2850
2851 printf_verbose("CTF visitor: metadata construction... ");
2852 trace->byte_order = byte_order;
2853 trace->clocks = g_hash_table_new_full(g_direct_hash, g_direct_equal,
2854 NULL, clock_free);
2855 trace->callsites = g_hash_table_new_full(g_direct_hash, g_direct_equal,
2856 NULL, callsite_free);
2857
2858 retry:
2859 trace->root_declaration_scope = new_declaration_scope(NULL);
2860
2861 switch (node->type) {
2862 case NODE_ROOT:
2863 if (!env_clock_done) {
2864 /*
2865 * declarations need to query clock hash table,
2866 * so clock need to be treated first.
2867 */
2868 if (bt_list_empty(&node->u.root.clock)) {
2869 ctf_clock_default(fd, depth + 1, trace);
2870 } else {
2871 bt_list_for_each_entry(iter, &node->u.root.clock, siblings) {
2872 ret = ctf_clock_visit(fd, depth + 1, iter,
2873 trace);
2874 if (ret) {
2875 fprintf(fd, "[error] %s: clock declaration error\n", __func__);
2876 goto error;
2877 }
2878 }
2879 }
2880 env_clock_done = 1;
2881 }
2882 bt_list_for_each_entry(iter, &node->u.root.declaration_list,
2883 siblings) {
2884 ret = ctf_root_declaration_visit(fd, depth + 1, iter, trace);
2885 if (ret) {
2886 fprintf(fd, "[error] %s: root declaration error\n", __func__);
2887 goto error;
2888 }
2889 }
2890 bt_list_for_each_entry(iter, &node->u.root.trace, siblings) {
2891 ret = ctf_trace_visit(fd, depth + 1, iter, trace);
2892 if (ret == -EINTR) {
2893 free_declaration_scope(trace->root_declaration_scope);
2894 /*
2895 * Need to restart creation of type
2896 * definitions, aliases and
2897 * trace header declarations.
2898 */
2899 goto retry;
2900 }
2901 if (ret) {
2902 fprintf(fd, "[error] %s: trace declaration error\n", __func__);
2903 goto error;
2904 }
2905 }
2906 bt_list_for_each_entry(iter, &node->u.root.callsite, siblings) {
2907 ret = ctf_callsite_visit(fd, depth + 1, iter,
2908 trace);
2909 if (ret) {
2910 fprintf(fd, "[error] %s: callsite declaration error\n", __func__);
2911 goto error;
2912 }
2913 }
2914 if (!trace->streams) {
2915 fprintf(fd, "[error] %s: missing trace declaration\n", __func__);
2916 ret = -EINVAL;
2917 goto error;
2918 }
2919 bt_list_for_each_entry(iter, &node->u.root.env, siblings) {
2920 ret = ctf_env_visit(fd, depth + 1, iter, trace);
2921 if (ret) {
2922 fprintf(fd, "[error] %s: env declaration error\n", __func__);
2923 goto error;
2924 }
2925 }
2926 bt_list_for_each_entry(iter, &node->u.root.stream, siblings) {
2927 ret = ctf_stream_visit(fd, depth + 1, iter,
2928 trace->root_declaration_scope, trace);
2929 if (ret) {
2930 fprintf(fd, "[error] %s: stream declaration error\n", __func__);
2931 goto error;
2932 }
2933 }
2934 bt_list_for_each_entry(iter, &node->u.root.event, siblings) {
2935 ret = ctf_event_visit(fd, depth + 1, iter,
2936 trace->root_declaration_scope, trace);
2937 if (ret) {
2938 fprintf(fd, "[error] %s: event declaration error\n", __func__);
2939 goto error;
2940 }
2941 }
2942 break;
2943 case NODE_UNKNOWN:
2944 default:
2945 fprintf(fd, "[error] %s: unknown node type %d\n", __func__,
2946 (int) node->type);
2947 ret = -EINVAL;
2948 goto error;
2949 }
2950 printf_verbose("done.\n");
2951 return ret;
2952
2953 error:
2954 free_declaration_scope(trace->root_declaration_scope);
2955 g_hash_table_destroy(trace->callsites);
2956 g_hash_table_destroy(trace->clocks);
2957 return ret;
2958 }
2959
2960 int ctf_destroy_metadata(struct ctf_trace *trace)
2961 {
2962 int i, j, k;
2963 struct ctf_file_stream *metadata_stream;
2964
2965 if (trace->streams) {
2966 for (i = 0; i < trace->streams->len; i++) {
2967 struct ctf_stream_declaration *stream;
2968
2969 stream = g_ptr_array_index(trace->streams, i);
2970 if (!stream)
2971 continue;
2972 for (j = 0; j < stream->streams->len; j++) {
2973 struct ctf_stream_definition *stream_def;
2974
2975 stream_def = g_ptr_array_index(stream->streams, j);
2976 if (!stream_def)
2977 continue;
2978 for (k = 0; k < stream_def->events_by_id->len; k++) {
2979 struct ctf_event_definition *event;
2980
2981 event = g_ptr_array_index(stream_def->events_by_id, k);
2982 if (!event)
2983 continue;
2984 if (&event->event_fields->p)
2985 definition_unref(&event->event_fields->p);
2986 if (&event->event_context->p)
2987 definition_unref(&event->event_context->p);
2988 g_free(event);
2989 }
2990 if (&stream_def->trace_packet_header->p)
2991 definition_unref(&stream_def->trace_packet_header->p);
2992 if (&stream_def->stream_event_header->p)
2993 definition_unref(&stream_def->stream_event_header->p);
2994 if (&stream_def->stream_packet_context->p)
2995 definition_unref(&stream_def->stream_packet_context->p);
2996 if (&stream_def->stream_event_context->p)
2997 definition_unref(&stream_def->stream_event_context->p);
2998 g_ptr_array_free(stream_def->events_by_id, TRUE);
2999 g_free(stream_def);
3000 }
3001 if (stream->event_header_decl)
3002 declaration_unref(&stream->event_header_decl->p);
3003 if (stream->event_context_decl)
3004 declaration_unref(&stream->event_context_decl->p);
3005 if (stream->packet_context_decl)
3006 declaration_unref(&stream->packet_context_decl->p);
3007 g_ptr_array_free(stream->streams, TRUE);
3008 g_ptr_array_free(stream->events_by_id, TRUE);
3009 g_hash_table_destroy(stream->event_quark_to_id);
3010 free_declaration_scope(stream->declaration_scope);
3011 g_free(stream);
3012 }
3013 g_ptr_array_free(trace->streams, TRUE);
3014 }
3015
3016 if (trace->event_declarations) {
3017 for (i = 0; i < trace->event_declarations->len; i++) {
3018 struct bt_ctf_event_decl *event_decl;
3019 struct ctf_event_declaration *event;
3020
3021 event_decl = g_ptr_array_index(trace->event_declarations, i);
3022 if (event_decl->context_decl)
3023 g_ptr_array_free(event_decl->context_decl, TRUE);
3024 if (event_decl->fields_decl)
3025 g_ptr_array_free(event_decl->fields_decl, TRUE);
3026 if (event_decl->packet_header_decl)
3027 g_ptr_array_free(event_decl->packet_header_decl, TRUE);
3028 if (event_decl->event_context_decl)
3029 g_ptr_array_free(event_decl->event_context_decl, TRUE);
3030 if (event_decl->event_header_decl)
3031 g_ptr_array_free(event_decl->event_header_decl, TRUE);
3032 if (event_decl->packet_context_decl)
3033 g_ptr_array_free(event_decl->packet_context_decl, TRUE);
3034
3035 event = &event_decl->parent;
3036 if (event->fields_decl)
3037 declaration_unref(&event->fields_decl->p);
3038 if (event->context_decl)
3039 declaration_unref(&event->context_decl->p);
3040 free_declaration_scope(event->declaration_scope);
3041
3042 g_free(event);
3043 }
3044 g_ptr_array_free(trace->event_declarations, TRUE);
3045 }
3046 if (trace->packet_header_decl)
3047 declaration_unref(&trace->packet_header_decl->p);
3048
3049 free_declaration_scope(trace->root_declaration_scope);
3050 free_declaration_scope(trace->declaration_scope);
3051
3052 g_hash_table_destroy(trace->callsites);
3053 g_hash_table_destroy(trace->clocks);
3054
3055 metadata_stream = container_of(trace->metadata, struct ctf_file_stream, parent);
3056 g_free(metadata_stream);
3057
3058 return 0;
3059 }
This page took 0.171773 seconds and 4 git commands to generate.