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