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