1 // SPDX-License-Identifier: MIT
3 * Copyright 2022 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
11 #include <side/trace.h>
14 void tracer_print_struct(const struct side_type_description
*type_desc
, const struct side_arg_vec_description
*sav_desc
);
16 void tracer_print_array(const struct side_type_description
*type_desc
, const struct side_arg_vec_description
*sav_desc
);
18 void tracer_print_vla(const struct side_type_description
*type_desc
, const struct side_arg_vec_description
*sav_desc
);
20 void tracer_print_vla_visitor(const struct side_type_description
*type_desc
, void *app_ctx
);
22 void tracer_print_array_fixint(const struct side_type_description
*type_desc
, const struct side_arg_vec
*item
);
24 void tracer_print_vla_fixint(const struct side_type_description
*type_desc
, const struct side_arg_vec
*item
);
26 void tracer_print_dynamic(const struct side_arg_dynamic_vec
*dynamic_item
);
29 void print_attributes(const char *prefix_str
, const struct side_attr
*attr
, uint32_t nr_attr
)
35 printf("%s[ ", prefix_str
);
36 for (i
= 0; i
< nr_attr
; i
++) {
37 printf("%s", i
? ", " : "");
38 printf("{ key: \"%s\", value: \"%s\" }",
39 attr
[i
].key
, attr
[i
].value
);
45 void tracer_print_type(const struct side_type_description
*type_desc
, const struct side_arg_vec
*item
)
48 case SIDE_TYPE_ARRAY_U8
:
49 case SIDE_TYPE_ARRAY_U16
:
50 case SIDE_TYPE_ARRAY_U32
:
51 case SIDE_TYPE_ARRAY_U64
:
52 case SIDE_TYPE_ARRAY_S8
:
53 case SIDE_TYPE_ARRAY_S16
:
54 case SIDE_TYPE_ARRAY_S32
:
55 case SIDE_TYPE_ARRAY_S64
:
56 if (type_desc
->type
!= SIDE_TYPE_ARRAY
) {
57 printf("ERROR: type mismatch between description and arguments\n");
61 case SIDE_TYPE_VLA_U8
:
62 case SIDE_TYPE_VLA_U16
:
63 case SIDE_TYPE_VLA_U32
:
64 case SIDE_TYPE_VLA_U64
:
65 case SIDE_TYPE_VLA_S8
:
66 case SIDE_TYPE_VLA_S16
:
67 case SIDE_TYPE_VLA_S32
:
68 case SIDE_TYPE_VLA_S64
:
69 if (type_desc
->type
!= SIDE_TYPE_VLA
) {
70 printf("ERROR: type mismatch between description and arguments\n");
76 if (type_desc
->type
!= item
->type
) {
77 printf("ERROR: type mismatch between description and arguments\n");
83 print_attributes("attr: ", type_desc
->attr
, type_desc
->nr_attr
);
84 printf("%s", type_desc
->nr_attr
? ", " : "");
88 printf("%s", item
->u
.side_bool
? "true" : "false");
91 printf("%" PRIu8
, item
->u
.side_u8
);
94 printf("%" PRIu16
, item
->u
.side_u16
);
97 printf("%" PRIu32
, item
->u
.side_u32
);
100 printf("%" PRIu64
, item
->u
.side_u64
);
103 printf("%" PRId8
, item
->u
.side_s8
);
106 printf("%" PRId16
, item
->u
.side_s16
);
109 printf("%" PRId32
, item
->u
.side_s32
);
112 printf("%" PRId64
, item
->u
.side_s64
);
114 case SIDE_TYPE_FLOAT_BINARY16
:
116 printf("%g", (double) item
->u
.side_float_binary16
);
119 printf("ERROR: Unsupported binary16 float type\n");
122 case SIDE_TYPE_FLOAT_BINARY32
:
124 printf("%g", (double) item
->u
.side_float_binary32
);
127 printf("ERROR: Unsupported binary32 float type\n");
130 case SIDE_TYPE_FLOAT_BINARY64
:
132 printf("%g", (double) item
->u
.side_float_binary64
);
135 printf("ERROR: Unsupported binary64 float type\n");
138 case SIDE_TYPE_FLOAT_BINARY128
:
140 printf("%Lg", (long double) item
->u
.side_float_binary128
);
143 printf("ERROR: Unsupported binary128 float type\n");
146 case SIDE_TYPE_STRING
:
147 printf("\"%s\"", item
->u
.string
);
149 case SIDE_TYPE_STRUCT
:
150 tracer_print_struct(type_desc
, item
->u
.side_struct
);
152 case SIDE_TYPE_ARRAY
:
153 tracer_print_array(type_desc
, item
->u
.side_array
);
156 tracer_print_vla(type_desc
, item
->u
.side_vla
);
158 case SIDE_TYPE_VLA_VISITOR
:
159 tracer_print_vla_visitor(type_desc
, item
->u
.side_vla_app_visitor_ctx
);
161 case SIDE_TYPE_ARRAY_U8
:
162 case SIDE_TYPE_ARRAY_U16
:
163 case SIDE_TYPE_ARRAY_U32
:
164 case SIDE_TYPE_ARRAY_U64
:
165 case SIDE_TYPE_ARRAY_S8
:
166 case SIDE_TYPE_ARRAY_S16
:
167 case SIDE_TYPE_ARRAY_S32
:
168 case SIDE_TYPE_ARRAY_S64
:
169 tracer_print_array_fixint(type_desc
, item
);
171 case SIDE_TYPE_VLA_U8
:
172 case SIDE_TYPE_VLA_U16
:
173 case SIDE_TYPE_VLA_U32
:
174 case SIDE_TYPE_VLA_U64
:
175 case SIDE_TYPE_VLA_S8
:
176 case SIDE_TYPE_VLA_S16
:
177 case SIDE_TYPE_VLA_S32
:
178 case SIDE_TYPE_VLA_S64
:
179 tracer_print_vla_fixint(type_desc
, item
);
181 case SIDE_TYPE_DYNAMIC
:
182 tracer_print_dynamic(&item
->u
.dynamic
);
185 printf("<UNKNOWN TYPE>");
192 void tracer_print_field(const struct side_event_field
*item_desc
, const struct side_arg_vec
*item
)
194 printf("%s: ", item_desc
->field_name
);
195 tracer_print_type(&item_desc
->side_type
, item
);
199 void tracer_print_struct(const struct side_type_description
*type_desc
, const struct side_arg_vec_description
*sav_desc
)
201 const struct side_arg_vec
*sav
= sav_desc
->sav
;
202 uint32_t side_sav_len
= sav_desc
->len
;
205 if (type_desc
->u
.side_struct
.nr_fields
!= side_sav_len
) {
206 printf("ERROR: number of fields mismatch between description and arguments of structure\n");
210 for (i
= 0; i
< side_sav_len
; i
++) {
211 printf("%s", i
? ", " : "");
212 tracer_print_field(&type_desc
->u
.side_struct
.fields
[i
], &sav
[i
]);
218 void tracer_print_array(const struct side_type_description
*type_desc
, const struct side_arg_vec_description
*sav_desc
)
220 const struct side_arg_vec
*sav
= sav_desc
->sav
;
221 uint32_t side_sav_len
= sav_desc
->len
;
224 if (type_desc
->u
.side_array
.length
!= side_sav_len
) {
225 printf("ERROR: length mismatch between description and arguments of array\n");
229 for (i
= 0; i
< side_sav_len
; i
++) {
230 printf("%s", i
? ", " : "");
231 tracer_print_type(type_desc
->u
.side_array
.elem_type
, &sav
[i
]);
237 void tracer_print_vla(const struct side_type_description
*type_desc
, const struct side_arg_vec_description
*sav_desc
)
239 const struct side_arg_vec
*sav
= sav_desc
->sav
;
240 uint32_t side_sav_len
= sav_desc
->len
;
244 for (i
= 0; i
< side_sav_len
; i
++) {
245 printf("%s", i
? ", " : "");
246 tracer_print_type(type_desc
->u
.side_vla
.elem_type
, &sav
[i
]);
251 struct tracer_visitor_priv
{
252 const struct side_type_description
*elem_type
;
257 enum side_visitor_status
tracer_write_elem_cb(const struct side_tracer_visitor_ctx
*tracer_ctx
,
258 const struct side_arg_vec
*elem
)
260 struct tracer_visitor_priv
*tracer_priv
= tracer_ctx
->priv
;
262 printf("%s", tracer_priv
->i
++ ? ", " : "");
263 tracer_print_type(tracer_priv
->elem_type
, elem
);
264 return SIDE_VISITOR_STATUS_OK
;
268 void tracer_print_vla_visitor(const struct side_type_description
*type_desc
, void *app_ctx
)
270 enum side_visitor_status status
;
271 struct tracer_visitor_priv tracer_priv
= {
272 .elem_type
= type_desc
->u
.side_vla_visitor
.elem_type
,
275 const struct side_tracer_visitor_ctx tracer_ctx
= {
276 .write_elem
= tracer_write_elem_cb
,
277 .priv
= &tracer_priv
,
281 status
= type_desc
->u
.side_vla_visitor
.visitor(&tracer_ctx
, app_ctx
);
283 case SIDE_VISITOR_STATUS_OK
:
285 case SIDE_VISITOR_STATUS_ERROR
:
286 printf("ERROR: Visitor error\n");
292 void tracer_print_array_fixint(const struct side_type_description
*type_desc
, const struct side_arg_vec
*item
)
294 const struct side_type_description
*elem_type
= type_desc
->u
.side_array
.elem_type
;
295 uint32_t side_sav_len
= type_desc
->u
.side_array
.length
;
296 void *p
= item
->u
.side_array_fixint
;
297 enum side_type side_type
;
300 switch (item
->type
) {
301 case SIDE_TYPE_ARRAY_U8
:
302 if (elem_type
->type
!= SIDE_TYPE_U8
)
305 case SIDE_TYPE_ARRAY_U16
:
306 if (elem_type
->type
!= SIDE_TYPE_U16
)
309 case SIDE_TYPE_ARRAY_U32
:
310 if (elem_type
->type
!= SIDE_TYPE_U32
)
313 case SIDE_TYPE_ARRAY_U64
:
314 if (elem_type
->type
!= SIDE_TYPE_U64
)
317 case SIDE_TYPE_ARRAY_S8
:
318 if (elem_type
->type
!= SIDE_TYPE_S8
)
321 case SIDE_TYPE_ARRAY_S16
:
322 if (elem_type
->type
!= SIDE_TYPE_S16
)
325 case SIDE_TYPE_ARRAY_S32
:
326 if (elem_type
->type
!= SIDE_TYPE_S32
)
329 case SIDE_TYPE_ARRAY_S64
:
330 if (elem_type
->type
!= SIDE_TYPE_S64
)
336 side_type
= elem_type
->type
;
339 for (i
= 0; i
< side_sav_len
; i
++) {
340 struct side_arg_vec sav_elem
= {
346 sav_elem
.u
.side_u8
= ((const uint8_t *) p
)[i
];
349 sav_elem
.u
.side_s8
= ((const int8_t *) p
)[i
];
352 sav_elem
.u
.side_u16
= ((const uint16_t *) p
)[i
];
355 sav_elem
.u
.side_s16
= ((const int16_t *) p
)[i
];
358 sav_elem
.u
.side_u32
= ((const uint32_t *) p
)[i
];
361 sav_elem
.u
.side_s32
= ((const int32_t *) p
)[i
];
364 sav_elem
.u
.side_u64
= ((const uint64_t *) p
)[i
];
367 sav_elem
.u
.side_s64
= ((const int64_t *) p
)[i
];
371 printf("ERROR: Unexpected type\n");
375 printf("%s", i
? ", " : "");
376 tracer_print_type(elem_type
, &sav_elem
);
382 printf("ERROR: type mismatch\n");
386 void tracer_print_vla_fixint(const struct side_type_description
*type_desc
, const struct side_arg_vec
*item
)
388 const struct side_type_description
*elem_type
= type_desc
->u
.side_vla
.elem_type
;
389 uint32_t side_sav_len
= item
->u
.side_vla_fixint
.length
;
390 void *p
= item
->u
.side_vla_fixint
.p
;
391 enum side_type side_type
;
394 switch (item
->type
) {
395 case SIDE_TYPE_VLA_U8
:
396 if (elem_type
->type
!= SIDE_TYPE_U8
)
399 case SIDE_TYPE_VLA_U16
:
400 if (elem_type
->type
!= SIDE_TYPE_U16
)
403 case SIDE_TYPE_VLA_U32
:
404 if (elem_type
->type
!= SIDE_TYPE_U32
)
407 case SIDE_TYPE_VLA_U64
:
408 if (elem_type
->type
!= SIDE_TYPE_U64
)
411 case SIDE_TYPE_VLA_S8
:
412 if (elem_type
->type
!= SIDE_TYPE_S8
)
415 case SIDE_TYPE_VLA_S16
:
416 if (elem_type
->type
!= SIDE_TYPE_S16
)
419 case SIDE_TYPE_VLA_S32
:
420 if (elem_type
->type
!= SIDE_TYPE_S32
)
423 case SIDE_TYPE_VLA_S64
:
424 if (elem_type
->type
!= SIDE_TYPE_S64
)
430 side_type
= elem_type
->type
;
433 for (i
= 0; i
< side_sav_len
; i
++) {
434 struct side_arg_vec sav_elem
= {
440 sav_elem
.u
.side_u8
= ((const uint8_t *) p
)[i
];
443 sav_elem
.u
.side_s8
= ((const int8_t *) p
)[i
];
446 sav_elem
.u
.side_u16
= ((const uint16_t *) p
)[i
];
449 sav_elem
.u
.side_s16
= ((const int16_t *) p
)[i
];
452 sav_elem
.u
.side_u32
= ((const uint32_t *) p
)[i
];
455 sav_elem
.u
.side_s32
= ((const int32_t *) p
)[i
];
458 sav_elem
.u
.side_u64
= ((const uint64_t *) p
)[i
];
461 sav_elem
.u
.side_s64
= ((const int64_t *) p
)[i
];
465 printf("ERROR: Unexpected type\n");
469 printf("%s", i
? ", " : "");
470 tracer_print_type(elem_type
, &sav_elem
);
476 printf("ERROR: type mismatch\n");
481 void tracer_print_dynamic_struct(const struct side_arg_dynamic_event_struct
*dynamic_struct
)
483 const struct side_arg_dynamic_event_field
*fields
= dynamic_struct
->fields
;
484 uint32_t len
= dynamic_struct
->len
;
488 for (i
= 0; i
< len
; i
++) {
489 printf("%s", i
? ", " : "");
490 printf("%s:: ", fields
[i
].field_name
);
491 tracer_print_dynamic(&fields
[i
].elem
);
496 struct tracer_dynamic_struct_visitor_priv
{
501 enum side_visitor_status
tracer_dynamic_struct_write_elem_cb(
502 const struct side_tracer_dynamic_struct_visitor_ctx
*tracer_ctx
,
503 const struct side_arg_dynamic_event_field
*dynamic_field
)
505 struct tracer_dynamic_struct_visitor_priv
*tracer_priv
= tracer_ctx
->priv
;
507 printf("%s", tracer_priv
->i
++ ? ", " : "");
508 printf("%s:: ", dynamic_field
->field_name
);
509 tracer_print_dynamic(&dynamic_field
->elem
);
510 return SIDE_VISITOR_STATUS_OK
;
514 void tracer_print_dynamic_struct_visitor(const struct side_arg_dynamic_vec
*item
)
516 enum side_visitor_status status
;
517 struct tracer_dynamic_struct_visitor_priv tracer_priv
= {
520 const struct side_tracer_dynamic_struct_visitor_ctx tracer_ctx
= {
521 .write_field
= tracer_dynamic_struct_write_elem_cb
,
522 .priv
= &tracer_priv
,
524 void *app_ctx
= item
->u
.side_dynamic_struct_visitor
.app_ctx
;
527 status
= item
->u
.side_dynamic_struct_visitor
.visitor(&tracer_ctx
, app_ctx
);
529 case SIDE_VISITOR_STATUS_OK
:
531 case SIDE_VISITOR_STATUS_ERROR
:
532 printf("ERROR: Visitor error\n");
539 void tracer_print_dynamic_vla(const struct side_arg_dynamic_vec_vla
*vla
)
541 const struct side_arg_dynamic_vec
*sav
= vla
->sav
;
542 uint32_t side_sav_len
= vla
->len
;
546 for (i
= 0; i
< side_sav_len
; i
++) {
547 printf("%s", i
? ", " : "");
548 tracer_print_dynamic(&sav
[i
]);
553 struct tracer_dynamic_vla_visitor_priv
{
558 enum side_visitor_status
tracer_dynamic_vla_write_elem_cb(
559 const struct side_tracer_dynamic_vla_visitor_ctx
*tracer_ctx
,
560 const struct side_arg_dynamic_vec
*elem
)
562 struct tracer_dynamic_vla_visitor_priv
*tracer_priv
= tracer_ctx
->priv
;
564 printf("%s", tracer_priv
->i
++ ? ", " : "");
565 tracer_print_dynamic(elem
);
566 return SIDE_VISITOR_STATUS_OK
;
570 void tracer_print_dynamic_vla_visitor(const struct side_arg_dynamic_vec
*item
)
572 enum side_visitor_status status
;
573 struct tracer_dynamic_vla_visitor_priv tracer_priv
= {
576 const struct side_tracer_dynamic_vla_visitor_ctx tracer_ctx
= {
577 .write_elem
= tracer_dynamic_vla_write_elem_cb
,
578 .priv
= &tracer_priv
,
580 void *app_ctx
= item
->u
.side_dynamic_vla_visitor
.app_ctx
;
583 status
= item
->u
.side_dynamic_vla_visitor
.visitor(&tracer_ctx
, app_ctx
);
585 case SIDE_VISITOR_STATUS_OK
:
587 case SIDE_VISITOR_STATUS_ERROR
:
588 printf("ERROR: Visitor error\n");
595 void tracer_print_dynamic(const struct side_arg_dynamic_vec
*item
)
598 print_attributes("attr: ", item
->attr
, item
->nr_attr
);
599 printf("%s", item
->nr_attr
? ", " : "");
601 switch (item
->dynamic_type
) {
602 case SIDE_DYNAMIC_TYPE_NULL
:
603 printf("<NULL TYPE>");
605 case SIDE_DYNAMIC_TYPE_BOOL
:
606 printf("%s", item
->u
.side_bool
? "true" : "false");
608 case SIDE_DYNAMIC_TYPE_U8
:
609 printf("%" PRIu8
, item
->u
.side_u8
);
611 case SIDE_DYNAMIC_TYPE_U16
:
612 printf("%" PRIu16
, item
->u
.side_u16
);
614 case SIDE_DYNAMIC_TYPE_U32
:
615 printf("%" PRIu32
, item
->u
.side_u32
);
617 case SIDE_DYNAMIC_TYPE_U64
:
618 printf("%" PRIu64
, item
->u
.side_u64
);
620 case SIDE_DYNAMIC_TYPE_S8
:
621 printf("%" PRId8
, item
->u
.side_s8
);
623 case SIDE_DYNAMIC_TYPE_S16
:
624 printf("%" PRId16
, item
->u
.side_s16
);
626 case SIDE_DYNAMIC_TYPE_S32
:
627 printf("%" PRId32
, item
->u
.side_s32
);
629 case SIDE_DYNAMIC_TYPE_S64
:
630 printf("%" PRId64
, item
->u
.side_s64
);
632 case SIDE_DYNAMIC_TYPE_FLOAT_BINARY16
:
634 printf("%g", (double) item
->u
.side_float_binary16
);
637 printf("ERROR: Unsupported binary16 float type\n");
640 case SIDE_DYNAMIC_TYPE_FLOAT_BINARY32
:
642 printf("%g", (double) item
->u
.side_float_binary32
);
645 printf("ERROR: Unsupported binary32 float type\n");
648 case SIDE_DYNAMIC_TYPE_FLOAT_BINARY64
:
650 printf("%g", (double) item
->u
.side_float_binary64
);
653 printf("ERROR: Unsupported binary64 float type\n");
656 case SIDE_DYNAMIC_TYPE_FLOAT_BINARY128
:
658 printf("%Lg", (long double) item
->u
.side_float_binary128
);
661 printf("ERROR: Unsupported binary128 float type\n");
664 case SIDE_DYNAMIC_TYPE_STRING
:
665 printf("\"%s\"", item
->u
.string
);
667 case SIDE_DYNAMIC_TYPE_STRUCT
:
668 tracer_print_dynamic_struct(item
->u
.side_dynamic_struct
);
670 case SIDE_DYNAMIC_TYPE_STRUCT_VISITOR
:
671 tracer_print_dynamic_struct_visitor(item
);
673 case SIDE_DYNAMIC_TYPE_VLA
:
674 tracer_print_dynamic_vla(item
->u
.side_dynamic_vla
);
676 case SIDE_DYNAMIC_TYPE_VLA_VISITOR
:
677 tracer_print_dynamic_vla_visitor(item
);
680 printf("<UNKNOWN TYPE>");
687 void tracer_print_static_fields(const struct side_event_description
*desc
,
688 const struct side_arg_vec_description
*sav_desc
,
691 const struct side_arg_vec
*sav
= sav_desc
->sav
;
692 uint32_t side_sav_len
= sav_desc
->len
;
695 printf("provider: %s, event: %s", desc
->provider_name
, desc
->event_name
);
696 if (desc
->nr_fields
!= side_sav_len
) {
697 printf("ERROR: number of fields mismatch between description and arguments\n");
700 print_attributes(", attributes: ", desc
->attr
, desc
->nr_attr
);
701 printf("%s", side_sav_len
? ", fields: [ " : "");
702 for (i
= 0; i
< side_sav_len
; i
++) {
703 printf("%s", i
? ", " : "");
704 tracer_print_field(&desc
->fields
[i
], &sav
[i
]);
710 void tracer_call(const struct side_event_description
*desc
, const struct side_arg_vec_description
*sav_desc
)
714 if (side_unlikely(desc
->flags
& SIDE_EVENT_FLAG_VARIADIC
)) {
715 printf("ERROR: unexpected variadic event description\n");
718 tracer_print_static_fields(desc
, sav_desc
, &nr_fields
);
724 void tracer_call_variadic(const struct side_event_description
*desc
,
725 const struct side_arg_vec_description
*sav_desc
,
726 const struct side_arg_dynamic_event_struct
*var_struct
)
728 uint32_t var_struct_len
= var_struct
->len
;
729 int nr_fields
= 0, i
;
731 tracer_print_static_fields(desc
, sav_desc
, &nr_fields
);
733 if (side_unlikely(!(desc
->flags
& SIDE_EVENT_FLAG_VARIADIC
))) {
734 printf("ERROR: unexpected non-variadic event description\n");
737 printf("%s", var_struct_len
&& !nr_fields
? ", fields: [ " : "");
738 for (i
= 0; i
< var_struct_len
; i
++, nr_fields
++) {
739 printf("%s", nr_fields
? ", " : "");
740 printf("%s:: ", var_struct
->fields
[i
].field_name
);
741 tracer_print_dynamic(&var_struct
->fields
[i
].elem
);