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