1 // SPDX-License-Identifier: MIT
3 * Copyright 2022 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
12 #include <side/trace.h>
14 static struct side_tracer_handle
*tracer_handle
;
17 void tracer_print_struct(const struct side_type_description
*type_desc
, const struct side_arg_vec_description
*sav_desc
);
19 void tracer_print_array(const struct side_type_description
*type_desc
, const struct side_arg_vec_description
*sav_desc
);
21 void tracer_print_vla(const struct side_type_description
*type_desc
, const struct side_arg_vec_description
*sav_desc
);
23 void tracer_print_vla_visitor(const struct side_type_description
*type_desc
, void *app_ctx
);
25 void tracer_print_array_fixint(const struct side_type_description
*type_desc
, const struct side_arg_vec
*item
);
27 void tracer_print_vla_fixint(const struct side_type_description
*type_desc
, const struct side_arg_vec
*item
);
29 void tracer_print_dynamic(const struct side_arg_dynamic_vec
*dynamic_item
);
31 void tracer_print_type(const struct side_type_description
*type_desc
, const struct side_arg_vec
*item
);
34 bool type_to_host_reverse_bo(const struct side_type_description
*type_desc
)
36 switch (type_desc
->type
) {
47 if (type_desc
->u
.side_basic
.byte_order
!= SIDE_TYPE_BYTE_ORDER_HOST
)
52 case SIDE_TYPE_FLOAT_BINARY16
:
53 case SIDE_TYPE_FLOAT_BINARY32
:
54 case SIDE_TYPE_FLOAT_BINARY64
:
55 case SIDE_TYPE_FLOAT_BINARY128
:
56 if (type_desc
->u
.side_basic
.byte_order
!= SIDE_TYPE_FLOAT_WORD_ORDER_HOST
)
62 fprintf(stderr
, "Unexpected type\n");
68 bool dynamic_type_to_host_reverse_bo(const struct side_arg_dynamic_vec
*item
)
70 switch (item
->dynamic_type
) {
71 case SIDE_DYNAMIC_TYPE_U8
:
72 case SIDE_DYNAMIC_TYPE_S8
:
73 case SIDE_DYNAMIC_TYPE_BYTE
:
75 case SIDE_DYNAMIC_TYPE_U16
:
76 case SIDE_DYNAMIC_TYPE_U32
:
77 case SIDE_DYNAMIC_TYPE_U64
:
78 case SIDE_DYNAMIC_TYPE_S16
:
79 case SIDE_DYNAMIC_TYPE_S32
:
80 case SIDE_DYNAMIC_TYPE_S64
:
81 if (item
->u
.side_basic
.byte_order
!= SIDE_TYPE_BYTE_ORDER_HOST
)
86 case SIDE_DYNAMIC_TYPE_FLOAT_BINARY16
:
87 case SIDE_DYNAMIC_TYPE_FLOAT_BINARY32
:
88 case SIDE_DYNAMIC_TYPE_FLOAT_BINARY64
:
89 case SIDE_DYNAMIC_TYPE_FLOAT_BINARY128
:
90 if (item
->u
.side_basic
.byte_order
!= SIDE_TYPE_FLOAT_WORD_ORDER_HOST
)
96 fprintf(stderr
, "Unexpected type\n");
102 void tracer_print_attr_type(const char *separator
, const struct side_attr
*attr
)
104 printf("{ key%s \"%s\", value%s ", separator
, attr
->key
, separator
);
105 switch (attr
->value
.type
) {
106 case SIDE_ATTR_TYPE_BOOL
:
107 printf("%s", attr
->value
.u
.side_bool
? "true" : "false");
109 case SIDE_ATTR_TYPE_U8
:
110 printf("%" PRIu8
, attr
->value
.u
.side_u8
);
112 case SIDE_ATTR_TYPE_U16
:
113 printf("%" PRIu16
, attr
->value
.u
.side_u16
);
115 case SIDE_ATTR_TYPE_U32
:
116 printf("%" PRIu32
, attr
->value
.u
.side_u32
);
118 case SIDE_ATTR_TYPE_U64
:
119 printf("%" PRIu64
, attr
->value
.u
.side_u64
);
121 case SIDE_ATTR_TYPE_S8
:
122 printf("%" PRId8
, attr
->value
.u
.side_s8
);
124 case SIDE_ATTR_TYPE_S16
:
125 printf("%" PRId16
, attr
->value
.u
.side_s16
);
127 case SIDE_ATTR_TYPE_S32
:
128 printf("%" PRId32
, attr
->value
.u
.side_s32
);
130 case SIDE_ATTR_TYPE_S64
:
131 printf("%" PRId64
, attr
->value
.u
.side_s64
);
133 case SIDE_ATTR_TYPE_FLOAT_BINARY16
:
135 printf("%g", (double) attr
->value
.u
.side_float_binary16
);
138 fprintf(stderr
, "ERROR: Unsupported binary16 float type\n");
141 case SIDE_ATTR_TYPE_FLOAT_BINARY32
:
143 printf("%g", (double) attr
->value
.u
.side_float_binary32
);
146 fprintf(stderr
, "ERROR: Unsupported binary32 float type\n");
149 case SIDE_ATTR_TYPE_FLOAT_BINARY64
:
151 printf("%g", (double) attr
->value
.u
.side_float_binary64
);
154 fprintf(stderr
, "ERROR: Unsupported binary64 float type\n");
157 case SIDE_ATTR_TYPE_FLOAT_BINARY128
:
159 printf("%Lg", (long double) attr
->value
.u
.side_float_binary128
);
162 fprintf(stderr
, "ERROR: Unsupported binary128 float type\n");
165 case SIDE_ATTR_TYPE_STRING
:
166 printf("\"%s\"", attr
->value
.u
.string
);
169 fprintf(stderr
, "ERROR: <UNKNOWN ATTRIBUTE TYPE>");
176 void print_attributes(const char *prefix_str
, const char *separator
,
177 const struct side_attr
*attr
, uint32_t nr_attr
)
183 printf("%s%s [ ", prefix_str
, separator
);
184 for (i
= 0; i
< nr_attr
; i
++) {
185 printf("%s", i
? ", " : "");
186 tracer_print_attr_type(separator
, &attr
[i
]);
192 void print_enum(const struct side_type_description
*type_desc
, const struct side_arg_vec
*item
)
194 const struct side_enum_mappings
*mappings
= type_desc
->u
.side_enum
.mappings
;
195 const struct side_type_description
*elem_type
= type_desc
->u
.side_enum
.elem_type
;
196 int i
, print_count
= 0;
199 if (elem_type
->type
!= item
->type
) {
200 fprintf(stderr
, "ERROR: Unexpected enum element type\n");
203 switch (item
->type
) {
205 value
= (int64_t) item
->u
.side_u8
;
211 v
= item
->u
.side_u16
;
212 if (type_to_host_reverse_bo(elem_type
))
213 v
= side_bswap_16(v
);
221 v
= item
->u
.side_u32
;
222 if (type_to_host_reverse_bo(elem_type
))
223 v
= side_bswap_32(v
);
231 v
= item
->u
.side_u64
;
232 if (type_to_host_reverse_bo(elem_type
))
233 v
= side_bswap_64(v
);
238 value
= (int64_t) item
->u
.side_s8
;
244 v
= item
->u
.side_s16
;
245 if (type_to_host_reverse_bo(elem_type
))
246 v
= side_bswap_16(v
);
254 v
= item
->u
.side_s32
;
255 if (type_to_host_reverse_bo(elem_type
))
256 v
= side_bswap_32(v
);
264 v
= item
->u
.side_s64
;
265 if (type_to_host_reverse_bo(elem_type
))
266 v
= side_bswap_64(v
);
271 fprintf(stderr
, "ERROR: Unexpected enum element type\n");
274 print_attributes("attr", ":", mappings
->attr
, mappings
->nr_attr
);
275 printf("%s", mappings
->nr_attr
? ", " : "");
276 tracer_print_type(type_desc
->u
.side_enum
.elem_type
, item
);
277 printf(", labels: [ ");
278 for (i
= 0; i
< mappings
->nr_mappings
; i
++) {
279 const struct side_enum_mapping
*mapping
= &mappings
->mappings
[i
];
281 if (mapping
->range_end
< mapping
->range_begin
) {
282 fprintf(stderr
, "ERROR: Unexpected enum range: %" PRIu64
"-%" PRIu64
"\n",
283 mapping
->range_begin
, mapping
->range_end
);
286 if (value
>= mapping
->range_begin
&& value
<= mapping
->range_end
) {
287 printf("%s", print_count
++ ? ", " : "");
288 printf("\"%s\"", mapping
->label
);
292 printf("<NO LABEL>");
297 uint32_t enum_elem_type_to_stride(const struct side_type_description
*elem_type
)
301 switch (elem_type
->type
) {
302 case SIDE_TYPE_U8
: /* Fall-through */
316 fprintf(stderr
, "ERROR: Unexpected enum element type\n");
323 void print_enum_bitmap(const struct side_type_description
*type_desc
,
324 const struct side_arg_vec
*item
)
326 const struct side_type_description
*elem_type
= type_desc
->u
.side_enum_bitmap
.elem_type
;
327 const struct side_enum_bitmap_mappings
*side_enum_mappings
= type_desc
->u
.side_enum_bitmap
.mappings
;
328 int i
, print_count
= 0;
329 uint32_t stride_bit
, nr_items
;
330 bool reverse_byte_order
= false;
331 const struct side_arg_vec
*array_item
;
333 switch (elem_type
->type
) {
334 case SIDE_TYPE_U8
: /* Fall-through */
335 case SIDE_TYPE_BYTE
: /* Fall-through */
336 case SIDE_TYPE_U16
: /* Fall-through */
337 case SIDE_TYPE_U32
: /* Fall-through */
339 stride_bit
= enum_elem_type_to_stride(elem_type
);
340 reverse_byte_order
= type_to_host_reverse_bo(elem_type
);
344 case SIDE_TYPE_ARRAY
:
345 stride_bit
= enum_elem_type_to_stride(elem_type
->u
.side_array
.elem_type
);
346 reverse_byte_order
= type_to_host_reverse_bo(elem_type
->u
.side_array
.elem_type
);
347 array_item
= item
->u
.side_array
->sav
;
348 nr_items
= type_desc
->u
.side_array
.length
;
351 stride_bit
= enum_elem_type_to_stride(elem_type
->u
.side_vla
.elem_type
);
352 reverse_byte_order
= type_to_host_reverse_bo(elem_type
->u
.side_vla
.elem_type
);
353 array_item
= item
->u
.side_vla
->sav
;
354 nr_items
= item
->u
.side_vla
->len
;
357 fprintf(stderr
, "ERROR: Unexpected enum element type\n");
361 print_attributes("attr", ":", side_enum_mappings
->attr
, side_enum_mappings
->nr_attr
);
362 printf("%s", side_enum_mappings
->nr_attr
? ", " : "");
363 printf("labels: [ ");
364 for (i
= 0; i
< side_enum_mappings
->nr_mappings
; i
++) {
365 const struct side_enum_bitmap_mapping
*mapping
= &side_enum_mappings
->mappings
[i
];
369 if (mapping
->range_end
< mapping
->range_begin
) {
370 fprintf(stderr
, "ERROR: Unexpected enum bitmap range: %" PRIu64
"-%" PRIu64
"\n",
371 mapping
->range_begin
, mapping
->range_end
);
374 for (bit
= mapping
->range_begin
; bit
<= mapping
->range_end
; bit
++) {
375 if (bit
> (nr_items
* stride_bit
) - 1)
377 switch (stride_bit
) {
380 uint8_t v
= array_item
[bit
/ 8].u
.side_u8
;
381 if (v
& (1ULL << (bit
% 8))) {
389 uint16_t v
= array_item
[bit
/ 16].u
.side_u16
;
390 if (reverse_byte_order
)
391 v
= side_bswap_16(v
);
392 if (v
& (1ULL << (bit
% 16))) {
400 uint32_t v
= array_item
[bit
/ 32].u
.side_u32
;
401 if (reverse_byte_order
)
402 v
= side_bswap_32(v
);
403 if (v
& (1ULL << (bit
% 32))) {
411 uint64_t v
= array_item
[bit
/ 64].u
.side_u64
;
412 if (reverse_byte_order
)
413 v
= side_bswap_64(v
);
414 if (v
& (1ULL << (bit
% 64))) {
426 printf("%s", print_count
++ ? ", " : "");
427 printf("\"%s\"", mapping
->label
);
431 printf("<NO LABEL>");
436 void tracer_print_basic_type_header(const struct side_type_description
*type_desc
)
438 print_attributes("attr", ":", type_desc
->u
.side_basic
.attr
, type_desc
->u
.side_basic
.nr_attr
);
439 printf("%s", type_desc
->u
.side_basic
.nr_attr
? ", " : "");
444 void tracer_print_type(const struct side_type_description
*type_desc
, const struct side_arg_vec
*item
)
448 switch (type_desc
->type
) {
449 case SIDE_TYPE_ARRAY
:
450 switch (item
->type
) {
451 case SIDE_TYPE_ARRAY_U8
:
452 case SIDE_TYPE_ARRAY_U16
:
453 case SIDE_TYPE_ARRAY_U32
:
454 case SIDE_TYPE_ARRAY_U64
:
455 case SIDE_TYPE_ARRAY_S8
:
456 case SIDE_TYPE_ARRAY_S16
:
457 case SIDE_TYPE_ARRAY_S32
:
458 case SIDE_TYPE_ARRAY_S64
:
459 case SIDE_TYPE_ARRAY_BYTE
:
460 case SIDE_TYPE_ARRAY
:
463 fprintf(stderr
, "ERROR: type mismatch between description and arguments\n");
470 switch (item
->type
) {
471 case SIDE_TYPE_VLA_U8
:
472 case SIDE_TYPE_VLA_U16
:
473 case SIDE_TYPE_VLA_U32
:
474 case SIDE_TYPE_VLA_U64
:
475 case SIDE_TYPE_VLA_S8
:
476 case SIDE_TYPE_VLA_S16
:
477 case SIDE_TYPE_VLA_S32
:
478 case SIDE_TYPE_VLA_S64
:
479 case SIDE_TYPE_VLA_BYTE
:
483 fprintf(stderr
, "ERROR: type mismatch between description and arguments\n");
490 switch (item
->type
) {
501 fprintf(stderr
, "ERROR: type mismatch between description and arguments\n");
507 case SIDE_TYPE_ENUM_BITMAP
:
508 switch (item
->type
) {
514 case SIDE_TYPE_ARRAY
:
518 fprintf(stderr
, "ERROR: type mismatch between description and arguments\n");
525 if (type_desc
->type
!= item
->type
) {
526 fprintf(stderr
, "ERROR: type mismatch between description and arguments\n");
532 if (type_desc
->type
== SIDE_TYPE_ENUM
|| type_desc
->type
== SIDE_TYPE_ENUM_BITMAP
)
533 type
= type_desc
->type
;
540 tracer_print_basic_type_header(type_desc
);
541 printf("%s", item
->u
.side_bool
? "true" : "false");
544 tracer_print_basic_type_header(type_desc
);
545 printf("%" PRIu8
, item
->u
.side_u8
);
551 v
= item
->u
.side_u16
;
552 if (type_to_host_reverse_bo(type_desc
))
553 v
= side_bswap_16(v
);
554 tracer_print_basic_type_header(type_desc
);
555 printf("%" PRIu16
, v
);
562 v
= item
->u
.side_u32
;
563 if (type_to_host_reverse_bo(type_desc
))
564 v
= side_bswap_32(v
);
565 tracer_print_basic_type_header(type_desc
);
566 printf("%" PRIu32
, v
);
573 v
= item
->u
.side_u64
;
574 if (type_to_host_reverse_bo(type_desc
))
575 v
= side_bswap_64(v
);
576 tracer_print_basic_type_header(type_desc
);
577 printf("%" PRIu64
, v
);
581 tracer_print_basic_type_header(type_desc
);
582 printf("%" PRId8
, item
->u
.side_s8
);
588 v
= item
->u
.side_s16
;
589 if (type_to_host_reverse_bo(type_desc
))
590 v
= side_bswap_16(v
);
591 tracer_print_basic_type_header(type_desc
);
592 printf("%" PRId16
, v
);
599 v
= item
->u
.side_s32
;
600 if (type_to_host_reverse_bo(type_desc
))
601 v
= side_bswap_32(v
);
602 tracer_print_basic_type_header(type_desc
);
603 printf("%" PRId32
, v
);
610 v
= item
->u
.side_s64
;
611 if (type_to_host_reverse_bo(type_desc
))
612 v
= side_bswap_64(v
);
613 tracer_print_basic_type_header(type_desc
);
614 printf("%" PRId64
, v
);
618 tracer_print_basic_type_header(type_desc
);
619 printf("0x%" PRIx8
, item
->u
.side_byte
);
623 print_enum(type_desc
, item
);
626 case SIDE_TYPE_ENUM_BITMAP
:
627 print_enum_bitmap(type_desc
, item
);
630 case SIDE_TYPE_FLOAT_BINARY16
:
637 .f
= item
->u
.side_float_binary16
,
640 if (type_to_host_reverse_bo(type_desc
))
641 float16
.u
= side_bswap_16(float16
.u
);
642 tracer_print_basic_type_header(type_desc
);
643 printf("%g", (double) float16
.f
);
646 fprintf(stderr
, "ERROR: Unsupported binary16 float type\n");
650 case SIDE_TYPE_FLOAT_BINARY32
:
657 .f
= item
->u
.side_float_binary32
,
660 if (type_to_host_reverse_bo(type_desc
))
661 float32
.u
= side_bswap_32(float32
.u
);
662 tracer_print_basic_type_header(type_desc
);
663 printf("%g", (double) float32
.f
);
666 fprintf(stderr
, "ERROR: Unsupported binary32 float type\n");
670 case SIDE_TYPE_FLOAT_BINARY64
:
677 .f
= item
->u
.side_float_binary64
,
680 if (type_to_host_reverse_bo(type_desc
))
681 float64
.u
= side_bswap_64(float64
.u
);
682 tracer_print_basic_type_header(type_desc
);
683 printf("%g", (double) float64
.f
);
686 fprintf(stderr
, "ERROR: Unsupported binary64 float type\n");
690 case SIDE_TYPE_FLOAT_BINARY128
:
697 .f
= item
->u
.side_float_binary128
,
700 if (type_to_host_reverse_bo(type_desc
))
701 side_bswap_128p(float128
.arr
);
702 tracer_print_basic_type_header(type_desc
);
703 printf("%Lg", (long double) float128
.f
);
706 fprintf(stderr
, "ERROR: Unsupported binary128 float type\n");
710 case SIDE_TYPE_STRING
:
711 tracer_print_basic_type_header(type_desc
);
712 printf("\"%s\"", item
->u
.string
);
714 case SIDE_TYPE_STRUCT
:
715 tracer_print_struct(type_desc
, item
->u
.side_struct
);
717 case SIDE_TYPE_ARRAY
:
718 tracer_print_array(type_desc
, item
->u
.side_array
);
721 tracer_print_vla(type_desc
, item
->u
.side_vla
);
723 case SIDE_TYPE_VLA_VISITOR
:
724 tracer_print_vla_visitor(type_desc
, item
->u
.side_vla_app_visitor_ctx
);
726 case SIDE_TYPE_ARRAY_U8
:
727 case SIDE_TYPE_ARRAY_U16
:
728 case SIDE_TYPE_ARRAY_U32
:
729 case SIDE_TYPE_ARRAY_U64
:
730 case SIDE_TYPE_ARRAY_S8
:
731 case SIDE_TYPE_ARRAY_S16
:
732 case SIDE_TYPE_ARRAY_S32
:
733 case SIDE_TYPE_ARRAY_S64
:
734 case SIDE_TYPE_ARRAY_BYTE
:
735 tracer_print_array_fixint(type_desc
, item
);
737 case SIDE_TYPE_VLA_U8
:
738 case SIDE_TYPE_VLA_U16
:
739 case SIDE_TYPE_VLA_U32
:
740 case SIDE_TYPE_VLA_U64
:
741 case SIDE_TYPE_VLA_S8
:
742 case SIDE_TYPE_VLA_S16
:
743 case SIDE_TYPE_VLA_S32
:
744 case SIDE_TYPE_VLA_S64
:
745 case SIDE_TYPE_VLA_BYTE
:
746 tracer_print_vla_fixint(type_desc
, item
);
748 case SIDE_TYPE_DYNAMIC
:
749 tracer_print_basic_type_header(type_desc
);
750 tracer_print_dynamic(&item
->u
.dynamic
);
753 fprintf(stderr
, "<UNKNOWN TYPE>");
760 void tracer_print_field(const struct side_event_field
*item_desc
, const struct side_arg_vec
*item
)
762 printf("%s: ", item_desc
->field_name
);
763 tracer_print_type(&item_desc
->side_type
, item
);
767 void tracer_print_struct(const struct side_type_description
*type_desc
, const struct side_arg_vec_description
*sav_desc
)
769 const struct side_arg_vec
*sav
= sav_desc
->sav
;
770 uint32_t side_sav_len
= sav_desc
->len
;
773 if (type_desc
->u
.side_struct
->nr_fields
!= side_sav_len
) {
774 fprintf(stderr
, "ERROR: number of fields mismatch between description and arguments of structure\n");
777 print_attributes("attr", ":", type_desc
->u
.side_struct
->attr
, type_desc
->u
.side_struct
->nr_attr
);
778 printf("%s", type_desc
->u
.side_struct
->nr_attr
? ", " : "");
779 printf("fields: { ");
780 for (i
= 0; i
< side_sav_len
; i
++) {
781 printf("%s", i
? ", " : "");
782 tracer_print_field(&type_desc
->u
.side_struct
->fields
[i
], &sav
[i
]);
788 void tracer_print_array(const struct side_type_description
*type_desc
, const struct side_arg_vec_description
*sav_desc
)
790 const struct side_arg_vec
*sav
= sav_desc
->sav
;
791 uint32_t side_sav_len
= sav_desc
->len
;
794 if (type_desc
->u
.side_array
.length
!= side_sav_len
) {
795 fprintf(stderr
, "ERROR: length mismatch between description and arguments of array\n");
798 print_attributes("attr", ":", type_desc
->u
.side_array
.attr
, type_desc
->u
.side_array
.nr_attr
);
799 printf("%s", type_desc
->u
.side_array
.nr_attr
? ", " : "");
800 printf("elements: ");
802 for (i
= 0; i
< side_sav_len
; i
++) {
803 printf("%s", i
? ", " : "");
804 tracer_print_type(type_desc
->u
.side_array
.elem_type
, &sav
[i
]);
810 void tracer_print_vla(const struct side_type_description
*type_desc
, const struct side_arg_vec_description
*sav_desc
)
812 const struct side_arg_vec
*sav
= sav_desc
->sav
;
813 uint32_t side_sav_len
= sav_desc
->len
;
816 print_attributes("attr", ":", type_desc
->u
.side_vla
.attr
, type_desc
->u
.side_vla
.nr_attr
);
817 printf("%s", type_desc
->u
.side_vla
.nr_attr
? ", " : "");
818 printf("elements: ");
820 for (i
= 0; i
< side_sav_len
; i
++) {
821 printf("%s", i
? ", " : "");
822 tracer_print_type(type_desc
->u
.side_vla
.elem_type
, &sav
[i
]);
827 struct tracer_visitor_priv
{
828 const struct side_type_description
*elem_type
;
833 enum side_visitor_status
tracer_write_elem_cb(const struct side_tracer_visitor_ctx
*tracer_ctx
,
834 const struct side_arg_vec
*elem
)
836 struct tracer_visitor_priv
*tracer_priv
= tracer_ctx
->priv
;
838 printf("%s", tracer_priv
->i
++ ? ", " : "");
839 tracer_print_type(tracer_priv
->elem_type
, elem
);
840 return SIDE_VISITOR_STATUS_OK
;
844 void tracer_print_vla_visitor(const struct side_type_description
*type_desc
, void *app_ctx
)
846 enum side_visitor_status status
;
847 struct tracer_visitor_priv tracer_priv
= {
848 .elem_type
= type_desc
->u
.side_vla_visitor
.elem_type
,
851 const struct side_tracer_visitor_ctx tracer_ctx
= {
852 .write_elem
= tracer_write_elem_cb
,
853 .priv
= &tracer_priv
,
856 print_attributes("attr", ":", type_desc
->u
.side_vla_visitor
.attr
, type_desc
->u
.side_vla_visitor
.nr_attr
);
857 printf("%s", type_desc
->u
.side_vla_visitor
.nr_attr
? ", " : "");
858 printf("elements: ");
860 status
= type_desc
->u
.side_vla_visitor
.visitor(&tracer_ctx
, app_ctx
);
862 case SIDE_VISITOR_STATUS_OK
:
864 case SIDE_VISITOR_STATUS_ERROR
:
865 fprintf(stderr
, "ERROR: Visitor error\n");
871 void tracer_print_array_fixint(const struct side_type_description
*type_desc
, const struct side_arg_vec
*item
)
873 const struct side_type_description
*elem_type
= type_desc
->u
.side_array
.elem_type
;
874 uint32_t side_sav_len
= type_desc
->u
.side_array
.length
;
875 void *p
= item
->u
.side_array_fixint
;
876 enum side_type side_type
;
879 print_attributes("attr", ":", type_desc
->u
.side_array
.attr
, type_desc
->u
.side_array
.nr_attr
);
880 printf("%s", type_desc
->u
.side_array
.nr_attr
? ", " : "");
881 printf("elements: ");
882 switch (item
->type
) {
883 case SIDE_TYPE_ARRAY_U8
:
884 if (elem_type
->type
!= SIDE_TYPE_U8
)
887 case SIDE_TYPE_ARRAY_U16
:
888 if (elem_type
->type
!= SIDE_TYPE_U16
)
891 case SIDE_TYPE_ARRAY_U32
:
892 if (elem_type
->type
!= SIDE_TYPE_U32
)
895 case SIDE_TYPE_ARRAY_U64
:
896 if (elem_type
->type
!= SIDE_TYPE_U64
)
899 case SIDE_TYPE_ARRAY_S8
:
900 if (elem_type
->type
!= SIDE_TYPE_S8
)
903 case SIDE_TYPE_ARRAY_S16
:
904 if (elem_type
->type
!= SIDE_TYPE_S16
)
907 case SIDE_TYPE_ARRAY_S32
:
908 if (elem_type
->type
!= SIDE_TYPE_S32
)
911 case SIDE_TYPE_ARRAY_S64
:
912 if (elem_type
->type
!= SIDE_TYPE_S64
)
915 case SIDE_TYPE_ARRAY_BYTE
:
916 if (elem_type
->type
!= SIDE_TYPE_BYTE
)
922 side_type
= elem_type
->type
;
925 for (i
= 0; i
< side_sav_len
; i
++) {
926 struct side_arg_vec sav_elem
= {
932 sav_elem
.u
.side_u8
= ((const uint8_t *) p
)[i
];
935 sav_elem
.u
.side_s8
= ((const int8_t *) p
)[i
];
938 sav_elem
.u
.side_u16
= ((const uint16_t *) p
)[i
];
941 sav_elem
.u
.side_s16
= ((const int16_t *) p
)[i
];
944 sav_elem
.u
.side_u32
= ((const uint32_t *) p
)[i
];
947 sav_elem
.u
.side_s32
= ((const int32_t *) p
)[i
];
950 sav_elem
.u
.side_u64
= ((const uint64_t *) p
)[i
];
953 sav_elem
.u
.side_s64
= ((const int64_t *) p
)[i
];
956 sav_elem
.u
.side_byte
= ((const uint8_t *) p
)[i
];
960 fprintf(stderr
, "ERROR: Unexpected type\n");
964 printf("%s", i
? ", " : "");
965 tracer_print_type(elem_type
, &sav_elem
);
971 fprintf(stderr
, "ERROR: type mismatch\n");
975 void tracer_print_vla_fixint(const struct side_type_description
*type_desc
, const struct side_arg_vec
*item
)
977 const struct side_type_description
*elem_type
= type_desc
->u
.side_vla
.elem_type
;
978 uint32_t side_sav_len
= item
->u
.side_vla_fixint
.length
;
979 void *p
= item
->u
.side_vla_fixint
.p
;
980 enum side_type side_type
;
983 print_attributes("attr", ":", type_desc
->u
.side_vla
.attr
, type_desc
->u
.side_vla
.nr_attr
);
984 printf("%s", type_desc
->u
.side_vla
.nr_attr
? ", " : "");
985 printf("elements: ");
986 switch (item
->type
) {
987 case SIDE_TYPE_VLA_U8
:
988 if (elem_type
->type
!= SIDE_TYPE_U8
)
991 case SIDE_TYPE_VLA_U16
:
992 if (elem_type
->type
!= SIDE_TYPE_U16
)
995 case SIDE_TYPE_VLA_U32
:
996 if (elem_type
->type
!= SIDE_TYPE_U32
)
999 case SIDE_TYPE_VLA_U64
:
1000 if (elem_type
->type
!= SIDE_TYPE_U64
)
1003 case SIDE_TYPE_VLA_S8
:
1004 if (elem_type
->type
!= SIDE_TYPE_S8
)
1007 case SIDE_TYPE_VLA_S16
:
1008 if (elem_type
->type
!= SIDE_TYPE_S16
)
1011 case SIDE_TYPE_VLA_S32
:
1012 if (elem_type
->type
!= SIDE_TYPE_S32
)
1015 case SIDE_TYPE_VLA_S64
:
1016 if (elem_type
->type
!= SIDE_TYPE_S64
)
1019 case SIDE_TYPE_VLA_BYTE
:
1020 if (elem_type
->type
!= SIDE_TYPE_BYTE
)
1026 side_type
= elem_type
->type
;
1029 for (i
= 0; i
< side_sav_len
; i
++) {
1030 struct side_arg_vec sav_elem
= {
1034 switch (side_type
) {
1036 sav_elem
.u
.side_u8
= ((const uint8_t *) p
)[i
];
1039 sav_elem
.u
.side_s8
= ((const int8_t *) p
)[i
];
1042 sav_elem
.u
.side_u16
= ((const uint16_t *) p
)[i
];
1045 sav_elem
.u
.side_s16
= ((const int16_t *) p
)[i
];
1048 sav_elem
.u
.side_u32
= ((const uint32_t *) p
)[i
];
1051 sav_elem
.u
.side_s32
= ((const int32_t *) p
)[i
];
1054 sav_elem
.u
.side_u64
= ((const uint64_t *) p
)[i
];
1057 sav_elem
.u
.side_s64
= ((const int64_t *) p
)[i
];
1059 case SIDE_TYPE_BYTE
:
1060 sav_elem
.u
.side_byte
= ((const uint8_t *) p
)[i
];
1064 fprintf(stderr
, "ERROR: Unexpected type\n");
1068 printf("%s", i
? ", " : "");
1069 tracer_print_type(elem_type
, &sav_elem
);
1075 fprintf(stderr
, "ERROR: type mismatch\n");
1080 void tracer_print_dynamic_struct(const struct side_arg_dynamic_event_struct
*dynamic_struct
)
1082 const struct side_arg_dynamic_event_field
*fields
= dynamic_struct
->fields
;
1083 uint32_t len
= dynamic_struct
->len
;
1086 print_attributes("attr", "::", dynamic_struct
->attr
, dynamic_struct
->nr_attr
);
1087 printf("%s", dynamic_struct
->nr_attr
? ", " : "");
1088 printf("fields:: ");
1090 for (i
= 0; i
< len
; i
++) {
1091 printf("%s", i
? ", " : "");
1092 printf("%s:: ", fields
[i
].field_name
);
1093 tracer_print_dynamic(&fields
[i
].elem
);
1098 struct tracer_dynamic_struct_visitor_priv
{
1103 enum side_visitor_status
tracer_dynamic_struct_write_elem_cb(
1104 const struct side_tracer_dynamic_struct_visitor_ctx
*tracer_ctx
,
1105 const struct side_arg_dynamic_event_field
*dynamic_field
)
1107 struct tracer_dynamic_struct_visitor_priv
*tracer_priv
= tracer_ctx
->priv
;
1109 printf("%s", tracer_priv
->i
++ ? ", " : "");
1110 printf("%s:: ", dynamic_field
->field_name
);
1111 tracer_print_dynamic(&dynamic_field
->elem
);
1112 return SIDE_VISITOR_STATUS_OK
;
1116 void tracer_print_dynamic_struct_visitor(const struct side_arg_dynamic_vec
*item
)
1118 enum side_visitor_status status
;
1119 struct tracer_dynamic_struct_visitor_priv tracer_priv
= {
1122 const struct side_tracer_dynamic_struct_visitor_ctx tracer_ctx
= {
1123 .write_field
= tracer_dynamic_struct_write_elem_cb
,
1124 .priv
= &tracer_priv
,
1126 void *app_ctx
= item
->u
.side_dynamic_struct_visitor
.app_ctx
;
1128 print_attributes("attr", "::", item
->u
.side_dynamic_struct_visitor
.attr
, item
->u
.side_dynamic_struct_visitor
.nr_attr
);
1129 printf("%s", item
->u
.side_dynamic_struct_visitor
.nr_attr
? ", " : "");
1130 printf("fields:: ");
1132 status
= item
->u
.side_dynamic_struct_visitor
.visitor(&tracer_ctx
, app_ctx
);
1134 case SIDE_VISITOR_STATUS_OK
:
1136 case SIDE_VISITOR_STATUS_ERROR
:
1137 fprintf(stderr
, "ERROR: Visitor error\n");
1144 void tracer_print_dynamic_vla(const struct side_arg_dynamic_vec_vla
*vla
)
1146 const struct side_arg_dynamic_vec
*sav
= vla
->sav
;
1147 uint32_t side_sav_len
= vla
->len
;
1150 print_attributes("attr", "::", vla
->attr
, vla
->nr_attr
);
1151 printf("%s", vla
->nr_attr
? ", " : "");
1152 printf("elements:: ");
1154 for (i
= 0; i
< side_sav_len
; i
++) {
1155 printf("%s", i
? ", " : "");
1156 tracer_print_dynamic(&sav
[i
]);
1161 struct tracer_dynamic_vla_visitor_priv
{
1166 enum side_visitor_status
tracer_dynamic_vla_write_elem_cb(
1167 const struct side_tracer_dynamic_vla_visitor_ctx
*tracer_ctx
,
1168 const struct side_arg_dynamic_vec
*elem
)
1170 struct tracer_dynamic_vla_visitor_priv
*tracer_priv
= tracer_ctx
->priv
;
1172 printf("%s", tracer_priv
->i
++ ? ", " : "");
1173 tracer_print_dynamic(elem
);
1174 return SIDE_VISITOR_STATUS_OK
;
1178 void tracer_print_dynamic_vla_visitor(const struct side_arg_dynamic_vec
*item
)
1180 enum side_visitor_status status
;
1181 struct tracer_dynamic_vla_visitor_priv tracer_priv
= {
1184 const struct side_tracer_dynamic_vla_visitor_ctx tracer_ctx
= {
1185 .write_elem
= tracer_dynamic_vla_write_elem_cb
,
1186 .priv
= &tracer_priv
,
1188 void *app_ctx
= item
->u
.side_dynamic_vla_visitor
.app_ctx
;
1190 print_attributes("attr", "::", item
->u
.side_dynamic_vla_visitor
.attr
, item
->u
.side_dynamic_vla_visitor
.nr_attr
);
1191 printf("%s", item
->u
.side_dynamic_vla_visitor
.nr_attr
? ", " : "");
1192 printf("elements:: ");
1194 status
= item
->u
.side_dynamic_vla_visitor
.visitor(&tracer_ctx
, app_ctx
);
1196 case SIDE_VISITOR_STATUS_OK
:
1198 case SIDE_VISITOR_STATUS_ERROR
:
1199 fprintf(stderr
, "ERROR: Visitor error\n");
1206 void tracer_print_dynamic_basic_type_header(const struct side_arg_dynamic_vec
*item
)
1208 print_attributes("attr", "::", item
->u
.side_basic
.attr
, item
->u
.side_basic
.nr_attr
);
1209 printf("%s", item
->u
.side_basic
.nr_attr
? ", " : "");
1214 void tracer_print_dynamic(const struct side_arg_dynamic_vec
*item
)
1217 switch (item
->dynamic_type
) {
1218 case SIDE_DYNAMIC_TYPE_NULL
:
1219 tracer_print_dynamic_basic_type_header(item
);
1220 printf("<NULL TYPE>");
1222 case SIDE_DYNAMIC_TYPE_BOOL
:
1223 tracer_print_dynamic_basic_type_header(item
);
1224 printf("%s", item
->u
.side_basic
.u
.side_bool
? "true" : "false");
1226 case SIDE_DYNAMIC_TYPE_U8
:
1227 tracer_print_dynamic_basic_type_header(item
);
1228 printf("%" PRIu8
, item
->u
.side_basic
.u
.side_u8
);
1230 case SIDE_DYNAMIC_TYPE_U16
:
1234 v
= item
->u
.side_basic
.u
.side_u16
;
1235 if (dynamic_type_to_host_reverse_bo(item
))
1236 v
= side_bswap_16(v
);
1237 tracer_print_dynamic_basic_type_header(item
);
1238 printf("%" PRIu16
, v
);
1241 case SIDE_DYNAMIC_TYPE_U32
:
1245 v
= item
->u
.side_basic
.u
.side_u32
;
1246 if (dynamic_type_to_host_reverse_bo(item
))
1247 v
= side_bswap_32(v
);
1248 tracer_print_dynamic_basic_type_header(item
);
1249 printf("%" PRIu32
, v
);
1252 case SIDE_DYNAMIC_TYPE_U64
:
1256 v
= item
->u
.side_basic
.u
.side_u64
;
1257 if (dynamic_type_to_host_reverse_bo(item
))
1258 v
= side_bswap_64(v
);
1259 tracer_print_dynamic_basic_type_header(item
);
1260 printf("%" PRIu64
, v
);
1263 case SIDE_DYNAMIC_TYPE_S8
:
1264 tracer_print_dynamic_basic_type_header(item
);
1265 printf("%" PRId8
, item
->u
.side_basic
.u
.side_s8
);
1267 case SIDE_DYNAMIC_TYPE_S16
:
1271 v
= item
->u
.side_basic
.u
.side_u16
;
1272 if (dynamic_type_to_host_reverse_bo(item
))
1273 v
= side_bswap_16(v
);
1274 tracer_print_dynamic_basic_type_header(item
);
1275 printf("%" PRId16
, v
);
1278 case SIDE_DYNAMIC_TYPE_S32
:
1282 v
= item
->u
.side_basic
.u
.side_u32
;
1283 if (dynamic_type_to_host_reverse_bo(item
))
1284 v
= side_bswap_32(v
);
1285 tracer_print_dynamic_basic_type_header(item
);
1286 printf("%" PRId32
, v
);
1289 case SIDE_DYNAMIC_TYPE_S64
:
1293 v
= item
->u
.side_basic
.u
.side_u64
;
1294 if (dynamic_type_to_host_reverse_bo(item
))
1295 v
= side_bswap_64(v
);
1296 tracer_print_dynamic_basic_type_header(item
);
1297 printf("%" PRId64
, v
);
1300 case SIDE_DYNAMIC_TYPE_BYTE
:
1301 tracer_print_dynamic_basic_type_header(item
);
1302 printf("0x%" PRIx8
, item
->u
.side_basic
.u
.side_byte
);
1305 case SIDE_DYNAMIC_TYPE_FLOAT_BINARY16
:
1312 .f
= item
->u
.side_basic
.u
.side_float_binary16
,
1315 if (dynamic_type_to_host_reverse_bo(item
))
1316 float16
.u
= side_bswap_16(float16
.u
);
1317 tracer_print_dynamic_basic_type_header(item
);
1318 printf("%g", (double) float16
.f
);
1321 fprintf(stderr
, "ERROR: Unsupported binary16 float type\n");
1325 case SIDE_DYNAMIC_TYPE_FLOAT_BINARY32
:
1332 .f
= item
->u
.side_basic
.u
.side_float_binary32
,
1335 if (dynamic_type_to_host_reverse_bo(item
))
1336 float32
.u
= side_bswap_32(float32
.u
);
1337 tracer_print_dynamic_basic_type_header(item
);
1338 printf("%g", (double) float32
.f
);
1341 fprintf(stderr
, "ERROR: Unsupported binary32 float type\n");
1345 case SIDE_DYNAMIC_TYPE_FLOAT_BINARY64
:
1352 .f
= item
->u
.side_basic
.u
.side_float_binary64
,
1355 if (dynamic_type_to_host_reverse_bo(item
))
1356 float64
.u
= side_bswap_64(float64
.u
);
1357 tracer_print_dynamic_basic_type_header(item
);
1358 printf("%g", (double) float64
.f
);
1361 fprintf(stderr
, "ERROR: Unsupported binary64 float type\n");
1365 case SIDE_DYNAMIC_TYPE_FLOAT_BINARY128
:
1372 .f
= item
->u
.side_basic
.u
.side_float_binary128
,
1375 if (dynamic_type_to_host_reverse_bo(item
))
1376 side_bswap_128p(float128
.arr
);
1377 tracer_print_dynamic_basic_type_header(item
);
1378 printf("%Lg", (long double) float128
.f
);
1381 fprintf(stderr
, "ERROR: Unsupported binary128 float type\n");
1385 case SIDE_DYNAMIC_TYPE_STRING
:
1386 tracer_print_dynamic_basic_type_header(item
);
1387 printf("\"%s\"", item
->u
.side_basic
.u
.string
);
1389 case SIDE_DYNAMIC_TYPE_STRUCT
:
1390 tracer_print_dynamic_struct(item
->u
.side_dynamic_struct
);
1392 case SIDE_DYNAMIC_TYPE_STRUCT_VISITOR
:
1393 tracer_print_dynamic_struct_visitor(item
);
1395 case SIDE_DYNAMIC_TYPE_VLA
:
1396 tracer_print_dynamic_vla(item
->u
.side_dynamic_vla
);
1398 case SIDE_DYNAMIC_TYPE_VLA_VISITOR
:
1399 tracer_print_dynamic_vla_visitor(item
);
1402 fprintf(stderr
, "<UNKNOWN TYPE>");
1409 void tracer_print_static_fields(const struct side_event_description
*desc
,
1410 const struct side_arg_vec_description
*sav_desc
,
1413 const struct side_arg_vec
*sav
= sav_desc
->sav
;
1414 uint32_t side_sav_len
= sav_desc
->len
;
1417 printf("provider: %s, event: %s", desc
->provider_name
, desc
->event_name
);
1418 if (desc
->nr_fields
!= side_sav_len
) {
1419 fprintf(stderr
, "ERROR: number of fields mismatch between description and arguments\n");
1422 print_attributes(", attr", ":", desc
->attr
, desc
->nr_attr
);
1423 printf("%s", side_sav_len
? ", fields: [ " : "");
1424 for (i
= 0; i
< side_sav_len
; i
++) {
1425 printf("%s", i
? ", " : "");
1426 tracer_print_field(&desc
->fields
[i
], &sav
[i
]);
1434 void tracer_call(const struct side_event_description
*desc
,
1435 const struct side_arg_vec_description
*sav_desc
,
1436 void *priv
__attribute__((unused
)))
1440 tracer_print_static_fields(desc
, sav_desc
, &nr_fields
);
1444 void tracer_call_variadic(const struct side_event_description
*desc
,
1445 const struct side_arg_vec_description
*sav_desc
,
1446 const struct side_arg_dynamic_event_struct
*var_struct
,
1447 void *priv
__attribute__((unused
)))
1449 uint32_t var_struct_len
= var_struct
->len
;
1450 int nr_fields
= 0, i
;
1452 tracer_print_static_fields(desc
, sav_desc
, &nr_fields
);
1454 if (side_unlikely(!(desc
->flags
& SIDE_EVENT_FLAG_VARIADIC
))) {
1455 fprintf(stderr
, "ERROR: unexpected non-variadic event description\n");
1458 print_attributes(", attr ", "::", var_struct
->attr
, var_struct
->nr_attr
);
1459 printf("%s", var_struct_len
? ", fields:: [ " : "");
1460 for (i
= 0; i
< var_struct_len
; i
++, nr_fields
++) {
1461 printf("%s", i
? ", " : "");
1462 printf("%s:: ", var_struct
->fields
[i
].field_name
);
1463 tracer_print_dynamic(&var_struct
->fields
[i
].elem
);
1470 void tracer_event_notification(enum side_tracer_notification notif
,
1471 struct side_event_description
**events
, uint32_t nr_events
, void *priv
)
1476 printf("----------------------------------------------------------\n");
1477 printf("Tracer notified of events %s\n",
1478 notif
== SIDE_TRACER_NOTIFICATION_INSERT_EVENTS
? "inserted" : "removed");
1479 for (i
= 0; i
< nr_events
; i
++) {
1480 struct side_event_description
*event
= events
[i
];
1482 /* Skip NULL pointers */
1485 printf("provider: %s, event: %s\n",
1486 event
->provider_name
, event
->event_name
);
1487 if (notif
== SIDE_TRACER_NOTIFICATION_INSERT_EVENTS
) {
1488 if (event
->flags
& SIDE_EVENT_FLAG_VARIADIC
) {
1489 ret
= side_tracer_callback_variadic_register(event
, tracer_call_variadic
, NULL
);
1493 ret
= side_tracer_callback_register(event
, tracer_call
, NULL
);
1498 if (event
->flags
& SIDE_EVENT_FLAG_VARIADIC
) {
1499 ret
= side_tracer_callback_variadic_unregister(event
, tracer_call_variadic
, NULL
);
1503 ret
= side_tracer_callback_unregister(event
, tracer_call
, NULL
);
1509 printf("----------------------------------------------------------\n");
1512 static __attribute__((constructor
))
1513 void tracer_init(void);
1515 void tracer_init(void)
1517 tracer_handle
= side_tracer_event_notification_register(tracer_event_notification
, NULL
);
1522 static __attribute__((destructor
))
1523 void tracer_exit(void);
1525 void tracer_exit(void)
1527 side_tracer_event_notification_unregister(tracer_handle
);