1 // SPDX-License-Identifier: MIT
3 * Copyright 2022 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
13 #include <side/trace.h>
15 enum tracer_display_base
{
16 TRACER_DISPLAY_BASE_2
,
17 TRACER_DISPLAY_BASE_8
,
18 TRACER_DISPLAY_BASE_10
,
19 TRACER_DISPLAY_BASE_16
,
22 static struct side_tracer_handle
*tracer_handle
;
25 void tracer_print_struct(const struct side_type_description
*type_desc
, const struct side_arg_vec_description
*sav_desc
);
27 void tracer_print_struct_sg(const struct side_type_description
*type_desc
, void *ptr
);
29 void tracer_print_array(const struct side_type_description
*type_desc
, const struct side_arg_vec_description
*sav_desc
);
31 void tracer_print_vla(const struct side_type_description
*type_desc
, const struct side_arg_vec_description
*sav_desc
);
33 void tracer_print_vla_visitor(const struct side_type_description
*type_desc
, void *app_ctx
);
35 void tracer_print_array_fixint(const struct side_type_description
*type_desc
, const struct side_arg_vec
*item
);
37 void tracer_print_vla_fixint(const struct side_type_description
*type_desc
, const struct side_arg_vec
*item
);
39 void tracer_print_dynamic(const struct side_arg_dynamic_vec
*dynamic_item
);
41 void tracer_print_type(const struct side_type_description
*type_desc
, const struct side_arg_vec
*item
);
44 int64_t get_attr_integer_value(const struct side_attr
*attr
)
48 switch (attr
->value
.type
) {
49 case SIDE_ATTR_TYPE_U8
:
50 val
= attr
->value
.u
.side_u8
;
52 case SIDE_ATTR_TYPE_U16
:
53 val
= attr
->value
.u
.side_u16
;
55 case SIDE_ATTR_TYPE_U32
:
56 val
= attr
->value
.u
.side_u32
;
58 case SIDE_ATTR_TYPE_U64
:
59 val
= attr
->value
.u
.side_u64
;
61 case SIDE_ATTR_TYPE_S8
:
62 val
= attr
->value
.u
.side_s8
;
64 case SIDE_ATTR_TYPE_S16
:
65 val
= attr
->value
.u
.side_s16
;
67 case SIDE_ATTR_TYPE_S32
:
68 val
= attr
->value
.u
.side_s32
;
70 case SIDE_ATTR_TYPE_S64
:
71 val
= attr
->value
.u
.side_s64
;
74 fprintf(stderr
, "Unexpected attribute type\n");
81 enum tracer_display_base
get_attr_display_base(const struct side_attr
*_attr
, uint32_t nr_attr
)
85 for (i
= 0; i
< nr_attr
; i
++) {
86 const struct side_attr
*attr
= &_attr
[i
];
88 if (!strcmp(attr
->key
, "std.integer.base")) {
89 int64_t val
= get_attr_integer_value(attr
);
93 return TRACER_DISPLAY_BASE_2
;
95 return TRACER_DISPLAY_BASE_8
;
97 return TRACER_DISPLAY_BASE_10
;
99 return TRACER_DISPLAY_BASE_16
;
101 fprintf(stderr
, "Unexpected integer display base: %" PRId64
"\n", val
);
106 return TRACER_DISPLAY_BASE_10
; /* Default */
110 bool type_to_host_reverse_bo(const struct side_type_description
*type_desc
)
112 switch (type_desc
->type
) {
123 case SIDE_TYPE_POINTER32
:
124 case SIDE_TYPE_POINTER64
:
125 if (type_desc
->u
.side_basic
.byte_order
!= SIDE_TYPE_BYTE_ORDER_HOST
)
130 case SIDE_TYPE_FLOAT_BINARY16
:
131 case SIDE_TYPE_FLOAT_BINARY32
:
132 case SIDE_TYPE_FLOAT_BINARY64
:
133 case SIDE_TYPE_FLOAT_BINARY128
:
134 if (type_desc
->u
.side_basic
.byte_order
!= SIDE_TYPE_FLOAT_WORD_ORDER_HOST
)
140 fprintf(stderr
, "Unexpected type\n");
146 bool sg_type_to_host_reverse_bo(const struct side_type_sg_description
*sg_type
)
148 switch (sg_type
->type
) {
149 case SIDE_TYPE_SG_UNSIGNED_INT
:
150 case SIDE_TYPE_SG_SIGNED_INT
:
151 if (sg_type
->u
.side_basic
.byte_order
!= SIDE_TYPE_BYTE_ORDER_HOST
)
157 fprintf(stderr
, "Unexpected type\n");
163 bool dynamic_type_to_host_reverse_bo(const struct side_arg_dynamic_vec
*item
)
165 switch (item
->dynamic_type
) {
166 case SIDE_DYNAMIC_TYPE_U8
:
167 case SIDE_DYNAMIC_TYPE_S8
:
168 case SIDE_DYNAMIC_TYPE_BYTE
:
170 case SIDE_DYNAMIC_TYPE_U16
:
171 case SIDE_DYNAMIC_TYPE_U32
:
172 case SIDE_DYNAMIC_TYPE_U64
:
173 case SIDE_DYNAMIC_TYPE_S16
:
174 case SIDE_DYNAMIC_TYPE_S32
:
175 case SIDE_DYNAMIC_TYPE_S64
:
176 case SIDE_DYNAMIC_TYPE_POINTER32
:
177 case SIDE_DYNAMIC_TYPE_POINTER64
:
178 if (item
->u
.side_basic
.byte_order
!= SIDE_TYPE_BYTE_ORDER_HOST
)
183 case SIDE_DYNAMIC_TYPE_FLOAT_BINARY16
:
184 case SIDE_DYNAMIC_TYPE_FLOAT_BINARY32
:
185 case SIDE_DYNAMIC_TYPE_FLOAT_BINARY64
:
186 case SIDE_DYNAMIC_TYPE_FLOAT_BINARY128
:
187 if (item
->u
.side_basic
.byte_order
!= SIDE_TYPE_FLOAT_WORD_ORDER_HOST
)
193 fprintf(stderr
, "Unexpected type\n");
199 void tracer_print_attr_type(const char *separator
, const struct side_attr
*attr
)
201 printf("{ key%s \"%s\", value%s ", separator
, attr
->key
, separator
);
202 switch (attr
->value
.type
) {
203 case SIDE_ATTR_TYPE_BOOL
:
204 printf("%s", attr
->value
.u
.side_bool
? "true" : "false");
206 case SIDE_ATTR_TYPE_U8
:
207 printf("%" PRIu8
, attr
->value
.u
.side_u8
);
209 case SIDE_ATTR_TYPE_U16
:
210 printf("%" PRIu16
, attr
->value
.u
.side_u16
);
212 case SIDE_ATTR_TYPE_U32
:
213 printf("%" PRIu32
, attr
->value
.u
.side_u32
);
215 case SIDE_ATTR_TYPE_U64
:
216 printf("%" PRIu64
, attr
->value
.u
.side_u64
);
218 case SIDE_ATTR_TYPE_S8
:
219 printf("%" PRId8
, attr
->value
.u
.side_s8
);
221 case SIDE_ATTR_TYPE_S16
:
222 printf("%" PRId16
, attr
->value
.u
.side_s16
);
224 case SIDE_ATTR_TYPE_S32
:
225 printf("%" PRId32
, attr
->value
.u
.side_s32
);
227 case SIDE_ATTR_TYPE_S64
:
228 printf("%" PRId64
, attr
->value
.u
.side_s64
);
230 case SIDE_ATTR_TYPE_POINTER32
:
231 printf("0x%" PRIx32
, attr
->value
.u
.side_u32
);
233 case SIDE_ATTR_TYPE_POINTER64
:
234 printf("0x%" PRIx64
, attr
->value
.u
.side_u64
);
236 case SIDE_ATTR_TYPE_FLOAT_BINARY16
:
238 printf("%g", (double) attr
->value
.u
.side_float_binary16
);
241 fprintf(stderr
, "ERROR: Unsupported binary16 float type\n");
244 case SIDE_ATTR_TYPE_FLOAT_BINARY32
:
246 printf("%g", (double) attr
->value
.u
.side_float_binary32
);
249 fprintf(stderr
, "ERROR: Unsupported binary32 float type\n");
252 case SIDE_ATTR_TYPE_FLOAT_BINARY64
:
254 printf("%g", (double) attr
->value
.u
.side_float_binary64
);
257 fprintf(stderr
, "ERROR: Unsupported binary64 float type\n");
260 case SIDE_ATTR_TYPE_FLOAT_BINARY128
:
262 printf("%Lg", (long double) attr
->value
.u
.side_float_binary128
);
265 fprintf(stderr
, "ERROR: Unsupported binary128 float type\n");
268 case SIDE_ATTR_TYPE_STRING
:
269 printf("\"%s\"", (const char *)(uintptr_t) attr
->value
.u
.string
);
272 fprintf(stderr
, "ERROR: <UNKNOWN ATTRIBUTE TYPE>");
279 void print_attributes(const char *prefix_str
, const char *separator
,
280 const struct side_attr
*attr
, uint32_t nr_attr
)
286 printf("%s%s [ ", prefix_str
, separator
);
287 for (i
= 0; i
< nr_attr
; i
++) {
288 printf("%s", i
? ", " : "");
289 tracer_print_attr_type(separator
, &attr
[i
]);
295 void print_enum(const struct side_type_description
*type_desc
, const struct side_arg_vec
*item
)
297 const struct side_enum_mappings
*mappings
= type_desc
->u
.side_enum
.mappings
;
298 const struct side_type_description
*elem_type
= type_desc
->u
.side_enum
.elem_type
;
299 int i
, print_count
= 0;
302 if (elem_type
->type
!= item
->type
) {
303 fprintf(stderr
, "ERROR: Unexpected enum element type\n");
306 switch (item
->type
) {
308 value
= (int64_t) item
->u
.side_u8
;
314 v
= item
->u
.side_u16
;
315 if (type_to_host_reverse_bo(elem_type
))
316 v
= side_bswap_16(v
);
324 v
= item
->u
.side_u32
;
325 if (type_to_host_reverse_bo(elem_type
))
326 v
= side_bswap_32(v
);
334 v
= item
->u
.side_u64
;
335 if (type_to_host_reverse_bo(elem_type
))
336 v
= side_bswap_64(v
);
341 value
= (int64_t) item
->u
.side_s8
;
347 v
= item
->u
.side_s16
;
348 if (type_to_host_reverse_bo(elem_type
))
349 v
= side_bswap_16(v
);
357 v
= item
->u
.side_s32
;
358 if (type_to_host_reverse_bo(elem_type
))
359 v
= side_bswap_32(v
);
367 v
= item
->u
.side_s64
;
368 if (type_to_host_reverse_bo(elem_type
))
369 v
= side_bswap_64(v
);
374 fprintf(stderr
, "ERROR: Unexpected enum element type\n");
377 print_attributes("attr", ":", mappings
->attr
, mappings
->nr_attr
);
378 printf("%s", mappings
->nr_attr
? ", " : "");
379 tracer_print_type(type_desc
->u
.side_enum
.elem_type
, item
);
380 printf(", labels: [ ");
381 for (i
= 0; i
< mappings
->nr_mappings
; i
++) {
382 const struct side_enum_mapping
*mapping
= &mappings
->mappings
[i
];
384 if (mapping
->range_end
< mapping
->range_begin
) {
385 fprintf(stderr
, "ERROR: Unexpected enum range: %" PRIu64
"-%" PRIu64
"\n",
386 mapping
->range_begin
, mapping
->range_end
);
389 if (value
>= mapping
->range_begin
&& value
<= mapping
->range_end
) {
390 printf("%s", print_count
++ ? ", " : "");
391 printf("\"%s\"", mapping
->label
);
395 printf("<NO LABEL>");
400 uint32_t enum_elem_type_to_stride(const struct side_type_description
*elem_type
)
404 switch (elem_type
->type
) {
405 case SIDE_TYPE_U8
: /* Fall-through */
419 fprintf(stderr
, "ERROR: Unexpected enum element type\n");
426 void print_enum_bitmap(const struct side_type_description
*type_desc
,
427 const struct side_arg_vec
*item
)
429 const struct side_type_description
*elem_type
= type_desc
->u
.side_enum_bitmap
.elem_type
;
430 const struct side_enum_bitmap_mappings
*side_enum_mappings
= type_desc
->u
.side_enum_bitmap
.mappings
;
431 int i
, print_count
= 0;
432 uint32_t stride_bit
, nr_items
;
433 bool reverse_byte_order
= false;
434 const struct side_arg_vec
*array_item
;
436 switch (elem_type
->type
) {
437 case SIDE_TYPE_U8
: /* Fall-through */
438 case SIDE_TYPE_BYTE
: /* Fall-through */
439 case SIDE_TYPE_U16
: /* Fall-through */
440 case SIDE_TYPE_U32
: /* Fall-through */
442 stride_bit
= enum_elem_type_to_stride(elem_type
);
443 reverse_byte_order
= type_to_host_reverse_bo(elem_type
);
447 case SIDE_TYPE_ARRAY
:
448 stride_bit
= enum_elem_type_to_stride(elem_type
->u
.side_array
.elem_type
);
449 reverse_byte_order
= type_to_host_reverse_bo(elem_type
->u
.side_array
.elem_type
);
450 array_item
= item
->u
.side_array
->sav
;
451 nr_items
= type_desc
->u
.side_array
.length
;
454 stride_bit
= enum_elem_type_to_stride(elem_type
->u
.side_vla
.elem_type
);
455 reverse_byte_order
= type_to_host_reverse_bo(elem_type
->u
.side_vla
.elem_type
);
456 array_item
= item
->u
.side_vla
->sav
;
457 nr_items
= item
->u
.side_vla
->len
;
460 fprintf(stderr
, "ERROR: Unexpected enum element type\n");
464 print_attributes("attr", ":", side_enum_mappings
->attr
, side_enum_mappings
->nr_attr
);
465 printf("%s", side_enum_mappings
->nr_attr
? ", " : "");
466 printf("labels: [ ");
467 for (i
= 0; i
< side_enum_mappings
->nr_mappings
; i
++) {
468 const struct side_enum_bitmap_mapping
*mapping
= &side_enum_mappings
->mappings
[i
];
472 if (mapping
->range_end
< mapping
->range_begin
) {
473 fprintf(stderr
, "ERROR: Unexpected enum bitmap range: %" PRIu64
"-%" PRIu64
"\n",
474 mapping
->range_begin
, mapping
->range_end
);
477 for (bit
= mapping
->range_begin
; bit
<= mapping
->range_end
; bit
++) {
478 if (bit
> (nr_items
* stride_bit
) - 1)
480 switch (stride_bit
) {
483 uint8_t v
= array_item
[bit
/ 8].u
.side_u8
;
484 if (v
& (1ULL << (bit
% 8))) {
492 uint16_t v
= array_item
[bit
/ 16].u
.side_u16
;
493 if (reverse_byte_order
)
494 v
= side_bswap_16(v
);
495 if (v
& (1ULL << (bit
% 16))) {
503 uint32_t v
= array_item
[bit
/ 32].u
.side_u32
;
504 if (reverse_byte_order
)
505 v
= side_bswap_32(v
);
506 if (v
& (1ULL << (bit
% 32))) {
514 uint64_t v
= array_item
[bit
/ 64].u
.side_u64
;
515 if (reverse_byte_order
)
516 v
= side_bswap_64(v
);
517 if (v
& (1ULL << (bit
% 64))) {
529 printf("%s", print_count
++ ? ", " : "");
530 printf("\"%s\"", mapping
->label
);
534 printf("<NO LABEL>");
539 void print_integer_binary(uint64_t v
, int bits
)
545 for (i
= 0; i
< bits
; i
++) {
546 printf("%c", v
& (1ULL << 63) ? '1' : '0');
552 void tracer_print_basic_type_header(const struct side_type_description
*type_desc
)
554 print_attributes("attr", ":", type_desc
->u
.side_basic
.attr
, type_desc
->u
.side_basic
.nr_attr
);
555 printf("%s", type_desc
->u
.side_basic
.nr_attr
? ", " : "");
560 void tracer_print_type(const struct side_type_description
*type_desc
, const struct side_arg_vec
*item
)
563 enum tracer_display_base base
= TRACER_DISPLAY_BASE_10
;
565 switch (type_desc
->type
) {
566 case SIDE_TYPE_ARRAY
:
567 switch (item
->type
) {
568 case SIDE_TYPE_ARRAY_U8
:
569 case SIDE_TYPE_ARRAY_U16
:
570 case SIDE_TYPE_ARRAY_U32
:
571 case SIDE_TYPE_ARRAY_U64
:
572 case SIDE_TYPE_ARRAY_S8
:
573 case SIDE_TYPE_ARRAY_S16
:
574 case SIDE_TYPE_ARRAY_S32
:
575 case SIDE_TYPE_ARRAY_S64
:
576 case SIDE_TYPE_ARRAY_POINTER32
:
577 case SIDE_TYPE_ARRAY_POINTER64
:
578 case SIDE_TYPE_ARRAY_BYTE
:
579 case SIDE_TYPE_ARRAY
:
582 fprintf(stderr
, "ERROR: type mismatch between description and arguments\n");
589 switch (item
->type
) {
590 case SIDE_TYPE_VLA_U8
:
591 case SIDE_TYPE_VLA_U16
:
592 case SIDE_TYPE_VLA_U32
:
593 case SIDE_TYPE_VLA_U64
:
594 case SIDE_TYPE_VLA_S8
:
595 case SIDE_TYPE_VLA_S16
:
596 case SIDE_TYPE_VLA_S32
:
597 case SIDE_TYPE_VLA_S64
:
598 case SIDE_TYPE_VLA_BYTE
:
599 case SIDE_TYPE_VLA_POINTER32
:
600 case SIDE_TYPE_VLA_POINTER64
:
604 fprintf(stderr
, "ERROR: type mismatch between description and arguments\n");
611 switch (item
->type
) {
622 fprintf(stderr
, "ERROR: type mismatch between description and arguments\n");
628 case SIDE_TYPE_ENUM_BITMAP
:
629 switch (item
->type
) {
635 case SIDE_TYPE_ARRAY
:
639 fprintf(stderr
, "ERROR: type mismatch between description and arguments\n");
646 if (type_desc
->type
!= item
->type
) {
647 fprintf(stderr
, "ERROR: type mismatch between description and arguments\n");
653 if (type_desc
->type
== SIDE_TYPE_ENUM
|| type_desc
->type
== SIDE_TYPE_ENUM_BITMAP
)
654 type
= type_desc
->type
;
667 base
= get_attr_display_base(type_desc
->u
.side_basic
.attr
,
668 type_desc
->u
.side_basic
.nr_attr
);
677 tracer_print_basic_type_header(type_desc
);
678 printf("%s", item
->u
.side_bool
? "true" : "false");
685 tracer_print_basic_type_header(type_desc
);
687 case TRACER_DISPLAY_BASE_2
:
688 print_integer_binary(v
, 8);
690 case TRACER_DISPLAY_BASE_8
:
691 printf("0%" PRIo8
, v
);
693 case TRACER_DISPLAY_BASE_10
:
694 printf("%" PRIu8
, v
);
696 case TRACER_DISPLAY_BASE_16
:
697 printf("0x%" PRIx8
, v
);
708 v
= item
->u
.side_u16
;
709 if (type_to_host_reverse_bo(type_desc
))
710 v
= side_bswap_16(v
);
711 tracer_print_basic_type_header(type_desc
);
713 case TRACER_DISPLAY_BASE_2
:
714 print_integer_binary(v
, 16);
716 case TRACER_DISPLAY_BASE_8
:
717 printf("0%" PRIo16
, v
);
719 case TRACER_DISPLAY_BASE_10
:
720 printf("%" PRIu16
, v
);
722 case TRACER_DISPLAY_BASE_16
:
723 printf("0x%" PRIx16
, v
);
734 v
= item
->u
.side_u32
;
735 if (type_to_host_reverse_bo(type_desc
))
736 v
= side_bswap_32(v
);
737 tracer_print_basic_type_header(type_desc
);
739 case TRACER_DISPLAY_BASE_2
:
740 print_integer_binary(v
, 32);
742 case TRACER_DISPLAY_BASE_8
:
743 printf("0%" PRIo32
, v
);
745 case TRACER_DISPLAY_BASE_10
:
746 printf("%" PRIu32
, v
);
748 case TRACER_DISPLAY_BASE_16
:
749 printf("0x%" PRIx32
, v
);
760 v
= item
->u
.side_u64
;
761 if (type_to_host_reverse_bo(type_desc
))
762 v
= side_bswap_64(v
);
763 tracer_print_basic_type_header(type_desc
);
765 case TRACER_DISPLAY_BASE_2
:
766 print_integer_binary(v
, 64);
768 case TRACER_DISPLAY_BASE_8
:
769 printf("0%" PRIo64
, v
);
771 case TRACER_DISPLAY_BASE_10
:
772 printf("%" PRIu64
, v
);
774 case TRACER_DISPLAY_BASE_16
:
775 printf("0x%" PRIx64
, v
);
787 tracer_print_basic_type_header(type_desc
);
789 case TRACER_DISPLAY_BASE_2
:
790 print_integer_binary(v
, 8);
792 case TRACER_DISPLAY_BASE_8
:
793 printf("0%" PRIo8
, v
);
795 case TRACER_DISPLAY_BASE_10
:
796 printf("%" PRId8
, v
);
798 case TRACER_DISPLAY_BASE_16
:
799 printf("0x%" PRIx8
, v
);
810 v
= item
->u
.side_s16
;
811 if (type_to_host_reverse_bo(type_desc
))
812 v
= side_bswap_16(v
);
813 tracer_print_basic_type_header(type_desc
);
815 case TRACER_DISPLAY_BASE_2
:
816 print_integer_binary(v
, 16);
818 case TRACER_DISPLAY_BASE_8
:
819 printf("0%" PRIo16
, v
);
821 case TRACER_DISPLAY_BASE_10
:
822 printf("%" PRId16
, v
);
824 case TRACER_DISPLAY_BASE_16
:
825 printf("0x%" PRIx16
, v
);
836 v
= item
->u
.side_s32
;
837 if (type_to_host_reverse_bo(type_desc
))
838 v
= side_bswap_32(v
);
839 tracer_print_basic_type_header(type_desc
);
841 case TRACER_DISPLAY_BASE_2
:
842 print_integer_binary(v
, 32);
844 case TRACER_DISPLAY_BASE_8
:
845 printf("0%" PRIo32
, v
);
847 case TRACER_DISPLAY_BASE_10
:
848 printf("%" PRId32
, v
);
850 case TRACER_DISPLAY_BASE_16
:
851 printf("0x%" PRIx32
, v
);
862 v
= item
->u
.side_s64
;
863 if (type_to_host_reverse_bo(type_desc
))
864 v
= side_bswap_64(v
);
865 tracer_print_basic_type_header(type_desc
);
867 case TRACER_DISPLAY_BASE_2
:
868 print_integer_binary(v
, 64);
870 case TRACER_DISPLAY_BASE_8
:
871 printf("0%" PRIo64
, v
);
873 case TRACER_DISPLAY_BASE_10
:
874 printf("%" PRId64
, v
);
876 case TRACER_DISPLAY_BASE_16
:
877 printf("0x%" PRIx64
, v
);
884 case SIDE_TYPE_POINTER32
:
888 v
= item
->u
.side_u32
;
889 if (type_to_host_reverse_bo(type_desc
))
890 v
= side_bswap_32(v
);
891 tracer_print_basic_type_header(type_desc
);
892 printf("0x%" PRIx32
, v
);
895 case SIDE_TYPE_POINTER64
:
899 v
= item
->u
.side_u64
;
900 if (type_to_host_reverse_bo(type_desc
))
901 v
= side_bswap_64(v
);
902 tracer_print_basic_type_header(type_desc
);
903 printf("0x%" PRIx64
, v
);
907 tracer_print_basic_type_header(type_desc
);
908 printf("0x%" PRIx8
, item
->u
.side_byte
);
912 print_enum(type_desc
, item
);
915 case SIDE_TYPE_ENUM_BITMAP
:
916 print_enum_bitmap(type_desc
, item
);
919 case SIDE_TYPE_FLOAT_BINARY16
:
926 .f
= item
->u
.side_float_binary16
,
929 if (type_to_host_reverse_bo(type_desc
))
930 float16
.u
= side_bswap_16(float16
.u
);
931 tracer_print_basic_type_header(type_desc
);
932 printf("%g", (double) float16
.f
);
935 fprintf(stderr
, "ERROR: Unsupported binary16 float type\n");
939 case SIDE_TYPE_FLOAT_BINARY32
:
946 .f
= item
->u
.side_float_binary32
,
949 if (type_to_host_reverse_bo(type_desc
))
950 float32
.u
= side_bswap_32(float32
.u
);
951 tracer_print_basic_type_header(type_desc
);
952 printf("%g", (double) float32
.f
);
955 fprintf(stderr
, "ERROR: Unsupported binary32 float type\n");
959 case SIDE_TYPE_FLOAT_BINARY64
:
966 .f
= item
->u
.side_float_binary64
,
969 if (type_to_host_reverse_bo(type_desc
))
970 float64
.u
= side_bswap_64(float64
.u
);
971 tracer_print_basic_type_header(type_desc
);
972 printf("%g", (double) float64
.f
);
975 fprintf(stderr
, "ERROR: Unsupported binary64 float type\n");
979 case SIDE_TYPE_FLOAT_BINARY128
:
986 .f
= item
->u
.side_float_binary128
,
989 if (type_to_host_reverse_bo(type_desc
))
990 side_bswap_128p(float128
.arr
);
991 tracer_print_basic_type_header(type_desc
);
992 printf("%Lg", (long double) float128
.f
);
995 fprintf(stderr
, "ERROR: Unsupported binary128 float type\n");
999 case SIDE_TYPE_STRING
:
1000 tracer_print_basic_type_header(type_desc
);
1001 printf("\"%s\"", (const char *)(uintptr_t) item
->u
.string
);
1003 case SIDE_TYPE_STRUCT
:
1004 tracer_print_struct(type_desc
, item
->u
.side_struct
);
1006 case SIDE_TYPE_STRUCT_SG
:
1007 tracer_print_struct_sg(type_desc
, item
->u
.side_struct_sg_ptr
);
1009 case SIDE_TYPE_ARRAY
:
1010 tracer_print_array(type_desc
, item
->u
.side_array
);
1013 tracer_print_vla(type_desc
, item
->u
.side_vla
);
1015 case SIDE_TYPE_VLA_VISITOR
:
1016 tracer_print_vla_visitor(type_desc
, item
->u
.side_vla_app_visitor_ctx
);
1018 case SIDE_TYPE_ARRAY_U8
:
1019 case SIDE_TYPE_ARRAY_U16
:
1020 case SIDE_TYPE_ARRAY_U32
:
1021 case SIDE_TYPE_ARRAY_U64
:
1022 case SIDE_TYPE_ARRAY_S8
:
1023 case SIDE_TYPE_ARRAY_S16
:
1024 case SIDE_TYPE_ARRAY_S32
:
1025 case SIDE_TYPE_ARRAY_S64
:
1026 case SIDE_TYPE_ARRAY_BYTE
:
1027 case SIDE_TYPE_ARRAY_POINTER32
:
1028 case SIDE_TYPE_ARRAY_POINTER64
:
1029 tracer_print_array_fixint(type_desc
, item
);
1031 case SIDE_TYPE_VLA_U8
:
1032 case SIDE_TYPE_VLA_U16
:
1033 case SIDE_TYPE_VLA_U32
:
1034 case SIDE_TYPE_VLA_U64
:
1035 case SIDE_TYPE_VLA_S8
:
1036 case SIDE_TYPE_VLA_S16
:
1037 case SIDE_TYPE_VLA_S32
:
1038 case SIDE_TYPE_VLA_S64
:
1039 case SIDE_TYPE_VLA_BYTE
:
1040 case SIDE_TYPE_VLA_POINTER32
:
1041 case SIDE_TYPE_VLA_POINTER64
:
1042 tracer_print_vla_fixint(type_desc
, item
);
1044 case SIDE_TYPE_DYNAMIC
:
1045 tracer_print_basic_type_header(type_desc
);
1046 tracer_print_dynamic(&item
->u
.dynamic
);
1049 fprintf(stderr
, "<UNKNOWN TYPE>");
1056 void tracer_print_field(const struct side_event_field
*item_desc
, const struct side_arg_vec
*item
)
1058 printf("%s: ", item_desc
->field_name
);
1059 tracer_print_type(&item_desc
->side_type
, item
);
1063 void tracer_print_struct(const struct side_type_description
*type_desc
, const struct side_arg_vec_description
*sav_desc
)
1065 const struct side_arg_vec
*sav
= sav_desc
->sav
;
1066 uint32_t side_sav_len
= sav_desc
->len
;
1069 if (type_desc
->u
.side_struct
->nr_fields
!= side_sav_len
) {
1070 fprintf(stderr
, "ERROR: number of fields mismatch between description and arguments of structure\n");
1073 print_attributes("attr", ":", type_desc
->u
.side_struct
->attr
, type_desc
->u
.side_struct
->nr_attr
);
1074 printf("%s", type_desc
->u
.side_struct
->nr_attr
? ", " : "");
1075 printf("fields: { ");
1076 for (i
= 0; i
< side_sav_len
; i
++) {
1077 printf("%s", i
? ", " : "");
1078 tracer_print_field(&type_desc
->u
.side_struct
->fields
[i
], &sav
[i
]);
1084 void tracer_print_sg_integer_type_header(const struct side_type_sg_description
*sg_type
)
1086 print_attributes("attr", ":", sg_type
->u
.side_basic
.attr
, sg_type
->u
.side_basic
.nr_attr
);
1087 printf("%s", sg_type
->u
.side_basic
.nr_attr
? ", " : "");
1092 void tracer_print_sg_type(const struct side_type_sg_description
*sg_type
, void *_ptr
)
1094 enum tracer_display_base base
= TRACER_DISPLAY_BASE_10
;
1095 const char *ptr
= (const char *) _ptr
;
1097 switch (sg_type
->type
) {
1098 case SIDE_TYPE_SG_UNSIGNED_INT
:
1099 case SIDE_TYPE_SG_SIGNED_INT
:
1100 base
= get_attr_display_base(sg_type
->u
.side_basic
.attr
,
1101 sg_type
->u
.side_basic
.nr_attr
);
1108 switch (sg_type
->type
) {
1109 case SIDE_TYPE_SG_UNSIGNED_INT
:
1111 tracer_print_sg_integer_type_header(sg_type
);
1112 switch (sg_type
->u
.side_basic
.integer_size_bits
) {
1117 if (!sg_type
->u
.side_basic
.len_bits
|| sg_type
->u
.side_basic
.len_bits
+ sg_type
->u
.side_basic
.offset_bits
> 8)
1119 memcpy(&v
, ptr
+ sg_type
->u
.side_basic
.integer_offset
, sizeof(v
));
1120 v
>>= sg_type
->u
.side_basic
.offset_bits
;
1121 if (sg_type
->u
.side_basic
.len_bits
< 8)
1122 v
&= (1U << sg_type
->u
.side_basic
.len_bits
) - 1;
1124 case TRACER_DISPLAY_BASE_2
:
1125 print_integer_binary(v
, sg_type
->u
.side_basic
.len_bits
);
1127 case TRACER_DISPLAY_BASE_8
:
1128 printf("0%" PRIo8
, v
);
1130 case TRACER_DISPLAY_BASE_10
:
1131 printf("%" PRIu8
, v
);
1133 case TRACER_DISPLAY_BASE_16
:
1134 printf("0x%" PRIx8
, v
);
1145 if (!sg_type
->u
.side_basic
.len_bits
|| sg_type
->u
.side_basic
.len_bits
+ sg_type
->u
.side_basic
.offset_bits
> 16)
1147 memcpy(&v
, ptr
+ sg_type
->u
.side_basic
.integer_offset
, sizeof(v
));
1148 if (sg_type_to_host_reverse_bo(sg_type
))
1149 v
= side_bswap_16(v
);
1150 v
>>= sg_type
->u
.side_basic
.offset_bits
;
1151 if (sg_type
->u
.side_basic
.len_bits
< 16)
1152 v
&= (1U << sg_type
->u
.side_basic
.len_bits
) - 1;
1154 case TRACER_DISPLAY_BASE_2
:
1155 print_integer_binary(v
, sg_type
->u
.side_basic
.len_bits
);
1157 case TRACER_DISPLAY_BASE_8
:
1158 printf("0%" PRIo16
, v
);
1160 case TRACER_DISPLAY_BASE_10
:
1161 printf("%" PRIu16
, v
);
1163 case TRACER_DISPLAY_BASE_16
:
1164 printf("0x%" PRIx16
, v
);
1175 if (!sg_type
->u
.side_basic
.len_bits
|| sg_type
->u
.side_basic
.len_bits
+ sg_type
->u
.side_basic
.offset_bits
> 32)
1177 memcpy(&v
, ptr
+ sg_type
->u
.side_basic
.integer_offset
, sizeof(v
));
1178 if (sg_type_to_host_reverse_bo(sg_type
))
1179 v
= side_bswap_32(v
);
1180 v
>>= sg_type
->u
.side_basic
.offset_bits
;
1181 if (sg_type
->u
.side_basic
.len_bits
< 32)
1182 v
&= (1U << sg_type
->u
.side_basic
.len_bits
) - 1;
1184 case TRACER_DISPLAY_BASE_2
:
1185 print_integer_binary(v
, sg_type
->u
.side_basic
.len_bits
);
1187 case TRACER_DISPLAY_BASE_8
:
1188 printf("0%" PRIo32
, v
);
1190 case TRACER_DISPLAY_BASE_10
:
1191 printf("%" PRIu32
, v
);
1193 case TRACER_DISPLAY_BASE_16
:
1194 printf("0x%" PRIx32
, v
);
1205 if (!sg_type
->u
.side_basic
.len_bits
|| sg_type
->u
.side_basic
.len_bits
+ sg_type
->u
.side_basic
.offset_bits
> 64)
1207 memcpy(&v
, ptr
+ sg_type
->u
.side_basic
.integer_offset
, sizeof(v
));
1208 if (sg_type_to_host_reverse_bo(sg_type
))
1209 v
= side_bswap_64(v
);
1210 v
>>= sg_type
->u
.side_basic
.offset_bits
;
1211 if (sg_type
->u
.side_basic
.len_bits
< 64)
1212 v
&= (1ULL << sg_type
->u
.side_basic
.len_bits
) - 1;
1214 case TRACER_DISPLAY_BASE_2
:
1215 print_integer_binary(v
, sg_type
->u
.side_basic
.len_bits
);
1217 case TRACER_DISPLAY_BASE_8
:
1218 printf("0%" PRIo64
, v
);
1220 case TRACER_DISPLAY_BASE_10
:
1221 printf("%" PRIu64
, v
);
1223 case TRACER_DISPLAY_BASE_16
:
1224 printf("0x%" PRIx64
, v
);
1232 fprintf(stderr
, "<UNKNOWN SCATTER-GATHER INTEGER SIZE>");
1237 case SIDE_TYPE_SG_SIGNED_INT
:
1239 tracer_print_sg_integer_type_header(sg_type
);
1240 switch (sg_type
->u
.side_basic
.integer_size_bits
) {
1245 if (!sg_type
->u
.side_basic
.len_bits
|| sg_type
->u
.side_basic
.len_bits
+ sg_type
->u
.side_basic
.offset_bits
> 8)
1247 memcpy(&v
, ptr
+ sg_type
->u
.side_basic
.integer_offset
, sizeof(v
));
1248 v
>>= sg_type
->u
.side_basic
.offset_bits
;
1249 if (sg_type
->u
.side_basic
.len_bits
< 8)
1250 v
&= (1U << sg_type
->u
.side_basic
.len_bits
) - 1;
1252 case TRACER_DISPLAY_BASE_2
:
1253 print_integer_binary(v
, sg_type
->u
.side_basic
.len_bits
);
1255 case TRACER_DISPLAY_BASE_8
:
1256 printf("0%" PRIo8
, v
);
1258 case TRACER_DISPLAY_BASE_10
:
1260 if (sg_type
->u
.side_basic
.len_bits
< 8) {
1261 if (v
& (1U << (sg_type
->u
.side_basic
.len_bits
- 1)))
1262 v
|= ~((1U << sg_type
->u
.side_basic
.len_bits
) - 1);
1264 printf("%" PRId8
, v
);
1266 case TRACER_DISPLAY_BASE_16
:
1267 printf("0x%" PRIx8
, v
);
1278 if (!sg_type
->u
.side_basic
.len_bits
|| sg_type
->u
.side_basic
.len_bits
+ sg_type
->u
.side_basic
.offset_bits
> 16)
1280 memcpy(&v
, ptr
+ sg_type
->u
.side_basic
.integer_offset
, sizeof(v
));
1281 if (sg_type_to_host_reverse_bo(sg_type
))
1282 v
= side_bswap_16(v
);
1283 v
>>= sg_type
->u
.side_basic
.offset_bits
;
1284 if (sg_type
->u
.side_basic
.len_bits
< 16)
1285 v
&= (1U << sg_type
->u
.side_basic
.len_bits
) - 1;
1287 case TRACER_DISPLAY_BASE_2
:
1288 print_integer_binary(v
, sg_type
->u
.side_basic
.len_bits
);
1290 case TRACER_DISPLAY_BASE_8
:
1291 printf("0%" PRIo16
, v
);
1293 case TRACER_DISPLAY_BASE_10
:
1295 if (sg_type
->u
.side_basic
.len_bits
< 16) {
1296 if (v
& (1U << (sg_type
->u
.side_basic
.len_bits
- 1)))
1297 v
|= ~((1U << sg_type
->u
.side_basic
.len_bits
) - 1);
1299 printf("%" PRId16
, v
);
1301 case TRACER_DISPLAY_BASE_16
:
1302 printf("0x%" PRIx16
, v
);
1313 if (!sg_type
->u
.side_basic
.len_bits
|| sg_type
->u
.side_basic
.len_bits
+ sg_type
->u
.side_basic
.offset_bits
> 32)
1315 memcpy(&v
, ptr
+ sg_type
->u
.side_basic
.integer_offset
, sizeof(v
));
1316 if (sg_type_to_host_reverse_bo(sg_type
))
1317 v
= side_bswap_32(v
);
1318 v
>>= sg_type
->u
.side_basic
.offset_bits
;
1319 if (sg_type
->u
.side_basic
.len_bits
< 32)
1320 v
&= (1U << sg_type
->u
.side_basic
.len_bits
) - 1;
1322 case TRACER_DISPLAY_BASE_2
:
1323 print_integer_binary(v
, sg_type
->u
.side_basic
.len_bits
);
1325 case TRACER_DISPLAY_BASE_8
:
1326 printf("0%" PRIo32
, v
);
1328 case TRACER_DISPLAY_BASE_10
:
1330 if (sg_type
->u
.side_basic
.len_bits
< 32) {
1331 if (v
& (1U << (sg_type
->u
.side_basic
.len_bits
- 1)))
1332 v
|= ~((1U << sg_type
->u
.side_basic
.len_bits
) - 1);
1334 printf("%" PRId32
, v
);
1336 case TRACER_DISPLAY_BASE_16
:
1337 printf("0x%" PRIx32
, v
);
1348 if (!sg_type
->u
.side_basic
.len_bits
|| sg_type
->u
.side_basic
.len_bits
+ sg_type
->u
.side_basic
.offset_bits
> 64)
1350 memcpy(&v
, ptr
+ sg_type
->u
.side_basic
.integer_offset
, sizeof(v
));
1351 if (sg_type_to_host_reverse_bo(sg_type
))
1352 v
= side_bswap_64(v
);
1353 v
>>= sg_type
->u
.side_basic
.offset_bits
;
1354 if (sg_type
->u
.side_basic
.len_bits
< 64)
1355 v
&= (1ULL << sg_type
->u
.side_basic
.len_bits
) - 1;
1357 case TRACER_DISPLAY_BASE_2
:
1358 print_integer_binary(v
, sg_type
->u
.side_basic
.len_bits
);
1360 case TRACER_DISPLAY_BASE_8
:
1361 printf("0%" PRIo64
, v
);
1363 case TRACER_DISPLAY_BASE_10
:
1365 if (sg_type
->u
.side_basic
.len_bits
< 64) {
1366 if (v
& (1ULL << (sg_type
->u
.side_basic
.len_bits
- 1)))
1367 v
|= ~((1ULL << sg_type
->u
.side_basic
.len_bits
) - 1);
1369 printf("%" PRId64
, v
);
1371 case TRACER_DISPLAY_BASE_16
:
1372 printf("0x%" PRIx64
, v
);
1380 fprintf(stderr
, "<UNKNOWN SCATTER-GATHER INTEGER SIZE>");
1386 fprintf(stderr
, "<UNKNOWN SCATTER-GATHER TYPE>");
1393 void tracer_print_sg_field(const struct side_struct_field_sg
*field_sg
, void *ptr
)
1395 printf("%s: ", field_sg
->field_name
);
1396 tracer_print_sg_type(&field_sg
->side_type
, ptr
);
1400 void tracer_print_struct_sg(const struct side_type_description
*type_desc
, void *ptr
)
1402 const struct side_type_struct_sg
*struct_sg
= type_desc
->u
.side_struct_sg
;
1405 print_attributes("attr", ":", struct_sg
->attr
, struct_sg
->nr_attr
);
1406 printf("%s", struct_sg
->nr_attr
? ", " : "");
1407 printf("fields: { ");
1408 for (i
= 0; i
< struct_sg
->nr_fields
; i
++) {
1409 printf("%s", i
? ", " : "");
1410 tracer_print_sg_field(&struct_sg
->fields_sg
[i
], ptr
);
1416 void tracer_print_array(const struct side_type_description
*type_desc
, const struct side_arg_vec_description
*sav_desc
)
1418 const struct side_arg_vec
*sav
= sav_desc
->sav
;
1419 uint32_t side_sav_len
= sav_desc
->len
;
1422 if (type_desc
->u
.side_array
.length
!= side_sav_len
) {
1423 fprintf(stderr
, "ERROR: length mismatch between description and arguments of array\n");
1426 print_attributes("attr", ":", type_desc
->u
.side_array
.attr
, type_desc
->u
.side_array
.nr_attr
);
1427 printf("%s", type_desc
->u
.side_array
.nr_attr
? ", " : "");
1428 printf("elements: ");
1430 for (i
= 0; i
< side_sav_len
; i
++) {
1431 printf("%s", i
? ", " : "");
1432 tracer_print_type(type_desc
->u
.side_array
.elem_type
, &sav
[i
]);
1438 void tracer_print_vla(const struct side_type_description
*type_desc
, const struct side_arg_vec_description
*sav_desc
)
1440 const struct side_arg_vec
*sav
= sav_desc
->sav
;
1441 uint32_t side_sav_len
= sav_desc
->len
;
1444 print_attributes("attr", ":", type_desc
->u
.side_vla
.attr
, type_desc
->u
.side_vla
.nr_attr
);
1445 printf("%s", type_desc
->u
.side_vla
.nr_attr
? ", " : "");
1446 printf("elements: ");
1448 for (i
= 0; i
< side_sav_len
; i
++) {
1449 printf("%s", i
? ", " : "");
1450 tracer_print_type(type_desc
->u
.side_vla
.elem_type
, &sav
[i
]);
1455 struct tracer_visitor_priv
{
1456 const struct side_type_description
*elem_type
;
1461 enum side_visitor_status
tracer_write_elem_cb(const struct side_tracer_visitor_ctx
*tracer_ctx
,
1462 const struct side_arg_vec
*elem
)
1464 struct tracer_visitor_priv
*tracer_priv
= tracer_ctx
->priv
;
1466 printf("%s", tracer_priv
->i
++ ? ", " : "");
1467 tracer_print_type(tracer_priv
->elem_type
, elem
);
1468 return SIDE_VISITOR_STATUS_OK
;
1472 void tracer_print_vla_visitor(const struct side_type_description
*type_desc
, void *app_ctx
)
1474 enum side_visitor_status status
;
1475 struct tracer_visitor_priv tracer_priv
= {
1476 .elem_type
= type_desc
->u
.side_vla_visitor
.elem_type
,
1479 const struct side_tracer_visitor_ctx tracer_ctx
= {
1480 .write_elem
= tracer_write_elem_cb
,
1481 .priv
= &tracer_priv
,
1484 print_attributes("attr", ":", type_desc
->u
.side_vla_visitor
.attr
, type_desc
->u
.side_vla_visitor
.nr_attr
);
1485 printf("%s", type_desc
->u
.side_vla_visitor
.nr_attr
? ", " : "");
1486 printf("elements: ");
1488 status
= type_desc
->u
.side_vla_visitor
.visitor(&tracer_ctx
, app_ctx
);
1490 case SIDE_VISITOR_STATUS_OK
:
1492 case SIDE_VISITOR_STATUS_ERROR
:
1493 fprintf(stderr
, "ERROR: Visitor error\n");
1499 void tracer_print_array_fixint(const struct side_type_description
*type_desc
, const struct side_arg_vec
*item
)
1501 const struct side_type_description
*elem_type
= type_desc
->u
.side_array
.elem_type
;
1502 uint32_t side_sav_len
= type_desc
->u
.side_array
.length
;
1503 void *p
= item
->u
.side_array_fixint
;
1504 enum side_type side_type
;
1507 print_attributes("attr", ":", type_desc
->u
.side_array
.attr
, type_desc
->u
.side_array
.nr_attr
);
1508 printf("%s", type_desc
->u
.side_array
.nr_attr
? ", " : "");
1509 printf("elements: ");
1510 switch (item
->type
) {
1511 case SIDE_TYPE_ARRAY_U8
:
1512 if (elem_type
->type
!= SIDE_TYPE_U8
)
1515 case SIDE_TYPE_ARRAY_U16
:
1516 if (elem_type
->type
!= SIDE_TYPE_U16
)
1519 case SIDE_TYPE_ARRAY_U32
:
1520 if (elem_type
->type
!= SIDE_TYPE_U32
)
1523 case SIDE_TYPE_ARRAY_U64
:
1524 if (elem_type
->type
!= SIDE_TYPE_U64
)
1527 case SIDE_TYPE_ARRAY_S8
:
1528 if (elem_type
->type
!= SIDE_TYPE_S8
)
1531 case SIDE_TYPE_ARRAY_S16
:
1532 if (elem_type
->type
!= SIDE_TYPE_S16
)
1535 case SIDE_TYPE_ARRAY_S32
:
1536 if (elem_type
->type
!= SIDE_TYPE_S32
)
1539 case SIDE_TYPE_ARRAY_S64
:
1540 if (elem_type
->type
!= SIDE_TYPE_S64
)
1543 case SIDE_TYPE_ARRAY_BYTE
:
1544 if (elem_type
->type
!= SIDE_TYPE_BYTE
)
1547 case SIDE_TYPE_ARRAY_POINTER32
:
1548 if (elem_type
->type
!= SIDE_TYPE_POINTER32
)
1550 case SIDE_TYPE_ARRAY_POINTER64
:
1551 if (elem_type
->type
!= SIDE_TYPE_POINTER64
)
1557 side_type
= elem_type
->type
;
1560 for (i
= 0; i
< side_sav_len
; i
++) {
1561 struct side_arg_vec sav_elem
= {
1565 switch (side_type
) {
1567 sav_elem
.u
.side_u8
= ((const uint8_t *) p
)[i
];
1570 sav_elem
.u
.side_s8
= ((const int8_t *) p
)[i
];
1573 sav_elem
.u
.side_u16
= ((const uint16_t *) p
)[i
];
1576 sav_elem
.u
.side_s16
= ((const int16_t *) p
)[i
];
1579 sav_elem
.u
.side_u32
= ((const uint32_t *) p
)[i
];
1582 sav_elem
.u
.side_s32
= ((const int32_t *) p
)[i
];
1585 sav_elem
.u
.side_u64
= ((const uint64_t *) p
)[i
];
1588 sav_elem
.u
.side_s64
= ((const int64_t *) p
)[i
];
1590 case SIDE_TYPE_BYTE
:
1591 sav_elem
.u
.side_byte
= ((const uint8_t *) p
)[i
];
1593 case SIDE_TYPE_POINTER32
:
1594 sav_elem
.u
.side_u32
= ((const uint32_t *) p
)[i
];
1596 case SIDE_TYPE_POINTER64
:
1597 sav_elem
.u
.side_u64
= ((const uint64_t *) p
)[i
];
1601 fprintf(stderr
, "ERROR: Unexpected type\n");
1605 printf("%s", i
? ", " : "");
1606 tracer_print_type(elem_type
, &sav_elem
);
1612 fprintf(stderr
, "ERROR: type mismatch\n");
1616 void tracer_print_vla_fixint(const struct side_type_description
*type_desc
, const struct side_arg_vec
*item
)
1618 const struct side_type_description
*elem_type
= type_desc
->u
.side_vla
.elem_type
;
1619 uint32_t side_sav_len
= item
->u
.side_vla_fixint
.length
;
1620 void *p
= item
->u
.side_vla_fixint
.p
;
1621 enum side_type side_type
;
1624 print_attributes("attr", ":", type_desc
->u
.side_vla
.attr
, type_desc
->u
.side_vla
.nr_attr
);
1625 printf("%s", type_desc
->u
.side_vla
.nr_attr
? ", " : "");
1626 printf("elements: ");
1627 switch (item
->type
) {
1628 case SIDE_TYPE_VLA_U8
:
1629 if (elem_type
->type
!= SIDE_TYPE_U8
)
1632 case SIDE_TYPE_VLA_U16
:
1633 if (elem_type
->type
!= SIDE_TYPE_U16
)
1636 case SIDE_TYPE_VLA_U32
:
1637 if (elem_type
->type
!= SIDE_TYPE_U32
)
1640 case SIDE_TYPE_VLA_U64
:
1641 if (elem_type
->type
!= SIDE_TYPE_U64
)
1644 case SIDE_TYPE_VLA_S8
:
1645 if (elem_type
->type
!= SIDE_TYPE_S8
)
1648 case SIDE_TYPE_VLA_S16
:
1649 if (elem_type
->type
!= SIDE_TYPE_S16
)
1652 case SIDE_TYPE_VLA_S32
:
1653 if (elem_type
->type
!= SIDE_TYPE_S32
)
1656 case SIDE_TYPE_VLA_S64
:
1657 if (elem_type
->type
!= SIDE_TYPE_S64
)
1660 case SIDE_TYPE_VLA_BYTE
:
1661 if (elem_type
->type
!= SIDE_TYPE_BYTE
)
1664 case SIDE_TYPE_VLA_POINTER32
:
1665 if (elem_type
->type
!= SIDE_TYPE_POINTER32
)
1667 case SIDE_TYPE_VLA_POINTER64
:
1668 if (elem_type
->type
!= SIDE_TYPE_POINTER64
)
1674 side_type
= elem_type
->type
;
1677 for (i
= 0; i
< side_sav_len
; i
++) {
1678 struct side_arg_vec sav_elem
= {
1682 switch (side_type
) {
1684 sav_elem
.u
.side_u8
= ((const uint8_t *) p
)[i
];
1687 sav_elem
.u
.side_s8
= ((const int8_t *) p
)[i
];
1690 sav_elem
.u
.side_u16
= ((const uint16_t *) p
)[i
];
1693 sav_elem
.u
.side_s16
= ((const int16_t *) p
)[i
];
1696 sav_elem
.u
.side_u32
= ((const uint32_t *) p
)[i
];
1699 sav_elem
.u
.side_s32
= ((const int32_t *) p
)[i
];
1702 sav_elem
.u
.side_u64
= ((const uint64_t *) p
)[i
];
1705 sav_elem
.u
.side_s64
= ((const int64_t *) p
)[i
];
1707 case SIDE_TYPE_BYTE
:
1708 sav_elem
.u
.side_byte
= ((const uint8_t *) p
)[i
];
1710 case SIDE_TYPE_POINTER32
:
1711 sav_elem
.u
.side_u32
= ((const uint32_t *) p
)[i
];
1713 case SIDE_TYPE_POINTER64
:
1714 sav_elem
.u
.side_u64
= ((const uint64_t *) p
)[i
];
1718 fprintf(stderr
, "ERROR: Unexpected type\n");
1722 printf("%s", i
? ", " : "");
1723 tracer_print_type(elem_type
, &sav_elem
);
1729 fprintf(stderr
, "ERROR: type mismatch\n");
1734 void tracer_print_dynamic_struct(const struct side_arg_dynamic_event_struct
*dynamic_struct
)
1736 const struct side_arg_dynamic_event_field
*fields
= dynamic_struct
->fields
;
1737 uint32_t len
= dynamic_struct
->len
;
1740 print_attributes("attr", "::", dynamic_struct
->attr
, dynamic_struct
->nr_attr
);
1741 printf("%s", dynamic_struct
->nr_attr
? ", " : "");
1742 printf("fields:: ");
1744 for (i
= 0; i
< len
; i
++) {
1745 printf("%s", i
? ", " : "");
1746 printf("%s:: ", fields
[i
].field_name
);
1747 tracer_print_dynamic(&fields
[i
].elem
);
1752 struct tracer_dynamic_struct_visitor_priv
{
1757 enum side_visitor_status
tracer_dynamic_struct_write_elem_cb(
1758 const struct side_tracer_dynamic_struct_visitor_ctx
*tracer_ctx
,
1759 const struct side_arg_dynamic_event_field
*dynamic_field
)
1761 struct tracer_dynamic_struct_visitor_priv
*tracer_priv
= tracer_ctx
->priv
;
1763 printf("%s", tracer_priv
->i
++ ? ", " : "");
1764 printf("%s:: ", dynamic_field
->field_name
);
1765 tracer_print_dynamic(&dynamic_field
->elem
);
1766 return SIDE_VISITOR_STATUS_OK
;
1770 void tracer_print_dynamic_struct_visitor(const struct side_arg_dynamic_vec
*item
)
1772 enum side_visitor_status status
;
1773 struct tracer_dynamic_struct_visitor_priv tracer_priv
= {
1776 const struct side_tracer_dynamic_struct_visitor_ctx tracer_ctx
= {
1777 .write_field
= tracer_dynamic_struct_write_elem_cb
,
1778 .priv
= &tracer_priv
,
1780 void *app_ctx
= item
->u
.side_dynamic_struct_visitor
.app_ctx
;
1782 print_attributes("attr", "::", item
->u
.side_dynamic_struct_visitor
.attr
, item
->u
.side_dynamic_struct_visitor
.nr_attr
);
1783 printf("%s", item
->u
.side_dynamic_struct_visitor
.nr_attr
? ", " : "");
1784 printf("fields:: ");
1786 status
= item
->u
.side_dynamic_struct_visitor
.visitor(&tracer_ctx
, app_ctx
);
1788 case SIDE_VISITOR_STATUS_OK
:
1790 case SIDE_VISITOR_STATUS_ERROR
:
1791 fprintf(stderr
, "ERROR: Visitor error\n");
1798 void tracer_print_dynamic_vla(const struct side_arg_dynamic_vec_vla
*vla
)
1800 const struct side_arg_dynamic_vec
*sav
= vla
->sav
;
1801 uint32_t side_sav_len
= vla
->len
;
1804 print_attributes("attr", "::", vla
->attr
, vla
->nr_attr
);
1805 printf("%s", vla
->nr_attr
? ", " : "");
1806 printf("elements:: ");
1808 for (i
= 0; i
< side_sav_len
; i
++) {
1809 printf("%s", i
? ", " : "");
1810 tracer_print_dynamic(&sav
[i
]);
1815 struct tracer_dynamic_vla_visitor_priv
{
1820 enum side_visitor_status
tracer_dynamic_vla_write_elem_cb(
1821 const struct side_tracer_dynamic_vla_visitor_ctx
*tracer_ctx
,
1822 const struct side_arg_dynamic_vec
*elem
)
1824 struct tracer_dynamic_vla_visitor_priv
*tracer_priv
= tracer_ctx
->priv
;
1826 printf("%s", tracer_priv
->i
++ ? ", " : "");
1827 tracer_print_dynamic(elem
);
1828 return SIDE_VISITOR_STATUS_OK
;
1832 void tracer_print_dynamic_vla_visitor(const struct side_arg_dynamic_vec
*item
)
1834 enum side_visitor_status status
;
1835 struct tracer_dynamic_vla_visitor_priv tracer_priv
= {
1838 const struct side_tracer_dynamic_vla_visitor_ctx tracer_ctx
= {
1839 .write_elem
= tracer_dynamic_vla_write_elem_cb
,
1840 .priv
= &tracer_priv
,
1842 void *app_ctx
= item
->u
.side_dynamic_vla_visitor
.app_ctx
;
1844 print_attributes("attr", "::", item
->u
.side_dynamic_vla_visitor
.attr
, item
->u
.side_dynamic_vla_visitor
.nr_attr
);
1845 printf("%s", item
->u
.side_dynamic_vla_visitor
.nr_attr
? ", " : "");
1846 printf("elements:: ");
1848 status
= item
->u
.side_dynamic_vla_visitor
.visitor(&tracer_ctx
, app_ctx
);
1850 case SIDE_VISITOR_STATUS_OK
:
1852 case SIDE_VISITOR_STATUS_ERROR
:
1853 fprintf(stderr
, "ERROR: Visitor error\n");
1860 void tracer_print_dynamic_basic_type_header(const struct side_arg_dynamic_vec
*item
)
1862 print_attributes("attr", "::", item
->u
.side_basic
.attr
, item
->u
.side_basic
.nr_attr
);
1863 printf("%s", item
->u
.side_basic
.nr_attr
? ", " : "");
1868 void tracer_print_dynamic(const struct side_arg_dynamic_vec
*item
)
1870 enum tracer_display_base base
= TRACER_DISPLAY_BASE_10
;
1872 switch (item
->dynamic_type
) {
1873 case SIDE_DYNAMIC_TYPE_U8
:
1874 case SIDE_DYNAMIC_TYPE_U16
:
1875 case SIDE_DYNAMIC_TYPE_U32
:
1876 case SIDE_DYNAMIC_TYPE_U64
:
1877 case SIDE_DYNAMIC_TYPE_S8
:
1878 case SIDE_DYNAMIC_TYPE_S16
:
1879 case SIDE_DYNAMIC_TYPE_S32
:
1880 case SIDE_DYNAMIC_TYPE_S64
:
1881 base
= get_attr_display_base(item
->u
.side_basic
.attr
,
1882 item
->u
.side_basic
.nr_attr
);
1890 switch (item
->dynamic_type
) {
1891 case SIDE_DYNAMIC_TYPE_NULL
:
1892 tracer_print_dynamic_basic_type_header(item
);
1893 printf("<NULL TYPE>");
1895 case SIDE_DYNAMIC_TYPE_BOOL
:
1896 tracer_print_dynamic_basic_type_header(item
);
1897 printf("%s", item
->u
.side_basic
.u
.side_bool
? "true" : "false");
1899 case SIDE_DYNAMIC_TYPE_U8
:
1903 v
= item
->u
.side_basic
.u
.side_u8
;
1904 tracer_print_dynamic_basic_type_header(item
);
1906 case TRACER_DISPLAY_BASE_2
:
1907 print_integer_binary(v
, 8);
1909 case TRACER_DISPLAY_BASE_8
:
1910 printf("0%" PRIo8
, v
);
1912 case TRACER_DISPLAY_BASE_10
:
1913 printf("%" PRIu8
, v
);
1915 case TRACER_DISPLAY_BASE_16
:
1916 printf("0x%" PRIx8
, v
);
1923 case SIDE_DYNAMIC_TYPE_U16
:
1927 v
= item
->u
.side_basic
.u
.side_u16
;
1928 if (dynamic_type_to_host_reverse_bo(item
))
1929 v
= side_bswap_16(v
);
1930 tracer_print_dynamic_basic_type_header(item
);
1932 case TRACER_DISPLAY_BASE_2
:
1933 print_integer_binary(v
, 16);
1935 case TRACER_DISPLAY_BASE_8
:
1936 printf("0%" PRIo16
, v
);
1938 case TRACER_DISPLAY_BASE_10
:
1939 printf("%" PRIu16
, v
);
1941 case TRACER_DISPLAY_BASE_16
:
1942 printf("0x%" PRIx16
, v
);
1949 case SIDE_DYNAMIC_TYPE_U32
:
1953 v
= item
->u
.side_basic
.u
.side_u32
;
1954 if (dynamic_type_to_host_reverse_bo(item
))
1955 v
= side_bswap_32(v
);
1956 tracer_print_dynamic_basic_type_header(item
);
1958 case TRACER_DISPLAY_BASE_2
:
1959 print_integer_binary(v
, 32);
1961 case TRACER_DISPLAY_BASE_8
:
1962 printf("0%" PRIo32
, v
);
1964 case TRACER_DISPLAY_BASE_10
:
1965 printf("%" PRIu32
, v
);
1967 case TRACER_DISPLAY_BASE_16
:
1968 printf("0x%" PRIx32
, v
);
1975 case SIDE_DYNAMIC_TYPE_U64
:
1979 v
= item
->u
.side_basic
.u
.side_u64
;
1980 if (dynamic_type_to_host_reverse_bo(item
))
1981 v
= side_bswap_64(v
);
1982 tracer_print_dynamic_basic_type_header(item
);
1984 case TRACER_DISPLAY_BASE_2
:
1985 print_integer_binary(v
, 64);
1987 case TRACER_DISPLAY_BASE_8
:
1988 printf("0%" PRIo64
, v
);
1990 case TRACER_DISPLAY_BASE_10
:
1991 printf("%" PRIu64
, v
);
1993 case TRACER_DISPLAY_BASE_16
:
1994 printf("0x%" PRIx64
, v
);
2001 case SIDE_DYNAMIC_TYPE_S8
:
2005 v
= item
->u
.side_basic
.u
.side_s8
;
2006 tracer_print_dynamic_basic_type_header(item
);
2008 case TRACER_DISPLAY_BASE_2
:
2009 print_integer_binary(v
, 8);
2011 case TRACER_DISPLAY_BASE_8
:
2012 printf("0%" PRIo8
, v
);
2014 case TRACER_DISPLAY_BASE_10
:
2015 printf("%" PRId8
, v
);
2017 case TRACER_DISPLAY_BASE_16
:
2018 printf("0x%" PRIx8
, v
);
2025 case SIDE_DYNAMIC_TYPE_S16
:
2029 v
= item
->u
.side_basic
.u
.side_u16
;
2030 if (dynamic_type_to_host_reverse_bo(item
))
2031 v
= side_bswap_16(v
);
2032 tracer_print_dynamic_basic_type_header(item
);
2034 case TRACER_DISPLAY_BASE_2
:
2035 print_integer_binary(v
, 16);
2037 case TRACER_DISPLAY_BASE_8
:
2038 printf("0%" PRIo16
, v
);
2040 case TRACER_DISPLAY_BASE_10
:
2041 printf("%" PRId16
, v
);
2043 case TRACER_DISPLAY_BASE_16
:
2044 printf("0x%" PRIx16
, v
);
2051 case SIDE_DYNAMIC_TYPE_S32
:
2055 v
= item
->u
.side_basic
.u
.side_u32
;
2056 if (dynamic_type_to_host_reverse_bo(item
))
2057 v
= side_bswap_32(v
);
2058 tracer_print_dynamic_basic_type_header(item
);
2060 case TRACER_DISPLAY_BASE_2
:
2061 print_integer_binary(v
, 32);
2063 case TRACER_DISPLAY_BASE_8
:
2064 printf("0%" PRIo32
, v
);
2066 case TRACER_DISPLAY_BASE_10
:
2067 printf("%" PRId32
, v
);
2069 case TRACER_DISPLAY_BASE_16
:
2070 printf("0x%" PRIx32
, v
);
2077 case SIDE_DYNAMIC_TYPE_S64
:
2081 v
= item
->u
.side_basic
.u
.side_u64
;
2082 if (dynamic_type_to_host_reverse_bo(item
))
2083 v
= side_bswap_64(v
);
2084 tracer_print_dynamic_basic_type_header(item
);
2086 case TRACER_DISPLAY_BASE_2
:
2087 print_integer_binary(v
, 64);
2089 case TRACER_DISPLAY_BASE_8
:
2090 printf("0%" PRIo64
, v
);
2092 case TRACER_DISPLAY_BASE_10
:
2093 printf("%" PRId64
, v
);
2095 case TRACER_DISPLAY_BASE_16
:
2096 printf("0x%" PRIx64
, v
);
2103 case SIDE_DYNAMIC_TYPE_BYTE
:
2104 tracer_print_dynamic_basic_type_header(item
);
2105 printf("0x%" PRIx8
, item
->u
.side_basic
.u
.side_byte
);
2107 case SIDE_DYNAMIC_TYPE_POINTER32
:
2111 v
= item
->u
.side_basic
.u
.side_u32
;
2112 if (dynamic_type_to_host_reverse_bo(item
))
2113 v
= side_bswap_32(v
);
2114 tracer_print_dynamic_basic_type_header(item
);
2115 printf("0x%" PRIx32
, v
);
2119 case SIDE_DYNAMIC_TYPE_POINTER64
:
2123 v
= item
->u
.side_basic
.u
.side_u64
;
2124 if (dynamic_type_to_host_reverse_bo(item
))
2125 v
= side_bswap_64(v
);
2126 tracer_print_dynamic_basic_type_header(item
);
2127 printf("0x%" PRIx64
, v
);
2131 case SIDE_DYNAMIC_TYPE_FLOAT_BINARY16
:
2138 .f
= item
->u
.side_basic
.u
.side_float_binary16
,
2141 if (dynamic_type_to_host_reverse_bo(item
))
2142 float16
.u
= side_bswap_16(float16
.u
);
2143 tracer_print_dynamic_basic_type_header(item
);
2144 printf("%g", (double) float16
.f
);
2147 fprintf(stderr
, "ERROR: Unsupported binary16 float type\n");
2151 case SIDE_DYNAMIC_TYPE_FLOAT_BINARY32
:
2158 .f
= item
->u
.side_basic
.u
.side_float_binary32
,
2161 if (dynamic_type_to_host_reverse_bo(item
))
2162 float32
.u
= side_bswap_32(float32
.u
);
2163 tracer_print_dynamic_basic_type_header(item
);
2164 printf("%g", (double) float32
.f
);
2167 fprintf(stderr
, "ERROR: Unsupported binary32 float type\n");
2171 case SIDE_DYNAMIC_TYPE_FLOAT_BINARY64
:
2178 .f
= item
->u
.side_basic
.u
.side_float_binary64
,
2181 if (dynamic_type_to_host_reverse_bo(item
))
2182 float64
.u
= side_bswap_64(float64
.u
);
2183 tracer_print_dynamic_basic_type_header(item
);
2184 printf("%g", (double) float64
.f
);
2187 fprintf(stderr
, "ERROR: Unsupported binary64 float type\n");
2191 case SIDE_DYNAMIC_TYPE_FLOAT_BINARY128
:
2198 .f
= item
->u
.side_basic
.u
.side_float_binary128
,
2201 if (dynamic_type_to_host_reverse_bo(item
))
2202 side_bswap_128p(float128
.arr
);
2203 tracer_print_dynamic_basic_type_header(item
);
2204 printf("%Lg", (long double) float128
.f
);
2207 fprintf(stderr
, "ERROR: Unsupported binary128 float type\n");
2211 case SIDE_DYNAMIC_TYPE_STRING
:
2212 tracer_print_dynamic_basic_type_header(item
);
2213 printf("\"%s\"", (const char *)(uintptr_t) item
->u
.side_basic
.u
.string
);
2215 case SIDE_DYNAMIC_TYPE_STRUCT
:
2216 tracer_print_dynamic_struct(item
->u
.side_dynamic_struct
);
2218 case SIDE_DYNAMIC_TYPE_STRUCT_VISITOR
:
2219 tracer_print_dynamic_struct_visitor(item
);
2221 case SIDE_DYNAMIC_TYPE_VLA
:
2222 tracer_print_dynamic_vla(item
->u
.side_dynamic_vla
);
2224 case SIDE_DYNAMIC_TYPE_VLA_VISITOR
:
2225 tracer_print_dynamic_vla_visitor(item
);
2228 fprintf(stderr
, "<UNKNOWN TYPE>");
2235 void tracer_print_static_fields(const struct side_event_description
*desc
,
2236 const struct side_arg_vec_description
*sav_desc
,
2239 const struct side_arg_vec
*sav
= sav_desc
->sav
;
2240 uint32_t side_sav_len
= sav_desc
->len
;
2243 printf("provider: %s, event: %s", desc
->provider_name
, desc
->event_name
);
2244 if (desc
->nr_fields
!= side_sav_len
) {
2245 fprintf(stderr
, "ERROR: number of fields mismatch between description and arguments\n");
2248 print_attributes(", attr", ":", desc
->attr
, desc
->nr_attr
);
2249 printf("%s", side_sav_len
? ", fields: [ " : "");
2250 for (i
= 0; i
< side_sav_len
; i
++) {
2251 printf("%s", i
? ", " : "");
2252 tracer_print_field(&desc
->fields
[i
], &sav
[i
]);
2260 void tracer_call(const struct side_event_description
*desc
,
2261 const struct side_arg_vec_description
*sav_desc
,
2262 void *priv
__attribute__((unused
)))
2266 tracer_print_static_fields(desc
, sav_desc
, &nr_fields
);
2270 void tracer_call_variadic(const struct side_event_description
*desc
,
2271 const struct side_arg_vec_description
*sav_desc
,
2272 const struct side_arg_dynamic_event_struct
*var_struct
,
2273 void *priv
__attribute__((unused
)))
2275 uint32_t var_struct_len
= var_struct
->len
;
2276 int nr_fields
= 0, i
;
2278 tracer_print_static_fields(desc
, sav_desc
, &nr_fields
);
2280 if (side_unlikely(!(desc
->flags
& SIDE_EVENT_FLAG_VARIADIC
))) {
2281 fprintf(stderr
, "ERROR: unexpected non-variadic event description\n");
2284 print_attributes(", attr ", "::", var_struct
->attr
, var_struct
->nr_attr
);
2285 printf("%s", var_struct_len
? ", fields:: [ " : "");
2286 for (i
= 0; i
< var_struct_len
; i
++, nr_fields
++) {
2287 printf("%s", i
? ", " : "");
2288 printf("%s:: ", var_struct
->fields
[i
].field_name
);
2289 tracer_print_dynamic(&var_struct
->fields
[i
].elem
);
2296 void tracer_event_notification(enum side_tracer_notification notif
,
2297 struct side_event_description
**events
, uint32_t nr_events
, void *priv
)
2302 printf("----------------------------------------------------------\n");
2303 printf("Tracer notified of events %s\n",
2304 notif
== SIDE_TRACER_NOTIFICATION_INSERT_EVENTS
? "inserted" : "removed");
2305 for (i
= 0; i
< nr_events
; i
++) {
2306 struct side_event_description
*event
= events
[i
];
2308 /* Skip NULL pointers */
2311 printf("provider: %s, event: %s\n",
2312 event
->provider_name
, event
->event_name
);
2313 if (notif
== SIDE_TRACER_NOTIFICATION_INSERT_EVENTS
) {
2314 if (event
->flags
& SIDE_EVENT_FLAG_VARIADIC
) {
2315 ret
= side_tracer_callback_variadic_register(event
, tracer_call_variadic
, NULL
);
2319 ret
= side_tracer_callback_register(event
, tracer_call
, NULL
);
2324 if (event
->flags
& SIDE_EVENT_FLAG_VARIADIC
) {
2325 ret
= side_tracer_callback_variadic_unregister(event
, tracer_call_variadic
, NULL
);
2329 ret
= side_tracer_callback_unregister(event
, tracer_call
, NULL
);
2335 printf("----------------------------------------------------------\n");
2338 static __attribute__((constructor
))
2339 void tracer_init(void);
2341 void tracer_init(void)
2343 tracer_handle
= side_tracer_event_notification_register(tracer_event_notification
, NULL
);
2348 static __attribute__((destructor
))
2349 void tracer_exit(void);
2351 void tracer_exit(void)
2353 side_tracer_event_notification_unregister(tracer_handle
);