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_STRING
:
115 printf("\"%s\"", item
->u
.string
);
117 case SIDE_TYPE_STRUCT
:
118 tracer_print_struct(type_desc
, item
->u
.side_struct
);
120 case SIDE_TYPE_ARRAY
:
121 tracer_print_array(type_desc
, item
->u
.side_array
);
124 tracer_print_vla(type_desc
, item
->u
.side_vla
);
126 case SIDE_TYPE_VLA_VISITOR
:
127 tracer_print_vla_visitor(type_desc
, item
->u
.side_vla_app_visitor_ctx
);
129 case SIDE_TYPE_ARRAY_U8
:
130 case SIDE_TYPE_ARRAY_U16
:
131 case SIDE_TYPE_ARRAY_U32
:
132 case SIDE_TYPE_ARRAY_U64
:
133 case SIDE_TYPE_ARRAY_S8
:
134 case SIDE_TYPE_ARRAY_S16
:
135 case SIDE_TYPE_ARRAY_S32
:
136 case SIDE_TYPE_ARRAY_S64
:
137 tracer_print_array_fixint(type_desc
, item
);
139 case SIDE_TYPE_VLA_U8
:
140 case SIDE_TYPE_VLA_U16
:
141 case SIDE_TYPE_VLA_U32
:
142 case SIDE_TYPE_VLA_U64
:
143 case SIDE_TYPE_VLA_S8
:
144 case SIDE_TYPE_VLA_S16
:
145 case SIDE_TYPE_VLA_S32
:
146 case SIDE_TYPE_VLA_S64
:
147 tracer_print_vla_fixint(type_desc
, item
);
149 case SIDE_TYPE_DYNAMIC
:
150 tracer_print_dynamic(&item
->u
.dynamic
);
153 printf("<UNKNOWN TYPE>");
160 void tracer_print_field(const struct side_event_field
*item_desc
, const struct side_arg_vec
*item
)
162 printf("%s: ", item_desc
->field_name
);
163 tracer_print_type(&item_desc
->side_type
, item
);
167 void tracer_print_struct(const struct side_type_description
*type_desc
, const struct side_arg_vec_description
*sav_desc
)
169 const struct side_arg_vec
*sav
= sav_desc
->sav
;
170 uint32_t side_sav_len
= sav_desc
->len
;
173 if (type_desc
->u
.side_struct
.nr_fields
!= side_sav_len
) {
174 printf("ERROR: number of fields mismatch between description and arguments of structure\n");
178 for (i
= 0; i
< side_sav_len
; i
++) {
179 printf("%s", i
? ", " : "");
180 tracer_print_field(&type_desc
->u
.side_struct
.fields
[i
], &sav
[i
]);
186 void tracer_print_array(const struct side_type_description
*type_desc
, const struct side_arg_vec_description
*sav_desc
)
188 const struct side_arg_vec
*sav
= sav_desc
->sav
;
189 uint32_t side_sav_len
= sav_desc
->len
;
192 if (type_desc
->u
.side_array
.length
!= side_sav_len
) {
193 printf("ERROR: length mismatch between description and arguments of array\n");
197 for (i
= 0; i
< side_sav_len
; i
++) {
198 printf("%s", i
? ", " : "");
199 tracer_print_type(type_desc
->u
.side_array
.elem_type
, &sav
[i
]);
205 void tracer_print_vla(const struct side_type_description
*type_desc
, const struct side_arg_vec_description
*sav_desc
)
207 const struct side_arg_vec
*sav
= sav_desc
->sav
;
208 uint32_t side_sav_len
= sav_desc
->len
;
212 for (i
= 0; i
< side_sav_len
; i
++) {
213 printf("%s", i
? ", " : "");
214 tracer_print_type(type_desc
->u
.side_vla
.elem_type
, &sav
[i
]);
219 struct tracer_visitor_priv
{
220 const struct side_type_description
*elem_type
;
225 enum side_visitor_status
tracer_write_elem_cb(const struct side_tracer_visitor_ctx
*tracer_ctx
,
226 const struct side_arg_vec
*elem
)
228 struct tracer_visitor_priv
*tracer_priv
= tracer_ctx
->priv
;
230 printf("%s", tracer_priv
->i
++ ? ", " : "");
231 tracer_print_type(tracer_priv
->elem_type
, elem
);
232 return SIDE_VISITOR_STATUS_OK
;
236 void tracer_print_vla_visitor(const struct side_type_description
*type_desc
, void *app_ctx
)
238 enum side_visitor_status status
;
239 struct tracer_visitor_priv tracer_priv
= {
240 .elem_type
= type_desc
->u
.side_vla_visitor
.elem_type
,
243 const struct side_tracer_visitor_ctx tracer_ctx
= {
244 .write_elem
= tracer_write_elem_cb
,
245 .priv
= &tracer_priv
,
249 status
= type_desc
->u
.side_vla_visitor
.visitor(&tracer_ctx
, app_ctx
);
251 case SIDE_VISITOR_STATUS_OK
:
253 case SIDE_VISITOR_STATUS_ERROR
:
254 printf("ERROR: Visitor error\n");
260 void tracer_print_array_fixint(const struct side_type_description
*type_desc
, const struct side_arg_vec
*item
)
262 const struct side_type_description
*elem_type
= type_desc
->u
.side_array
.elem_type
;
263 uint32_t side_sav_len
= type_desc
->u
.side_array
.length
;
264 void *p
= item
->u
.side_array_fixint
;
265 enum side_type side_type
;
268 switch (item
->type
) {
269 case SIDE_TYPE_ARRAY_U8
:
270 if (elem_type
->type
!= SIDE_TYPE_U8
)
273 case SIDE_TYPE_ARRAY_U16
:
274 if (elem_type
->type
!= SIDE_TYPE_U16
)
277 case SIDE_TYPE_ARRAY_U32
:
278 if (elem_type
->type
!= SIDE_TYPE_U32
)
281 case SIDE_TYPE_ARRAY_U64
:
282 if (elem_type
->type
!= SIDE_TYPE_U64
)
285 case SIDE_TYPE_ARRAY_S8
:
286 if (elem_type
->type
!= SIDE_TYPE_S8
)
289 case SIDE_TYPE_ARRAY_S16
:
290 if (elem_type
->type
!= SIDE_TYPE_S16
)
293 case SIDE_TYPE_ARRAY_S32
:
294 if (elem_type
->type
!= SIDE_TYPE_S32
)
297 case SIDE_TYPE_ARRAY_S64
:
298 if (elem_type
->type
!= SIDE_TYPE_S64
)
304 side_type
= elem_type
->type
;
307 for (i
= 0; i
< side_sav_len
; i
++) {
308 struct side_arg_vec sav_elem
= {
314 sav_elem
.u
.side_u8
= ((const uint8_t *) p
)[i
];
317 sav_elem
.u
.side_s8
= ((const int8_t *) p
)[i
];
320 sav_elem
.u
.side_u16
= ((const uint16_t *) p
)[i
];
323 sav_elem
.u
.side_s16
= ((const int16_t *) p
)[i
];
326 sav_elem
.u
.side_u32
= ((const uint32_t *) p
)[i
];
329 sav_elem
.u
.side_s32
= ((const int32_t *) p
)[i
];
332 sav_elem
.u
.side_u64
= ((const uint64_t *) p
)[i
];
335 sav_elem
.u
.side_s64
= ((const int64_t *) p
)[i
];
339 printf("ERROR: Unexpected type\n");
343 printf("%s", i
? ", " : "");
344 tracer_print_type(elem_type
, &sav_elem
);
350 printf("ERROR: type mismatch\n");
354 void tracer_print_vla_fixint(const struct side_type_description
*type_desc
, const struct side_arg_vec
*item
)
356 const struct side_type_description
*elem_type
= type_desc
->u
.side_vla
.elem_type
;
357 uint32_t side_sav_len
= item
->u
.side_vla_fixint
.length
;
358 void *p
= item
->u
.side_vla_fixint
.p
;
359 enum side_type side_type
;
362 switch (item
->type
) {
363 case SIDE_TYPE_VLA_U8
:
364 if (elem_type
->type
!= SIDE_TYPE_U8
)
367 case SIDE_TYPE_VLA_U16
:
368 if (elem_type
->type
!= SIDE_TYPE_U16
)
371 case SIDE_TYPE_VLA_U32
:
372 if (elem_type
->type
!= SIDE_TYPE_U32
)
375 case SIDE_TYPE_VLA_U64
:
376 if (elem_type
->type
!= SIDE_TYPE_U64
)
379 case SIDE_TYPE_VLA_S8
:
380 if (elem_type
->type
!= SIDE_TYPE_S8
)
383 case SIDE_TYPE_VLA_S16
:
384 if (elem_type
->type
!= SIDE_TYPE_S16
)
387 case SIDE_TYPE_VLA_S32
:
388 if (elem_type
->type
!= SIDE_TYPE_S32
)
391 case SIDE_TYPE_VLA_S64
:
392 if (elem_type
->type
!= SIDE_TYPE_S64
)
398 side_type
= elem_type
->type
;
401 for (i
= 0; i
< side_sav_len
; i
++) {
402 struct side_arg_vec sav_elem
= {
408 sav_elem
.u
.side_u8
= ((const uint8_t *) p
)[i
];
411 sav_elem
.u
.side_s8
= ((const int8_t *) p
)[i
];
414 sav_elem
.u
.side_u16
= ((const uint16_t *) p
)[i
];
417 sav_elem
.u
.side_s16
= ((const int16_t *) p
)[i
];
420 sav_elem
.u
.side_u32
= ((const uint32_t *) p
)[i
];
423 sav_elem
.u
.side_s32
= ((const int32_t *) p
)[i
];
426 sav_elem
.u
.side_u64
= ((const uint64_t *) p
)[i
];
429 sav_elem
.u
.side_s64
= ((const int64_t *) p
)[i
];
433 printf("ERROR: Unexpected type\n");
437 printf("%s", i
? ", " : "");
438 tracer_print_type(elem_type
, &sav_elem
);
444 printf("ERROR: type mismatch\n");
449 void tracer_print_dynamic_struct(const struct side_arg_dynamic_event_struct
*dynamic_struct
)
451 const struct side_arg_dynamic_event_field
*fields
= dynamic_struct
->fields
;
452 uint32_t len
= dynamic_struct
->len
;
456 for (i
= 0; i
< len
; i
++) {
457 printf("%s", i
? ", " : "");
458 printf("%s:: ", fields
[i
].field_name
);
459 tracer_print_dynamic(&fields
[i
].elem
);
464 struct tracer_dynamic_struct_visitor_priv
{
469 enum side_visitor_status
tracer_dynamic_struct_write_elem_cb(
470 const struct side_tracer_dynamic_struct_visitor_ctx
*tracer_ctx
,
471 const struct side_arg_dynamic_event_field
*dynamic_field
)
473 struct tracer_dynamic_struct_visitor_priv
*tracer_priv
= tracer_ctx
->priv
;
475 printf("%s", tracer_priv
->i
++ ? ", " : "");
476 printf("%s:: ", dynamic_field
->field_name
);
477 tracer_print_dynamic(&dynamic_field
->elem
);
478 return SIDE_VISITOR_STATUS_OK
;
482 void tracer_print_dynamic_struct_visitor(const struct side_arg_dynamic_vec
*item
)
484 enum side_visitor_status status
;
485 struct tracer_dynamic_struct_visitor_priv tracer_priv
= {
488 const struct side_tracer_dynamic_struct_visitor_ctx tracer_ctx
= {
489 .write_field
= tracer_dynamic_struct_write_elem_cb
,
490 .priv
= &tracer_priv
,
492 void *app_ctx
= item
->u
.side_dynamic_struct_visitor
.app_ctx
;
495 status
= item
->u
.side_dynamic_struct_visitor
.visitor(&tracer_ctx
, app_ctx
);
497 case SIDE_VISITOR_STATUS_OK
:
499 case SIDE_VISITOR_STATUS_ERROR
:
500 printf("ERROR: Visitor error\n");
507 void tracer_print_dynamic_vla(const struct side_arg_dynamic_vec_vla
*vla
)
509 const struct side_arg_dynamic_vec
*sav
= vla
->sav
;
510 uint32_t side_sav_len
= vla
->len
;
514 for (i
= 0; i
< side_sav_len
; i
++) {
515 printf("%s", i
? ", " : "");
516 tracer_print_dynamic(&sav
[i
]);
521 struct tracer_dynamic_vla_visitor_priv
{
526 enum side_visitor_status
tracer_dynamic_vla_write_elem_cb(
527 const struct side_tracer_dynamic_vla_visitor_ctx
*tracer_ctx
,
528 const struct side_arg_dynamic_vec
*elem
)
530 struct tracer_dynamic_vla_visitor_priv
*tracer_priv
= tracer_ctx
->priv
;
532 printf("%s", tracer_priv
->i
++ ? ", " : "");
533 tracer_print_dynamic(elem
);
534 return SIDE_VISITOR_STATUS_OK
;
538 void tracer_print_dynamic_vla_visitor(const struct side_arg_dynamic_vec
*item
)
540 enum side_visitor_status status
;
541 struct tracer_dynamic_vla_visitor_priv tracer_priv
= {
544 const struct side_tracer_dynamic_vla_visitor_ctx tracer_ctx
= {
545 .write_elem
= tracer_dynamic_vla_write_elem_cb
,
546 .priv
= &tracer_priv
,
548 void *app_ctx
= item
->u
.side_dynamic_vla_visitor
.app_ctx
;
551 status
= item
->u
.side_dynamic_vla_visitor
.visitor(&tracer_ctx
, app_ctx
);
553 case SIDE_VISITOR_STATUS_OK
:
555 case SIDE_VISITOR_STATUS_ERROR
:
556 printf("ERROR: Visitor error\n");
563 void tracer_print_dynamic(const struct side_arg_dynamic_vec
*item
)
565 switch (item
->dynamic_type
) {
566 case SIDE_DYNAMIC_TYPE_NULL
:
567 printf("<NULL TYPE>");
569 case SIDE_DYNAMIC_TYPE_BOOL
:
570 printf("%s", item
->u
.side_bool
? "true" : "false");
572 case SIDE_DYNAMIC_TYPE_U8
:
573 printf("%" PRIu8
, item
->u
.side_u8
);
575 case SIDE_DYNAMIC_TYPE_U16
:
576 printf("%" PRIu16
, item
->u
.side_u16
);
578 case SIDE_DYNAMIC_TYPE_U32
:
579 printf("%" PRIu32
, item
->u
.side_u32
);
581 case SIDE_DYNAMIC_TYPE_U64
:
582 printf("%" PRIu64
, item
->u
.side_u64
);
584 case SIDE_DYNAMIC_TYPE_S8
:
585 printf("%" PRId8
, item
->u
.side_s8
);
587 case SIDE_DYNAMIC_TYPE_S16
:
588 printf("%" PRId16
, item
->u
.side_s16
);
590 case SIDE_DYNAMIC_TYPE_S32
:
591 printf("%" PRId32
, item
->u
.side_s32
);
593 case SIDE_DYNAMIC_TYPE_S64
:
594 printf("%" PRId64
, item
->u
.side_s64
);
596 case SIDE_DYNAMIC_TYPE_STRING
:
597 printf("\"%s\"", item
->u
.string
);
599 case SIDE_DYNAMIC_TYPE_STRUCT
:
600 tracer_print_dynamic_struct(item
->u
.side_dynamic_struct
);
602 case SIDE_DYNAMIC_TYPE_STRUCT_VISITOR
:
603 tracer_print_dynamic_struct_visitor(item
);
605 case SIDE_DYNAMIC_TYPE_VLA
:
606 tracer_print_dynamic_vla(item
->u
.side_dynamic_vla
);
608 case SIDE_DYNAMIC_TYPE_VLA_VISITOR
:
609 tracer_print_dynamic_vla_visitor(item
);
612 printf("<UNKNOWN TYPE>");
618 void tracer_print_static_fields(const struct side_event_description
*desc
,
619 const struct side_arg_vec_description
*sav_desc
,
622 const struct side_arg_vec
*sav
= sav_desc
->sav
;
623 uint32_t side_sav_len
= sav_desc
->len
;
626 printf("provider: %s, event: %s", desc
->provider_name
, desc
->event_name
);
627 if (desc
->nr_fields
!= side_sav_len
) {
628 printf("ERROR: number of fields mismatch between description and arguments\n");
631 print_attributes(", attributes: ", desc
->attr
, desc
->nr_attr
);
632 printf("%s", side_sav_len
? ", fields: [ " : "");
633 for (i
= 0; i
< side_sav_len
; i
++) {
634 printf("%s", i
? ", " : "");
635 tracer_print_field(&desc
->fields
[i
], &sav
[i
]);
641 void tracer_call(const struct side_event_description
*desc
, const struct side_arg_vec_description
*sav_desc
)
645 if (side_unlikely(desc
->flags
& SIDE_EVENT_FLAG_VARIADIC
)) {
646 printf("ERROR: unexpected variadic event description\n");
649 tracer_print_static_fields(desc
, sav_desc
, &nr_fields
);
655 void tracer_call_variadic(const struct side_event_description
*desc
,
656 const struct side_arg_vec_description
*sav_desc
,
657 const struct side_arg_dynamic_event_struct
*var_struct
)
659 uint32_t var_struct_len
= var_struct
->len
;
660 int nr_fields
= 0, i
;
662 tracer_print_static_fields(desc
, sav_desc
, &nr_fields
);
664 if (side_unlikely(!(desc
->flags
& SIDE_EVENT_FLAG_VARIADIC
))) {
665 printf("ERROR: unexpected non-variadic event description\n");
668 printf("%s", var_struct_len
&& !nr_fields
? ", fields: [ " : "");
669 for (i
= 0; i
< var_struct_len
; i
++, nr_fields
++) {
670 printf("%s", nr_fields
? ", " : "");
671 printf("%s:: ", var_struct
->fields
[i
].field_name
);
672 tracer_print_dynamic(&var_struct
->fields
[i
].elem
);