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