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