Implement support for host/le/be integer and float endianness
[libside.git] / src / tracer.c
1 // SPDX-License-Identifier: MIT
2 /*
3 * Copyright 2022 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
4 */
5
6 #include <stdint.h>
7 #include <inttypes.h>
8 #include <stdlib.h>
9 #include <stdio.h>
10 #include <stdbool.h>
11
12 #include <side/trace.h>
13
14 static struct side_tracer_handle *tracer_handle;
15
16 static
17 void tracer_print_struct(const struct side_type_description *type_desc, const struct side_arg_vec_description *sav_desc);
18 static
19 void tracer_print_array(const struct side_type_description *type_desc, const struct side_arg_vec_description *sav_desc);
20 static
21 void tracer_print_vla(const struct side_type_description *type_desc, const struct side_arg_vec_description *sav_desc);
22 static
23 void tracer_print_vla_visitor(const struct side_type_description *type_desc, void *app_ctx);
24 static
25 void tracer_print_array_fixint(const struct side_type_description *type_desc, const struct side_arg_vec *item);
26 static
27 void tracer_print_vla_fixint(const struct side_type_description *type_desc, const struct side_arg_vec *item);
28 static
29 void tracer_print_dynamic(const struct side_arg_dynamic_vec *dynamic_item);
30 static
31 void tracer_print_type(const struct side_type_description *type_desc, const struct side_arg_vec *item);
32
33 static
34 bool type_to_host_reverse_bo(const struct side_type_description *type_desc)
35 {
36 switch (type_desc->type) {
37 case SIDE_TYPE_U8:
38 case SIDE_TYPE_S8:
39 case SIDE_TYPE_BYTE:
40 return false;
41 case SIDE_TYPE_U16:
42 case SIDE_TYPE_U32:
43 case SIDE_TYPE_U64:
44 case SIDE_TYPE_S16:
45 case SIDE_TYPE_S32:
46 case SIDE_TYPE_S64:
47 if (type_desc->u.side_basic.byte_order != SIDE_TYPE_BYTE_ORDER_HOST)
48 return true;
49 else
50 return false;
51 break;
52 case SIDE_TYPE_FLOAT_BINARY16:
53 case SIDE_TYPE_FLOAT_BINARY32:
54 case SIDE_TYPE_FLOAT_BINARY64:
55 case SIDE_TYPE_FLOAT_BINARY128:
56 if (type_desc->u.side_basic.byte_order != SIDE_TYPE_FLOAT_WORD_ORDER_HOST)
57 return true;
58 else
59 return false;
60 break;
61 default:
62 fprintf(stderr, "Unexpected type\n");
63 abort();
64 }
65 }
66
67 static
68 bool dynamic_type_to_host_reverse_bo(const struct side_arg_dynamic_vec *item)
69 {
70 switch (item->dynamic_type) {
71 case SIDE_DYNAMIC_TYPE_U8:
72 case SIDE_DYNAMIC_TYPE_S8:
73 case SIDE_DYNAMIC_TYPE_BYTE:
74 return false;
75 case SIDE_DYNAMIC_TYPE_U16:
76 case SIDE_DYNAMIC_TYPE_U32:
77 case SIDE_DYNAMIC_TYPE_U64:
78 case SIDE_DYNAMIC_TYPE_S16:
79 case SIDE_DYNAMIC_TYPE_S32:
80 case SIDE_DYNAMIC_TYPE_S64:
81 if (item->u.side_basic.byte_order != SIDE_TYPE_BYTE_ORDER_HOST)
82 return true;
83 else
84 return false;
85 break;
86 case SIDE_DYNAMIC_TYPE_FLOAT_BINARY16:
87 case SIDE_DYNAMIC_TYPE_FLOAT_BINARY32:
88 case SIDE_DYNAMIC_TYPE_FLOAT_BINARY64:
89 case SIDE_DYNAMIC_TYPE_FLOAT_BINARY128:
90 if (item->u.side_basic.byte_order != SIDE_TYPE_FLOAT_WORD_ORDER_HOST)
91 return true;
92 else
93 return false;
94 break;
95 default:
96 fprintf(stderr, "Unexpected type\n");
97 abort();
98 }
99 }
100
101 static
102 void tracer_print_attr_type(const char *separator, const struct side_attr *attr)
103 {
104 printf("{ key%s \"%s\", value%s ", separator, attr->key, separator);
105 switch (attr->value.type) {
106 case SIDE_ATTR_TYPE_BOOL:
107 printf("%s", attr->value.u.side_bool ? "true" : "false");
108 break;
109 case SIDE_ATTR_TYPE_U8:
110 printf("%" PRIu8, attr->value.u.side_u8);
111 break;
112 case SIDE_ATTR_TYPE_U16:
113 printf("%" PRIu16, attr->value.u.side_u16);
114 break;
115 case SIDE_ATTR_TYPE_U32:
116 printf("%" PRIu32, attr->value.u.side_u32);
117 break;
118 case SIDE_ATTR_TYPE_U64:
119 printf("%" PRIu64, attr->value.u.side_u64);
120 break;
121 case SIDE_ATTR_TYPE_S8:
122 printf("%" PRId8, attr->value.u.side_s8);
123 break;
124 case SIDE_ATTR_TYPE_S16:
125 printf("%" PRId16, attr->value.u.side_s16);
126 break;
127 case SIDE_ATTR_TYPE_S32:
128 printf("%" PRId32, attr->value.u.side_s32);
129 break;
130 case SIDE_ATTR_TYPE_S64:
131 printf("%" PRId64, attr->value.u.side_s64);
132 break;
133 case SIDE_ATTR_TYPE_FLOAT_BINARY16:
134 #if __HAVE_FLOAT16
135 printf("%g", (double) attr->value.u.side_float_binary16);
136 break;
137 #else
138 fprintf(stderr, "ERROR: Unsupported binary16 float type\n");
139 abort();
140 #endif
141 case SIDE_ATTR_TYPE_FLOAT_BINARY32:
142 #if __HAVE_FLOAT32
143 printf("%g", (double) attr->value.u.side_float_binary32);
144 break;
145 #else
146 fprintf(stderr, "ERROR: Unsupported binary32 float type\n");
147 abort();
148 #endif
149 case SIDE_ATTR_TYPE_FLOAT_BINARY64:
150 #if __HAVE_FLOAT64
151 printf("%g", (double) attr->value.u.side_float_binary64);
152 break;
153 #else
154 fprintf(stderr, "ERROR: Unsupported binary64 float type\n");
155 abort();
156 #endif
157 case SIDE_ATTR_TYPE_FLOAT_BINARY128:
158 #if __HAVE_FLOAT128
159 printf("%Lg", (long double) attr->value.u.side_float_binary128);
160 break;
161 #else
162 fprintf(stderr, "ERROR: Unsupported binary128 float type\n");
163 abort();
164 #endif
165 case SIDE_ATTR_TYPE_STRING:
166 printf("\"%s\"", attr->value.u.string);
167 break;
168 default:
169 fprintf(stderr, "ERROR: <UNKNOWN ATTRIBUTE TYPE>");
170 abort();
171 }
172 printf(" }");
173 }
174
175 static
176 void print_attributes(const char *prefix_str, const char *separator,
177 const struct side_attr *attr, uint32_t nr_attr)
178 {
179 int i;
180
181 if (!nr_attr)
182 return;
183 printf("%s%s [ ", prefix_str, separator);
184 for (i = 0; i < nr_attr; i++) {
185 printf("%s", i ? ", " : "");
186 tracer_print_attr_type(separator, &attr[i]);
187 }
188 printf(" ]");
189 }
190
191 static
192 void print_enum(const struct side_type_description *type_desc, const struct side_arg_vec *item)
193 {
194 const struct side_enum_mappings *mappings = type_desc->u.side_enum.mappings;
195 const struct side_type_description *elem_type = type_desc->u.side_enum.elem_type;
196 int i, print_count = 0;
197 int64_t value;
198
199 if (elem_type->type != item->type) {
200 fprintf(stderr, "ERROR: Unexpected enum element type\n");
201 abort();
202 }
203 switch (item->type) {
204 case SIDE_TYPE_U8:
205 value = (int64_t) item->u.side_u8;
206 break;
207 case SIDE_TYPE_U16:
208 {
209 uint16_t v;
210
211 v = item->u.side_u16;
212 if (type_to_host_reverse_bo(elem_type))
213 v = side_bswap_16(v);
214 value = (int64_t) v;
215 break;
216 }
217 case SIDE_TYPE_U32:
218 {
219 uint32_t v;
220
221 v = item->u.side_u32;
222 if (type_to_host_reverse_bo(elem_type))
223 v = side_bswap_32(v);
224 value = (int64_t) v;
225 break;
226 }
227 case SIDE_TYPE_U64:
228 {
229 uint64_t v;
230
231 v = item->u.side_u64;
232 if (type_to_host_reverse_bo(elem_type))
233 v = side_bswap_64(v);
234 value = (int64_t) v;
235 break;
236 }
237 case SIDE_TYPE_S8:
238 value = (int64_t) item->u.side_s8;
239 break;
240 case SIDE_TYPE_S16:
241 {
242 int16_t v;
243
244 v = item->u.side_s16;
245 if (type_to_host_reverse_bo(elem_type))
246 v = side_bswap_16(v);
247 value = (int64_t) v;
248 break;
249 }
250 case SIDE_TYPE_S32:
251 {
252 int32_t v;
253
254 v = item->u.side_s32;
255 if (type_to_host_reverse_bo(elem_type))
256 v = side_bswap_32(v);
257 value = (int64_t) v;
258 break;
259 }
260 case SIDE_TYPE_S64:
261 {
262 int64_t v;
263
264 v = item->u.side_s64;
265 if (type_to_host_reverse_bo(elem_type))
266 v = side_bswap_64(v);
267 value = v;
268 break;
269 }
270 default:
271 fprintf(stderr, "ERROR: Unexpected enum element type\n");
272 abort();
273 }
274 print_attributes("attr", ":", mappings->attr, mappings->nr_attr);
275 printf("%s", mappings->nr_attr ? ", " : "");
276 tracer_print_type(type_desc->u.side_enum.elem_type, item);
277 printf(", labels: [ ");
278 for (i = 0; i < mappings->nr_mappings; i++) {
279 const struct side_enum_mapping *mapping = &mappings->mappings[i];
280
281 if (mapping->range_end < mapping->range_begin) {
282 fprintf(stderr, "ERROR: Unexpected enum range: %" PRIu64 "-%" PRIu64 "\n",
283 mapping->range_begin, mapping->range_end);
284 abort();
285 }
286 if (value >= mapping->range_begin && value <= mapping->range_end) {
287 printf("%s", print_count++ ? ", " : "");
288 printf("\"%s\"", mapping->label);
289 }
290 }
291 if (!print_count)
292 printf("<NO LABEL>");
293 printf(" ]");
294 }
295
296 static
297 uint32_t enum_elem_type_to_stride(const struct side_type_description *elem_type)
298 {
299 uint32_t stride_bit;
300
301 switch (elem_type->type) {
302 case SIDE_TYPE_U8: /* Fall-through */
303 case SIDE_TYPE_BYTE:
304 stride_bit = 8;
305 break;
306 case SIDE_TYPE_U16:
307 stride_bit = 16;
308 break;
309 case SIDE_TYPE_U32:
310 stride_bit = 32;
311 break;
312 case SIDE_TYPE_U64:
313 stride_bit = 64;
314 break;
315 default:
316 fprintf(stderr, "ERROR: Unexpected enum element type\n");
317 abort();
318 }
319 return stride_bit;
320 }
321
322 static
323 void print_enum_bitmap(const struct side_type_description *type_desc,
324 const struct side_arg_vec *item)
325 {
326 const struct side_type_description *elem_type = type_desc->u.side_enum_bitmap.elem_type;
327 const struct side_enum_bitmap_mappings *side_enum_mappings = type_desc->u.side_enum_bitmap.mappings;
328 int i, print_count = 0;
329 uint32_t stride_bit, nr_items;
330 bool reverse_byte_order = false;
331 const struct side_arg_vec *array_item;
332
333 switch (elem_type->type) {
334 case SIDE_TYPE_U8: /* Fall-through */
335 case SIDE_TYPE_BYTE: /* Fall-through */
336 case SIDE_TYPE_U16: /* Fall-through */
337 case SIDE_TYPE_U32: /* Fall-through */
338 case SIDE_TYPE_U64:
339 stride_bit = enum_elem_type_to_stride(elem_type);
340 reverse_byte_order = type_to_host_reverse_bo(elem_type);
341 array_item = item;
342 nr_items = 1;
343 break;
344 case SIDE_TYPE_ARRAY:
345 stride_bit = enum_elem_type_to_stride(elem_type->u.side_array.elem_type);
346 reverse_byte_order = type_to_host_reverse_bo(elem_type->u.side_array.elem_type);
347 array_item = item->u.side_array->sav;
348 nr_items = type_desc->u.side_array.length;
349 break;
350 case SIDE_TYPE_VLA:
351 stride_bit = enum_elem_type_to_stride(elem_type->u.side_vla.elem_type);
352 reverse_byte_order = type_to_host_reverse_bo(elem_type->u.side_vla.elem_type);
353 array_item = item->u.side_vla->sav;
354 nr_items = item->u.side_vla->len;
355 break;
356 default:
357 fprintf(stderr, "ERROR: Unexpected enum element type\n");
358 abort();
359 }
360
361 print_attributes("attr", ":", side_enum_mappings->attr, side_enum_mappings->nr_attr);
362 printf("%s", side_enum_mappings->nr_attr ? ", " : "");
363 printf("labels: [ ");
364 for (i = 0; i < side_enum_mappings->nr_mappings; i++) {
365 const struct side_enum_bitmap_mapping *mapping = &side_enum_mappings->mappings[i];
366 bool match = false;
367 uint64_t bit;
368
369 if (mapping->range_end < mapping->range_begin) {
370 fprintf(stderr, "ERROR: Unexpected enum bitmap range: %" PRIu64 "-%" PRIu64 "\n",
371 mapping->range_begin, mapping->range_end);
372 abort();
373 }
374 for (bit = mapping->range_begin; bit <= mapping->range_end; bit++) {
375 if (bit > (nr_items * stride_bit) - 1)
376 break;
377 switch (stride_bit) {
378 case 8:
379 {
380 uint8_t v = array_item[bit / 8].u.side_u8;
381 if (v & (1ULL << (bit % 8))) {
382 match = true;
383 goto match;
384 }
385 break;
386 }
387 case 16:
388 {
389 uint16_t v = array_item[bit / 16].u.side_u16;
390 if (reverse_byte_order)
391 v = side_bswap_16(v);
392 if (v & (1ULL << (bit % 16))) {
393 match = true;
394 goto match;
395 }
396 break;
397 }
398 case 32:
399 {
400 uint32_t v = array_item[bit / 32].u.side_u32;
401 if (reverse_byte_order)
402 v = side_bswap_32(v);
403 if (v & (1ULL << (bit % 32))) {
404 match = true;
405 goto match;
406 }
407 break;
408 }
409 case 64:
410 {
411 uint64_t v = array_item[bit / 64].u.side_u64;
412 if (reverse_byte_order)
413 v = side_bswap_64(v);
414 if (v & (1ULL << (bit % 64))) {
415 match = true;
416 goto match;
417 }
418 break;
419 }
420 default:
421 abort();
422 }
423 }
424 match:
425 if (match) {
426 printf("%s", print_count++ ? ", " : "");
427 printf("\"%s\"", mapping->label);
428 }
429 }
430 if (!print_count)
431 printf("<NO LABEL>");
432 printf(" ]");
433 }
434
435 static
436 void tracer_print_basic_type_header(const struct side_type_description *type_desc)
437 {
438 print_attributes("attr", ":", type_desc->u.side_basic.attr, type_desc->u.side_basic.nr_attr);
439 printf("%s", type_desc->u.side_basic.nr_attr ? ", " : "");
440 printf("value: ");
441 }
442
443 static
444 void tracer_print_type(const struct side_type_description *type_desc, const struct side_arg_vec *item)
445 {
446 enum side_type type;
447
448 switch (type_desc->type) {
449 case SIDE_TYPE_ARRAY:
450 switch (item->type) {
451 case SIDE_TYPE_ARRAY_U8:
452 case SIDE_TYPE_ARRAY_U16:
453 case SIDE_TYPE_ARRAY_U32:
454 case SIDE_TYPE_ARRAY_U64:
455 case SIDE_TYPE_ARRAY_S8:
456 case SIDE_TYPE_ARRAY_S16:
457 case SIDE_TYPE_ARRAY_S32:
458 case SIDE_TYPE_ARRAY_S64:
459 case SIDE_TYPE_ARRAY_BYTE:
460 case SIDE_TYPE_ARRAY:
461 break;
462 default:
463 fprintf(stderr, "ERROR: type mismatch between description and arguments\n");
464 abort();
465 break;
466 }
467 break;
468
469 case SIDE_TYPE_VLA:
470 switch (item->type) {
471 case SIDE_TYPE_VLA_U8:
472 case SIDE_TYPE_VLA_U16:
473 case SIDE_TYPE_VLA_U32:
474 case SIDE_TYPE_VLA_U64:
475 case SIDE_TYPE_VLA_S8:
476 case SIDE_TYPE_VLA_S16:
477 case SIDE_TYPE_VLA_S32:
478 case SIDE_TYPE_VLA_S64:
479 case SIDE_TYPE_VLA_BYTE:
480 case SIDE_TYPE_VLA:
481 break;
482 default:
483 fprintf(stderr, "ERROR: type mismatch between description and arguments\n");
484 abort();
485 break;
486 }
487 break;
488
489 case SIDE_TYPE_ENUM:
490 switch (item->type) {
491 case SIDE_TYPE_U8:
492 case SIDE_TYPE_U16:
493 case SIDE_TYPE_U32:
494 case SIDE_TYPE_U64:
495 case SIDE_TYPE_S8:
496 case SIDE_TYPE_S16:
497 case SIDE_TYPE_S32:
498 case SIDE_TYPE_S64:
499 break;
500 default:
501 fprintf(stderr, "ERROR: type mismatch between description and arguments\n");
502 abort();
503 break;
504 }
505 break;
506
507 case SIDE_TYPE_ENUM_BITMAP:
508 switch (item->type) {
509 case SIDE_TYPE_U8:
510 case SIDE_TYPE_BYTE:
511 case SIDE_TYPE_U16:
512 case SIDE_TYPE_U32:
513 case SIDE_TYPE_U64:
514 case SIDE_TYPE_ARRAY:
515 case SIDE_TYPE_VLA:
516 break;
517 default:
518 fprintf(stderr, "ERROR: type mismatch between description and arguments\n");
519 abort();
520 break;
521 }
522 break;
523
524 default:
525 if (type_desc->type != item->type) {
526 fprintf(stderr, "ERROR: type mismatch between description and arguments\n");
527 abort();
528 }
529 break;
530 }
531
532 if (type_desc->type == SIDE_TYPE_ENUM || type_desc->type == SIDE_TYPE_ENUM_BITMAP)
533 type = type_desc->type;
534 else
535 type = item->type;
536
537 printf("{ ");
538 switch (type) {
539 case SIDE_TYPE_BOOL:
540 tracer_print_basic_type_header(type_desc);
541 printf("%s", item->u.side_bool ? "true" : "false");
542 break;
543 case SIDE_TYPE_U8:
544 tracer_print_basic_type_header(type_desc);
545 printf("%" PRIu8, item->u.side_u8);
546 break;
547 case SIDE_TYPE_U16:
548 {
549 uint16_t v;
550
551 v = item->u.side_u16;
552 if (type_to_host_reverse_bo(type_desc))
553 v = side_bswap_16(v);
554 tracer_print_basic_type_header(type_desc);
555 printf("%" PRIu16, v);
556 break;
557 }
558 case SIDE_TYPE_U32:
559 {
560 uint32_t v;
561
562 v = item->u.side_u32;
563 if (type_to_host_reverse_bo(type_desc))
564 v = side_bswap_32(v);
565 tracer_print_basic_type_header(type_desc);
566 printf("%" PRIu32, v);
567 break;
568 }
569 case SIDE_TYPE_U64:
570 {
571 uint64_t v;
572
573 v = item->u.side_u64;
574 if (type_to_host_reverse_bo(type_desc))
575 v = side_bswap_64(v);
576 tracer_print_basic_type_header(type_desc);
577 printf("%" PRIu64, v);
578 break;
579 }
580 case SIDE_TYPE_S8:
581 tracer_print_basic_type_header(type_desc);
582 printf("%" PRId8, item->u.side_s8);
583 break;
584 case SIDE_TYPE_S16:
585 {
586 int16_t v;
587
588 v = item->u.side_s16;
589 if (type_to_host_reverse_bo(type_desc))
590 v = side_bswap_16(v);
591 tracer_print_basic_type_header(type_desc);
592 printf("%" PRId16, v);
593 break;
594 }
595 case SIDE_TYPE_S32:
596 {
597 int32_t v;
598
599 v = item->u.side_s32;
600 if (type_to_host_reverse_bo(type_desc))
601 v = side_bswap_32(v);
602 tracer_print_basic_type_header(type_desc);
603 printf("%" PRId32, v);
604 break;
605 }
606 case SIDE_TYPE_S64:
607 {
608 int64_t v;
609
610 v = item->u.side_s64;
611 if (type_to_host_reverse_bo(type_desc))
612 v = side_bswap_64(v);
613 tracer_print_basic_type_header(type_desc);
614 printf("%" PRId64, v);
615 break;
616 }
617 case SIDE_TYPE_BYTE:
618 tracer_print_basic_type_header(type_desc);
619 printf("0x%" PRIx8, item->u.side_byte);
620 break;
621
622 case SIDE_TYPE_ENUM:
623 print_enum(type_desc, item);
624 break;
625
626 case SIDE_TYPE_ENUM_BITMAP:
627 print_enum_bitmap(type_desc, item);
628 break;
629
630 case SIDE_TYPE_FLOAT_BINARY16:
631 {
632 #if __HAVE_FLOAT16
633 union {
634 _Float16 f;
635 uint16_t u;
636 } float16 = {
637 .f = item->u.side_float_binary16,
638 };
639
640 if (type_to_host_reverse_bo(type_desc))
641 float16.u = side_bswap_16(float16.u);
642 tracer_print_basic_type_header(type_desc);
643 printf("%g", (double) float16.f);
644 break;
645 #else
646 fprintf(stderr, "ERROR: Unsupported binary16 float type\n");
647 abort();
648 #endif
649 }
650 case SIDE_TYPE_FLOAT_BINARY32:
651 {
652 #if __HAVE_FLOAT32
653 union {
654 _Float32 f;
655 uint32_t u;
656 } float32 = {
657 .f = item->u.side_float_binary32,
658 };
659
660 if (type_to_host_reverse_bo(type_desc))
661 float32.u = side_bswap_32(float32.u);
662 tracer_print_basic_type_header(type_desc);
663 printf("%g", (double) float32.f);
664 break;
665 #else
666 fprintf(stderr, "ERROR: Unsupported binary32 float type\n");
667 abort();
668 #endif
669 }
670 case SIDE_TYPE_FLOAT_BINARY64:
671 {
672 #if __HAVE_FLOAT64
673 union {
674 _Float64 f;
675 uint64_t u;
676 } float64 = {
677 .f = item->u.side_float_binary64,
678 };
679
680 if (type_to_host_reverse_bo(type_desc))
681 float64.u = side_bswap_64(float64.u);
682 tracer_print_basic_type_header(type_desc);
683 printf("%g", (double) float64.f);
684 break;
685 #else
686 fprintf(stderr, "ERROR: Unsupported binary64 float type\n");
687 abort();
688 #endif
689 }
690 case SIDE_TYPE_FLOAT_BINARY128:
691 {
692 #if __HAVE_FLOAT128
693 union {
694 _Float128 f;
695 char arr[16];
696 } float128 = {
697 .f = item->u.side_float_binary128,
698 };
699
700 if (type_to_host_reverse_bo(type_desc))
701 side_bswap_128p(float128.arr);
702 tracer_print_basic_type_header(type_desc);
703 printf("%Lg", (long double) float128.f);
704 break;
705 #else
706 fprintf(stderr, "ERROR: Unsupported binary128 float type\n");
707 abort();
708 #endif
709 }
710 case SIDE_TYPE_STRING:
711 tracer_print_basic_type_header(type_desc);
712 printf("\"%s\"", item->u.string);
713 break;
714 case SIDE_TYPE_STRUCT:
715 tracer_print_struct(type_desc, item->u.side_struct);
716 break;
717 case SIDE_TYPE_ARRAY:
718 tracer_print_array(type_desc, item->u.side_array);
719 break;
720 case SIDE_TYPE_VLA:
721 tracer_print_vla(type_desc, item->u.side_vla);
722 break;
723 case SIDE_TYPE_VLA_VISITOR:
724 tracer_print_vla_visitor(type_desc, item->u.side_vla_app_visitor_ctx);
725 break;
726 case SIDE_TYPE_ARRAY_U8:
727 case SIDE_TYPE_ARRAY_U16:
728 case SIDE_TYPE_ARRAY_U32:
729 case SIDE_TYPE_ARRAY_U64:
730 case SIDE_TYPE_ARRAY_S8:
731 case SIDE_TYPE_ARRAY_S16:
732 case SIDE_TYPE_ARRAY_S32:
733 case SIDE_TYPE_ARRAY_S64:
734 case SIDE_TYPE_ARRAY_BYTE:
735 tracer_print_array_fixint(type_desc, item);
736 break;
737 case SIDE_TYPE_VLA_U8:
738 case SIDE_TYPE_VLA_U16:
739 case SIDE_TYPE_VLA_U32:
740 case SIDE_TYPE_VLA_U64:
741 case SIDE_TYPE_VLA_S8:
742 case SIDE_TYPE_VLA_S16:
743 case SIDE_TYPE_VLA_S32:
744 case SIDE_TYPE_VLA_S64:
745 case SIDE_TYPE_VLA_BYTE:
746 tracer_print_vla_fixint(type_desc, item);
747 break;
748 case SIDE_TYPE_DYNAMIC:
749 tracer_print_basic_type_header(type_desc);
750 tracer_print_dynamic(&item->u.dynamic);
751 break;
752 default:
753 fprintf(stderr, "<UNKNOWN TYPE>");
754 abort();
755 }
756 printf(" }");
757 }
758
759 static
760 void tracer_print_field(const struct side_event_field *item_desc, const struct side_arg_vec *item)
761 {
762 printf("%s: ", item_desc->field_name);
763 tracer_print_type(&item_desc->side_type, item);
764 }
765
766 static
767 void tracer_print_struct(const struct side_type_description *type_desc, const struct side_arg_vec_description *sav_desc)
768 {
769 const struct side_arg_vec *sav = sav_desc->sav;
770 uint32_t side_sav_len = sav_desc->len;
771 int i;
772
773 if (type_desc->u.side_struct->nr_fields != side_sav_len) {
774 fprintf(stderr, "ERROR: number of fields mismatch between description and arguments of structure\n");
775 abort();
776 }
777 print_attributes("attr", ":", type_desc->u.side_struct->attr, type_desc->u.side_struct->nr_attr);
778 printf("%s", type_desc->u.side_struct->nr_attr ? ", " : "");
779 printf("fields: { ");
780 for (i = 0; i < side_sav_len; i++) {
781 printf("%s", i ? ", " : "");
782 tracer_print_field(&type_desc->u.side_struct->fields[i], &sav[i]);
783 }
784 printf(" }");
785 }
786
787 static
788 void tracer_print_array(const struct side_type_description *type_desc, const struct side_arg_vec_description *sav_desc)
789 {
790 const struct side_arg_vec *sav = sav_desc->sav;
791 uint32_t side_sav_len = sav_desc->len;
792 int i;
793
794 if (type_desc->u.side_array.length != side_sav_len) {
795 fprintf(stderr, "ERROR: length mismatch between description and arguments of array\n");
796 abort();
797 }
798 print_attributes("attr", ":", type_desc->u.side_array.attr, type_desc->u.side_array.nr_attr);
799 printf("%s", type_desc->u.side_array.nr_attr ? ", " : "");
800 printf("elements: ");
801 printf("[ ");
802 for (i = 0; i < side_sav_len; i++) {
803 printf("%s", i ? ", " : "");
804 tracer_print_type(type_desc->u.side_array.elem_type, &sav[i]);
805 }
806 printf(" ]");
807 }
808
809 static
810 void tracer_print_vla(const struct side_type_description *type_desc, const struct side_arg_vec_description *sav_desc)
811 {
812 const struct side_arg_vec *sav = sav_desc->sav;
813 uint32_t side_sav_len = sav_desc->len;
814 int i;
815
816 print_attributes("attr", ":", type_desc->u.side_vla.attr, type_desc->u.side_vla.nr_attr);
817 printf("%s", type_desc->u.side_vla.nr_attr ? ", " : "");
818 printf("elements: ");
819 printf("[ ");
820 for (i = 0; i < side_sav_len; i++) {
821 printf("%s", i ? ", " : "");
822 tracer_print_type(type_desc->u.side_vla.elem_type, &sav[i]);
823 }
824 printf(" ]");
825 }
826
827 struct tracer_visitor_priv {
828 const struct side_type_description *elem_type;
829 int i;
830 };
831
832 static
833 enum side_visitor_status tracer_write_elem_cb(const struct side_tracer_visitor_ctx *tracer_ctx,
834 const struct side_arg_vec *elem)
835 {
836 struct tracer_visitor_priv *tracer_priv = tracer_ctx->priv;
837
838 printf("%s", tracer_priv->i++ ? ", " : "");
839 tracer_print_type(tracer_priv->elem_type, elem);
840 return SIDE_VISITOR_STATUS_OK;
841 }
842
843 static
844 void tracer_print_vla_visitor(const struct side_type_description *type_desc, void *app_ctx)
845 {
846 enum side_visitor_status status;
847 struct tracer_visitor_priv tracer_priv = {
848 .elem_type = type_desc->u.side_vla_visitor.elem_type,
849 .i = 0,
850 };
851 const struct side_tracer_visitor_ctx tracer_ctx = {
852 .write_elem = tracer_write_elem_cb,
853 .priv = &tracer_priv,
854 };
855
856 print_attributes("attr", ":", type_desc->u.side_vla_visitor.attr, type_desc->u.side_vla_visitor.nr_attr);
857 printf("%s", type_desc->u.side_vla_visitor.nr_attr ? ", " : "");
858 printf("elements: ");
859 printf("[ ");
860 status = type_desc->u.side_vla_visitor.visitor(&tracer_ctx, app_ctx);
861 switch (status) {
862 case SIDE_VISITOR_STATUS_OK:
863 break;
864 case SIDE_VISITOR_STATUS_ERROR:
865 fprintf(stderr, "ERROR: Visitor error\n");
866 abort();
867 }
868 printf(" ]");
869 }
870
871 void tracer_print_array_fixint(const struct side_type_description *type_desc, const struct side_arg_vec *item)
872 {
873 const struct side_type_description *elem_type = type_desc->u.side_array.elem_type;
874 uint32_t side_sav_len = type_desc->u.side_array.length;
875 void *p = item->u.side_array_fixint;
876 enum side_type side_type;
877 int i;
878
879 print_attributes("attr", ":", type_desc->u.side_array.attr, type_desc->u.side_array.nr_attr);
880 printf("%s", type_desc->u.side_array.nr_attr ? ", " : "");
881 printf("elements: ");
882 switch (item->type) {
883 case SIDE_TYPE_ARRAY_U8:
884 if (elem_type->type != SIDE_TYPE_U8)
885 goto type_error;
886 break;
887 case SIDE_TYPE_ARRAY_U16:
888 if (elem_type->type != SIDE_TYPE_U16)
889 goto type_error;
890 break;
891 case SIDE_TYPE_ARRAY_U32:
892 if (elem_type->type != SIDE_TYPE_U32)
893 goto type_error;
894 break;
895 case SIDE_TYPE_ARRAY_U64:
896 if (elem_type->type != SIDE_TYPE_U64)
897 goto type_error;
898 break;
899 case SIDE_TYPE_ARRAY_S8:
900 if (elem_type->type != SIDE_TYPE_S8)
901 goto type_error;
902 break;
903 case SIDE_TYPE_ARRAY_S16:
904 if (elem_type->type != SIDE_TYPE_S16)
905 goto type_error;
906 break;
907 case SIDE_TYPE_ARRAY_S32:
908 if (elem_type->type != SIDE_TYPE_S32)
909 goto type_error;
910 break;
911 case SIDE_TYPE_ARRAY_S64:
912 if (elem_type->type != SIDE_TYPE_S64)
913 goto type_error;
914 break;
915 case SIDE_TYPE_ARRAY_BYTE:
916 if (elem_type->type != SIDE_TYPE_BYTE)
917 goto type_error;
918 break;
919 default:
920 goto type_error;
921 }
922 side_type = elem_type->type;
923
924 printf("[ ");
925 for (i = 0; i < side_sav_len; i++) {
926 struct side_arg_vec sav_elem = {
927 .type = side_type,
928 };
929
930 switch (side_type) {
931 case SIDE_TYPE_U8:
932 sav_elem.u.side_u8 = ((const uint8_t *) p)[i];
933 break;
934 case SIDE_TYPE_S8:
935 sav_elem.u.side_s8 = ((const int8_t *) p)[i];
936 break;
937 case SIDE_TYPE_U16:
938 sav_elem.u.side_u16 = ((const uint16_t *) p)[i];
939 break;
940 case SIDE_TYPE_S16:
941 sav_elem.u.side_s16 = ((const int16_t *) p)[i];
942 break;
943 case SIDE_TYPE_U32:
944 sav_elem.u.side_u32 = ((const uint32_t *) p)[i];
945 break;
946 case SIDE_TYPE_S32:
947 sav_elem.u.side_s32 = ((const int32_t *) p)[i];
948 break;
949 case SIDE_TYPE_U64:
950 sav_elem.u.side_u64 = ((const uint64_t *) p)[i];
951 break;
952 case SIDE_TYPE_S64:
953 sav_elem.u.side_s64 = ((const int64_t *) p)[i];
954 break;
955 case SIDE_TYPE_BYTE:
956 sav_elem.u.side_byte = ((const uint8_t *) p)[i];
957 break;
958
959 default:
960 fprintf(stderr, "ERROR: Unexpected type\n");
961 abort();
962 }
963
964 printf("%s", i ? ", " : "");
965 tracer_print_type(elem_type, &sav_elem);
966 }
967 printf(" ]");
968 return;
969
970 type_error:
971 fprintf(stderr, "ERROR: type mismatch\n");
972 abort();
973 }
974
975 void tracer_print_vla_fixint(const struct side_type_description *type_desc, const struct side_arg_vec *item)
976 {
977 const struct side_type_description *elem_type = type_desc->u.side_vla.elem_type;
978 uint32_t side_sav_len = item->u.side_vla_fixint.length;
979 void *p = item->u.side_vla_fixint.p;
980 enum side_type side_type;
981 int i;
982
983 print_attributes("attr", ":", type_desc->u.side_vla.attr, type_desc->u.side_vla.nr_attr);
984 printf("%s", type_desc->u.side_vla.nr_attr ? ", " : "");
985 printf("elements: ");
986 switch (item->type) {
987 case SIDE_TYPE_VLA_U8:
988 if (elem_type->type != SIDE_TYPE_U8)
989 goto type_error;
990 break;
991 case SIDE_TYPE_VLA_U16:
992 if (elem_type->type != SIDE_TYPE_U16)
993 goto type_error;
994 break;
995 case SIDE_TYPE_VLA_U32:
996 if (elem_type->type != SIDE_TYPE_U32)
997 goto type_error;
998 break;
999 case SIDE_TYPE_VLA_U64:
1000 if (elem_type->type != SIDE_TYPE_U64)
1001 goto type_error;
1002 break;
1003 case SIDE_TYPE_VLA_S8:
1004 if (elem_type->type != SIDE_TYPE_S8)
1005 goto type_error;
1006 break;
1007 case SIDE_TYPE_VLA_S16:
1008 if (elem_type->type != SIDE_TYPE_S16)
1009 goto type_error;
1010 break;
1011 case SIDE_TYPE_VLA_S32:
1012 if (elem_type->type != SIDE_TYPE_S32)
1013 goto type_error;
1014 break;
1015 case SIDE_TYPE_VLA_S64:
1016 if (elem_type->type != SIDE_TYPE_S64)
1017 goto type_error;
1018 break;
1019 case SIDE_TYPE_VLA_BYTE:
1020 if (elem_type->type != SIDE_TYPE_BYTE)
1021 goto type_error;
1022 break;
1023 default:
1024 goto type_error;
1025 }
1026 side_type = elem_type->type;
1027
1028 printf("[ ");
1029 for (i = 0; i < side_sav_len; i++) {
1030 struct side_arg_vec sav_elem = {
1031 .type = side_type,
1032 };
1033
1034 switch (side_type) {
1035 case SIDE_TYPE_U8:
1036 sav_elem.u.side_u8 = ((const uint8_t *) p)[i];
1037 break;
1038 case SIDE_TYPE_S8:
1039 sav_elem.u.side_s8 = ((const int8_t *) p)[i];
1040 break;
1041 case SIDE_TYPE_U16:
1042 sav_elem.u.side_u16 = ((const uint16_t *) p)[i];
1043 break;
1044 case SIDE_TYPE_S16:
1045 sav_elem.u.side_s16 = ((const int16_t *) p)[i];
1046 break;
1047 case SIDE_TYPE_U32:
1048 sav_elem.u.side_u32 = ((const uint32_t *) p)[i];
1049 break;
1050 case SIDE_TYPE_S32:
1051 sav_elem.u.side_s32 = ((const int32_t *) p)[i];
1052 break;
1053 case SIDE_TYPE_U64:
1054 sav_elem.u.side_u64 = ((const uint64_t *) p)[i];
1055 break;
1056 case SIDE_TYPE_S64:
1057 sav_elem.u.side_s64 = ((const int64_t *) p)[i];
1058 break;
1059 case SIDE_TYPE_BYTE:
1060 sav_elem.u.side_byte = ((const uint8_t *) p)[i];
1061 break;
1062
1063 default:
1064 fprintf(stderr, "ERROR: Unexpected type\n");
1065 abort();
1066 }
1067
1068 printf("%s", i ? ", " : "");
1069 tracer_print_type(elem_type, &sav_elem);
1070 }
1071 printf(" ]");
1072 return;
1073
1074 type_error:
1075 fprintf(stderr, "ERROR: type mismatch\n");
1076 abort();
1077 }
1078
1079 static
1080 void tracer_print_dynamic_struct(const struct side_arg_dynamic_event_struct *dynamic_struct)
1081 {
1082 const struct side_arg_dynamic_event_field *fields = dynamic_struct->fields;
1083 uint32_t len = dynamic_struct->len;
1084 int i;
1085
1086 print_attributes("attr", "::", dynamic_struct->attr, dynamic_struct->nr_attr);
1087 printf("%s", dynamic_struct->nr_attr ? ", " : "");
1088 printf("fields:: ");
1089 printf("[ ");
1090 for (i = 0; i < len; i++) {
1091 printf("%s", i ? ", " : "");
1092 printf("%s:: ", fields[i].field_name);
1093 tracer_print_dynamic(&fields[i].elem);
1094 }
1095 printf(" ]");
1096 }
1097
1098 struct tracer_dynamic_struct_visitor_priv {
1099 int i;
1100 };
1101
1102 static
1103 enum side_visitor_status tracer_dynamic_struct_write_elem_cb(
1104 const struct side_tracer_dynamic_struct_visitor_ctx *tracer_ctx,
1105 const struct side_arg_dynamic_event_field *dynamic_field)
1106 {
1107 struct tracer_dynamic_struct_visitor_priv *tracer_priv = tracer_ctx->priv;
1108
1109 printf("%s", tracer_priv->i++ ? ", " : "");
1110 printf("%s:: ", dynamic_field->field_name);
1111 tracer_print_dynamic(&dynamic_field->elem);
1112 return SIDE_VISITOR_STATUS_OK;
1113 }
1114
1115 static
1116 void tracer_print_dynamic_struct_visitor(const struct side_arg_dynamic_vec *item)
1117 {
1118 enum side_visitor_status status;
1119 struct tracer_dynamic_struct_visitor_priv tracer_priv = {
1120 .i = 0,
1121 };
1122 const struct side_tracer_dynamic_struct_visitor_ctx tracer_ctx = {
1123 .write_field = tracer_dynamic_struct_write_elem_cb,
1124 .priv = &tracer_priv,
1125 };
1126 void *app_ctx = item->u.side_dynamic_struct_visitor.app_ctx;
1127
1128 print_attributes("attr", "::", item->u.side_dynamic_struct_visitor.attr, item->u.side_dynamic_struct_visitor.nr_attr);
1129 printf("%s", item->u.side_dynamic_struct_visitor.nr_attr ? ", " : "");
1130 printf("fields:: ");
1131 printf("[ ");
1132 status = item->u.side_dynamic_struct_visitor.visitor(&tracer_ctx, app_ctx);
1133 switch (status) {
1134 case SIDE_VISITOR_STATUS_OK:
1135 break;
1136 case SIDE_VISITOR_STATUS_ERROR:
1137 fprintf(stderr, "ERROR: Visitor error\n");
1138 abort();
1139 }
1140 printf(" ]");
1141 }
1142
1143 static
1144 void tracer_print_dynamic_vla(const struct side_arg_dynamic_vec_vla *vla)
1145 {
1146 const struct side_arg_dynamic_vec *sav = vla->sav;
1147 uint32_t side_sav_len = vla->len;
1148 int i;
1149
1150 print_attributes("attr", "::", vla->attr, vla->nr_attr);
1151 printf("%s", vla->nr_attr ? ", " : "");
1152 printf("elements:: ");
1153 printf("[ ");
1154 for (i = 0; i < side_sav_len; i++) {
1155 printf("%s", i ? ", " : "");
1156 tracer_print_dynamic(&sav[i]);
1157 }
1158 printf(" ]");
1159 }
1160
1161 struct tracer_dynamic_vla_visitor_priv {
1162 int i;
1163 };
1164
1165 static
1166 enum side_visitor_status tracer_dynamic_vla_write_elem_cb(
1167 const struct side_tracer_dynamic_vla_visitor_ctx *tracer_ctx,
1168 const struct side_arg_dynamic_vec *elem)
1169 {
1170 struct tracer_dynamic_vla_visitor_priv *tracer_priv = tracer_ctx->priv;
1171
1172 printf("%s", tracer_priv->i++ ? ", " : "");
1173 tracer_print_dynamic(elem);
1174 return SIDE_VISITOR_STATUS_OK;
1175 }
1176
1177 static
1178 void tracer_print_dynamic_vla_visitor(const struct side_arg_dynamic_vec *item)
1179 {
1180 enum side_visitor_status status;
1181 struct tracer_dynamic_vla_visitor_priv tracer_priv = {
1182 .i = 0,
1183 };
1184 const struct side_tracer_dynamic_vla_visitor_ctx tracer_ctx = {
1185 .write_elem = tracer_dynamic_vla_write_elem_cb,
1186 .priv = &tracer_priv,
1187 };
1188 void *app_ctx = item->u.side_dynamic_vla_visitor.app_ctx;
1189
1190 print_attributes("attr", "::", item->u.side_dynamic_vla_visitor.attr, item->u.side_dynamic_vla_visitor.nr_attr);
1191 printf("%s", item->u.side_dynamic_vla_visitor.nr_attr ? ", " : "");
1192 printf("elements:: ");
1193 printf("[ ");
1194 status = item->u.side_dynamic_vla_visitor.visitor(&tracer_ctx, app_ctx);
1195 switch (status) {
1196 case SIDE_VISITOR_STATUS_OK:
1197 break;
1198 case SIDE_VISITOR_STATUS_ERROR:
1199 fprintf(stderr, "ERROR: Visitor error\n");
1200 abort();
1201 }
1202 printf(" ]");
1203 }
1204
1205 static
1206 void tracer_print_dynamic_basic_type_header(const struct side_arg_dynamic_vec *item)
1207 {
1208 print_attributes("attr", "::", item->u.side_basic.attr, item->u.side_basic.nr_attr);
1209 printf("%s", item->u.side_basic.nr_attr ? ", " : "");
1210 printf("value:: ");
1211 }
1212
1213 static
1214 void tracer_print_dynamic(const struct side_arg_dynamic_vec *item)
1215 {
1216 printf("{ ");
1217 switch (item->dynamic_type) {
1218 case SIDE_DYNAMIC_TYPE_NULL:
1219 tracer_print_dynamic_basic_type_header(item);
1220 printf("<NULL TYPE>");
1221 break;
1222 case SIDE_DYNAMIC_TYPE_BOOL:
1223 tracer_print_dynamic_basic_type_header(item);
1224 printf("%s", item->u.side_basic.u.side_bool ? "true" : "false");
1225 break;
1226 case SIDE_DYNAMIC_TYPE_U8:
1227 tracer_print_dynamic_basic_type_header(item);
1228 printf("%" PRIu8, item->u.side_basic.u.side_u8);
1229 break;
1230 case SIDE_DYNAMIC_TYPE_U16:
1231 {
1232 uint16_t v;
1233
1234 v = item->u.side_basic.u.side_u16;
1235 if (dynamic_type_to_host_reverse_bo(item))
1236 v = side_bswap_16(v);
1237 tracer_print_dynamic_basic_type_header(item);
1238 printf("%" PRIu16, v);
1239 break;
1240 }
1241 case SIDE_DYNAMIC_TYPE_U32:
1242 {
1243 uint32_t v;
1244
1245 v = item->u.side_basic.u.side_u32;
1246 if (dynamic_type_to_host_reverse_bo(item))
1247 v = side_bswap_32(v);
1248 tracer_print_dynamic_basic_type_header(item);
1249 printf("%" PRIu32, v);
1250 break;
1251 }
1252 case SIDE_DYNAMIC_TYPE_U64:
1253 {
1254 uint64_t v;
1255
1256 v = item->u.side_basic.u.side_u64;
1257 if (dynamic_type_to_host_reverse_bo(item))
1258 v = side_bswap_64(v);
1259 tracer_print_dynamic_basic_type_header(item);
1260 printf("%" PRIu64, v);
1261 break;
1262 }
1263 case SIDE_DYNAMIC_TYPE_S8:
1264 tracer_print_dynamic_basic_type_header(item);
1265 printf("%" PRId8, item->u.side_basic.u.side_s8);
1266 break;
1267 case SIDE_DYNAMIC_TYPE_S16:
1268 {
1269 int16_t v;
1270
1271 v = item->u.side_basic.u.side_u16;
1272 if (dynamic_type_to_host_reverse_bo(item))
1273 v = side_bswap_16(v);
1274 tracer_print_dynamic_basic_type_header(item);
1275 printf("%" PRId16, v);
1276 break;
1277 }
1278 case SIDE_DYNAMIC_TYPE_S32:
1279 {
1280 int32_t v;
1281
1282 v = item->u.side_basic.u.side_u32;
1283 if (dynamic_type_to_host_reverse_bo(item))
1284 v = side_bswap_32(v);
1285 tracer_print_dynamic_basic_type_header(item);
1286 printf("%" PRId32, v);
1287 break;
1288 }
1289 case SIDE_DYNAMIC_TYPE_S64:
1290 {
1291 int64_t v;
1292
1293 v = item->u.side_basic.u.side_u64;
1294 if (dynamic_type_to_host_reverse_bo(item))
1295 v = side_bswap_64(v);
1296 tracer_print_dynamic_basic_type_header(item);
1297 printf("%" PRId64, v);
1298 break;
1299 }
1300 case SIDE_DYNAMIC_TYPE_BYTE:
1301 tracer_print_dynamic_basic_type_header(item);
1302 printf("0x%" PRIx8, item->u.side_basic.u.side_byte);
1303 break;
1304
1305 case SIDE_DYNAMIC_TYPE_FLOAT_BINARY16:
1306 {
1307 #if __HAVE_FLOAT16
1308 union {
1309 _Float16 f;
1310 uint16_t u;
1311 } float16 = {
1312 .f = item->u.side_basic.u.side_float_binary16,
1313 };
1314
1315 if (dynamic_type_to_host_reverse_bo(item))
1316 float16.u = side_bswap_16(float16.u);
1317 tracer_print_dynamic_basic_type_header(item);
1318 printf("%g", (double) float16.f);
1319 break;
1320 #else
1321 fprintf(stderr, "ERROR: Unsupported binary16 float type\n");
1322 abort();
1323 #endif
1324 }
1325 case SIDE_DYNAMIC_TYPE_FLOAT_BINARY32:
1326 {
1327 #if __HAVE_FLOAT32
1328 union {
1329 _Float32 f;
1330 uint32_t u;
1331 } float32 = {
1332 .f = item->u.side_basic.u.side_float_binary32,
1333 };
1334
1335 if (dynamic_type_to_host_reverse_bo(item))
1336 float32.u = side_bswap_32(float32.u);
1337 tracer_print_dynamic_basic_type_header(item);
1338 printf("%g", (double) float32.f);
1339 break;
1340 #else
1341 fprintf(stderr, "ERROR: Unsupported binary32 float type\n");
1342 abort();
1343 #endif
1344 }
1345 case SIDE_DYNAMIC_TYPE_FLOAT_BINARY64:
1346 {
1347 #if __HAVE_FLOAT64
1348 union {
1349 _Float64 f;
1350 uint64_t u;
1351 } float64 = {
1352 .f = item->u.side_basic.u.side_float_binary64,
1353 };
1354
1355 if (dynamic_type_to_host_reverse_bo(item))
1356 float64.u = side_bswap_64(float64.u);
1357 tracer_print_dynamic_basic_type_header(item);
1358 printf("%g", (double) float64.f);
1359 break;
1360 #else
1361 fprintf(stderr, "ERROR: Unsupported binary64 float type\n");
1362 abort();
1363 #endif
1364 }
1365 case SIDE_DYNAMIC_TYPE_FLOAT_BINARY128:
1366 {
1367 #if __HAVE_FLOAT128
1368 union {
1369 _Float128 f;
1370 char arr[16];
1371 } float128 = {
1372 .f = item->u.side_basic.u.side_float_binary128,
1373 };
1374
1375 if (dynamic_type_to_host_reverse_bo(item))
1376 side_bswap_128p(float128.arr);
1377 tracer_print_dynamic_basic_type_header(item);
1378 printf("%Lg", (long double) float128.f);
1379 break;
1380 #else
1381 fprintf(stderr, "ERROR: Unsupported binary128 float type\n");
1382 abort();
1383 #endif
1384 }
1385 case SIDE_DYNAMIC_TYPE_STRING:
1386 tracer_print_dynamic_basic_type_header(item);
1387 printf("\"%s\"", item->u.side_basic.u.string);
1388 break;
1389 case SIDE_DYNAMIC_TYPE_STRUCT:
1390 tracer_print_dynamic_struct(item->u.side_dynamic_struct);
1391 break;
1392 case SIDE_DYNAMIC_TYPE_STRUCT_VISITOR:
1393 tracer_print_dynamic_struct_visitor(item);
1394 break;
1395 case SIDE_DYNAMIC_TYPE_VLA:
1396 tracer_print_dynamic_vla(item->u.side_dynamic_vla);
1397 break;
1398 case SIDE_DYNAMIC_TYPE_VLA_VISITOR:
1399 tracer_print_dynamic_vla_visitor(item);
1400 break;
1401 default:
1402 fprintf(stderr, "<UNKNOWN TYPE>");
1403 abort();
1404 }
1405 printf(" }");
1406 }
1407
1408 static
1409 void tracer_print_static_fields(const struct side_event_description *desc,
1410 const struct side_arg_vec_description *sav_desc,
1411 int *nr_items)
1412 {
1413 const struct side_arg_vec *sav = sav_desc->sav;
1414 uint32_t side_sav_len = sav_desc->len;
1415 int i;
1416
1417 printf("provider: %s, event: %s", desc->provider_name, desc->event_name);
1418 if (desc->nr_fields != side_sav_len) {
1419 fprintf(stderr, "ERROR: number of fields mismatch between description and arguments\n");
1420 abort();
1421 }
1422 print_attributes(", attr", ":", desc->attr, desc->nr_attr);
1423 printf("%s", side_sav_len ? ", fields: [ " : "");
1424 for (i = 0; i < side_sav_len; i++) {
1425 printf("%s", i ? ", " : "");
1426 tracer_print_field(&desc->fields[i], &sav[i]);
1427 }
1428 if (nr_items)
1429 *nr_items = i;
1430 if (side_sav_len)
1431 printf(" ]");
1432 }
1433
1434 void tracer_call(const struct side_event_description *desc,
1435 const struct side_arg_vec_description *sav_desc,
1436 void *priv __attribute__((unused)))
1437 {
1438 int nr_fields = 0;
1439
1440 tracer_print_static_fields(desc, sav_desc, &nr_fields);
1441 printf("\n");
1442 }
1443
1444 void tracer_call_variadic(const struct side_event_description *desc,
1445 const struct side_arg_vec_description *sav_desc,
1446 const struct side_arg_dynamic_event_struct *var_struct,
1447 void *priv __attribute__((unused)))
1448 {
1449 uint32_t var_struct_len = var_struct->len;
1450 int nr_fields = 0, i;
1451
1452 tracer_print_static_fields(desc, sav_desc, &nr_fields);
1453
1454 if (side_unlikely(!(desc->flags & SIDE_EVENT_FLAG_VARIADIC))) {
1455 fprintf(stderr, "ERROR: unexpected non-variadic event description\n");
1456 abort();
1457 }
1458 print_attributes(", attr ", "::", var_struct->attr, var_struct->nr_attr);
1459 printf("%s", var_struct_len ? ", fields:: [ " : "");
1460 for (i = 0; i < var_struct_len; i++, nr_fields++) {
1461 printf("%s", i ? ", " : "");
1462 printf("%s:: ", var_struct->fields[i].field_name);
1463 tracer_print_dynamic(&var_struct->fields[i].elem);
1464 }
1465 if (i)
1466 printf(" ]");
1467 printf("\n");
1468 }
1469
1470 void tracer_event_notification(enum side_tracer_notification notif,
1471 struct side_event_description **events, uint32_t nr_events, void *priv)
1472 {
1473 uint32_t i;
1474 int ret;
1475
1476 printf("----------------------------------------------------------\n");
1477 printf("Tracer notified of events %s\n",
1478 notif == SIDE_TRACER_NOTIFICATION_INSERT_EVENTS ? "inserted" : "removed");
1479 for (i = 0; i < nr_events; i++) {
1480 struct side_event_description *event = events[i];
1481
1482 /* Skip NULL pointers */
1483 if (!event)
1484 continue;
1485 printf("provider: %s, event: %s\n",
1486 event->provider_name, event->event_name);
1487 if (notif == SIDE_TRACER_NOTIFICATION_INSERT_EVENTS) {
1488 if (event->flags & SIDE_EVENT_FLAG_VARIADIC) {
1489 ret = side_tracer_callback_variadic_register(event, tracer_call_variadic, NULL);
1490 if (ret)
1491 abort();
1492 } else {
1493 ret = side_tracer_callback_register(event, tracer_call, NULL);
1494 if (ret)
1495 abort();
1496 }
1497 } else {
1498 if (event->flags & SIDE_EVENT_FLAG_VARIADIC) {
1499 ret = side_tracer_callback_variadic_unregister(event, tracer_call_variadic, NULL);
1500 if (ret)
1501 abort();
1502 } else {
1503 ret = side_tracer_callback_unregister(event, tracer_call, NULL);
1504 if (ret)
1505 abort();
1506 }
1507 }
1508 }
1509 printf("----------------------------------------------------------\n");
1510 }
1511
1512 static __attribute__((constructor))
1513 void tracer_init(void);
1514 static
1515 void tracer_init(void)
1516 {
1517 tracer_handle = side_tracer_event_notification_register(tracer_event_notification, NULL);
1518 if (!tracer_handle)
1519 abort();
1520 }
1521
1522 static __attribute__((destructor))
1523 void tracer_exit(void);
1524 static
1525 void tracer_exit(void)
1526 {
1527 side_tracer_event_notification_unregister(tracer_handle);
1528 }
This page took 0.069755 seconds and 5 git commands to generate.