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 memcpy(&v
, ptr
+ sg_type
->u
.side_basic
.integer_offset
, sizeof(v
));
1118 v
>>= sg_type
->u
.side_basic
.offset_bits
;
1119 if (sg_type
->u
.side_basic
.len_bits
< 8)
1120 v
&= (1U << sg_type
->u
.side_basic
.len_bits
) - 1;
1122 case TRACER_DISPLAY_BASE_2
:
1123 print_integer_binary(v
, sg_type
->u
.side_basic
.len_bits
);
1125 case TRACER_DISPLAY_BASE_8
:
1126 printf("0%" PRIo8
, v
);
1128 case TRACER_DISPLAY_BASE_10
:
1129 printf("%" PRIu8
, v
);
1131 case TRACER_DISPLAY_BASE_16
:
1132 printf("0x%" PRIx8
, v
);
1143 memcpy(&v
, ptr
+ sg_type
->u
.side_basic
.integer_offset
, sizeof(v
));
1144 if (sg_type_to_host_reverse_bo(sg_type
))
1145 v
= side_bswap_16(v
);
1146 v
>>= sg_type
->u
.side_basic
.offset_bits
;
1147 if (sg_type
->u
.side_basic
.len_bits
< 16)
1148 v
&= (1U << sg_type
->u
.side_basic
.len_bits
) - 1;
1150 case TRACER_DISPLAY_BASE_2
:
1151 print_integer_binary(v
, sg_type
->u
.side_basic
.len_bits
);
1153 case TRACER_DISPLAY_BASE_8
:
1154 printf("0%" PRIo16
, v
);
1156 case TRACER_DISPLAY_BASE_10
:
1157 printf("%" PRIu16
, v
);
1159 case TRACER_DISPLAY_BASE_16
:
1160 printf("0x%" PRIx16
, v
);
1171 memcpy(&v
, ptr
+ sg_type
->u
.side_basic
.integer_offset
, sizeof(v
));
1172 if (sg_type_to_host_reverse_bo(sg_type
))
1173 v
= side_bswap_32(v
);
1174 v
>>= sg_type
->u
.side_basic
.offset_bits
;
1175 if (sg_type
->u
.side_basic
.len_bits
< 32)
1176 v
&= (1U << sg_type
->u
.side_basic
.len_bits
) - 1;
1178 case TRACER_DISPLAY_BASE_2
:
1179 print_integer_binary(v
, sg_type
->u
.side_basic
.len_bits
);
1181 case TRACER_DISPLAY_BASE_8
:
1182 printf("0%" PRIo32
, v
);
1184 case TRACER_DISPLAY_BASE_10
:
1185 printf("%" PRIu32
, v
);
1187 case TRACER_DISPLAY_BASE_16
:
1188 printf("0x%" PRIx32
, v
);
1199 memcpy(&v
, ptr
+ sg_type
->u
.side_basic
.integer_offset
, sizeof(v
));
1200 if (sg_type_to_host_reverse_bo(sg_type
))
1201 v
= side_bswap_64(v
);
1202 v
>>= sg_type
->u
.side_basic
.offset_bits
;
1203 if (sg_type
->u
.side_basic
.len_bits
< 64)
1204 v
&= (1ULL << sg_type
->u
.side_basic
.len_bits
) - 1;
1206 case TRACER_DISPLAY_BASE_2
:
1207 print_integer_binary(v
, sg_type
->u
.side_basic
.len_bits
);
1209 case TRACER_DISPLAY_BASE_8
:
1210 printf("0%" PRIo64
, v
);
1212 case TRACER_DISPLAY_BASE_10
:
1213 printf("%" PRIu64
, v
);
1215 case TRACER_DISPLAY_BASE_16
:
1216 printf("0x%" PRIx64
, v
);
1224 fprintf(stderr
, "<UNKNOWN SCATTER-GATHER INTEGER SIZE>");
1229 case SIDE_TYPE_SG_SIGNED_INT
:
1231 tracer_print_sg_integer_type_header(sg_type
);
1232 switch (sg_type
->u
.side_basic
.integer_size_bits
) {
1237 memcpy(&v
, ptr
+ sg_type
->u
.side_basic
.integer_offset
, sizeof(v
));
1238 v
>>= sg_type
->u
.side_basic
.offset_bits
;
1239 if (sg_type
->u
.side_basic
.len_bits
< 8)
1240 v
&= (1U << sg_type
->u
.side_basic
.len_bits
) - 1;
1242 case TRACER_DISPLAY_BASE_2
:
1243 print_integer_binary(v
, sg_type
->u
.side_basic
.len_bits
);
1245 case TRACER_DISPLAY_BASE_8
:
1246 printf("0%" PRIo8
, v
);
1248 case TRACER_DISPLAY_BASE_10
:
1249 printf("%" PRId8
, v
);
1251 case TRACER_DISPLAY_BASE_16
:
1252 printf("0x%" PRIx8
, v
);
1263 memcpy(&v
, ptr
+ sg_type
->u
.side_basic
.integer_offset
, sizeof(v
));
1264 if (sg_type_to_host_reverse_bo(sg_type
))
1265 v
= side_bswap_16(v
);
1266 v
>>= sg_type
->u
.side_basic
.offset_bits
;
1267 if (sg_type
->u
.side_basic
.len_bits
< 16)
1268 v
&= (1U << sg_type
->u
.side_basic
.len_bits
) - 1;
1270 case TRACER_DISPLAY_BASE_2
:
1271 print_integer_binary(v
, sg_type
->u
.side_basic
.len_bits
);
1273 case TRACER_DISPLAY_BASE_8
:
1274 printf("0%" PRIo16
, v
);
1276 case TRACER_DISPLAY_BASE_10
:
1277 printf("%" PRId16
, v
);
1279 case TRACER_DISPLAY_BASE_16
:
1280 printf("0x%" PRIx16
, v
);
1291 memcpy(&v
, ptr
+ sg_type
->u
.side_basic
.integer_offset
, sizeof(v
));
1292 if (sg_type_to_host_reverse_bo(sg_type
))
1293 v
= side_bswap_32(v
);
1294 v
>>= sg_type
->u
.side_basic
.offset_bits
;
1295 if (sg_type
->u
.side_basic
.len_bits
< 32)
1296 v
&= (1U << sg_type
->u
.side_basic
.len_bits
) - 1;
1298 case TRACER_DISPLAY_BASE_2
:
1299 print_integer_binary(v
, sg_type
->u
.side_basic
.len_bits
);
1301 case TRACER_DISPLAY_BASE_8
:
1302 printf("0%" PRIo32
, v
);
1304 case TRACER_DISPLAY_BASE_10
:
1305 printf("%" PRId32
, v
);
1307 case TRACER_DISPLAY_BASE_16
:
1308 printf("0x%" PRIx32
, v
);
1319 memcpy(&v
, ptr
+ sg_type
->u
.side_basic
.integer_offset
, sizeof(v
));
1320 if (sg_type_to_host_reverse_bo(sg_type
))
1321 v
= side_bswap_64(v
);
1322 v
>>= sg_type
->u
.side_basic
.offset_bits
;
1323 if (sg_type
->u
.side_basic
.len_bits
< 64)
1324 v
&= (1ULL << sg_type
->u
.side_basic
.len_bits
) - 1;
1326 case TRACER_DISPLAY_BASE_2
:
1327 print_integer_binary(v
, sg_type
->u
.side_basic
.len_bits
);
1329 case TRACER_DISPLAY_BASE_8
:
1330 printf("0%" PRIo64
, v
);
1332 case TRACER_DISPLAY_BASE_10
:
1333 printf("%" PRId64
, v
);
1335 case TRACER_DISPLAY_BASE_16
:
1336 printf("0x%" PRIx64
, v
);
1344 fprintf(stderr
, "<UNKNOWN SCATTER-GATHER INTEGER SIZE>");
1350 fprintf(stderr
, "<UNKNOWN SCATTER-GATHER TYPE>");
1357 void tracer_print_sg_field(const struct side_struct_field_sg
*field_sg
, void *ptr
)
1359 printf("%s: ", field_sg
->field_name
);
1360 tracer_print_sg_type(&field_sg
->side_type
, ptr
);
1364 void tracer_print_struct_sg(const struct side_type_description
*type_desc
, void *ptr
)
1366 const struct side_type_struct_sg
*struct_sg
= type_desc
->u
.side_struct_sg
;
1369 print_attributes("attr", ":", struct_sg
->attr
, struct_sg
->nr_attr
);
1370 printf("%s", struct_sg
->nr_attr
? ", " : "");
1371 printf("fields: { ");
1372 for (i
= 0; i
< struct_sg
->nr_fields
; i
++) {
1373 printf("%s", i
? ", " : "");
1374 tracer_print_sg_field(&struct_sg
->fields_sg
[i
], ptr
);
1380 void tracer_print_array(const struct side_type_description
*type_desc
, const struct side_arg_vec_description
*sav_desc
)
1382 const struct side_arg_vec
*sav
= sav_desc
->sav
;
1383 uint32_t side_sav_len
= sav_desc
->len
;
1386 if (type_desc
->u
.side_array
.length
!= side_sav_len
) {
1387 fprintf(stderr
, "ERROR: length mismatch between description and arguments of array\n");
1390 print_attributes("attr", ":", type_desc
->u
.side_array
.attr
, type_desc
->u
.side_array
.nr_attr
);
1391 printf("%s", type_desc
->u
.side_array
.nr_attr
? ", " : "");
1392 printf("elements: ");
1394 for (i
= 0; i
< side_sav_len
; i
++) {
1395 printf("%s", i
? ", " : "");
1396 tracer_print_type(type_desc
->u
.side_array
.elem_type
, &sav
[i
]);
1402 void tracer_print_vla(const struct side_type_description
*type_desc
, const struct side_arg_vec_description
*sav_desc
)
1404 const struct side_arg_vec
*sav
= sav_desc
->sav
;
1405 uint32_t side_sav_len
= sav_desc
->len
;
1408 print_attributes("attr", ":", type_desc
->u
.side_vla
.attr
, type_desc
->u
.side_vla
.nr_attr
);
1409 printf("%s", type_desc
->u
.side_vla
.nr_attr
? ", " : "");
1410 printf("elements: ");
1412 for (i
= 0; i
< side_sav_len
; i
++) {
1413 printf("%s", i
? ", " : "");
1414 tracer_print_type(type_desc
->u
.side_vla
.elem_type
, &sav
[i
]);
1419 struct tracer_visitor_priv
{
1420 const struct side_type_description
*elem_type
;
1425 enum side_visitor_status
tracer_write_elem_cb(const struct side_tracer_visitor_ctx
*tracer_ctx
,
1426 const struct side_arg_vec
*elem
)
1428 struct tracer_visitor_priv
*tracer_priv
= tracer_ctx
->priv
;
1430 printf("%s", tracer_priv
->i
++ ? ", " : "");
1431 tracer_print_type(tracer_priv
->elem_type
, elem
);
1432 return SIDE_VISITOR_STATUS_OK
;
1436 void tracer_print_vla_visitor(const struct side_type_description
*type_desc
, void *app_ctx
)
1438 enum side_visitor_status status
;
1439 struct tracer_visitor_priv tracer_priv
= {
1440 .elem_type
= type_desc
->u
.side_vla_visitor
.elem_type
,
1443 const struct side_tracer_visitor_ctx tracer_ctx
= {
1444 .write_elem
= tracer_write_elem_cb
,
1445 .priv
= &tracer_priv
,
1448 print_attributes("attr", ":", type_desc
->u
.side_vla_visitor
.attr
, type_desc
->u
.side_vla_visitor
.nr_attr
);
1449 printf("%s", type_desc
->u
.side_vla_visitor
.nr_attr
? ", " : "");
1450 printf("elements: ");
1452 status
= type_desc
->u
.side_vla_visitor
.visitor(&tracer_ctx
, app_ctx
);
1454 case SIDE_VISITOR_STATUS_OK
:
1456 case SIDE_VISITOR_STATUS_ERROR
:
1457 fprintf(stderr
, "ERROR: Visitor error\n");
1463 void tracer_print_array_fixint(const struct side_type_description
*type_desc
, const struct side_arg_vec
*item
)
1465 const struct side_type_description
*elem_type
= type_desc
->u
.side_array
.elem_type
;
1466 uint32_t side_sav_len
= type_desc
->u
.side_array
.length
;
1467 void *p
= item
->u
.side_array_fixint
;
1468 enum side_type side_type
;
1471 print_attributes("attr", ":", type_desc
->u
.side_array
.attr
, type_desc
->u
.side_array
.nr_attr
);
1472 printf("%s", type_desc
->u
.side_array
.nr_attr
? ", " : "");
1473 printf("elements: ");
1474 switch (item
->type
) {
1475 case SIDE_TYPE_ARRAY_U8
:
1476 if (elem_type
->type
!= SIDE_TYPE_U8
)
1479 case SIDE_TYPE_ARRAY_U16
:
1480 if (elem_type
->type
!= SIDE_TYPE_U16
)
1483 case SIDE_TYPE_ARRAY_U32
:
1484 if (elem_type
->type
!= SIDE_TYPE_U32
)
1487 case SIDE_TYPE_ARRAY_U64
:
1488 if (elem_type
->type
!= SIDE_TYPE_U64
)
1491 case SIDE_TYPE_ARRAY_S8
:
1492 if (elem_type
->type
!= SIDE_TYPE_S8
)
1495 case SIDE_TYPE_ARRAY_S16
:
1496 if (elem_type
->type
!= SIDE_TYPE_S16
)
1499 case SIDE_TYPE_ARRAY_S32
:
1500 if (elem_type
->type
!= SIDE_TYPE_S32
)
1503 case SIDE_TYPE_ARRAY_S64
:
1504 if (elem_type
->type
!= SIDE_TYPE_S64
)
1507 case SIDE_TYPE_ARRAY_BYTE
:
1508 if (elem_type
->type
!= SIDE_TYPE_BYTE
)
1511 case SIDE_TYPE_ARRAY_POINTER32
:
1512 if (elem_type
->type
!= SIDE_TYPE_POINTER32
)
1514 case SIDE_TYPE_ARRAY_POINTER64
:
1515 if (elem_type
->type
!= SIDE_TYPE_POINTER64
)
1521 side_type
= elem_type
->type
;
1524 for (i
= 0; i
< side_sav_len
; i
++) {
1525 struct side_arg_vec sav_elem
= {
1529 switch (side_type
) {
1531 sav_elem
.u
.side_u8
= ((const uint8_t *) p
)[i
];
1534 sav_elem
.u
.side_s8
= ((const int8_t *) p
)[i
];
1537 sav_elem
.u
.side_u16
= ((const uint16_t *) p
)[i
];
1540 sav_elem
.u
.side_s16
= ((const int16_t *) p
)[i
];
1543 sav_elem
.u
.side_u32
= ((const uint32_t *) p
)[i
];
1546 sav_elem
.u
.side_s32
= ((const int32_t *) p
)[i
];
1549 sav_elem
.u
.side_u64
= ((const uint64_t *) p
)[i
];
1552 sav_elem
.u
.side_s64
= ((const int64_t *) p
)[i
];
1554 case SIDE_TYPE_BYTE
:
1555 sav_elem
.u
.side_byte
= ((const uint8_t *) p
)[i
];
1557 case SIDE_TYPE_POINTER32
:
1558 sav_elem
.u
.side_u32
= ((const uint32_t *) p
)[i
];
1560 case SIDE_TYPE_POINTER64
:
1561 sav_elem
.u
.side_u64
= ((const uint64_t *) p
)[i
];
1565 fprintf(stderr
, "ERROR: Unexpected type\n");
1569 printf("%s", i
? ", " : "");
1570 tracer_print_type(elem_type
, &sav_elem
);
1576 fprintf(stderr
, "ERROR: type mismatch\n");
1580 void tracer_print_vla_fixint(const struct side_type_description
*type_desc
, const struct side_arg_vec
*item
)
1582 const struct side_type_description
*elem_type
= type_desc
->u
.side_vla
.elem_type
;
1583 uint32_t side_sav_len
= item
->u
.side_vla_fixint
.length
;
1584 void *p
= item
->u
.side_vla_fixint
.p
;
1585 enum side_type side_type
;
1588 print_attributes("attr", ":", type_desc
->u
.side_vla
.attr
, type_desc
->u
.side_vla
.nr_attr
);
1589 printf("%s", type_desc
->u
.side_vla
.nr_attr
? ", " : "");
1590 printf("elements: ");
1591 switch (item
->type
) {
1592 case SIDE_TYPE_VLA_U8
:
1593 if (elem_type
->type
!= SIDE_TYPE_U8
)
1596 case SIDE_TYPE_VLA_U16
:
1597 if (elem_type
->type
!= SIDE_TYPE_U16
)
1600 case SIDE_TYPE_VLA_U32
:
1601 if (elem_type
->type
!= SIDE_TYPE_U32
)
1604 case SIDE_TYPE_VLA_U64
:
1605 if (elem_type
->type
!= SIDE_TYPE_U64
)
1608 case SIDE_TYPE_VLA_S8
:
1609 if (elem_type
->type
!= SIDE_TYPE_S8
)
1612 case SIDE_TYPE_VLA_S16
:
1613 if (elem_type
->type
!= SIDE_TYPE_S16
)
1616 case SIDE_TYPE_VLA_S32
:
1617 if (elem_type
->type
!= SIDE_TYPE_S32
)
1620 case SIDE_TYPE_VLA_S64
:
1621 if (elem_type
->type
!= SIDE_TYPE_S64
)
1624 case SIDE_TYPE_VLA_BYTE
:
1625 if (elem_type
->type
!= SIDE_TYPE_BYTE
)
1628 case SIDE_TYPE_VLA_POINTER32
:
1629 if (elem_type
->type
!= SIDE_TYPE_POINTER32
)
1631 case SIDE_TYPE_VLA_POINTER64
:
1632 if (elem_type
->type
!= SIDE_TYPE_POINTER64
)
1638 side_type
= elem_type
->type
;
1641 for (i
= 0; i
< side_sav_len
; i
++) {
1642 struct side_arg_vec sav_elem
= {
1646 switch (side_type
) {
1648 sav_elem
.u
.side_u8
= ((const uint8_t *) p
)[i
];
1651 sav_elem
.u
.side_s8
= ((const int8_t *) p
)[i
];
1654 sav_elem
.u
.side_u16
= ((const uint16_t *) p
)[i
];
1657 sav_elem
.u
.side_s16
= ((const int16_t *) p
)[i
];
1660 sav_elem
.u
.side_u32
= ((const uint32_t *) p
)[i
];
1663 sav_elem
.u
.side_s32
= ((const int32_t *) p
)[i
];
1666 sav_elem
.u
.side_u64
= ((const uint64_t *) p
)[i
];
1669 sav_elem
.u
.side_s64
= ((const int64_t *) p
)[i
];
1671 case SIDE_TYPE_BYTE
:
1672 sav_elem
.u
.side_byte
= ((const uint8_t *) p
)[i
];
1674 case SIDE_TYPE_POINTER32
:
1675 sav_elem
.u
.side_u32
= ((const uint32_t *) p
)[i
];
1677 case SIDE_TYPE_POINTER64
:
1678 sav_elem
.u
.side_u64
= ((const uint64_t *) p
)[i
];
1682 fprintf(stderr
, "ERROR: Unexpected type\n");
1686 printf("%s", i
? ", " : "");
1687 tracer_print_type(elem_type
, &sav_elem
);
1693 fprintf(stderr
, "ERROR: type mismatch\n");
1698 void tracer_print_dynamic_struct(const struct side_arg_dynamic_event_struct
*dynamic_struct
)
1700 const struct side_arg_dynamic_event_field
*fields
= dynamic_struct
->fields
;
1701 uint32_t len
= dynamic_struct
->len
;
1704 print_attributes("attr", "::", dynamic_struct
->attr
, dynamic_struct
->nr_attr
);
1705 printf("%s", dynamic_struct
->nr_attr
? ", " : "");
1706 printf("fields:: ");
1708 for (i
= 0; i
< len
; i
++) {
1709 printf("%s", i
? ", " : "");
1710 printf("%s:: ", fields
[i
].field_name
);
1711 tracer_print_dynamic(&fields
[i
].elem
);
1716 struct tracer_dynamic_struct_visitor_priv
{
1721 enum side_visitor_status
tracer_dynamic_struct_write_elem_cb(
1722 const struct side_tracer_dynamic_struct_visitor_ctx
*tracer_ctx
,
1723 const struct side_arg_dynamic_event_field
*dynamic_field
)
1725 struct tracer_dynamic_struct_visitor_priv
*tracer_priv
= tracer_ctx
->priv
;
1727 printf("%s", tracer_priv
->i
++ ? ", " : "");
1728 printf("%s:: ", dynamic_field
->field_name
);
1729 tracer_print_dynamic(&dynamic_field
->elem
);
1730 return SIDE_VISITOR_STATUS_OK
;
1734 void tracer_print_dynamic_struct_visitor(const struct side_arg_dynamic_vec
*item
)
1736 enum side_visitor_status status
;
1737 struct tracer_dynamic_struct_visitor_priv tracer_priv
= {
1740 const struct side_tracer_dynamic_struct_visitor_ctx tracer_ctx
= {
1741 .write_field
= tracer_dynamic_struct_write_elem_cb
,
1742 .priv
= &tracer_priv
,
1744 void *app_ctx
= item
->u
.side_dynamic_struct_visitor
.app_ctx
;
1746 print_attributes("attr", "::", item
->u
.side_dynamic_struct_visitor
.attr
, item
->u
.side_dynamic_struct_visitor
.nr_attr
);
1747 printf("%s", item
->u
.side_dynamic_struct_visitor
.nr_attr
? ", " : "");
1748 printf("fields:: ");
1750 status
= item
->u
.side_dynamic_struct_visitor
.visitor(&tracer_ctx
, app_ctx
);
1752 case SIDE_VISITOR_STATUS_OK
:
1754 case SIDE_VISITOR_STATUS_ERROR
:
1755 fprintf(stderr
, "ERROR: Visitor error\n");
1762 void tracer_print_dynamic_vla(const struct side_arg_dynamic_vec_vla
*vla
)
1764 const struct side_arg_dynamic_vec
*sav
= vla
->sav
;
1765 uint32_t side_sav_len
= vla
->len
;
1768 print_attributes("attr", "::", vla
->attr
, vla
->nr_attr
);
1769 printf("%s", vla
->nr_attr
? ", " : "");
1770 printf("elements:: ");
1772 for (i
= 0; i
< side_sav_len
; i
++) {
1773 printf("%s", i
? ", " : "");
1774 tracer_print_dynamic(&sav
[i
]);
1779 struct tracer_dynamic_vla_visitor_priv
{
1784 enum side_visitor_status
tracer_dynamic_vla_write_elem_cb(
1785 const struct side_tracer_dynamic_vla_visitor_ctx
*tracer_ctx
,
1786 const struct side_arg_dynamic_vec
*elem
)
1788 struct tracer_dynamic_vla_visitor_priv
*tracer_priv
= tracer_ctx
->priv
;
1790 printf("%s", tracer_priv
->i
++ ? ", " : "");
1791 tracer_print_dynamic(elem
);
1792 return SIDE_VISITOR_STATUS_OK
;
1796 void tracer_print_dynamic_vla_visitor(const struct side_arg_dynamic_vec
*item
)
1798 enum side_visitor_status status
;
1799 struct tracer_dynamic_vla_visitor_priv tracer_priv
= {
1802 const struct side_tracer_dynamic_vla_visitor_ctx tracer_ctx
= {
1803 .write_elem
= tracer_dynamic_vla_write_elem_cb
,
1804 .priv
= &tracer_priv
,
1806 void *app_ctx
= item
->u
.side_dynamic_vla_visitor
.app_ctx
;
1808 print_attributes("attr", "::", item
->u
.side_dynamic_vla_visitor
.attr
, item
->u
.side_dynamic_vla_visitor
.nr_attr
);
1809 printf("%s", item
->u
.side_dynamic_vla_visitor
.nr_attr
? ", " : "");
1810 printf("elements:: ");
1812 status
= item
->u
.side_dynamic_vla_visitor
.visitor(&tracer_ctx
, app_ctx
);
1814 case SIDE_VISITOR_STATUS_OK
:
1816 case SIDE_VISITOR_STATUS_ERROR
:
1817 fprintf(stderr
, "ERROR: Visitor error\n");
1824 void tracer_print_dynamic_basic_type_header(const struct side_arg_dynamic_vec
*item
)
1826 print_attributes("attr", "::", item
->u
.side_basic
.attr
, item
->u
.side_basic
.nr_attr
);
1827 printf("%s", item
->u
.side_basic
.nr_attr
? ", " : "");
1832 void tracer_print_dynamic(const struct side_arg_dynamic_vec
*item
)
1834 enum tracer_display_base base
= TRACER_DISPLAY_BASE_10
;
1836 switch (item
->dynamic_type
) {
1837 case SIDE_DYNAMIC_TYPE_U8
:
1838 case SIDE_DYNAMIC_TYPE_U16
:
1839 case SIDE_DYNAMIC_TYPE_U32
:
1840 case SIDE_DYNAMIC_TYPE_U64
:
1841 case SIDE_DYNAMIC_TYPE_S8
:
1842 case SIDE_DYNAMIC_TYPE_S16
:
1843 case SIDE_DYNAMIC_TYPE_S32
:
1844 case SIDE_DYNAMIC_TYPE_S64
:
1845 base
= get_attr_display_base(item
->u
.side_basic
.attr
,
1846 item
->u
.side_basic
.nr_attr
);
1854 switch (item
->dynamic_type
) {
1855 case SIDE_DYNAMIC_TYPE_NULL
:
1856 tracer_print_dynamic_basic_type_header(item
);
1857 printf("<NULL TYPE>");
1859 case SIDE_DYNAMIC_TYPE_BOOL
:
1860 tracer_print_dynamic_basic_type_header(item
);
1861 printf("%s", item
->u
.side_basic
.u
.side_bool
? "true" : "false");
1863 case SIDE_DYNAMIC_TYPE_U8
:
1867 v
= item
->u
.side_basic
.u
.side_u8
;
1868 tracer_print_dynamic_basic_type_header(item
);
1870 case TRACER_DISPLAY_BASE_2
:
1871 print_integer_binary(v
, 8);
1873 case TRACER_DISPLAY_BASE_8
:
1874 printf("0%" PRIo8
, v
);
1876 case TRACER_DISPLAY_BASE_10
:
1877 printf("%" PRIu8
, v
);
1879 case TRACER_DISPLAY_BASE_16
:
1880 printf("0x%" PRIx8
, v
);
1887 case SIDE_DYNAMIC_TYPE_U16
:
1891 v
= item
->u
.side_basic
.u
.side_u16
;
1892 if (dynamic_type_to_host_reverse_bo(item
))
1893 v
= side_bswap_16(v
);
1894 tracer_print_dynamic_basic_type_header(item
);
1896 case TRACER_DISPLAY_BASE_2
:
1897 print_integer_binary(v
, 16);
1899 case TRACER_DISPLAY_BASE_8
:
1900 printf("0%" PRIo16
, v
);
1902 case TRACER_DISPLAY_BASE_10
:
1903 printf("%" PRIu16
, v
);
1905 case TRACER_DISPLAY_BASE_16
:
1906 printf("0x%" PRIx16
, v
);
1913 case SIDE_DYNAMIC_TYPE_U32
:
1917 v
= item
->u
.side_basic
.u
.side_u32
;
1918 if (dynamic_type_to_host_reverse_bo(item
))
1919 v
= side_bswap_32(v
);
1920 tracer_print_dynamic_basic_type_header(item
);
1922 case TRACER_DISPLAY_BASE_2
:
1923 print_integer_binary(v
, 32);
1925 case TRACER_DISPLAY_BASE_8
:
1926 printf("0%" PRIo32
, v
);
1928 case TRACER_DISPLAY_BASE_10
:
1929 printf("%" PRIu32
, v
);
1931 case TRACER_DISPLAY_BASE_16
:
1932 printf("0x%" PRIx32
, v
);
1939 case SIDE_DYNAMIC_TYPE_U64
:
1943 v
= item
->u
.side_basic
.u
.side_u64
;
1944 if (dynamic_type_to_host_reverse_bo(item
))
1945 v
= side_bswap_64(v
);
1946 tracer_print_dynamic_basic_type_header(item
);
1948 case TRACER_DISPLAY_BASE_2
:
1949 print_integer_binary(v
, 64);
1951 case TRACER_DISPLAY_BASE_8
:
1952 printf("0%" PRIo64
, v
);
1954 case TRACER_DISPLAY_BASE_10
:
1955 printf("%" PRIu64
, v
);
1957 case TRACER_DISPLAY_BASE_16
:
1958 printf("0x%" PRIx64
, v
);
1965 case SIDE_DYNAMIC_TYPE_S8
:
1969 v
= item
->u
.side_basic
.u
.side_s8
;
1970 tracer_print_dynamic_basic_type_header(item
);
1972 case TRACER_DISPLAY_BASE_2
:
1973 print_integer_binary(v
, 8);
1975 case TRACER_DISPLAY_BASE_8
:
1976 printf("0%" PRIo8
, v
);
1978 case TRACER_DISPLAY_BASE_10
:
1979 printf("%" PRId8
, v
);
1981 case TRACER_DISPLAY_BASE_16
:
1982 printf("0x%" PRIx8
, v
);
1989 case SIDE_DYNAMIC_TYPE_S16
:
1993 v
= item
->u
.side_basic
.u
.side_u16
;
1994 if (dynamic_type_to_host_reverse_bo(item
))
1995 v
= side_bswap_16(v
);
1996 tracer_print_dynamic_basic_type_header(item
);
1998 case TRACER_DISPLAY_BASE_2
:
1999 print_integer_binary(v
, 16);
2001 case TRACER_DISPLAY_BASE_8
:
2002 printf("0%" PRIo16
, v
);
2004 case TRACER_DISPLAY_BASE_10
:
2005 printf("%" PRId16
, v
);
2007 case TRACER_DISPLAY_BASE_16
:
2008 printf("0x%" PRIx16
, v
);
2015 case SIDE_DYNAMIC_TYPE_S32
:
2019 v
= item
->u
.side_basic
.u
.side_u32
;
2020 if (dynamic_type_to_host_reverse_bo(item
))
2021 v
= side_bswap_32(v
);
2022 tracer_print_dynamic_basic_type_header(item
);
2024 case TRACER_DISPLAY_BASE_2
:
2025 print_integer_binary(v
, 32);
2027 case TRACER_DISPLAY_BASE_8
:
2028 printf("0%" PRIo32
, v
);
2030 case TRACER_DISPLAY_BASE_10
:
2031 printf("%" PRId32
, v
);
2033 case TRACER_DISPLAY_BASE_16
:
2034 printf("0x%" PRIx32
, v
);
2041 case SIDE_DYNAMIC_TYPE_S64
:
2045 v
= item
->u
.side_basic
.u
.side_u64
;
2046 if (dynamic_type_to_host_reverse_bo(item
))
2047 v
= side_bswap_64(v
);
2048 tracer_print_dynamic_basic_type_header(item
);
2050 case TRACER_DISPLAY_BASE_2
:
2051 print_integer_binary(v
, 64);
2053 case TRACER_DISPLAY_BASE_8
:
2054 printf("0%" PRIo64
, v
);
2056 case TRACER_DISPLAY_BASE_10
:
2057 printf("%" PRId64
, v
);
2059 case TRACER_DISPLAY_BASE_16
:
2060 printf("0x%" PRIx64
, v
);
2067 case SIDE_DYNAMIC_TYPE_BYTE
:
2068 tracer_print_dynamic_basic_type_header(item
);
2069 printf("0x%" PRIx8
, item
->u
.side_basic
.u
.side_byte
);
2071 case SIDE_DYNAMIC_TYPE_POINTER32
:
2075 v
= item
->u
.side_basic
.u
.side_u32
;
2076 if (dynamic_type_to_host_reverse_bo(item
))
2077 v
= side_bswap_32(v
);
2078 tracer_print_dynamic_basic_type_header(item
);
2079 printf("0x%" PRIx32
, v
);
2083 case SIDE_DYNAMIC_TYPE_POINTER64
:
2087 v
= item
->u
.side_basic
.u
.side_u64
;
2088 if (dynamic_type_to_host_reverse_bo(item
))
2089 v
= side_bswap_64(v
);
2090 tracer_print_dynamic_basic_type_header(item
);
2091 printf("0x%" PRIx64
, v
);
2095 case SIDE_DYNAMIC_TYPE_FLOAT_BINARY16
:
2102 .f
= item
->u
.side_basic
.u
.side_float_binary16
,
2105 if (dynamic_type_to_host_reverse_bo(item
))
2106 float16
.u
= side_bswap_16(float16
.u
);
2107 tracer_print_dynamic_basic_type_header(item
);
2108 printf("%g", (double) float16
.f
);
2111 fprintf(stderr
, "ERROR: Unsupported binary16 float type\n");
2115 case SIDE_DYNAMIC_TYPE_FLOAT_BINARY32
:
2122 .f
= item
->u
.side_basic
.u
.side_float_binary32
,
2125 if (dynamic_type_to_host_reverse_bo(item
))
2126 float32
.u
= side_bswap_32(float32
.u
);
2127 tracer_print_dynamic_basic_type_header(item
);
2128 printf("%g", (double) float32
.f
);
2131 fprintf(stderr
, "ERROR: Unsupported binary32 float type\n");
2135 case SIDE_DYNAMIC_TYPE_FLOAT_BINARY64
:
2142 .f
= item
->u
.side_basic
.u
.side_float_binary64
,
2145 if (dynamic_type_to_host_reverse_bo(item
))
2146 float64
.u
= side_bswap_64(float64
.u
);
2147 tracer_print_dynamic_basic_type_header(item
);
2148 printf("%g", (double) float64
.f
);
2151 fprintf(stderr
, "ERROR: Unsupported binary64 float type\n");
2155 case SIDE_DYNAMIC_TYPE_FLOAT_BINARY128
:
2162 .f
= item
->u
.side_basic
.u
.side_float_binary128
,
2165 if (dynamic_type_to_host_reverse_bo(item
))
2166 side_bswap_128p(float128
.arr
);
2167 tracer_print_dynamic_basic_type_header(item
);
2168 printf("%Lg", (long double) float128
.f
);
2171 fprintf(stderr
, "ERROR: Unsupported binary128 float type\n");
2175 case SIDE_DYNAMIC_TYPE_STRING
:
2176 tracer_print_dynamic_basic_type_header(item
);
2177 printf("\"%s\"", (const char *)(uintptr_t) item
->u
.side_basic
.u
.string
);
2179 case SIDE_DYNAMIC_TYPE_STRUCT
:
2180 tracer_print_dynamic_struct(item
->u
.side_dynamic_struct
);
2182 case SIDE_DYNAMIC_TYPE_STRUCT_VISITOR
:
2183 tracer_print_dynamic_struct_visitor(item
);
2185 case SIDE_DYNAMIC_TYPE_VLA
:
2186 tracer_print_dynamic_vla(item
->u
.side_dynamic_vla
);
2188 case SIDE_DYNAMIC_TYPE_VLA_VISITOR
:
2189 tracer_print_dynamic_vla_visitor(item
);
2192 fprintf(stderr
, "<UNKNOWN TYPE>");
2199 void tracer_print_static_fields(const struct side_event_description
*desc
,
2200 const struct side_arg_vec_description
*sav_desc
,
2203 const struct side_arg_vec
*sav
= sav_desc
->sav
;
2204 uint32_t side_sav_len
= sav_desc
->len
;
2207 printf("provider: %s, event: %s", desc
->provider_name
, desc
->event_name
);
2208 if (desc
->nr_fields
!= side_sav_len
) {
2209 fprintf(stderr
, "ERROR: number of fields mismatch between description and arguments\n");
2212 print_attributes(", attr", ":", desc
->attr
, desc
->nr_attr
);
2213 printf("%s", side_sav_len
? ", fields: [ " : "");
2214 for (i
= 0; i
< side_sav_len
; i
++) {
2215 printf("%s", i
? ", " : "");
2216 tracer_print_field(&desc
->fields
[i
], &sav
[i
]);
2224 void tracer_call(const struct side_event_description
*desc
,
2225 const struct side_arg_vec_description
*sav_desc
,
2226 void *priv
__attribute__((unused
)))
2230 tracer_print_static_fields(desc
, sav_desc
, &nr_fields
);
2234 void tracer_call_variadic(const struct side_event_description
*desc
,
2235 const struct side_arg_vec_description
*sav_desc
,
2236 const struct side_arg_dynamic_event_struct
*var_struct
,
2237 void *priv
__attribute__((unused
)))
2239 uint32_t var_struct_len
= var_struct
->len
;
2240 int nr_fields
= 0, i
;
2242 tracer_print_static_fields(desc
, sav_desc
, &nr_fields
);
2244 if (side_unlikely(!(desc
->flags
& SIDE_EVENT_FLAG_VARIADIC
))) {
2245 fprintf(stderr
, "ERROR: unexpected non-variadic event description\n");
2248 print_attributes(", attr ", "::", var_struct
->attr
, var_struct
->nr_attr
);
2249 printf("%s", var_struct_len
? ", fields:: [ " : "");
2250 for (i
= 0; i
< var_struct_len
; i
++, nr_fields
++) {
2251 printf("%s", i
? ", " : "");
2252 printf("%s:: ", var_struct
->fields
[i
].field_name
);
2253 tracer_print_dynamic(&var_struct
->fields
[i
].elem
);
2260 void tracer_event_notification(enum side_tracer_notification notif
,
2261 struct side_event_description
**events
, uint32_t nr_events
, void *priv
)
2266 printf("----------------------------------------------------------\n");
2267 printf("Tracer notified of events %s\n",
2268 notif
== SIDE_TRACER_NOTIFICATION_INSERT_EVENTS
? "inserted" : "removed");
2269 for (i
= 0; i
< nr_events
; i
++) {
2270 struct side_event_description
*event
= events
[i
];
2272 /* Skip NULL pointers */
2275 printf("provider: %s, event: %s\n",
2276 event
->provider_name
, event
->event_name
);
2277 if (notif
== SIDE_TRACER_NOTIFICATION_INSERT_EVENTS
) {
2278 if (event
->flags
& SIDE_EVENT_FLAG_VARIADIC
) {
2279 ret
= side_tracer_callback_variadic_register(event
, tracer_call_variadic
, NULL
);
2283 ret
= side_tracer_callback_register(event
, tracer_call
, NULL
);
2288 if (event
->flags
& SIDE_EVENT_FLAG_VARIADIC
) {
2289 ret
= side_tracer_callback_variadic_unregister(event
, tracer_call_variadic
, NULL
);
2293 ret
= side_tracer_callback_unregister(event
, tracer_call
, NULL
);
2299 printf("----------------------------------------------------------\n");
2302 static __attribute__((constructor
))
2303 void tracer_init(void);
2305 void tracer_init(void)
2307 tracer_handle
= side_tracer_event_notification_register(tracer_event_notification
, NULL
);
2312 static __attribute__((destructor
))
2313 void tracer_exit(void);
2315 void tracer_exit(void)
2317 side_tracer_event_notification_unregister(tracer_handle
);