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 struct side_attr
*attr
, uint32_t nr_attr
)
35 printf(", attributes: [ ");
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");
84 printf("%s", item
->u
.side_bool
? "true" : "false");
87 printf("%" PRIu8
, item
->u
.side_u8
);
90 printf("%" PRIu16
, item
->u
.side_u16
);
93 printf("%" PRIu32
, item
->u
.side_u32
);
96 printf("%" PRIu64
, item
->u
.side_u64
);
99 printf("%" PRId8
, item
->u
.side_s8
);
102 printf("%" PRId16
, item
->u
.side_s16
);
105 printf("%" PRId32
, item
->u
.side_s32
);
108 printf("%" PRId64
, item
->u
.side_s64
);
110 case SIDE_TYPE_STRING
:
111 printf("\"%s\"", item
->u
.string
);
113 case SIDE_TYPE_STRUCT
:
114 tracer_print_struct(type_desc
, item
->u
.side_struct
);
116 case SIDE_TYPE_ARRAY
:
117 tracer_print_array(type_desc
, item
->u
.side_array
);
120 tracer_print_vla(type_desc
, item
->u
.side_vla
);
122 case SIDE_TYPE_VLA_VISITOR
:
123 tracer_print_vla_visitor(type_desc
, item
->u
.side_vla_app_visitor_ctx
);
125 case SIDE_TYPE_ARRAY_U8
:
126 case SIDE_TYPE_ARRAY_U16
:
127 case SIDE_TYPE_ARRAY_U32
:
128 case SIDE_TYPE_ARRAY_U64
:
129 case SIDE_TYPE_ARRAY_S8
:
130 case SIDE_TYPE_ARRAY_S16
:
131 case SIDE_TYPE_ARRAY_S32
:
132 case SIDE_TYPE_ARRAY_S64
:
133 tracer_print_array_fixint(type_desc
, item
);
135 case SIDE_TYPE_VLA_U8
:
136 case SIDE_TYPE_VLA_U16
:
137 case SIDE_TYPE_VLA_U32
:
138 case SIDE_TYPE_VLA_U64
:
139 case SIDE_TYPE_VLA_S8
:
140 case SIDE_TYPE_VLA_S16
:
141 case SIDE_TYPE_VLA_S32
:
142 case SIDE_TYPE_VLA_S64
:
143 tracer_print_vla_fixint(type_desc
, item
);
145 case SIDE_TYPE_DYNAMIC
:
146 tracer_print_dynamic(&item
->u
.dynamic
);
149 printf("<UNKNOWN TYPE>");
155 void tracer_print_field(const struct side_event_field
*item_desc
, const struct side_arg_vec
*item
)
157 printf("%s: ", item_desc
->field_name
);
158 tracer_print_type(&item_desc
->side_type
, item
);
162 void tracer_print_struct(const struct side_type_description
*type_desc
, const struct side_arg_vec_description
*sav_desc
)
164 const struct side_arg_vec
*sav
= sav_desc
->sav
;
165 uint32_t side_sav_len
= sav_desc
->len
;
168 if (type_desc
->u
.side_struct
.nr_fields
!= side_sav_len
) {
169 printf("ERROR: number of fields mismatch between description and arguments of structure\n");
173 for (i
= 0; i
< side_sav_len
; i
++) {
174 printf("%s", i
? ", " : "");
175 tracer_print_field(&type_desc
->u
.side_struct
.fields
[i
], &sav
[i
]);
181 void tracer_print_array(const struct side_type_description
*type_desc
, const struct side_arg_vec_description
*sav_desc
)
183 const struct side_arg_vec
*sav
= sav_desc
->sav
;
184 uint32_t side_sav_len
= sav_desc
->len
;
187 if (type_desc
->u
.side_array
.length
!= side_sav_len
) {
188 printf("ERROR: length mismatch between description and arguments of array\n");
192 for (i
= 0; i
< side_sav_len
; i
++) {
193 printf("%s", i
? ", " : "");
194 tracer_print_type(type_desc
->u
.side_array
.elem_type
, &sav
[i
]);
200 void tracer_print_vla(const struct side_type_description
*type_desc
, const struct side_arg_vec_description
*sav_desc
)
202 const struct side_arg_vec
*sav
= sav_desc
->sav
;
203 uint32_t side_sav_len
= sav_desc
->len
;
207 for (i
= 0; i
< side_sav_len
; i
++) {
208 printf("%s", i
? ", " : "");
209 tracer_print_type(type_desc
->u
.side_vla
.elem_type
, &sav
[i
]);
214 struct tracer_visitor_priv
{
215 const struct side_type_description
*elem_type
;
220 enum side_visitor_status
tracer_write_elem_cb(const struct side_tracer_visitor_ctx
*tracer_ctx
,
221 const struct side_arg_vec
*elem
)
223 struct tracer_visitor_priv
*tracer_priv
= tracer_ctx
->priv
;
225 printf("%s", tracer_priv
->i
++ ? ", " : "");
226 tracer_print_type(tracer_priv
->elem_type
, elem
);
227 return SIDE_VISITOR_STATUS_OK
;
231 void tracer_print_vla_visitor(const struct side_type_description
*type_desc
, void *app_ctx
)
233 enum side_visitor_status status
;
234 struct tracer_visitor_priv tracer_priv
= {
235 .elem_type
= type_desc
->u
.side_vla_visitor
.elem_type
,
238 const struct side_tracer_visitor_ctx tracer_ctx
= {
239 .write_elem
= tracer_write_elem_cb
,
240 .priv
= &tracer_priv
,
244 status
= type_desc
->u
.side_vla_visitor
.visitor(&tracer_ctx
, app_ctx
);
246 case SIDE_VISITOR_STATUS_OK
:
248 case SIDE_VISITOR_STATUS_ERROR
:
249 printf("ERROR: Visitor error\n");
255 void tracer_print_array_fixint(const struct side_type_description
*type_desc
, const struct side_arg_vec
*item
)
257 const struct side_type_description
*elem_type
= type_desc
->u
.side_array
.elem_type
;
258 uint32_t side_sav_len
= type_desc
->u
.side_array
.length
;
259 void *p
= item
->u
.side_array_fixint
;
260 enum side_type side_type
;
263 switch (item
->type
) {
264 case SIDE_TYPE_ARRAY_U8
:
265 if (elem_type
->type
!= SIDE_TYPE_U8
)
268 case SIDE_TYPE_ARRAY_U16
:
269 if (elem_type
->type
!= SIDE_TYPE_U16
)
272 case SIDE_TYPE_ARRAY_U32
:
273 if (elem_type
->type
!= SIDE_TYPE_U32
)
276 case SIDE_TYPE_ARRAY_U64
:
277 if (elem_type
->type
!= SIDE_TYPE_U64
)
280 case SIDE_TYPE_ARRAY_S8
:
281 if (elem_type
->type
!= SIDE_TYPE_S8
)
284 case SIDE_TYPE_ARRAY_S16
:
285 if (elem_type
->type
!= SIDE_TYPE_S16
)
288 case SIDE_TYPE_ARRAY_S32
:
289 if (elem_type
->type
!= SIDE_TYPE_S32
)
292 case SIDE_TYPE_ARRAY_S64
:
293 if (elem_type
->type
!= SIDE_TYPE_S64
)
299 side_type
= elem_type
->type
;
302 for (i
= 0; i
< side_sav_len
; i
++) {
303 struct side_arg_vec sav_elem
= {
309 sav_elem
.u
.side_u8
= ((const uint8_t *) p
)[i
];
312 sav_elem
.u
.side_s8
= ((const int8_t *) p
)[i
];
315 sav_elem
.u
.side_u16
= ((const uint16_t *) p
)[i
];
318 sav_elem
.u
.side_s16
= ((const int16_t *) p
)[i
];
321 sav_elem
.u
.side_u32
= ((const uint32_t *) p
)[i
];
324 sav_elem
.u
.side_s32
= ((const int32_t *) p
)[i
];
327 sav_elem
.u
.side_u64
= ((const uint64_t *) p
)[i
];
330 sav_elem
.u
.side_s64
= ((const int64_t *) p
)[i
];
334 printf("ERROR: Unexpected type\n");
338 printf("%s", i
? ", " : "");
339 tracer_print_type(elem_type
, &sav_elem
);
345 printf("ERROR: type mismatch\n");
349 void tracer_print_vla_fixint(const struct side_type_description
*type_desc
, const struct side_arg_vec
*item
)
351 const struct side_type_description
*elem_type
= type_desc
->u
.side_vla
.elem_type
;
352 uint32_t side_sav_len
= item
->u
.side_vla_fixint
.length
;
353 void *p
= item
->u
.side_vla_fixint
.p
;
354 enum side_type side_type
;
357 switch (item
->type
) {
358 case SIDE_TYPE_VLA_U8
:
359 if (elem_type
->type
!= SIDE_TYPE_U8
)
362 case SIDE_TYPE_VLA_U16
:
363 if (elem_type
->type
!= SIDE_TYPE_U16
)
366 case SIDE_TYPE_VLA_U32
:
367 if (elem_type
->type
!= SIDE_TYPE_U32
)
370 case SIDE_TYPE_VLA_U64
:
371 if (elem_type
->type
!= SIDE_TYPE_U64
)
374 case SIDE_TYPE_VLA_S8
:
375 if (elem_type
->type
!= SIDE_TYPE_S8
)
378 case SIDE_TYPE_VLA_S16
:
379 if (elem_type
->type
!= SIDE_TYPE_S16
)
382 case SIDE_TYPE_VLA_S32
:
383 if (elem_type
->type
!= SIDE_TYPE_S32
)
386 case SIDE_TYPE_VLA_S64
:
387 if (elem_type
->type
!= SIDE_TYPE_S64
)
393 side_type
= elem_type
->type
;
396 for (i
= 0; i
< side_sav_len
; i
++) {
397 struct side_arg_vec sav_elem
= {
403 sav_elem
.u
.side_u8
= ((const uint8_t *) p
)[i
];
406 sav_elem
.u
.side_s8
= ((const int8_t *) p
)[i
];
409 sav_elem
.u
.side_u16
= ((const uint16_t *) p
)[i
];
412 sav_elem
.u
.side_s16
= ((const int16_t *) p
)[i
];
415 sav_elem
.u
.side_u32
= ((const uint32_t *) p
)[i
];
418 sav_elem
.u
.side_s32
= ((const int32_t *) p
)[i
];
421 sav_elem
.u
.side_u64
= ((const uint64_t *) p
)[i
];
424 sav_elem
.u
.side_s64
= ((const int64_t *) p
)[i
];
428 printf("ERROR: Unexpected type\n");
432 printf("%s", i
? ", " : "");
433 tracer_print_type(elem_type
, &sav_elem
);
439 printf("ERROR: type mismatch\n");
444 void tracer_print_dynamic_struct(const struct side_arg_dynamic_event_struct
*dynamic_struct
)
446 const struct side_arg_dynamic_event_field
*fields
= dynamic_struct
->fields
;
447 uint32_t len
= dynamic_struct
->len
;
451 for (i
= 0; i
< len
; i
++) {
452 printf("%s", i
? ", " : "");
453 printf("%s:: ", fields
[i
].field_name
);
454 tracer_print_dynamic(&fields
[i
].elem
);
459 struct tracer_dynamic_struct_visitor_priv
{
464 enum side_visitor_status
tracer_dynamic_struct_write_elem_cb(
465 const struct side_tracer_dynamic_struct_visitor_ctx
*tracer_ctx
,
466 const struct side_arg_dynamic_event_field
*dynamic_field
)
468 struct tracer_dynamic_struct_visitor_priv
*tracer_priv
= tracer_ctx
->priv
;
470 printf("%s", tracer_priv
->i
++ ? ", " : "");
471 printf("%s:: ", dynamic_field
->field_name
);
472 tracer_print_dynamic(&dynamic_field
->elem
);
473 return SIDE_VISITOR_STATUS_OK
;
477 void tracer_print_dynamic_struct_visitor(const struct side_arg_dynamic_vec
*item
)
479 enum side_visitor_status status
;
480 struct tracer_dynamic_struct_visitor_priv tracer_priv
= {
483 const struct side_tracer_dynamic_struct_visitor_ctx tracer_ctx
= {
484 .write_field
= tracer_dynamic_struct_write_elem_cb
,
485 .priv
= &tracer_priv
,
487 void *app_ctx
= item
->u
.side_dynamic_struct_visitor
.app_ctx
;
490 status
= item
->u
.side_dynamic_struct_visitor
.visitor(&tracer_ctx
, app_ctx
);
492 case SIDE_VISITOR_STATUS_OK
:
494 case SIDE_VISITOR_STATUS_ERROR
:
495 printf("ERROR: Visitor error\n");
502 void tracer_print_dynamic_vla(const struct side_arg_dynamic_vec_vla
*vla
)
504 const struct side_arg_dynamic_vec
*sav
= vla
->sav
;
505 uint32_t side_sav_len
= vla
->len
;
509 for (i
= 0; i
< side_sav_len
; i
++) {
510 printf("%s", i
? ", " : "");
511 tracer_print_dynamic(&sav
[i
]);
516 struct tracer_dynamic_vla_visitor_priv
{
521 enum side_visitor_status
tracer_dynamic_vla_write_elem_cb(
522 const struct side_tracer_dynamic_vla_visitor_ctx
*tracer_ctx
,
523 const struct side_arg_dynamic_vec
*elem
)
525 struct tracer_dynamic_vla_visitor_priv
*tracer_priv
= tracer_ctx
->priv
;
527 printf("%s", tracer_priv
->i
++ ? ", " : "");
528 tracer_print_dynamic(elem
);
529 return SIDE_VISITOR_STATUS_OK
;
533 void tracer_print_dynamic_vla_visitor(const struct side_arg_dynamic_vec
*item
)
535 enum side_visitor_status status
;
536 struct tracer_dynamic_vla_visitor_priv tracer_priv
= {
539 const struct side_tracer_dynamic_vla_visitor_ctx tracer_ctx
= {
540 .write_elem
= tracer_dynamic_vla_write_elem_cb
,
541 .priv
= &tracer_priv
,
543 void *app_ctx
= item
->u
.side_dynamic_vla_visitor
.app_ctx
;
546 status
= item
->u
.side_dynamic_vla_visitor
.visitor(&tracer_ctx
, app_ctx
);
548 case SIDE_VISITOR_STATUS_OK
:
550 case SIDE_VISITOR_STATUS_ERROR
:
551 printf("ERROR: Visitor error\n");
558 void tracer_print_dynamic(const struct side_arg_dynamic_vec
*item
)
560 switch (item
->dynamic_type
) {
561 case SIDE_DYNAMIC_TYPE_NULL
:
562 printf("<NULL TYPE>");
564 case SIDE_DYNAMIC_TYPE_BOOL
:
565 printf("%s", item
->u
.side_bool
? "true" : "false");
567 case SIDE_DYNAMIC_TYPE_U8
:
568 printf("%" PRIu8
, item
->u
.side_u8
);
570 case SIDE_DYNAMIC_TYPE_U16
:
571 printf("%" PRIu16
, item
->u
.side_u16
);
573 case SIDE_DYNAMIC_TYPE_U32
:
574 printf("%" PRIu32
, item
->u
.side_u32
);
576 case SIDE_DYNAMIC_TYPE_U64
:
577 printf("%" PRIu64
, item
->u
.side_u64
);
579 case SIDE_DYNAMIC_TYPE_S8
:
580 printf("%" PRId8
, item
->u
.side_s8
);
582 case SIDE_DYNAMIC_TYPE_S16
:
583 printf("%" PRId16
, item
->u
.side_s16
);
585 case SIDE_DYNAMIC_TYPE_S32
:
586 printf("%" PRId32
, item
->u
.side_s32
);
588 case SIDE_DYNAMIC_TYPE_S64
:
589 printf("%" PRId64
, item
->u
.side_s64
);
591 case SIDE_DYNAMIC_TYPE_STRING
:
592 printf("\"%s\"", item
->u
.string
);
594 case SIDE_DYNAMIC_TYPE_STRUCT
:
595 tracer_print_dynamic_struct(item
->u
.side_dynamic_struct
);
597 case SIDE_DYNAMIC_TYPE_STRUCT_VISITOR
:
598 tracer_print_dynamic_struct_visitor(item
);
600 case SIDE_DYNAMIC_TYPE_VLA
:
601 tracer_print_dynamic_vla(item
->u
.side_dynamic_vla
);
603 case SIDE_DYNAMIC_TYPE_VLA_VISITOR
:
604 tracer_print_dynamic_vla_visitor(item
);
607 printf("<UNKNOWN TYPE>");
613 void tracer_print_static_fields(const struct side_event_description
*desc
,
614 const struct side_arg_vec_description
*sav_desc
,
617 const struct side_arg_vec
*sav
= sav_desc
->sav
;
618 uint32_t side_sav_len
= sav_desc
->len
;
621 printf("provider: %s, event: %s", desc
->provider_name
, desc
->event_name
);
622 if (desc
->nr_fields
!= side_sav_len
) {
623 printf("ERROR: number of fields mismatch between description and arguments\n");
626 print_attributes(desc
->attr
, desc
->nr_attr
);
627 printf("%s", side_sav_len
? ", " : "");
628 for (i
= 0; i
< side_sav_len
; i
++) {
629 printf("%s", i
? ", " : "");
630 tracer_print_field(&desc
->fields
[i
], &sav
[i
]);
636 void tracer_call(const struct side_event_description
*desc
, const struct side_arg_vec_description
*sav_desc
)
638 if (side_unlikely(desc
->flags
& SIDE_EVENT_FLAG_VARIADIC
)) {
639 printf("ERROR: unexpected variadic event description\n");
642 tracer_print_static_fields(desc
, sav_desc
, NULL
);
646 void tracer_call_variadic(const struct side_event_description
*desc
,
647 const struct side_arg_vec_description
*sav_desc
,
648 const struct side_arg_dynamic_event_struct
*var_struct
)
650 uint32_t var_struct_len
= var_struct
->len
;
651 int nr_fields
= 0, i
;
653 tracer_print_static_fields(desc
, sav_desc
, &nr_fields
);
655 if (side_unlikely(!(desc
->flags
& SIDE_EVENT_FLAG_VARIADIC
))) {
656 printf("ERROR: unexpected non-variadic event description\n");
659 printf("%s", var_struct_len
&& !nr_fields
? ", " : "");
660 for (i
= 0; i
< var_struct_len
; i
++, nr_fields
++) {
661 printf("%s", nr_fields
? ", " : "");
662 printf("%s:: ", var_struct
->fields
[i
].field_name
);
663 tracer_print_dynamic(&var_struct
->fields
[i
].elem
);