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