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 tracer_print_type(const struct side_type_description
*type_desc
, const struct side_arg_vec
*item
)
32 case SIDE_TYPE_ARRAY_U8
:
33 case SIDE_TYPE_ARRAY_U16
:
34 case SIDE_TYPE_ARRAY_U32
:
35 case SIDE_TYPE_ARRAY_U64
:
36 case SIDE_TYPE_ARRAY_S8
:
37 case SIDE_TYPE_ARRAY_S16
:
38 case SIDE_TYPE_ARRAY_S32
:
39 case SIDE_TYPE_ARRAY_S64
:
40 if (type_desc
->type
!= SIDE_TYPE_ARRAY
) {
41 printf("ERROR: type mismatch between description and arguments\n");
45 case SIDE_TYPE_VLA_U8
:
46 case SIDE_TYPE_VLA_U16
:
47 case SIDE_TYPE_VLA_U32
:
48 case SIDE_TYPE_VLA_U64
:
49 case SIDE_TYPE_VLA_S8
:
50 case SIDE_TYPE_VLA_S16
:
51 case SIDE_TYPE_VLA_S32
:
52 case SIDE_TYPE_VLA_S64
:
53 if (type_desc
->type
!= SIDE_TYPE_VLA
) {
54 printf("ERROR: type mismatch between description and arguments\n");
60 if (type_desc
->type
!= item
->type
) {
61 printf("ERROR: type mismatch between description and arguments\n");
68 printf("%s", item
->u
.side_bool
? "true" : "false");
71 printf("%" PRIu8
, item
->u
.side_u8
);
74 printf("%" PRIu16
, item
->u
.side_u16
);
77 printf("%" PRIu32
, item
->u
.side_u32
);
80 printf("%" PRIu64
, item
->u
.side_u64
);
83 printf("%" PRId8
, item
->u
.side_s8
);
86 printf("%" PRId16
, item
->u
.side_s16
);
89 printf("%" PRId32
, item
->u
.side_s32
);
92 printf("%" PRId64
, item
->u
.side_s64
);
94 case SIDE_TYPE_STRING
:
95 printf("\"%s\"", item
->u
.string
);
97 case SIDE_TYPE_STRUCT
:
98 tracer_print_struct(type_desc
, item
->u
.side_struct
);
100 case SIDE_TYPE_ARRAY
:
101 tracer_print_array(type_desc
, item
->u
.side_array
);
104 tracer_print_vla(type_desc
, item
->u
.side_vla
);
106 case SIDE_TYPE_VLA_VISITOR
:
107 tracer_print_vla_visitor(type_desc
, item
->u
.side_vla_app_visitor_ctx
);
109 case SIDE_TYPE_ARRAY_U8
:
110 case SIDE_TYPE_ARRAY_U16
:
111 case SIDE_TYPE_ARRAY_U32
:
112 case SIDE_TYPE_ARRAY_U64
:
113 case SIDE_TYPE_ARRAY_S8
:
114 case SIDE_TYPE_ARRAY_S16
:
115 case SIDE_TYPE_ARRAY_S32
:
116 case SIDE_TYPE_ARRAY_S64
:
117 tracer_print_array_fixint(type_desc
, item
);
119 case SIDE_TYPE_VLA_U8
:
120 case SIDE_TYPE_VLA_U16
:
121 case SIDE_TYPE_VLA_U32
:
122 case SIDE_TYPE_VLA_U64
:
123 case SIDE_TYPE_VLA_S8
:
124 case SIDE_TYPE_VLA_S16
:
125 case SIDE_TYPE_VLA_S32
:
126 case SIDE_TYPE_VLA_S64
:
127 tracer_print_vla_fixint(type_desc
, item
);
129 case SIDE_TYPE_DYNAMIC
:
130 tracer_print_dynamic(&item
->u
.dynamic
);
133 printf("<UNKNOWN TYPE>");
139 void tracer_print_field(const struct side_event_field
*item_desc
, const struct side_arg_vec
*item
)
141 printf("%s: ", item_desc
->field_name
);
142 tracer_print_type(&item_desc
->side_type
, item
);
146 void tracer_print_struct(const struct side_type_description
*type_desc
, const struct side_arg_vec_description
*sav_desc
)
148 const struct side_arg_vec
*sav
= sav_desc
->sav
;
149 uint32_t side_sav_len
= sav_desc
->len
;
152 if (type_desc
->u
.side_struct
.nr_fields
!= side_sav_len
) {
153 printf("ERROR: number of fields mismatch between description and arguments of structure\n");
157 for (i
= 0; i
< side_sav_len
; i
++) {
158 printf("%s", i
? ", " : "");
159 tracer_print_field(&type_desc
->u
.side_struct
.fields
[i
], &sav
[i
]);
165 void tracer_print_array(const struct side_type_description
*type_desc
, const struct side_arg_vec_description
*sav_desc
)
167 const struct side_arg_vec
*sav
= sav_desc
->sav
;
168 uint32_t side_sav_len
= sav_desc
->len
;
171 if (type_desc
->u
.side_array
.length
!= side_sav_len
) {
172 printf("ERROR: length mismatch between description and arguments of array\n");
176 for (i
= 0; i
< side_sav_len
; i
++) {
177 printf("%s", i
? ", " : "");
178 tracer_print_type(type_desc
->u
.side_array
.elem_type
, &sav
[i
]);
184 void tracer_print_vla(const struct side_type_description
*type_desc
, const struct side_arg_vec_description
*sav_desc
)
186 const struct side_arg_vec
*sav
= sav_desc
->sav
;
187 uint32_t side_sav_len
= sav_desc
->len
;
191 for (i
= 0; i
< side_sav_len
; i
++) {
192 printf("%s", i
? ", " : "");
193 tracer_print_type(type_desc
->u
.side_vla
.elem_type
, &sav
[i
]);
198 struct tracer_visitor_priv
{
199 const struct side_type_description
*elem_type
;
204 enum side_visitor_status
tracer_write_elem_cb(const struct side_tracer_visitor_ctx
*tracer_ctx
,
205 const struct side_arg_vec
*elem
)
207 struct tracer_visitor_priv
*tracer_priv
= tracer_ctx
->priv
;
209 printf("%s", tracer_priv
->i
++ ? ", " : "");
210 tracer_print_type(tracer_priv
->elem_type
, elem
);
211 return SIDE_VISITOR_STATUS_OK
;
215 void tracer_print_vla_visitor(const struct side_type_description
*type_desc
, void *app_ctx
)
217 enum side_visitor_status status
;
218 struct tracer_visitor_priv tracer_priv
= {
219 .elem_type
= type_desc
->u
.side_vla_visitor
.elem_type
,
222 const struct side_tracer_visitor_ctx tracer_ctx
= {
223 .write_elem
= tracer_write_elem_cb
,
224 .priv
= &tracer_priv
,
228 status
= type_desc
->u
.side_vla_visitor
.visitor(&tracer_ctx
, app_ctx
);
230 case SIDE_VISITOR_STATUS_OK
:
232 case SIDE_VISITOR_STATUS_ERROR
:
233 printf("ERROR: Visitor error\n");
239 void tracer_print_array_fixint(const struct side_type_description
*type_desc
, const struct side_arg_vec
*item
)
241 const struct side_type_description
*elem_type
= type_desc
->u
.side_array
.elem_type
;
242 uint32_t side_sav_len
= type_desc
->u
.side_array
.length
;
243 void *p
= item
->u
.side_array_fixint
;
244 enum side_type side_type
;
247 switch (item
->type
) {
248 case SIDE_TYPE_ARRAY_U8
:
249 if (elem_type
->type
!= SIDE_TYPE_U8
)
252 case SIDE_TYPE_ARRAY_U16
:
253 if (elem_type
->type
!= SIDE_TYPE_U16
)
256 case SIDE_TYPE_ARRAY_U32
:
257 if (elem_type
->type
!= SIDE_TYPE_U32
)
260 case SIDE_TYPE_ARRAY_U64
:
261 if (elem_type
->type
!= SIDE_TYPE_U64
)
264 case SIDE_TYPE_ARRAY_S8
:
265 if (elem_type
->type
!= SIDE_TYPE_S8
)
268 case SIDE_TYPE_ARRAY_S16
:
269 if (elem_type
->type
!= SIDE_TYPE_S16
)
272 case SIDE_TYPE_ARRAY_S32
:
273 if (elem_type
->type
!= SIDE_TYPE_S32
)
276 case SIDE_TYPE_ARRAY_S64
:
277 if (elem_type
->type
!= SIDE_TYPE_S64
)
283 side_type
= elem_type
->type
;
286 for (i
= 0; i
< side_sav_len
; i
++) {
287 struct side_arg_vec sav_elem
= {
293 sav_elem
.u
.side_u8
= ((const uint8_t *) p
)[i
];
296 sav_elem
.u
.side_s8
= ((const int8_t *) p
)[i
];
299 sav_elem
.u
.side_u16
= ((const uint16_t *) p
)[i
];
302 sav_elem
.u
.side_s16
= ((const int16_t *) p
)[i
];
305 sav_elem
.u
.side_u32
= ((const uint32_t *) p
)[i
];
308 sav_elem
.u
.side_s32
= ((const int32_t *) p
)[i
];
311 sav_elem
.u
.side_u64
= ((const uint64_t *) p
)[i
];
314 sav_elem
.u
.side_s64
= ((const int64_t *) p
)[i
];
318 printf("ERROR: Unexpected type\n");
322 printf("%s", i
? ", " : "");
323 tracer_print_type(elem_type
, &sav_elem
);
329 printf("ERROR: type mismatch\n");
333 void tracer_print_vla_fixint(const struct side_type_description
*type_desc
, const struct side_arg_vec
*item
)
335 const struct side_type_description
*elem_type
= type_desc
->u
.side_vla
.elem_type
;
336 uint32_t side_sav_len
= item
->u
.side_vla_fixint
.length
;
337 void *p
= item
->u
.side_vla_fixint
.p
;
338 enum side_type side_type
;
341 switch (item
->type
) {
342 case SIDE_TYPE_VLA_U8
:
343 if (elem_type
->type
!= SIDE_TYPE_U8
)
346 case SIDE_TYPE_VLA_U16
:
347 if (elem_type
->type
!= SIDE_TYPE_U16
)
350 case SIDE_TYPE_VLA_U32
:
351 if (elem_type
->type
!= SIDE_TYPE_U32
)
354 case SIDE_TYPE_VLA_U64
:
355 if (elem_type
->type
!= SIDE_TYPE_U64
)
358 case SIDE_TYPE_VLA_S8
:
359 if (elem_type
->type
!= SIDE_TYPE_S8
)
362 case SIDE_TYPE_VLA_S16
:
363 if (elem_type
->type
!= SIDE_TYPE_S16
)
366 case SIDE_TYPE_VLA_S32
:
367 if (elem_type
->type
!= SIDE_TYPE_S32
)
370 case SIDE_TYPE_VLA_S64
:
371 if (elem_type
->type
!= SIDE_TYPE_S64
)
377 side_type
= elem_type
->type
;
380 for (i
= 0; i
< side_sav_len
; i
++) {
381 struct side_arg_vec sav_elem
= {
387 sav_elem
.u
.side_u8
= ((const uint8_t *) p
)[i
];
390 sav_elem
.u
.side_s8
= ((const int8_t *) p
)[i
];
393 sav_elem
.u
.side_u16
= ((const uint16_t *) p
)[i
];
396 sav_elem
.u
.side_s16
= ((const int16_t *) p
)[i
];
399 sav_elem
.u
.side_u32
= ((const uint32_t *) p
)[i
];
402 sav_elem
.u
.side_s32
= ((const int32_t *) p
)[i
];
405 sav_elem
.u
.side_u64
= ((const uint64_t *) p
)[i
];
408 sav_elem
.u
.side_s64
= ((const int64_t *) p
)[i
];
412 printf("ERROR: Unexpected type\n");
416 printf("%s", i
? ", " : "");
417 tracer_print_type(elem_type
, &sav_elem
);
423 printf("ERROR: type mismatch\n");
428 void tracer_print_dynamic_struct(const struct side_arg_dynamic_event_struct
*dynamic_struct
)
430 const struct side_arg_dynamic_event_field
*fields
= dynamic_struct
->fields
;
431 uint32_t len
= dynamic_struct
->len
;
435 for (i
= 0; i
< len
; i
++) {
436 printf("%s", i
? ", " : "");
437 printf("%s:: ", fields
[i
].field_name
);
438 tracer_print_dynamic(&fields
[i
].elem
);
443 struct tracer_dynamic_struct_visitor_priv
{
448 enum side_visitor_status
tracer_dynamic_struct_write_elem_cb(
449 const struct side_tracer_dynamic_struct_visitor_ctx
*tracer_ctx
,
450 const struct side_arg_dynamic_event_field
*dynamic_field
)
452 struct tracer_dynamic_struct_visitor_priv
*tracer_priv
= tracer_ctx
->priv
;
454 printf("%s", tracer_priv
->i
++ ? ", " : "");
455 printf("%s:: ", dynamic_field
->field_name
);
456 tracer_print_dynamic(&dynamic_field
->elem
);
457 return SIDE_VISITOR_STATUS_OK
;
461 void tracer_print_dynamic_struct_visitor(const struct side_arg_dynamic_vec
*item
)
463 enum side_visitor_status status
;
464 struct tracer_dynamic_struct_visitor_priv tracer_priv
= {
467 const struct side_tracer_dynamic_struct_visitor_ctx tracer_ctx
= {
468 .write_field
= tracer_dynamic_struct_write_elem_cb
,
469 .priv
= &tracer_priv
,
471 void *app_ctx
= item
->u
.side_dynamic_struct_visitor
.app_ctx
;
474 status
= item
->u
.side_dynamic_struct_visitor
.visitor(&tracer_ctx
, app_ctx
);
476 case SIDE_VISITOR_STATUS_OK
:
478 case SIDE_VISITOR_STATUS_ERROR
:
479 printf("ERROR: Visitor error\n");
486 void tracer_print_dynamic_vla(const struct side_arg_dynamic_vec_vla
*vla
)
488 const struct side_arg_dynamic_vec
*sav
= vla
->sav
;
489 uint32_t side_sav_len
= vla
->len
;
493 for (i
= 0; i
< side_sav_len
; i
++) {
494 printf("%s", i
? ", " : "");
495 tracer_print_dynamic(&sav
[i
]);
500 struct tracer_dynamic_vla_visitor_priv
{
505 enum side_visitor_status
tracer_dynamic_vla_write_elem_cb(
506 const struct side_tracer_dynamic_vla_visitor_ctx
*tracer_ctx
,
507 const struct side_arg_dynamic_vec
*elem
)
509 struct tracer_dynamic_vla_visitor_priv
*tracer_priv
= tracer_ctx
->priv
;
511 printf("%s", tracer_priv
->i
++ ? ", " : "");
512 tracer_print_dynamic(elem
);
513 return SIDE_VISITOR_STATUS_OK
;
517 void tracer_print_dynamic_vla_visitor(const struct side_arg_dynamic_vec
*item
)
519 enum side_visitor_status status
;
520 struct tracer_dynamic_vla_visitor_priv tracer_priv
= {
523 const struct side_tracer_dynamic_vla_visitor_ctx tracer_ctx
= {
524 .write_elem
= tracer_dynamic_vla_write_elem_cb
,
525 .priv
= &tracer_priv
,
527 void *app_ctx
= item
->u
.side_dynamic_vla_visitor
.app_ctx
;
530 status
= item
->u
.side_dynamic_vla_visitor
.visitor(&tracer_ctx
, app_ctx
);
532 case SIDE_VISITOR_STATUS_OK
:
534 case SIDE_VISITOR_STATUS_ERROR
:
535 printf("ERROR: Visitor error\n");
542 void tracer_print_dynamic(const struct side_arg_dynamic_vec
*item
)
544 switch (item
->dynamic_type
) {
545 case SIDE_DYNAMIC_TYPE_NULL
:
546 printf("<NULL TYPE>");
548 case SIDE_DYNAMIC_TYPE_BOOL
:
549 printf("%s", item
->u
.side_bool
? "true" : "false");
551 case SIDE_DYNAMIC_TYPE_U8
:
552 printf("%" PRIu8
, item
->u
.side_u8
);
554 case SIDE_DYNAMIC_TYPE_U16
:
555 printf("%" PRIu16
, item
->u
.side_u16
);
557 case SIDE_DYNAMIC_TYPE_U32
:
558 printf("%" PRIu32
, item
->u
.side_u32
);
560 case SIDE_DYNAMIC_TYPE_U64
:
561 printf("%" PRIu64
, item
->u
.side_u64
);
563 case SIDE_DYNAMIC_TYPE_S8
:
564 printf("%" PRId8
, item
->u
.side_s8
);
566 case SIDE_DYNAMIC_TYPE_S16
:
567 printf("%" PRId16
, item
->u
.side_s16
);
569 case SIDE_DYNAMIC_TYPE_S32
:
570 printf("%" PRId32
, item
->u
.side_s32
);
572 case SIDE_DYNAMIC_TYPE_S64
:
573 printf("%" PRId64
, item
->u
.side_s64
);
575 case SIDE_DYNAMIC_TYPE_STRING
:
576 printf("\"%s\"", item
->u
.string
);
578 case SIDE_DYNAMIC_TYPE_STRUCT
:
579 tracer_print_dynamic_struct(item
->u
.side_dynamic_struct
);
581 case SIDE_DYNAMIC_TYPE_STRUCT_VISITOR
:
582 tracer_print_dynamic_struct_visitor(item
);
584 case SIDE_DYNAMIC_TYPE_VLA
:
585 tracer_print_dynamic_vla(item
->u
.side_dynamic_vla
);
587 case SIDE_DYNAMIC_TYPE_VLA_VISITOR
:
588 tracer_print_dynamic_vla_visitor(item
);
591 printf("<UNKNOWN TYPE>");
597 void tracer_print_static_fields(const struct side_event_description
*desc
,
598 const struct side_arg_vec_description
*sav_desc
,
601 const struct side_arg_vec
*sav
= sav_desc
->sav
;
602 uint32_t side_sav_len
= sav_desc
->len
;
605 printf("provider: %s, event: %s, ", desc
->provider_name
, desc
->event_name
);
606 if (desc
->nr_fields
!= side_sav_len
) {
607 printf("ERROR: number of fields mismatch between description and arguments\n");
610 for (i
= 0; i
< side_sav_len
; i
++) {
611 printf("%s", i
? ", " : "");
612 tracer_print_field(&desc
->fields
[i
], &sav
[i
]);
618 void tracer_call(const struct side_event_description
*desc
, const struct side_arg_vec_description
*sav_desc
)
620 if (side_unlikely(desc
->flags
& SIDE_EVENT_FLAG_VARIADIC
)) {
621 printf("ERROR: unexpected variadic event description\n");
624 tracer_print_static_fields(desc
, sav_desc
, NULL
);
628 void tracer_call_variadic(const struct side_event_description
*desc
,
629 const struct side_arg_vec_description
*sav_desc
,
630 const struct side_arg_dynamic_event_struct
*var_struct
)
632 uint32_t var_struct_len
= var_struct
->len
;
633 int nr_fields
= 0, i
;
635 tracer_print_static_fields(desc
, sav_desc
, &nr_fields
);
637 if (side_unlikely(!(desc
->flags
& SIDE_EVENT_FLAG_VARIADIC
))) {
638 printf("ERROR: unexpected non-variadic event description\n");
641 for (i
= 0; i
< var_struct_len
; i
++, nr_fields
++) {
642 printf("%s", nr_fields
? ", " : "");
643 printf("%s:: ", var_struct
->fields
[i
].field_name
);
644 tracer_print_dynamic(&var_struct
->fields
[i
].elem
);